Compare commits

...

179 Commits

Author SHA1 Message Date
Simon Frei
e2e5643c3c all: Fix versioning path handling (#7407) 2021-02-26 13:21:13 +01:00
Simon Frei
956d212e99 gui: Folder versioning editing cleanup (#7384) 2021-02-26 13:20:53 +01:00
tomasz1986
60c218efdb all: Fix Microsoft documentation links in code comments (#7387) 2021-02-22 18:27:41 +01:00
tomasz1986
8d290eb055 gui: Handle info labels that are longer than available space (fixes #944) (#7386)
Apply to table headers the same code as already used for table data.
This way, the headers will be either pushed to the next line, or cut
with an ellipsis if the single word is too long.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2021-02-22 18:27:41 +01:00
tomasz1986
cd17aa2cab gui: Show "Last seen" at the top when device is disconnected (ref #7166) (#7373)
Move the "Last seen" field to the very top in the device information.
This way, if a device has disconnected unexpectly, we can quickly check
the time when it was last available. Right now, due to the very long
address field, it is usually necessary to scroll down in order to view
the "Last seen" field.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2021-02-22 18:27:41 +01:00
tomasz1986
edaff81c0a gui: Remove cleanupIntervalS leftovers from External Versioning (ref #7360) (#7378) 2021-02-22 18:27:41 +01:00
tomasz1986
dd7d6188f2 gui: Allow setting custom path for all versioning except external (#7377) 2021-02-22 18:27:41 +01:00
Simon Frei
9be6f1a70e lib/fs: Consider options in case-fs caching (fixes #7371) (#7381) 2021-02-22 18:27:40 +01:00
Simon Frei
b0cce98648 lib/scanner: Pass on errors while hashing (#7380) 2021-02-22 18:27:40 +01:00
Simon Frei
e159f76ced build: Update pfilter (#7376) 2021-02-22 18:27:40 +01:00
tomasz1986
07d3af21c2 gui: Hide the Rescan All button when no folders exist (#7367)
If there are no folders present, show only the "Add Folder" button, and
hide the "Rescan All" button. Only show the latter when at least one
folder exists.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2021-02-22 18:27:40 +01:00
Jakob Borg
35316e9142 lib/connections: Allow QUIC with Go 1.16 (#7372) 2021-02-17 11:17:45 +01:00
tomasz1986
2a0775da03 gui: Hide non-functional Versions button when using External Versioning (#7365)
The button does nothing when the External Versioning is being used, so
it should not be displayed at all to avoid confusing the users.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2021-02-17 11:17:45 +01:00
Jakob Borg
8bd67f72dd gui, man, authors: Update docs, translations, and contributors 2021-02-17 11:17:45 +01:00
Simon Frei
82f190285a gui: Fix setting external versioning command (fixes #7361) (#7362) 2021-02-17 11:17:44 +01:00
Simon Frei
f5590c3345 lib/versioner: Improve error messages (fixes #7354) (#7357) 2021-02-17 11:17:44 +01:00
tomasz1986
9be07de7c6 gui: Disable Cleanup Interval with External File Versioning as unsupported (#7360)
As for right now, the External File Versioning does not support Cleanup
Interval. Therefore, the option should no be available at all when using
it.

Ref: https://forum.syncthing.net/t/16346

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2021-02-17 11:17:44 +01:00
Jakob Borg
802b933778 gui, man, authors: Update docs, translations, and contributors 2021-02-10 07:45:27 +01:00
Simon Frei
f1ec7fe55b gui: Check that connection exists on event (fixes #7347) (#7348) 2021-02-09 12:37:35 +01:00
Simon Frei
d842197931 lib/model: Disable tests involving scrypt with -short (fixes #7344) (#7346) 2021-02-08 17:13:28 +01:00
tomasz1986
4e7510dea9 build: Fix strings in versioninfo for Windows (fixes #7340) (#7342) 2021-02-08 15:48:05 +01:00
Simon Frei
c0f353c0e8 lib: Do not set ModifiedBy on meta only changes (#7345) 2021-02-08 15:30:39 +01:00
Simon Frei
e95d005c21 gui: Add defaults config to advanced menu (ref #7131) (#7343) 2021-02-08 12:59:02 +01:00
Simon Frei
11e9d575c8 lib/model: Refactor folder.scanSubdirs into smaller parts (#7321) 2021-02-08 08:40:57 +01:00
Simon Frei
46bbc78e82 lib/db: Fix and improve removing entries from global (ref #6501) (#7336) 2021-02-08 08:38:41 +01:00
Simon Frei
50a621bc7b gui: Apply #7339 to untrusted 2021-02-07 10:53:55 +01:00
Christian Prescott
d0c84916c7 gui: fix setDeviceConfig updating devices with undefined key (#7339) 2021-02-07 10:52:36 +01:00
Jakob Borg
6db8dc33f2 lib/model: Correctly verify short read blocks (fixes #7333) (#7334)
An untrusted device will receive padded info for small blocks, and hence
sometimes request a larger block than actually exists on disk.
Previously we let this pass because we didn't have a hash to compare to
in that case and we ignored the EOF error based on that.

Now the untrusted device does pass an encrypted hash that we decrypt and
verify. This means we can't check for len(hash)==0 any more, but on the
other hand we do have a valid hash we can apply to the data we actually
read. If it matches then we don't need to worry about the read
supposedly being a bit short.
2021-02-05 16:07:21 +01:00
Jakob Borg
194501c958 lib/api: Give the config changes some more time? (#7335) 2021-02-05 15:33:37 +01:00
Simon Frei
27a34609a1 all: Failure reporting fixes (#7331) 2021-02-05 11:21:14 +01:00
Simon Frei
ffc14a77c6 all: Add configurable defaults (fixes #4224, fixes #6086) (#7131) 2021-02-04 21:10:41 +01:00
greatroar
31119ed61a lib/ignore: Store cache timestamps as Unix ns counts (#7326) 2021-02-04 18:39:06 +01:00
Simon Frei
070bf3b776 lib/db: Report number of repaired items from checkGlobal (#7329) 2021-02-04 14:42:46 +01:00
Quentin Hibon
ade8d79d42 gui: Do not touch .stignore when not needed (fixes #7284) (#7325) 2021-02-03 20:58:24 +01:00
greatroar
42917d707d lib/scanner: Remove unused field, move WaitGroup.Add out of loop (#7323) 2021-02-03 14:25:24 +01:00
Jakob Borg
1522cf74bc gui, man, authors: Update docs, translations, and contributors 2021-02-03 07:45:28 +01:00
Jakob Borg
3b7a57d108 lib/protocol: Hide repeated data blocks in a given file (#7319) 2021-02-02 20:15:14 +01:00
Audrius Butkevicius
a7d9268e4d lib/model: Make /browse endpoint return sane objects (#7306) 2021-02-01 09:27:34 +01:00
Simon Frei
052dc13487 lib/model: Correct pull progress for small files (fixes #7263) (#7316) 2021-01-31 23:40:15 +01:00
Simon Frei
249bcb3a01 lib/model: Optimize rename detection in scanner (#7315) 2021-01-31 21:02:42 +01:00
greatroar
fbe52faf49 lib/scanner: Allocate structure for final partial block (#7310)
Benchmark results on Linux/amd64, using updated benchmark for old and
new:

name        old time/op    new time/op    delta
HashFile-8    88.6ms ± 1%    88.3ms ± 1%   -0.33%  (p=0.046 n=19+19)

name        old speed      new speed      delta
HashFile-8   201MB/s ± 1%   202MB/s ± 1%   +0.33%  (p=0.044 n=19+19)

name        old alloc/op   new alloc/op   delta
HashFile-8    59.4kB ± 0%    46.1kB ± 0%  -22.47%  (p=0.000 n=14+20)

name        old allocs/op  new allocs/op  delta
HashFile-8      29.0 ± 0%      27.0 ± 0%   -6.90%  (p=0.000 n=20+20)

Co-authored-by: greatroar <@>
2021-01-28 14:23:24 +01:00
greatroar
8b86171642 lib/stun: Inline util.OnDone, comment on its purpose (#7308)
Co-authored-by: greatroar <@>
2021-01-27 19:27:00 +01:00
Simon Frei
e19d6e993d lib/fs: Cache all real-case results (fixes #7270) (#7286) 2021-01-27 19:25:34 +01:00
greatroar
ef0473c091 lib/util, lib/svcutil: Remove unused code (#7309)
Duplicates the definition in lib/svcutil.

Co-authored-by: greatroar <@>
2021-01-27 16:33:01 +01:00
Tomasz Wilczyński
3406a3ba95 gui: Reduce checkboxes size in Advanced Configuration (fixes #6949) (#7296) 2021-01-27 12:23:58 +01:00
Jakob Borg
7c1ed420a9 gui, man, authors: Update docs, translations, and contributors 2021-01-27 07:45:21 +01:00
André Colomb
d7e86af6c6 gui/untrusted: Mirror changes from #7205 and #7192 (#7302) 2021-01-25 20:19:55 +01:00
Tomasz Wilczyński
76cf326290 gui: Make label and input IDs in Advanced Configuration unique (fixes #7287) (#7290) 2021-01-25 19:54:42 +01:00
greatroar
6c3e187d1d lib/svcutil: Simplify doneService (#7303)
OnSupervisorDone no longer allocates.

Co-authored-by: greatroar <@>
2021-01-25 16:27:17 +01:00
André Colomb
e32a516b5f lib/model: Forget pending folders no longer announced in ClusterConfig (fixes #5187) (#7205)
* lib/db: Add ExpirePendingFolders().

Use-case is to drop any no-longer-pending folders for a specific
device when parsing its ClusterConfig message where previously offered
folders are not mentioned any more.

The timestamp in ObservedFolder is stored with only second precision,
so round to seconds here as well.  This allows calling the function
within the same second of adding or updating entries.

* lib/model: Weed out pending folders when receiving ClusterConfig.

Filter the entries by timestamp, which must be newer than or equal to
the reception time of the ClusterConfig.  For just mentioned ones,
this assumption will hold as AddOrUpdatePendingFolder() updates the
timestamp.

* lib/model, gui: Notify when one or more pending folders expired.

Introduce new event type FolderOfferCancelled and use it to trigger a
complete refreshCluster() cycle.  Listing individual entries would be
much more code and probably just as much work to answer the API
request.

* lib/model: Add comment and rename ExpirePendingFolders().

* lib/events: Rename FolderOfferCancelled to ClusterPendingChanged.

* lib/model: Reuse ClusterPendingChanged event for cleanPending()

Changing the config does not necessarily mean that the
/resut/cluster/pending endpoints need to be refreshed, but only if
something was actually removed.  Detect this and indicate it through
the ClusterPendingChanged event, which is already hooked up to requery
respective endpoints within the GUI.

No more need for a separate refreshCluster() in reaction to
ConfigSaved event or calling refreshConfig().

* lib/model: Gofmt.

* lib/db: Warn instead of info log for failed removal.

* gui: Fix pending notifications not loading on GUI start.

* lib/db: Use short device ID in log message.

* lib/db: Return list of expired folder IDs after deleting them.

* lib/model: Refactor Pending...Changed events.

* lib/model: Adjust format of removed pending folders enumeration.

Use an array of objects with device / folder ID properties, matching
the other places where it's used.

* lib/db: Drop invalid entries in RemovePendingFoldersBeforeTime().

* lib/model: Gofmt.

My local gofmt did not complain here, strangely...

* gui: Handle PendingDevicesChanged event.

Even though it currently only holds one device at a time, wrap the
contents in an array under the "added" property name.

* lib/model: Fix null values in PendingFoldersChanged removed member.

* gui: Handle PendingFoldersChanged event.

* lib/model: Simplify construction of expiredPendingList.

* lib/model: Reduce code duplication in cleanPending().

Use goto and a label for the common parts of calling the DB removal
function and building the event data part.

* lib/events, gui: Mark ...Rejected events deprecated.

Extend comments explaining the conditions when the replacement event
types are emitted.

* lib/model: Wrap removed devices in array of objects as well.

* lib/db: Use iter.Value() instead of needless db.Get(iter.Key())

* lib/db: Add comment explaining RemovePendingFoldersBeforeTime().

* lib/model: Rename fields folderID and deviceID in event data.

* lib/db: Only list actually expired IDs as removed.

Skip entries where Delete() failed as well as invalid entries that got
removed automatically.

* lib/model: Gofmt
2021-01-25 10:58:10 +00:00
greatroar
6da83ac9f5 lib/util: Remove duplicate error handling code (#7299)
This is also in lib/svcutil, and never used by clients.

Co-authored-by: greatroar <@>
2021-01-24 20:19:10 +01:00
Jakob Borg
adc07eddf6 gui, man, authors: Update docs, translations, and contributors 2021-01-20 07:45:29 +01:00
greatroar
9c88efd55f lib/util: Don't modify input in UniqueTrimmedStrings (#7288)
Also clarified the comment.
2021-01-16 17:39:15 +01:00
Jakob Borg
ffcb57580f cmd/syncthing: Provide early startup for config service (ref #7188) (#7285) 2021-01-16 12:58:02 +01:00
Quentin Hibon
abfbd13f17 gui: Allow device removal even if possibly reintroduced (fixes #5426) (#7216) 2021-01-15 20:46:04 +01:00
Simon Frei
f63cdbfcfa lib: Apply config changes sequentially (ref #5298) (#7188) 2021-01-15 15:43:34 +01:00
Simon Frei
b2d82da20d lib/model: Pull when folder leaves error state (fixes #7280) (#7281) 2021-01-14 13:29:01 +01:00
Choongkyu
70fddb6523 gui: Disable "Rescan All" when all folders are paused (fixes #7257) (#7278) 2021-01-14 09:15:47 +01:00
Choongkyu
83cfd308b4 gui: Fix log-tailing behavior when scrolled to top (fixes #7267) (#7272) 2021-01-13 20:08:39 +01:00
Jakob Borg
36acaf5e21 lib/fs: Avoid blocking new caseFs creation while waiting to drop cache (fixes #7273) (#7275) 2021-01-13 17:45:29 +01:00
Jakob Borg
572ccfe3e2 gui, man, authors: Update docs, translations, and contributors 2021-01-13 07:45:46 +01:00
Jakob Borg
253049a4cc lib/api, lib/model: Avoid contention on filesystem for DB status call (ref #7270) (#7271)
This splits the ignore getting to two methods, one that loads from disk
(the old one) and one that just returns whatever is already loaded (the
new one). The folder summary service which is just interested in stats
now uses the latter method. This means that it, and API calls that call
it, does not get blocked by folder I/O.
2021-01-12 16:25:21 +01:00
Jakob Borg
8f199e12b3 lib/fs, lib/model: Reduce lock contention on NewCaseFilesystem (fixes #7268) (#7269) 2021-01-12 16:22:21 +01:00
greatroar
f6fac3e949 lib/ur: Plug file descriptor leak in Linux memorySize (#7266) 2021-01-11 15:15:21 +01:00
Jakob Borg
0b193b76c2 lib/config, lib/connections: Add optional connection limits (fixes #7176) (#7223)
This adds two new configuration options:

    // The number of connections at which we stop trying to connect to more
    // devices, zero meaning no limit. Does not affect incoming connections.
    ConnectionLimitEnough int

    // The maximum number of connections which we will allow in total, zero
    // meaning no limit. Affects incoming connections and prevents
    // attempting outgoing connections.
    ConnectionLimitMax int

These can be used to limit the number of concurrent connections in
various ways.
2021-01-11 15:14:44 +01:00
Jakob Borg
e6f0ed65be gui, man, authors: Update docs, translations, and contributors 2021-01-06 07:45:28 +01:00
Jakob Borg
b13b15758d lib/connections, lib/model: Track last connection duration (ref #7223) (#7242)
This adds a statistic to track the last connection duration per device.
It isn't used for much in this PR, but it's available for #7223 to use
in deciding how to order device connection attempts (deprioritizing
devices that just dropped our connection the last time).
2021-01-05 17:45:07 +01:00
Simon Frei
c48eb4241a lib/model: Fix child-check when deleting dirs in pull (#7236) 2021-01-02 21:40:37 +01:00
Simon Frei
0f8290485e lib/model: Handle index sender terminating due to error (fixes #7231) (#7232) 2020-12-30 09:59:11 +01:00
André Colomb
3d1edd2492 lib/fs: Fix TestChmodDir depending on umask (fixes #6551) (#7241)
The test would fail if the umask on UNIX is greater than 0022, because
the OS transparently subtracts it from the mode passed to Mkdir(), as
the Go documentation confirms.

Our goal here is not to test os.Mkdir(), so just make sure the desired
mode is actually set by forcing it afterwards.
2020-12-30 09:56:10 +01:00
Jakob Borg
a73db6fd84 gui, man, authors: Update docs, translations, and contributors 2020-12-30 07:45:26 +01:00
Simon Frei
a05dc6cc47 lib/model: Cleanup redundant filesystem variables in folders (#7237) 2020-12-27 22:26:25 +01:00
Simon Frei
5440d1dc3b gui: Do not replace zero versioning cleanup interval (#7234) 2020-12-27 10:08:15 +01:00
Simon Frei
f13e6ca631 lib/model: Remove obsolete return val from ccHandleFolders (ref #6443) (#7229) 2020-12-23 13:10:08 +01:00
Jakob Borg
81553b4da7 gui, man, authors: Update docs, translations, and contributors 2020-12-23 07:45:28 +01:00
André Colomb
07618f8674 gui: Fix missing sharing device when adding pending folder (#7227) 2020-12-22 22:37:29 +01:00
André Colomb
1555a4da7f cmd/stevents: Add command line argument for event type filtering. (#7226)
Add a -types flag which can be set to a comma-separated list of event
types.  The contents will be included verbatim in the URL parameter
"events".
2020-12-22 22:10:26 +01:00
Simon Frei
a20a5f61f0 lib/ur: Send unreported failures on shutdown (#7164) 2020-12-22 20:17:14 +01:00
André Colomb
4bcc38cf63 gui: Fix nonfunctional ignore button on pending folder notification (#7224)
The merge of #6443 apparently introduced a wrong argument name in
$scope.ignoreFolder().
2020-12-22 07:28:10 +01:00
Jakob Borg
05f25e600e lib/connections: Refactor connection loop (#7177)
This breaks out some methods from the connection loop to make it simpler
to manage and understand.

Some slight simplifications to remove the `seen` variable (we can filter
`nextDial` based on times are in the future or not, so we don't need to
track `seen`) and adding a minimum loop interval (5s) in case some
dialer goes haywire and requests a 0s redial interval or such.

Otherwise no significant behavioral changes.
2020-12-21 16:40:13 +01:00
Simon Frei
a744dee94c lib/fs: Correct wrapping order for meaningful log-caller (#7209) 2020-12-21 13:01:34 +01:00
Simon Frei
78bd0341a8 all: Handle errors opening db/creating file-set (ref #5907) (#7150) 2020-12-21 12:59:22 +01:00
Roberto Santalla
b5de49917c cmd/relaypoolsrv: Allow validation of relay join requests by certificate (fixes #7196) (#7217) 2020-12-21 11:55:16 +01:00
Simon Frei
c845e245a1 lib: Close underlying conn in protocol (fixes #7165) (#7212) 2020-12-21 11:40:51 +01:00
Simon Frei
4a787986cd lib/db: Prevent IndexID creation race (#7211) 2020-12-21 11:32:59 +01:00
Simon Frei
78a41828fc gui: Reflect change in untrusted in sharing tab (#7201) 2020-12-21 11:11:44 +01:00
Simon Frei
bd0c9913cf lib/db: Remove index ids when dropping folder (#7200) 2020-12-21 11:10:59 +01:00
Simon Frei
d904dfa191 lib/model: Fix flaky test and add some scanning debug (#7214) 2020-12-20 18:13:35 +01:00
Simon Frei
fa40ccece1 lib: Consistently set suture logging (#7202) 2020-12-18 19:44:00 +01:00
Simon Frei
7919310dc6 lib/model: Unflake TestIgnoreDeleteUnignore (#7208) 2020-12-18 18:42:09 +01:00
Simon Frei
7669af578a gui: Apply changes to untrusted (ref #6443) (#7206) 2020-12-17 23:13:28 +01:00
Simon Frei
739e99c4d9 lib/config: Remove deprecated pending entries from config (ref #6443) (#7204) 2020-12-17 22:49:29 +01:00
André Colomb
7502997e7e all: Store pending devices and folders in database (fixes #7178) (#6443) 2020-12-17 19:54:31 +01:00
Jakob Borg
4470cd5aaa gui, man, authors: Update docs, translations, and contributors 2020-12-16 07:45:23 +01:00
André Colomb
466e8a5cd0 gui: Sort folders and devices in advanced config modal (#7192) 2020-12-14 16:45:38 +01:00
Jakob Borg
4142a431b5 model: Actually print folder description in "Overriding" log message 2020-12-12 12:32:24 +01:00
Jakob Borg
5565afdd9f gui: version.tags is an array, which is truthy when empty 2020-12-12 10:34:26 +01:00
Simon Frei
0db3b7a530 build: Switch to gopsutil's v3 module (#7191) 2020-12-10 16:43:15 +01:00
Simon Frei
b37ecc3cf4 build: Update notify (fixes #7076) (#7189) 2020-12-10 15:43:05 +01:00
Jakob Borg
ec5a5d5218 lib/api: Returns tags in version as list (#7190) 2020-12-10 12:22:09 +01:00
Jakob Borg
7980c8cea2 gui: Harmonize architecture names 2020-12-10 11:23:47 +01:00
Jakob Borg
e9b68a224c lib/connections: Handle QUIC not being available (#7186)
This does two things:

- Exclude QUIC from go1.16 builds, automatically, for now, since it
  doesn't work and just panics.

- Provide some fake listeners and dialers when QUIC is disabled.

These fake listeners and dialers indicate that they are disabled and
unsupported, which silences "Dialing $address: unknown address scheme:
quic" type of stuff which is not super helpful to the user.
2020-12-09 19:23:50 +01:00
Simon Frei
8fd6b1d428 lib/protocol: Handle slashified paths in IsEncryptedParent (fixes #7184) (#7187) 2020-12-09 18:16:14 +01:00
André Colomb
4198b5061f gui: Split folders into two categories on the sharing tab for devices (#7162) 2020-12-09 14:54:51 +01:00
Jakob Borg
b0a525a504 gui, man, authors: Update docs, translations, and contributors 2020-12-09 07:45:25 +01:00
Eric Lesiuta
25d904dc37 gui: Fix blank device name under "Recent Changes" (#7185)
fixes the device showing up as blank if the friendly name is known
2020-12-07 22:19:28 +01:00
Simon Frei
c1b452df93 build: Upgrade quic-go to v0.19.3 (ref #7146) (#7180) 2020-12-06 13:46:27 +01:00
Jakob Borg
28bc8b6153 gui, man, authors: Update docs, translations, and contributors 2020-12-02 07:45:24 +01:00
Simon Frei
cccbb0bd5e lib/ur: Reset timer when there's nothing to report (#7169) 2020-11-28 20:09:22 +01:00
Simon Frei
240ae0c14f lib/model: Unflake TestRequestReceiveEncryptedLocalNoSend (#7167) 2020-11-27 20:53:03 +01:00
Jakob Borg
9a9b7002cd Merge branch 'release' into main
* release:
  gui: Restore Select / Deselect All buttons in device sharing tab. (#7161)
2020-11-27 16:41:16 +01:00
André Colomb
b16cc72fc7 gui: Restore Select / Deselect All buttons in device sharing tab. (#7161)
This fixes a regression by restoring two functions removed in commit
a20d85d451, but still used from the HTML
template.  Adjust the restored versions to access the new flag storage
structure.

The replacement functions selectAllSharedFolders() and
selectAllUnrelatedFolders() are not functional, so this is just a
quick fix to restore a working state before making the new functions
actually work sensibly.

Just like the respective functions for sharing device selections, give
it a boolean argument instead of writing two almost identical
functions.

In line with the other selectAll...() functions, avoid calling
angular.forEach() and iterate over the folders object directly.
2020-11-27 14:33:58 +01:00
André Colomb
ab53687c38 gui: Restore Select / Deselect All buttons in device sharing tab. (#7161)
This fixes a regression by restoring two functions removed in commit
a20d85d451, but still used from the HTML
template.  Adjust the restored versions to access the new flag storage
structure.

The replacement functions selectAllSharedFolders() and
selectAllUnrelatedFolders() are not functional, so this is just a
quick fix to restore a working state before making the new functions
actually work sensibly.

Just like the respective functions for sharing device selections, give
it a boolean argument instead of writing two almost identical
functions.

In line with the other selectAll...() functions, avoid calling
angular.forEach() and iterate over the folders object directly.
2020-11-27 11:48:48 +01:00
Simon Frei
bbb22c8c80 lib/protocol: Send Close message on read error (#7141) 2020-11-27 11:31:20 +01:00
Simon Frei
a9764fc16c lib: Skip deleted, locally changed on recv-enc folders (fixes #7153) (#7154) 2020-11-27 11:26:36 +01:00
Audrius Butkevicius
af13f0cd35 lib/stun: Don't notify about address changes if it's not useful (fixes #7144) (#7159) 2020-11-27 07:34:30 +01:00
Simon Frei
e1b958284e lib/api: Shut the api down gracefully (fixes #7138) (#7157) 2020-11-26 15:49:39 +01:00
Simon Frei
bf7d03d029 lib/model: Fix enc file size when pulling (fixes #7152) (#7155) 2020-11-25 22:57:25 +01:00
Simon Frei
3169212046 lib/db: Do not reset index-id when dropping device (ref #7135) (#7156)
This reverts commit 641b7aee38.
2020-11-25 22:54:05 +01:00
Simon Frei
54b50e3d52 lib/fs, lib/model: Cover more windowsyness sanitizing paths (fixes #7075) (#7158) 2020-11-25 22:52:46 +01:00
Jakob Borg
c6f2ec9400 gui, man, authors: Update docs, translations, and contributors 2020-11-25 07:45:27 +01:00
André Colomb
e6595c1ab9 lib/model: Simplify access to Folder and Device configuration. (#7151)
Use the accessor methods with a device argument instead of looking up
in a temporary map of the same data.
2020-11-24 22:20:50 +01:00
Simon Frei
6c7e8c08db build: Ignore noscript in translation-script (#7149) 2020-11-24 22:17:52 +01:00
Jakob Borg
6864f7c9d0 gui: Remove probing for remote GUI address (ref #7017) (#7136) 2020-11-24 22:07:22 +01:00
Simon Frei
e5c1948b94 gui: Fix & improve sharing with untrusted device (#7148) 2020-11-24 22:02:16 +01:00
Simon Frei
100ef10d84 lib/model: Don't send locally changed on recv-enc (fixes #7137) (#7147) 2020-11-24 21:49:45 +01:00
Simon Frei
5d2c83a7e9 lib/protocol: Fix OOR panic on recv-only folders (#7143) 2020-11-23 18:37:27 +01:00
Simon Frei
8e5c844370 gui: Incorrect recv-enc folder status after revert (#7142) 2020-11-23 18:35:36 +01:00
Simon Frei
8ebd893349 lib/db: Store versions for last successful db migration (#7140) 2020-11-23 18:31:32 +01:00
dependabot-preview[bot]
cc4071d0ba build(deps): bump github.com/lucas-clemente/quic-go (#7139)
Bumps [github.com/lucas-clemente/quic-go](https://github.com/lucas-clemente/quic-go) from 0.18.1 to 0.19.2.
- [Release notes](https://github.com/lucas-clemente/quic-go/releases)
- [Changelog](https://github.com/lucas-clemente/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/lucas-clemente/quic-go/compare/v0.18.1...v0.19.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-23 09:04:58 +01:00
Jakob Borg
b253022a96 build: Take extra tags in account for tar, zip 2020-11-20 17:45:07 +01:00
Simon Frei
db1f20603a lib/model: Retain index info for new folders/devs (ref #7100) (#7133) 2020-11-20 15:53:13 +01:00
Simon Frei
24af89c8e2 all: Refactor preparing configuration (#7127) 2020-11-20 14:21:54 +01:00
Simon Frei
641b7aee38 lib/db: Reset index-id when dropping device (#7135) 2020-11-20 14:17:09 +01:00
Simon Frei
b43eccf2fe lib/model: Never send unpaused folder without index info (#7134) 2020-11-20 14:13:50 +01:00
Jakob Borg
7f63afcb99 Merge branch 'release' into main
* release:
  gui: Remove erronous $ from scope in directive (fixes #7124) (#7125)
2020-11-18 14:27:00 +01:00
Simon Frei
dcddd9c1e4 gui: Remove erronous $ from scope in directive (fixes #7124) (#7125) 2020-11-18 14:22:38 +01:00
Simon Frei
e11b309379 lib/model, lib/util: Replace IsComplete with NoRestartErr (ref #6947) (#7126) 2020-11-18 13:43:57 +01:00
Simon Frei
53fd54e308 gui: Remove erronous $ from scope in directive (fixes #7124) (#7125) 2020-11-18 13:33:19 +01:00
Simon Frei
2d3a535ced lib/model: Handle cluster-config before folder start (fixes #7122) (#7123) 2020-11-17 15:30:21 +01:00
Simon Frei
9524b51708 all: Implement suture v4-api (#6947) 2020-11-17 13:19:04 +01:00
Simon Frei
e8fc465ea8 lib/config: Use correct var in MaxConcurrentIncomingRequestKiB() (#7121) 2020-11-16 16:51:51 +01:00
Phani Rithvij
1491898fd4 build: Update delve issue link (#7119) 2020-11-16 09:54:31 +01:00
Jakob Borg
cca73de6a1 lib/osutil: Consider sync() best effort (fixes #7117) 2020-11-14 09:23:27 +01:00
Jakob Borg
5e669e0ae1 Merge branch 'release' into main
* release:
  gui: Initialise sharing when accepting new device (fixes #7113) (#7114)
2020-11-11 18:19:44 +01:00
Simon Frei
35c813f56f gui: Initialise sharing when accepting new device (fixes #7113) (#7114) 2020-11-11 18:18:52 +01:00
Simon Frei
1f81940a1f gui: Initialise sharing when accepting new device (fixes #7113) (#7114) 2020-11-11 18:18:34 +01:00
Simon Frei
b8051fb37e lib/model: Prevent test deadlock (#7110) 2020-11-10 12:32:07 +01:00
Simon Frei
1d3b9876f6 lib/api, lib/db: Add file debug endpoint (#7095) 2020-11-10 09:24:45 +01:00
Rahmi Pruitt
2f6a25a56f gui: Add advance config port mapping to gui (fixes #4824) (#7017) 2020-11-10 09:24:11 +01:00
Jakob Borg
846b265430 lib/tlsutil: Add O and OU to generated certificates (fixes #7108) (#7109) 2020-11-09 17:02:56 +01:00
Simon Frei
31559e908b all: Add untrusted folders behind feature flag (ref #62) (#7055) 2020-11-09 15:33:32 +01:00
Simon Frei
4db5ea5893 build: Update notify (fixes #5360) (#7106) 2020-11-09 14:25:19 +01:00
Simon Frei
54643e86b5 lib/model: Fix locking when resending cluster-configs (#7107) 2020-11-09 14:05:21 +01:00
Jakob Borg
326111d10f gui: Remove superfluous translate in previous (ref #7102) 2020-11-09 09:46:45 +01:00
Tomasz Wilczyński
0fb7cc186c gui: Add warning when JavaScript is disabled in Web browser (fixes #7099) (#7102)
When using a Web browser with JavaScript either disabled or unavailable,
show a warning to let the user know that the Web GUI requires JS in
order to operate.

To achieve this, add a <div> that wraps both the navbar and the main
content, and then move the CSS class ng-cloak from the <html> element to
that <div>. This way, only the JavaScript-dependent part is hidden when
JS is unavailable, and not the whole website, as it is the case right
now. Then, add a <noscript> element right at the start of the <body>
element, so that the warning is also shown right away in text-based Web
browsers. The <noscript> element includes a stripped down version of the
navbar showing only the Syncthing logo, and then a container with the
warning itself. Lastly, leave the footer untouched and always visible,
because it does not rely on JavaScript at all.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2020-11-09 09:15:22 +01:00
Simon Frei
1f1729ba43 lib/model: Add done chan to track folder-lifetime (fixes #6664) (#7094) 2020-11-09 09:05:48 +01:00
Simon Frei
d4ce0dfd84 lib/model: Send indexes for newly shared folder (fixes #7098) (#7100) 2020-11-09 08:58:46 +01:00
Simon Frei
cc9ea9db89 lib/folder: Clear pull errors when nothing is needed anymore (#7093) 2020-11-06 14:22:20 +01:00
Simon Frei
a08a1b6998 lib/api: Fix debug endpoints (ref #7001) (#7092) 2020-11-06 14:21:37 +01:00
Jakob Borg
33185fdeb5 gui, man, authors: Update docs, translations, and contributors 2020-11-04 07:45:27 +01:00
Simon Frei
d0ccea0404 lib/config: Sanity checks on MaxConcurrentWrites (ref #7064) (#7069) 2020-11-03 19:09:32 +01:00
Jakob Borg
c206fbdc58 Merge branch 'release' into main
* release:
  lib/ur: Fix panics in failure-reporting (fixes #7090) (#7091)
2020-11-03 12:34:23 +01:00
Simon Frei
2b9cef3ae5 lib/ur: Fix panics in failure-reporting (fixes #7090) (#7091) 2020-11-03 12:29:54 +01:00
Simon Frei
a38b370c8d lib/ur: Fix panics in failure-reporting (fixes #7090) (#7091) 2020-11-03 12:29:33 +01:00
Jakob Borg
942b8ebb27 build: Update dependencies (#7088) 2020-11-03 09:11:00 +01:00
Jakob Borg
7892547873 lib: Remove USE_BADGER experiment (#7089)
This removes the switch for using a Badger database, because it has bugs
that it seems there is no interest in fixing, and no actual bug tracker
to track them in.

It retains the actual implementation for the sole purpose of being able
to do the conversion back to LevelDB if anyone is actually running with
USE_BADGER. At some point in a couple of versions we can remove the
implementation as well.
2020-11-03 09:10:35 +01:00
Simon Frei
5b9280c50f build: Update notify (fixes #7063) (#7080) 2020-11-01 21:37:31 +01:00
Simon Frei
4d1bcd718c lib/api: Fix /rest/config path and add methods to cors (ref #7001) (#7081) 2020-11-01 21:36:54 +01:00
André Colomb
7dc0c6ab43 lib/api: Allow OPTIONS method in CORS preflight request handling (ref #7017) (#7079)
This allows for checking GUI / API availability without actually doing
a GET or POST request.
2020-11-01 14:29:55 +01:00
André Colomb
9d1ee2f7e0 gui: Fix another undefined variable access (fixes #7077) (#7078) 2020-11-01 13:15:20 +01:00
Tomasz Wilczyński
4a616f3cb2 lib/config: Check for "msdos" when detecting FAT FS in Android (#7072) 2020-10-30 15:13:56 +01:00
Jakob Borg
deafe4ca53 gui, man, authors: Update docs, translations, and contributors 2020-10-28 07:45:27 +01:00
Simon Frei
bc012d750d gui: Readd check if device exists (ref #7059) (#7061)
This reverts commit c7d40ccbae.
2020-10-27 16:40:16 +01:00
André Colomb
c7d40ccbae gui: Remove needless looping in ignoreFolder() (#7059) 2020-10-26 11:27:03 +01:00
André Colomb
0d90ae26ac gui: Fix undefined variables fallout from #7049 (#7056) 2020-10-26 09:09:32 +01:00
Simon Frei
9189c79d74 lib/api: Add missing config mod. locks (ref #7001) (#7053) 2020-10-23 10:34:20 +02:00
Simon Frei
a20d85d451 gui: Refactor to make encryption diff smaller (#7049) 2020-10-23 08:27:02 +02:00
Simon Frei
f0f60ba2e7 lib/api: Add /rest/config endpoint (fixes #6540) (#7001) 2020-10-22 19:54:35 +02:00
260 changed files with 19399 additions and 6760 deletions

View File

@@ -61,9 +61,11 @@ Carsten Hagemann (carstenhag) <moter8@gmail.com> <carsten@chagemann.de>
Cathryne Linenweaver (Cathryne) <cathryne.linenweaver@gmail.com> <Cathryne@users.noreply.github.com> <katrinleinweber@MAC.local>
Cedric Staniewski (xduugu) <cedric@gmx.ca>
chenrui <rui@meetup.com>
Choongkyu <choongkyu.kim+gh@gmail.com> <vapidlyrapid+gh@gmail.com>
Chris Howie (cdhowie) <me@chrishowie.com>
Chris Joel (cdata) <chris@scriptolo.gy>
Chris Tonkinson <chris@masterbran.ch>
Christian Prescott <me@christianprescott.com>
chucic <chucic@seznam.cz>
Colin Kennedy (moshen) <moshen.colin@gmail.com>
Cromefire_ <tim.l@nghorst.net> <26320625+cromefire@users.noreply.github.com>
@@ -87,6 +89,7 @@ Dominik Heidler (asdil12) <dominik@heidler.eu>
Elias Jarlebring (jarlebring) <jarlebring@gmail.com>
Elliot Huffman <thelich2@gmail.com>
Emil Hessman (ceh) <emil@hessman.se>
Eric Lesiuta <elesiuta@gmail.com>
Erik Meitner (WSGCSysadmin) <e.meitner@willystreet.coop>
Evgeny Kuznetsov <evgeny@kuznetsov.md>
Federico Castagnini (facastagnini) <federico.castagnini@gmail.com>
@@ -125,6 +128,7 @@ Jaya Chithra (jayachithra) <s.k.jayachithra@gmail.com>
jelle van der Waa <jelle@vdwaa.nl>
Jens Diemer (jedie) <github.com@jensdiemer.de> <git@jensdiemer.de>
Jerry Jacobs (xor-gate) <jerry.jacobs@xor-gate.org> <xor-gate@users.noreply.github.com>
Jesse Lucas <jesse@jesselucas.com>
Jochen Voss (seehuhn) <voss@seehuhn.de>
Johan Andersson <j@i19.se>
Johan Vromans (sciurius) <jvromans@squirrel.nl>
@@ -204,15 +208,18 @@ Peter Badida <KeyWeeUsr@users.noreply.github.com>
Peter Dave Hello <hsu@peterdavehello.org>
Peter Hoeg (peterhoeg) <peter@speartail.com>
Peter Marquardt (wwwutz) <wwwutz@gmail.com> <wwwutz@googlemail.com>
Phani Rithvij <phanirithvij2000@gmail.com>
Phil Davis <phil.davis@inf.org>
Philippe Schommers (filoozoom) <philippe@schommers.be>
Phill Luby (pluby) <phill.luby@newredo.com>
Pier Paolo Ramon <ramonpierre@gmail.com>
Piotr Bejda (piobpl) <piotrb10@gmail.com>
Pramodh KP (pramodhkp) <pramodh.p@directi.com> <1507241+pramodhkp@users.noreply.github.com>
Quentin Hibon <qh.public@yahoo.com>
Rahmi Pruitt <rjpruitt16@gmail.com>
Richard Hartmann <RichiH@users.noreply.github.com>
Robert Carosi (nov1n) <robert@carosi.nl>
Roberto Santalla <roobre@users.noreply.github.com>
Robin Schoonover <robin@cornhooves.org>
Roman Zaynetdinov (zaynetro) <romanznet@gmail.com>
Ross Smith II (rasa) <ross@smithii.com>

View File

@@ -278,22 +278,18 @@ func main() {
}
func runCommand(cmd string, target target) {
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
}
tags = append(tags, strings.Fields(extraTags)...)
switch cmd {
case "install":
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
}
tags = append(tags, strings.Fields(extraTags)...)
install(target, tags)
metalintShort()
case "build":
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
}
tags = append(tags, strings.Fields(extraTags)...)
build(target, tags)
case "test":
@@ -321,10 +317,10 @@ func runCommand(cmd string, target target) {
transifex()
case "tar":
buildTar(target)
buildTar(target, tags)
case "zip":
buildZip(target)
buildZip(target, tags)
case "deb":
buildDeb(target)
@@ -532,21 +528,22 @@ func appendParameters(args []string, tags []string, pkgs ...string) []string {
// -gcflags to disable optimizations and inlining. Skip -ldflags
// because `Could not launch program: decoding dwarf section info at
// offset 0x0: too short` on 'dlv exec ...' see
// https://github.com/derekparker/delve/issues/79
// https://github.com/go-delve/delve/issues/79
args = append(args, "-gcflags", "-N -l")
}
return append(args, pkgs...)
}
func buildTar(target target) {
func buildTar(target target, tags []string) {
name := archiveName(target)
filename := name + ".tar.gz"
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
name += "-noupgrade"
for _, tag := range tags {
if tag == "noupgrade" {
name += "-noupgrade"
break
}
}
build(target, tags)
@@ -562,14 +559,15 @@ func buildTar(target target) {
fmt.Println(filename)
}
func buildZip(target target) {
func buildZip(target target, tags []string) {
name := archiveName(target)
filename := name + ".zip"
var tags []string
if noupgrade {
tags = []string{"noupgrade"}
name += "-noupgrade"
for _, tag := range tags {
if tag == "noupgrade" {
name += "-noupgrade"
break
}
}
build(target, tags)
@@ -668,11 +666,14 @@ func shouldBuildSyso(dir string) (string, error) {
},
},
"StringFileInfo": M{
"FileDescription": "Open Source Continuous File Synchronization",
"LegalCopyright": "The Syncthing Authors",
"FileVersion": version,
"ProductVersion": version,
"ProductName": "Syncthing",
"CompanyName": "The Syncthing Authors",
"FileDescription": "Syncthing - Open Source Continuous File Synchronization",
"FileVersion": version,
"InternalName": "syncthing",
"LegalCopyright": "The Syncthing Authors",
"OriginalFilename": "syncthing",
"ProductName": "Syncthing",
"ProductVersion": version,
},
"IconPath": "assets/logo.ico",
})

View File

@@ -47,7 +47,7 @@ func main() {
mux.Handle("/", cr)
if *dsn != "" {
mux.HandleFunc("/failure", handleFailureFn(*dsn))
mux.HandleFunc("/newcrash/failure", handleFailureFn(*dsn))
}
log.SetOutput(os.Stdout)
@@ -74,6 +74,7 @@ func handleFailureFn(dsn string) func(w http.ResponseWriter, req *http.Request)
}
if len(reports) == 0 {
// Shouldn't happen
log.Printf("Got zero failure reports")
return
}
@@ -91,7 +92,9 @@ func handleFailureFn(dsn string) func(w http.ResponseWriter, req *http.Request)
pkt.Fingerprint = []string{r.Description}
if err := sendReport(dsn, pkt, userIDFor(req)); err != nil {
log.Println("Failed to send crash report:", err)
log.Println("Failed to send failure report:", err)
} else {
log.Println("Sent failure report:", r.Description)
}
}
}

View File

@@ -130,7 +130,7 @@ func (r *crashReceiver) servePut(reportID, fullPath string, w http.ResponseWrite
return
}
if err := sendReport(r.dsn, pkt, user); err != nil {
log.Println("Failed to send crash report:", err)
log.Println("Failed to send crash report:", err)
}
}()
}

View File

@@ -7,6 +7,7 @@
package main
import (
"context"
"crypto/rand"
"encoding/binary"
"flag"
@@ -47,14 +48,16 @@ func main() {
log.Println("My ID:", myID)
}
runbeacon(beacon.NewMulticast(mc), fake)
runbeacon(beacon.NewBroadcast(bc), fake)
ctx := context.Background()
runbeacon(ctx, beacon.NewMulticast(mc), fake)
runbeacon(ctx, beacon.NewBroadcast(bc), fake)
select {}
}
func runbeacon(bc beacon.Interface, fake bool) {
go bc.Serve()
func runbeacon(ctx context.Context, bc beacon.Interface, fake bool) {
go bc.Serve(ctx)
go recv(bc)
if fake {
go send(bc)

View File

@@ -66,12 +66,12 @@ func newAPISrv(addr string, cert tls.Certificate, db database, repl replicator,
}
}
func (s *apiSrv) Serve() {
func (s *apiSrv) Serve(ctx context.Context) error {
if s.useHTTP {
listener, err := net.Listen("tcp", s.addr)
if err != nil {
log.Println("Listen:", err)
return
return err
}
s.listener = listener
} else {
@@ -93,7 +93,7 @@ func (s *apiSrv) Serve() {
tlsListener, err := tls.Listen("tcp", s.addr, tlsCfg)
if err != nil {
log.Println("Listen:", err)
return
return err
}
s.listener = tlsListener
}
@@ -107,9 +107,11 @@ func (s *apiSrv) Serve() {
MaxHeaderBytes: httpMaxHeaderBytes,
}
if err := srv.Serve(s.listener); err != nil {
err := srv.Serve(s.listener)
if err != nil {
log.Println("Serve:", err)
}
return err
}
var topCtx = context.Background()

View File

@@ -10,6 +10,7 @@
package main
import (
"context"
"log"
"sort"
"time"
@@ -37,7 +38,6 @@ type database interface {
type levelDBStore struct {
db *leveldb.DB
inbox chan func()
stop chan struct{}
clock clock
marshalBuf []byte
}
@@ -50,7 +50,6 @@ func newLevelDBStore(dir string) (*levelDBStore, error) {
return &levelDBStore{
db: db,
inbox: make(chan func(), 16),
stop: make(chan struct{}),
clock: defaultClock{},
}, nil
}
@@ -155,7 +154,7 @@ func (s *levelDBStore) get(key string) (DatabaseRecord, error) {
return rec, nil
}
func (s *levelDBStore) Serve() {
func (s *levelDBStore) Serve(ctx context.Context) error {
t := time.NewTimer(0)
defer t.Stop()
defer s.db.Close()
@@ -183,7 +182,7 @@ loop:
// the next.
t.Reset(databaseStatisticsInterval)
case <-s.stop:
case <-ctx.Done():
// We're done.
close(statisticsTrigger)
break loop
@@ -192,6 +191,8 @@ loop:
// Also wait for statisticsServe to return
<-statisticsDone
return nil
}
func (s *levelDBStore) statisticsServe(trigger <-chan struct{}, done chan<- struct{}) {
@@ -255,10 +256,6 @@ func (s *levelDBStore) statisticsServe(trigger <-chan struct{}, done chan<- stru
}
}
func (s *levelDBStore) Stop() {
close(s.stop)
}
// merge returns the merged result of the two database records a and b. The
// result is the union of the two address sets, with the newer expiry time
// chosen for any duplicates.

View File

@@ -7,6 +7,7 @@
package main
import (
"context"
"fmt"
"os"
"testing"
@@ -20,8 +21,9 @@ func TestDatabaseGetSet(t *testing.T) {
if err != nil {
t.Fatal(err)
}
go db.Serve()
defer db.Stop()
ctx, cancel := context.WithCancel(context.Background())
go db.Serve(ctx)
defer cancel()
// Check missing record

View File

@@ -7,6 +7,7 @@
package main
import (
"context"
"crypto/tls"
"flag"
"log"
@@ -21,7 +22,7 @@ import (
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/tlsutil"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/thejerf/suture"
"github.com/thejerf/suture/v4"
)
const (
@@ -183,5 +184,5 @@ func main() {
}
// Engage!
main.Serve()
main.Serve(context.Background())
}

View File

@@ -7,6 +7,7 @@
package main
import (
"context"
"crypto/tls"
"encoding/binary"
"fmt"
@@ -32,7 +33,6 @@ type replicationSender struct {
cert tls.Certificate // our certificate
allowedIDs []protocol.DeviceID
outbox chan ReplicationRecord
stop chan struct{}
}
func newReplicationSender(dst string, cert tls.Certificate, allowedIDs []protocol.DeviceID) *replicationSender {
@@ -41,11 +41,10 @@ func newReplicationSender(dst string, cert tls.Certificate, allowedIDs []protoco
cert: cert,
allowedIDs: allowedIDs,
outbox: make(chan ReplicationRecord, replicationOutboxSize),
stop: make(chan struct{}),
}
}
func (s *replicationSender) Serve() {
func (s *replicationSender) Serve(ctx context.Context) error {
// Sleep a little at startup. Peers often restart at the same time, and
// this avoid the service failing and entering backoff state
// unnecessarily, while also reducing the reconnect rate to something
@@ -62,7 +61,7 @@ func (s *replicationSender) Serve() {
conn, err := tls.Dial("tcp", s.dst, tlsCfg)
if err != nil {
log.Println("Replication connect:", err)
return
return err
}
defer func() {
conn.SetWriteDeadline(time.Now().Add(time.Second))
@@ -73,13 +72,13 @@ func (s *replicationSender) Serve() {
remoteID, err := deviceID(conn)
if err != nil {
log.Println("Replication connect:", err)
return
return err
}
// Verify it's in the set of allowed device IDs.
if !deviceIDIn(remoteID, s.allowedIDs) {
log.Println("Replication connect: unexpected device ID:", remoteID)
return
return err
}
heartBeatTicker := time.NewTicker(replicationHeartbeatInterval)
@@ -122,20 +121,16 @@ func (s *replicationSender) Serve() {
replicationSendsTotal.WithLabelValues("error").Inc()
log.Println("Replication write:", err)
// Yes, we are loosing the replication event here.
return
return err
}
replicationSendsTotal.WithLabelValues("success").Inc()
case <-s.stop:
return
case <-ctx.Done():
return nil
}
}
}
func (s *replicationSender) Stop() {
close(s.stop)
}
func (s *replicationSender) String() string {
return fmt.Sprintf("replicationSender(%q)", s.dst)
}
@@ -172,7 +167,6 @@ type replicationListener struct {
cert tls.Certificate
allowedIDs []protocol.DeviceID
db database
stop chan struct{}
}
func newReplicationListener(addr string, cert tls.Certificate, allowedIDs []protocol.DeviceID, db database) *replicationListener {
@@ -181,11 +175,10 @@ func newReplicationListener(addr string, cert tls.Certificate, allowedIDs []prot
cert: cert,
allowedIDs: allowedIDs,
db: db,
stop: make(chan struct{}),
}
}
func (l *replicationListener) Serve() {
func (l *replicationListener) Serve(ctx context.Context) error {
tlsCfg := &tls.Config{
Certificates: []tls.Certificate{l.cert},
ClientAuth: tls.RequestClientCert,
@@ -196,14 +189,14 @@ func (l *replicationListener) Serve() {
lst, err := tls.Listen("tcp", l.addr, tlsCfg)
if err != nil {
log.Println("Replication listen:", err)
return
return err
}
defer lst.Close()
for {
select {
case <-l.stop:
return
case <-ctx.Done():
return nil
default:
}
@@ -211,7 +204,7 @@ func (l *replicationListener) Serve() {
conn, err := lst.Accept()
if err != nil {
log.Println("Replication accept:", err)
return
return err
}
// Figure out the other side device ID
@@ -231,19 +224,15 @@ func (l *replicationListener) Serve() {
continue
}
go l.handle(conn)
go l.handle(ctx, conn)
}
}
func (l *replicationListener) Stop() {
close(l.stop)
}
func (l *replicationListener) String() string {
return fmt.Sprintf("replicationListener(%q)", l.addr)
}
func (l *replicationListener) handle(conn net.Conn) {
func (l *replicationListener) handle(ctx context.Context, conn net.Conn) {
defer func() {
conn.SetWriteDeadline(time.Now().Add(time.Second))
conn.Close()
@@ -253,7 +242,7 @@ func (l *replicationListener) handle(conn net.Conn) {
for {
select {
case <-l.stop:
case <-ctx.Done():
return
default:
}

View File

@@ -28,16 +28,21 @@ func main() {
log.SetFlags(0)
target := flag.String("target", "localhost:8384", "Target Syncthing instance")
types := flag.String("types", "", "Filter for specific event types (comma-separated)")
apikey := flag.String("apikey", "", "Syncthing API key")
flag.Parse()
if *apikey == "" {
log.Fatal("Must give -apikey argument")
}
var eventsArg string
if len(*types) > 0 {
eventsArg = "&events=" + *types
}
since := 0
for {
req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/rest/events?since=%d", *target, since), nil)
req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/rest/events?since=%d%s", *target, since, eventsArg), nil)
if err != nil {
log.Fatal(err)
}

View File

@@ -131,6 +131,23 @@ func dump(ldb backend.Backend) {
fmt.Printf(" V:%v\n", v)
}
case db.KeyTypePendingFolder:
device := binary.BigEndian.Uint32(key[1:])
folder := string(key[5:])
var of db.ObservedFolder
of.Unmarshal(it.Value())
fmt.Printf("[pendingFolder] D:%d F:%s V:%v\n", device, folder, of)
case db.KeyTypePendingDevice:
device := "<invalid>"
dev, err := protocol.DeviceIDFromBytes(key[1:])
if err == nil {
device = dev.String()
}
var od db.ObservedDevice
od.Unmarshal(it.Value())
fmt.Printf("[pendingDevice] D:%v V:%v\n", device, od)
default:
fmt.Printf("[??? %d]\n %x\n %x\n", key[0], key, it.Value())
}

View File

@@ -6,9 +6,11 @@ import (
"compress/gzip"
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"flag"
"fmt"
"github.com/syncthing/syncthing/lib/protocol"
"io"
"io/ioutil"
"log"
@@ -208,6 +210,7 @@ func main() {
tlsCfg := &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS10, // No SSLv3
ClientAuth: tls.RequestClientCert,
CipherSuites: []uint16{
// No RC4
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
@@ -338,6 +341,12 @@ func handleGetRequest(rw http.ResponseWriter, r *http.Request) {
}
func handlePostRequest(w http.ResponseWriter, r *http.Request) {
var relayCert *x509.Certificate
if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
relayCert = r.TLS.PeerCertificates[0]
log.Printf("Got TLS cert from relay server")
}
var newRelay relay
err := json.NewDecoder(r.Body).Decode(&newRelay)
r.Body.Close()
@@ -359,6 +368,16 @@ func handlePostRequest(w http.ResponseWriter, r *http.Request) {
return
}
if relayCert != nil {
advertisedId := uri.Query().Get("id")
idFromCert := protocol.NewDeviceID(relayCert.Raw).String()
if advertisedId != idFromCert {
log.Println("Warning: Relay server requested to join with an ID different from the join request, rejecting")
http.Error(w, "mismatched advertised id and join request cert", http.StatusBadRequest)
return
}
}
host, port, err := net.SplitHostPort(uri.Host)
if err != nil {
if debug {
@@ -379,7 +398,7 @@ func handlePostRequest(w http.ResponseWriter, r *http.Request) {
if ip == nil || ip.IsUnspecified() {
uri.Host = net.JoinHostPort(rhost, port)
newRelay.URL = uri.String()
} else if host != rhost {
} else if host != rhost && relayCert == nil {
if debug {
log.Println("IP address advertised does not match client IP address", r.RemoteAddr, uri)
}

View File

@@ -3,6 +3,7 @@
package main
import (
"context"
"crypto/tls"
"flag"
"fmt"
@@ -184,17 +185,19 @@ func main() {
log.Println("ID:", id)
}
wrapper := config.Wrap("config", config.New(id), events.NoopLogger)
wrapper.SetOptions(config.OptionsConfiguration{
NATLeaseM: natLease,
NATRenewalM: natRenewal,
NATTimeoutS: natTimeout,
wrapper := config.Wrap("config", config.New(id), id, events.NoopLogger)
wrapper.Modify(func(cfg *config.Configuration) {
cfg.Options.NATLeaseM = natLease
cfg.Options.NATRenewalM = natRenewal
cfg.Options.NATTimeoutS = natTimeout
})
natSvc := nat.NewService(id, wrapper)
mapping := mapping{natSvc.NewMapping(nat.TCP, addr.IP, addr.Port)}
if natEnabled {
go natSvc.Serve()
ctx, cancel := context.WithCancel(context.Background())
go natSvc.Serve(ctx)
defer cancel()
found := make(chan struct{})
mapping.OnChanged(func(_ *nat.Mapping, _, _ []nat.Address) {
select {
@@ -244,7 +247,7 @@ func main() {
for _, pool := range pools {
pool = strings.TrimSpace(pool)
if len(pool) > 0 {
go poolHandler(pool, uri, mapping)
go poolHandler(pool, uri, mapping, cert)
}
}

View File

@@ -4,6 +4,7 @@ package main
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
"log"
@@ -16,7 +17,7 @@ const (
httpStatusEnhanceYourCalm = 429
)
func poolHandler(pool string, uri *url.URL, mapping mapping) {
func poolHandler(pool string, uri *url.URL, mapping mapping, ownCert tls.Certificate) {
if debug {
log.Println("Joining", pool)
}
@@ -31,7 +32,24 @@ func poolHandler(pool string, uri *url.URL, mapping mapping) {
uriCopy.String(),
})
resp, err := httpClient.Post(pool, "application/json", &b)
poolUrl, err := url.Parse(pool)
if err != nil {
log.Printf("Could not parse pool url '%s': %v", pool, err)
}
client := http.DefaultClient
if poolUrl.Scheme == "https" {
// Sent our certificate in join request
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{ownCert},
},
},
}
}
resp, err := client.Post(pool, "application/json", &b)
if err != nil {
log.Printf("Error joining pool %v: HTTP request: %v", pool, err)
time.Sleep(time.Minute)

View File

@@ -20,7 +20,8 @@ import (
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
log.SetOutput(os.Stdout)
log.SetFlags(log.LstdFlags | log.Lshortfile)
@@ -62,7 +63,7 @@ func main() {
}
log.Println("Created client")
go relay.Serve()
go relay.Serve(ctx)
recv := make(chan protocol.SessionInvitation)

View File

@@ -8,6 +8,7 @@ package main
import (
"bytes"
"context"
"crypto/tls"
"flag"
"fmt"
@@ -38,11 +39,13 @@ import (
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/svcutil"
"github.com/syncthing/syncthing/lib/syncthing"
"github.com/syncthing/syncthing/lib/tlsutil"
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/pkg/errors"
"github.com/thejerf/suture/v4"
)
const (
@@ -321,7 +324,7 @@ func main() {
}
if err != nil {
l.Warnln("Command line options:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
if options.logFile == "default" || options.logFile == "" {
@@ -358,7 +361,7 @@ func main() {
)
if err != nil {
l.Warnln("Error reading device ID:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
fmt.Println(protocol.NewDeviceID(cert.Certificate[0]))
@@ -368,7 +371,7 @@ func main() {
if options.browserOnly {
if err := openGUI(protocol.EmptyDeviceID); err != nil {
l.Warnln("Failed to open web UI:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
return
}
@@ -376,7 +379,7 @@ func main() {
if options.generateDir != "" {
if err := generate(options.generateDir); err != nil {
l.Warnln("Failed to generate config and keys:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
return
}
@@ -384,14 +387,14 @@ func main() {
// Ensure that our home directory exists.
if err := ensureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0700); err != nil {
l.Warnln("Failure on home directory:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
if options.upgradeTo != "" {
err := upgrade.ToURL(options.upgradeTo)
if err != nil {
l.Warnln("Error while Upgrading:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
l.Infoln("Upgraded from", options.upgradeTo)
return
@@ -422,13 +425,13 @@ func main() {
os.Exit(exitCodeForUpgrade(err))
}
l.Infof("Upgraded to %q", release.Tag)
os.Exit(syncthing.ExitUpgrade.AsInt())
os.Exit(svcutil.ExitUpgrade.AsInt())
}
if options.resetDatabase {
if err := resetDB(); err != nil {
l.Warnln("Resetting database:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
l.Infoln("Successfully reset database - it will be rebuilt after next start.")
return
@@ -600,14 +603,25 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
os.Exit(1)
}
evLogger := events.NewLogger()
go evLogger.Serve()
defer evLogger.Stop()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
cfg, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, runtimeOptions.allowNewerConfig, noDefaultFolder)
// earlyService is a supervisor that runs the services needed for or
// before app startup; the event logger, and the config service.
spec := svcutil.SpecWithDebugLogger(l)
earlyService := suture.New("early", spec)
earlyService.ServeBackground(ctx)
evLogger := events.NewLogger()
earlyService.Add(evLogger)
cfgWrapper, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, runtimeOptions.allowNewerConfig, noDefaultFolder)
if err != nil {
l.Warnln("Failed to initialize config:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
if cfgService, ok := cfgWrapper.(suture.Service); ok {
earlyService.Add(cfgService)
}
// Candidate builds should auto upgrade. Make sure the option is set,
@@ -615,20 +629,20 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// environment variable is set.
if build.IsCandidate && !upgrade.DisabledByCompilation && !runtimeOptions.NoUpgrade {
l.Infoln("Automatic upgrade is always enabled for candidate releases.")
if opts := cfg.Options(); opts.AutoUpgradeIntervalH == 0 || opts.AutoUpgradeIntervalH > 24 {
opts.AutoUpgradeIntervalH = 12
// Set the option into the config as well, as the auto upgrade
// loop expects to read a valid interval from there.
cfg.SetOptions(opts)
cfg.Save()
}
// We don't tweak the user's choice of upgrading to pre-releases or
// not, as otherwise they cannot step off the candidate channel.
cfgWrapper.Modify(func(cfg *config.Configuration) {
l.Infoln("Automatic upgrade is always enabled for candidate releases.")
if cfg.Options.AutoUpgradeIntervalH == 0 || cfg.Options.AutoUpgradeIntervalH > 24 {
cfg.Options.AutoUpgradeIntervalH = 12
// Set the option into the config as well, as the auto upgrade
// loop expects to read a valid interval from there.
}
// We don't tweak the user's choice of upgrading to pre-releases or
// not, as otherwise they cannot step off the candidate channel.
})
}
dbFile := locations.Get(locations.Database)
ldb, err := syncthing.OpenDBBackend(dbFile, cfg.Options().DatabaseTuning)
ldb, err := syncthing.OpenDBBackend(dbFile, cfgWrapper.Options().DatabaseTuning)
if err != nil {
l.Warnln("Error opening database:", err)
os.Exit(1)
@@ -639,7 +653,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// later after App is initialised.
autoUpgradePossible := autoUpgradePossible(runtimeOptions)
if autoUpgradePossible && cfg.Options().AutoUpgradeEnabled() {
if autoUpgradePossible && cfgWrapper.Options().AutoUpgradeEnabled() {
// try to do upgrade directly and log the error if relevant.
release, err := initialAutoUpgradeCheck(db.NewMiscDataNamespace(ldb))
if err == nil {
@@ -653,14 +667,14 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
}
} else {
l.Infof("Upgraded to %q, exiting now.", release.Tag)
os.Exit(syncthing.ExitUpgrade.AsInt())
os.Exit(svcutil.ExitUpgrade.AsInt())
}
}
if runtimeOptions.unpaused {
setPauseState(cfg, false)
setPauseState(cfgWrapper, false)
} else if runtimeOptions.paused {
setPauseState(cfg, true)
setPauseState(cfgWrapper, true)
}
appOpts := runtimeOptions.Options
@@ -678,10 +692,14 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
appOpts.DBIndirectGCInterval = dur
}
app := syncthing.New(cfg, ldb, evLogger, cert, appOpts)
app, err := syncthing.New(cfgWrapper, ldb, evLogger, cert, appOpts)
if err != nil {
l.Warnln("Failed to start Syncthing:", err)
os.Exit(svcutil.ExitError.AsInt())
}
if autoUpgradePossible {
go autoUpgrade(cfg, app, evLogger)
go autoUpgrade(cfgWrapper, app, evLogger)
}
setupSignalHandling(app)
@@ -694,30 +712,34 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
f, err := os.Create(fmt.Sprintf("cpu-%d.pprof", os.Getpid()))
if err != nil {
l.Warnln("Creating profile:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
if err := pprof.StartCPUProfile(f); err != nil {
l.Warnln("Starting profile:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
}
go standbyMonitor(app, cfg)
go standbyMonitor(app, cfgWrapper)
if err := app.Start(); err != nil {
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
cleanConfigDirectory()
if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting {
if cfgWrapper.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 its own routine.
go func() { _ = openURL(cfg.GUI().URL()) }()
go func() { _ = openURL(cfgWrapper.GUI().URL()) }()
}
status := app.Wait()
if status == svcutil.ExitError {
l.Warnln("Syncthing stopped with error:", app.Error())
}
if runtimeOptions.cpuProfile {
pprof.StopCPUProfile()
}
@@ -733,7 +755,7 @@ func setupSignalHandling(app *syncthing.App) {
signal.Notify(restartSign, sigHup)
go func() {
<-restartSign
app.Stop(syncthing.ExitRestart)
app.Stop(svcutil.ExitRestart)
}()
// Exit with "success" code (no restart) on INT/TERM
@@ -742,7 +764,7 @@ func setupSignalHandling(app *syncthing.App) {
signal.Notify(stopSign, os.Interrupt, sigTerm)
go func() {
<-stopSign
app.Stop(syncthing.ExitSuccess)
app.Stop(svcutil.ExitSuccess)
}()
}
@@ -779,7 +801,7 @@ func auditWriter(auditFile string) io.Writer {
fd, err = os.OpenFile(auditFile, auditFlags, 0600)
if err != nil {
l.Warnln("Audit:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
auditDest = auditFile
}
@@ -829,7 +851,7 @@ func standbyMonitor(app *syncthing.App, cfg config.Wrapper) {
// things a moment to stabilize.
time.Sleep(restartDelay)
app.Stop(syncthing.ExitRestart)
app.Stop(svcutil.ExitRestart)
return
}
now = time.Now()
@@ -899,7 +921,7 @@ func autoUpgrade(cfg config.Wrapper, app *syncthing.App, evLogger events.Logger)
sub.Unsubscribe()
l.Warnf("Automatically upgraded to version %q. Restarting in 1 minute.", rel.Tag)
time.Sleep(time.Minute)
app.Stop(syncthing.ExitUpgrade)
app.Stop(svcutil.ExitUpgrade)
return
}
}
@@ -977,23 +999,24 @@ func showPaths(options RuntimeOptions) {
fmt.Printf("Default sync folder directory:\n\t%s\n\n", locations.Get(locations.DefFolder))
}
func setPauseState(cfg config.Wrapper, paused bool) {
raw := cfg.RawCopy()
for i := range raw.Devices {
raw.Devices[i].Paused = paused
}
for i := range raw.Folders {
raw.Folders[i].Paused = paused
}
if _, err := cfg.Replace(raw); err != nil {
func setPauseState(cfgWrapper config.Wrapper, paused bool) {
_, err := cfgWrapper.Modify(func(cfg *config.Configuration) {
for i := range cfg.Devices {
cfg.Devices[i].Paused = paused
}
for i := range cfg.Folders {
cfg.Folders[i].Paused = paused
}
})
if err != nil {
l.Warnln("Cannot adjust paused state:", err)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
}
func exitCodeForUpgrade(err error) int {
if _, ok := err.(*errNoUpgrade); ok {
return syncthing.ExitNoUpgradeAvailable.AsInt()
return svcutil.ExitNoUpgradeAvailable.AsInt()
}
return syncthing.ExitError.AsInt()
return svcutil.ExitError.AsInt()
}

View File

@@ -25,8 +25,8 @@ import (
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/svcutil"
"github.com/syncthing/syncthing/lib/sync"
"github.com/syncthing/syncthing/lib/syncthing"
)
var (
@@ -99,7 +99,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
if t := time.Since(restarts[0]); t < loopThreshold {
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
copy(restarts[0:], restarts[1:])
@@ -169,7 +169,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
if err == nil {
// Successful exit indicates an intentional shutdown
os.Exit(syncthing.ExitSuccess.AsInt())
os.Exit(svcutil.ExitSuccess.AsInt())
}
if exiterr, ok := err.(*exec.ExitError); ok {
@@ -177,7 +177,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
if stopped || runtimeOptions.noRestart {
os.Exit(exitCode)
}
if exitCode == syncthing.ExitUpgrade.AsInt() {
if exitCode == svcutil.ExitUpgrade.AsInt() {
// Restart the monitor process to release the .old
// binary as part of the upgrade process.
l.Infoln("Restarting monitor...")
@@ -189,7 +189,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
}
if runtimeOptions.noRestart {
os.Exit(syncthing.ExitError.AsInt())
os.Exit(svcutil.ExitError.AsInt())
}
l.Infoln("Syncthing exited:", err)

View File

@@ -754,6 +754,8 @@ func getReport(db *sql.DB) map[string]interface{} {
add(featureGroups["Folder"]["v3"], "Pull Order", prettyCase(key), value)
}
inc(features["Device"]["v3"], "Untrusted", rep.DeviceUsesV3.Untrusted)
totals["GUI"] += rep.GUIStats.Enabled
inc(features["GUI"]["v3"], "Auth Enabled", rep.GUIStats.UseAuth)

51
go.mod
View File

@@ -1,54 +1,53 @@
module github.com/syncthing/syncthing
require (
github.com/AudriusButkevicius/pfilter v0.0.0-20190627213056-c55ef6137fc6
github.com/AudriusButkevicius/pfilter v0.0.0-20210218141631-7468b85d810a
github.com/AudriusButkevicius/recli v0.0.5
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/bkaradzic/go-lz4 v0.0.0-20160924222819-7224d8d8f27e
github.com/calmh/xdr v1.1.0
github.com/ccding/go-stun v0.0.0-20180726100737-be486d185f3d
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67 // indirect
github.com/ccding/go-stun v0.1.2
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect
github.com/chmduquesne/rollinghash v0.0.0-20180912150627-a60f8e7142b5
github.com/d4l3k/messagediff v1.2.1
github.com/dchest/siphash v1.2.1
github.com/dchest/siphash v1.2.2
github.com/dgraph-io/badger/v2 v2.0.3
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568
github.com/getsentry/raven-go v0.2.0
github.com/go-ldap/ldap/v3 v3.2.0
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-ldap/ldap/v3 v3.2.4
github.com/gobwas/glob v0.2.3
github.com/gogo/protobuf v1.3.1
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9
github.com/golang/protobuf v1.4.2
github.com/greatroar/blobloom v0.3.0
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
github.com/golang/protobuf v1.4.3
github.com/greatroar/blobloom v0.5.0
github.com/hashicorp/golang-lru v0.5.1
github.com/jackpal/gateway v1.0.6
github.com/jackpal/go-nat-pmp v1.0.2
github.com/julienschmidt/httprouter v1.3.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kr/pretty v0.2.0 // indirect
github.com/lib/pq v1.2.0
github.com/lucas-clemente/quic-go v0.18.0
github.com/lib/pq v1.8.0
github.com/lucas-clemente/quic-go v0.19.3
github.com/maruel/panicparse v1.5.1
github.com/mattn/go-isatty v0.0.12
github.com/minio/sha256-simd v0.1.1
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75
github.com/oschwald/geoip2-golang v1.4.0
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.2.1
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563
github.com/prometheus/client_golang v1.8.0
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
github.com/sasha-s/go-deadlock v0.2.0
github.com/shirou/gopsutil v2.20.7+incompatible
github.com/syncthing/notify v0.0.0-20190709140112-69c7a957d3e2
github.com/shirou/gopsutil/v3 v3.20.11
github.com/syncthing/notify v0.0.0-20201210100135-17de26665ddc
github.com/syndtr/goleveldb v1.0.1-0.20200815071216-d9e9293bd0f7
github.com/thejerf/suture v3.0.2+incompatible
github.com/urfave/cli v1.22.2
github.com/thejerf/suture/v4 v4.0.0
github.com/urfave/cli v1.22.4
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860
golang.org/x/text v0.3.3
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
google.golang.org/protobuf v1.25.0 // indirect
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1
golang.org/x/text v0.3.4
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
google.golang.org/protobuf v1.23.0
)
go 1.14

397
go.sum
View File

@@ -7,8 +7,8 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AudriusButkevicius/pfilter v0.0.0-20190627213056-c55ef6137fc6 h1:Apvc4kyfdrOxG+F5dn8osz+45kwGJa6CySQn0tB38SU=
github.com/AudriusButkevicius/pfilter v0.0.0-20190627213056-c55ef6137fc6/go.mod h1:1N0EEx/irz4B1qV17wW82TFbjQrE7oX316Cki6eDY0Q=
github.com/AudriusButkevicius/pfilter v0.0.0-20210218141631-7468b85d810a h1:dUzIAgRmHLIUU0PT+OJ0X1WI5j1hlLbf+G420gUjIQg=
github.com/AudriusButkevicius/pfilter v0.0.0-20210218141631-7468b85d810a/go.mod h1:1N0EEx/irz4B1qV17wW82TFbjQrE7oX316Cki6eDY0Q=
github.com/AudriusButkevicius/recli v0.0.5 h1:xUa55PvWTHBm17T6RvjElRO3y5tALpdceH86vhzQ5wg=
github.com/AudriusButkevicius/recli v0.0.5/go.mod h1:Q2E26yc6RvWWEz/TJ/goUp6yXvipYdJI096hpoaqsNs=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
@@ -16,76 +16,103 @@ github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzS
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bkaradzic/go-lz4 v0.0.0-20160924222819-7224d8d8f27e h1:2augTYh6E+XoNrrivZJBadpThP/dsvYKj0nzqfQ8tM4=
github.com/bkaradzic/go-lz4 v0.0.0-20160924222819-7224d8d8f27e/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/calmh/xdr v1.1.0 h1:U/Dd4CXNLoo8EiQ4ulJUXkgO1/EyQLgDKLgpY1SOoJE=
github.com/calmh/xdr v1.1.0/go.mod h1:E8sz2ByAdXC8MbANf1LCRYzedSnnc+/sXXJs/PVqoeg=
github.com/ccding/go-stun v0.0.0-20180726100737-be486d185f3d h1:As4937T5NVbJ/DmZT9z33pyLEprMd6CUSfhbmMY57Io=
github.com/ccding/go-stun v0.0.0-20180726100737-be486d185f3d/go.mod h1:3FK1bMar37f7jqVY7q/63k3OMX1c47pGCufzt3X0sYE=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/ccding/go-stun v0.1.2 h1:1CZhjVwfyO/jGxk06a+0OSOGBWZu588kuZQQO4nihsw=
github.com/ccding/go-stun v0.1.2/go.mod h1:3FK1bMar37f7jqVY7q/63k3OMX1c47pGCufzt3X0sYE=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67 h1:8k9FLYBLKT+9v2HQJ/a95ZemmTx+/ltJcAiRhVushG8=
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/chmduquesne/rollinghash v0.0.0-20180912150627-a60f8e7142b5 h1:Wg96Dh0MLTanEaPO0OkGtUIaa2jOnShAIOVUIzRHUxo=
github.com/chmduquesne/rollinghash v0.0.0-20180912150627-a60f8e7142b5/go.mod h1:Uc2I36RRfTAf7Dge82bi3RU0OQUmXT9iweIcPqvr8A0=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dchest/siphash v1.2.2 h1:9DFz8tQwl9pTVt5iok/9zKyzA1Q6bRGiF3HPiEEVr9I=
github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dgraph-io/badger/v2 v2.0.3 h1:inzdf6VF/NZ+tJ8RwwYMjJMvsOALTHYdozn0qSl6XJI=
github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM=
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3 h1:MQLRM35Pp0yAyBYksjbj1nZI/w6eyRY/mWoM1sFf4kU=
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWTLOJKlh+lOBt6nUQgXAfB7oVIQt5cNreqSLI=
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -93,191 +120,288 @@ github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JY
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-asn1-ber/asn1-ber v1.5.0 h1:/S4hO/AO6tLMlPX0oftGSOcdGJJN/MuYzfgWRMn199E=
github.com/go-asn1-ber/asn1-ber v1.5.0/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-ldap/ldap/v3 v3.2.0 h1:fkS0nXg43MZvU0UNTOGyQv60WdwHRXa1eX0CSzuKLvY=
github.com/go-ldap/ldap/v3 v3.2.0/go.mod h1:dtLsnBXnSLIsMRbCBuRpHflCGaYzZ5jn+x1q7XqMTKU=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E=
github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE=
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/greatroar/blobloom v0.3.0 h1:TSf9vu9lZ840bnMXNFpFKe61AISBZL5a9uRL62KixCY=
github.com/greatroar/blobloom v0.3.0/go.mod h1:we9vO6GNYMmsNvCWINtZnQbcGEHUT6hGBAznNHd6RlE=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/greatroar/blobloom v0.5.0 h1:jNbCsgDpZ23AI6jgZsXm7oFatkFaLCxr+ZWzlYasONU=
github.com/greatroar/blobloom v0.5.0/go.mod h1:M+yFtr/P96aNZYDYowvNWL3WdDluSMK2PPPHN49LMw8=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jackpal/gateway v1.0.6 h1:/MJORKvJEwNVldtGVJC2p2cwCnsSoLn3hl3zxmZT7tk=
github.com/jackpal/gateway v1.0.6/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lucas-clemente/quic-go v0.18.0 h1:JhQDdqxdwdmGdKsKgXi1+coHRoGhvU6z0rNzOJqZ/4o=
github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4=
github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc=
github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
github.com/marten-seemann/qtls-go1-15 v0.1.0 h1:i/YPXVxz8q9umso/5y474CNcHmTpA+5DH+mFPjx6PZg=
github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ=
github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
github.com/maruel/panicparse v1.5.1 h1:hUPcXI7ubtEqj/k+P34KsHQqb86zuVk7zBfkP6tBBPc=
github.com/maruel/panicparse v1.5.1/go.mod h1:aOutY/MUjdj80R0AEVI9qE2zHqig+67t2ffUDDiLzAM=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 h1:cUVxyR+UfmdEAZGJ8IiKld1O0dbGotEnkMolG5hfMSY=
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75/go.mod h1:pBbZyGwC5i16IBkjVKoy/sznA8jPD/K9iedwe1ESE6w=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9PvrpOfz+Ug=
github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng=
github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4=
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y=
github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.20.11 h1:NeVf1K0cgxsWz+N3671ojRptdgzvp7BXL3KV21R0JnA=
github.com/shirou/gopsutil/v3 v3.20.11/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkUcCLlYhZzdr/4=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
@@ -303,8 +427,12 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -312,129 +440,165 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/syncthing/notify v0.0.0-20190709140112-69c7a957d3e2 h1:6tuEEEpg+mxM82E0YingzoXzXXISYR/o/7I9n573LWI=
github.com/syncthing/notify v0.0.0-20190709140112-69c7a957d3e2/go.mod h1:Sn4ChoS7e4FxjCN1XHPVBT43AgnRLbuaB8pEc1Zcdjg=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syncthing/notify v0.0.0-20201210100135-17de26665ddc h1:b6b5XVKqpwxC6keIYThA5/XhFue4zNWRwv8FfqlKoxA=
github.com/syncthing/notify v0.0.0-20201210100135-17de26665ddc/go.mod h1:Sn4ChoS7e4FxjCN1XHPVBT43AgnRLbuaB8pEc1Zcdjg=
github.com/syndtr/goleveldb v1.0.1-0.20200815071216-d9e9293bd0f7 h1:udtnv1cokhJYqnUfCMCppJ71bFN9VKfG1BQ6UsYZnx8=
github.com/syndtr/goleveldb v1.0.1-0.20200815071216-d9e9293bd0f7/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/thejerf/suture v3.0.2+incompatible h1:GtMydYcnK4zBJ0KL6Lx9vLzl6Oozb65wh252FTBxrvM=
github.com/thejerf/suture v3.0.2+incompatible/go.mod h1:ibKwrVj+Uzf3XZdAiNWUouPaAbSoemxOHLmJmwheEMc=
github.com/thejerf/suture/v4 v4.0.0 h1:GX3X+1Qaewtj9flL2wgoTBfLA5NcmrCY39TJRpPbUrI=
github.com/thejerf/suture/v4 v4.0.0/go.mod h1:g0e8vwskm9tI0jRjxrnA6lSr0q6OfPdWJVX7G5bVWRs=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0 h1:okhMind4q9H1OxF44gNegWkiP4H/gsTFLalHFa4OOUI=
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0/go.mod h1:TTbGUfE+cXXceWtbTHq6lqcTvYPBKLNejBEbnUsQJtU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 h1:YEu4SMq7D0cmT7CBbXfcH0NZeuChAXwsHe/9XueUO6o=
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -442,15 +606,23 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -460,53 +632,60 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -21,7 +21,7 @@ ul+h5 {
margin-top: 1.5em;
}
#content {
.content {
margin-bottom: 50px;
}
@@ -41,6 +41,12 @@ ul+h5 {
float: none; /* issue #1197 */
}
#advancedAccordion input.form-control[type="checkbox"] {
box-shadow: none;
margin: 0;
width: auto;
}
.popover {
max-width: none;
min-width: 250px;
@@ -114,7 +120,8 @@ table.table-dynamic {
word-break: break-all;
}
table.table-condensed td {
table.table-condensed td,
table.table-condensed th {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -357,7 +364,8 @@ ul.three-columns li, ul.two-columns li {
overflow-y: scroll;
}
table.table-condensed td {
table.table-condensed td,
table.table-condensed th {
/* for mobile phones to allow linebreaks in long repro folder/shared with
* columns. */
white-space: normal;
@@ -421,3 +429,11 @@ ul.three-columns li, ul.two-columns li {
margin-bottom: 1rem;
}
}
.form-horizontal .form-group {
margin-bottom: 5px;
}
.form-horizontal {
margin-bottom: 10px;
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Допълнителни",
"Advanced Configuration": "Допълнителни настройки",
"All Data": "Всички данни",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Разрешаване изпращането на анонимни статистически данни?",
"Allowed Networks": "Разрешени мрежи",
"Alphabetic": "Азбучен ред",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Външна команда се занимава с версиите. Тази команда трябва да премахне файла от синхронизираната папка. Ако пътят до това приложение използва интервали, то той трябва да бъде заграден в кавички.",
"Anonymous Usage Reporting": "Анонимен доклад",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Форматът на анонимния доклад е променен. Желаете ли да преминете към новия формат?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Сигурни ли сте, че искате да премахнете устройството {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Сигурни ли сте, че искате да премахнете папката {{label}}?",
"Are you sure you want to restore {%count%} files?": "Сигурни ли сте, че искате да възстановите файла {{count}}?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Опасност!",
"Debugging Facilities": "Дебъг функционалност",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Път до папка по подразбиране",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Изтрито",
"Deselect All": "Никое",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Устройство",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Устройство \"{{name}}\" ({{device}}) с адрес {{address}} желае да се свърже. Да бъде ли добавено?",
"Device ID": "Идентификатор на устройство",
"Device Identification": "Идентификатор на устройството",
"Device Name": "Име на устройството",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Устройство, което последно промени обекта",
"Devices": "Устройства",
@@ -92,7 +101,9 @@
"Downloading": "Изтегляне",
"Edit": "Промени",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Променяне на {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable NAT traversal": "Разреши NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Име на папката",
"Folder Path": "Път до папката",
"Folder Type": "Вид папка",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Папки",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Интервал(и) за периодичното сканиране",
@@ -139,6 +151,7 @@
"Help": "Помощ",
"Home page": "Начална страница",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Игнорирай",
"Ignore Patterns": "Шаблони за игнориране",
@@ -187,6 +200,7 @@
"No File Versioning": "Без версии",
"No files will be deleted as a result of this operation.": "Няма да бъдат изтрити файлове като резултат от тази операция.",
"No upgrades": "Няма обновления",
"Not shared": "Not shared",
"Notice": "Известие",
"OK": "ОК",
"Off": "Изключено",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Преглед на статистиката",
"Quick guide to supported patterns": "Бърз наръчник към поддържаните шаблони",
"Random": "Произволен",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Само получаване",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Последни промени",
"Reduced by ignore patterns": "Намалено посредством шаблон за игнориране",
"Release Notes": "Бележки по обновяването",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Кандидат версиите съдържат най-новата функционалност и поправки. Те са близки до традиционните дву-седмични Synchthing обновления.",
"Remote Devices": "Устройства",
"Remote GUI": "Remote GUI",
"Remove": "Премахни",
"Remove Device": "Премахване на устройство",
"Remove Folder": "Премахване на папка",
@@ -249,6 +266,7 @@
"Select All": "Всички",
"Select a version": "Изберете версия",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Избор на най-новата версия",
"Select oldest version": "Избор на най-старата версия",
"Select the folders to share with this device.": "Изберете папките за споделяне с това устройство.",
@@ -259,6 +277,7 @@
"Share Folder": "Сподели папка",
"Share Folders With Device": "Споделяне на папки с устройството",
"Share this folder?": "Сподели тази папка?",
"Shared Folders": "Shared Folders",
"Shared With": "Споделена с",
"Sharing": "Споделяне",
"Show ID": "Покажи идентификатора",
@@ -281,6 +300,7 @@
"Start Browser": "Стартирай браузъра",
"Statistics": "Статистика",
"Stopped": "Не се синхронизира",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Помощ",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Адрес за слушане на синхронизиращия протокол",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Максималната възраст трябва да е число, полето не може да бъде празно.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Ограничението на скоростта трябва да бъде положително число (0: неограничено)",
"The rescan interval must be a non-negative number of seconds.": "Интервала на сканиране трябва да бъде не отрицателно число в секунди.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "Така се предоставя изключително лесен достъп (четене, редактиране и изтриване) до всеки файл, на компютъра Ви.",
@@ -335,10 +357,14 @@
"Unavailable": "Не е на разположение",
"Unavailable/Disabled by administrator or maintainer": "Не е на разположение/Деактивриан от администраторът или поддръжника",
"Undecided (will prompt)": "Неизбрано (ще попита)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Неясно",
"Unshared": "Несподелена",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Синхронизирано",
"Updated": "Обновено",
"Upgrade": "Обнови",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Няма игнорирани папки.",
"You have unsaved changes. Do you really want to discard them?": "Има незапазени промени. Наистина ли желаете да ги отмените?",
"You must keep at least one version.": "Трябва да пазиш поне една версия.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "дни",
"directories": "directories",
"files": "файла",
@@ -381,5 +408,6 @@
"items": "елемента",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} желае да сподели папката \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} желае да сподели папката \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} желае да сподели папката \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avançat",
"Advanced Configuration": "Configuració avançada",
"All Data": "Totes les dades",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Permetre informes d'ús anònim?",
"Allowed Networks": "Xarxes permeses",
"Alphabetic": "Alfabètic",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Un comandament extern maneja el versionat. És necessari eliminar el fitxer de la carpeta compartida. Si la ruta a l'aplicació conté espais, hi ha que ficar-los entre cometes.",
"Anonymous Usage Reporting": "Informe d'ús anònim",
"Anonymous usage report format has changed. Would you like to move to the new format?": "El format del informe anònim d'ús ha canviat. Vols canviar al nou format?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Estàs segur de que vols eliminar el dispositiu {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Estàs segur de que vols eliminar la carpeta {{label}}?",
"Are you sure you want to restore {%count%} files?": "Estàs segur de que vols restaurar {{count}} fitxers?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Perill!",
"Debugging Facilities": "Utilitats de Depuració",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Carpeta de la Ruta per Defecte",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Esborrat",
"Deselect All": "Anul·lar tota la selecció",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Dispositiu",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Dispositiu \"{{name}}\" ({{device}} a l'adreça {{address}}) vol connectar. Afegir nou dispositiu?",
"Device ID": "ID del dispositiu",
"Device Identification": "Identificació del dispositiu",
"Device Name": "Nom del dispositiu",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Límits de la tasa del dispositiu",
"Device that last modified the item": "El dispositiu que va modificar el item per última vegada",
"Devices": "Dispositius",
@@ -92,7 +101,9 @@
"Downloading": "Descarregant",
"Edit": "Editar",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Editant {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable NAT traversal": "Permetre NAT transversal",
@@ -122,6 +133,7 @@
"Folder Label": "Etiqueta de la Carpeta",
"Folder Path": "Ruta de la carpeta",
"Folder Type": "Tipus de carpeta",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Carpetes",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Per a les següents carpetes va ocòrrer un error mentre es començava a vigilar els canvis. Es tornarà a intentar cada minut, així que potser els errors desapareguen pronte. Si persisteixen, tracta d'arreglar el motiu subjacent i demana ajuda si no pots.",
"Full Rescan Interval (s)": "Interval de l'Escaneig Complet (segons)",
@@ -139,6 +151,7 @@
"Help": "Ajuda",
"Home page": "Pàgina inicial",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignorar",
"Ignore Patterns": "Patrons a ignorar",
@@ -187,6 +200,7 @@
"No File Versioning": "Sense versionat de fitxer",
"No files will be deleted as a result of this operation.": "Amb aquesta operació no s'esborrarà cap fitxer.",
"No upgrades": "Sense actualitzacions",
"Not shared": "Not shared",
"Notice": "Avís",
"OK": "OK",
"Off": "Off",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Informe d'ús de vista prèvia",
"Quick guide to supported patterns": "Guía ràpida de patrons suportats",
"Random": "Aleatori",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Només rebre",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Canvis Recents",
"Reduced by ignore patterns": "Reduït ignorant patrons",
"Release Notes": "Notes de la versió",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Les versions candidates (Release Candidates) contenen les darreres característiques i arreglos. Són paregudes a les versions tradicionals bi-semanals de Syncthing. ",
"Remote Devices": "Dispositius Remots",
"Remote GUI": "Remote GUI",
"Remove": "Eliminar",
"Remove Device": "Eliminar Dispositiu",
"Remove Folder": "Eliminar Carpeta",
@@ -249,6 +266,7 @@
"Select All": "Sel·leccionar Tot",
"Select a version": "Seleccionar una versió",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Seleccionar l'última versió",
"Select oldest version": "Seleccionar la versió més antiga",
"Select the folders to share with this device.": "Selecciona les carpetes per a compartir amb aquest dispositiu.",
@@ -259,6 +277,7 @@
"Share Folder": "Compartir carpeta",
"Share Folders With Device": "Compartir carpetes amb el dispositiu",
"Share this folder?": "Compartir aquesta carpeta?",
"Shared Folders": "Shared Folders",
"Shared With": "Compartit amb",
"Sharing": "Compartint",
"Show ID": "Mostrar ID",
@@ -281,6 +300,7 @@
"Start Browser": "Iniciar navegador",
"Statistics": "Estadístiques",
"Stopped": "Parat",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Suport",
"Support Bundle": "Lot de Suport",
"Sync Protocol Listen Addresses": "Direccions d'escolta del protocol de sincronització",
@@ -310,6 +330,7 @@
"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.": "S'utilitzen els següents intervals: per a la primera hora es guarda una versió cada 30 segons, per al primer dia es guarda una versió cada hora, per als primers 30 dies es guarda una versió diaria, fins l'edat màxima es guarda una versió cada setmana.",
"The following items could not be synchronized.": "Els següents objectes no s'han pogut sincronitzar.",
"The following items were changed locally.": "Els següents ítems es canviaren localment.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "L'edat màxima deu ser un nombre i no pot estar buida.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "El llímit del ritme deu ser un nombre no negatiu (0: sense llímit)",
"The rescan interval must be a non-negative number of seconds.": "L'interval de reescaneig deu ser un nombre positiu de segons.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Es reintenta automàticament i es sincronitzaràn quant el resolga l'error.",
"This Device": "Aquest Dispositiu",
"This can easily give hackers access to read and change any files on your computer.": "Açò pot donar accés fàcilment als hackers per a llegir i canviar qualsevol fitxer al teu ordinador.",
@@ -335,10 +357,14 @@
"Unavailable": "No disponible",
"Unavailable/Disabled by administrator or maintainer": "No disponible/Desactivar per l'administrador o mantenedor",
"Undecided (will prompt)": "No decidit (es preguntarà)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Designorar",
"Unknown": "Desconegut",
"Unshared": "No compartit",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Actualitzat",
"Updated": "Actualitzat",
"Upgrade": "Actualitzar",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "No tens carpetes ignorades.",
"You have unsaved changes. Do you really want to discard them?": "Tens canvis sense guardar. Realment vols descartar-los?",
"You must keep at least one version.": "Es deu mantindre al menys una versió.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dies",
"directories": "directories",
"files": "arxius",
@@ -381,5 +408,6 @@
"items": "Elements",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vol compartit la carpeta \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vol compartir la carpeta \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vol compartir la carpeta \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Pokročilé",
"Advanced Configuration": "Pokročilá nastavení",
"All Data": "Všechna data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Povolit anonymní hlášení o používání?",
"Allowed Networks": "Sítě, ze kterých je umožněn přístup",
"Alphabetic": "Abecední",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Správu verzí obstarává externí příkaz. U toho je třeba, aby neaktuální soubory jím byly odsouvány pryč ze sdílené složky. Pokud popis umístění tohoto příkazu obsahuje mezeru, je třeba popis umístění uzavřít do uvozovek.",
"Anonymous Usage Reporting": "Anonymní hlášení o používání",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formát anonymního hlášení o používání byl změněn. Chcete přejít na nový formát?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Opravdu chcete odebrat zařízení {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Opravdu chcete odebrat složku {{label}}?",
"Are you sure you want to restore {%count%} files?": "Opravdu chcete obnovit {{count}} souborů?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Aktuálně sdíleno se zařízeními",
"Danger!": "Nebezpečí!",
"Debugging Facilities": "Nástroje pro ladění",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Popis umístění výchozí složky",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Smazáno",
"Deselect All": "Zrušit výběr všeho",
"Deselect devices to stop sharing this folder with.": "Zrušte výběr zařízení, se kterými již nemá být tato složka sdílena.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Zařízení",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Zařízení „{{name}}“ ({{device}} na {{address}}) se chce připojit. Přidat nové zařízení?",
"Device ID": "Identifikátor zařízení",
"Device Identification": "Identifikace zařízení",
"Device Name": "Název zařízení",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Omezení přenosové rychlosti pro zařízení",
"Device that last modified the item": "Zařízení, které položku změnilo naposledy",
"Devices": "Zařízení",
@@ -92,7 +101,9 @@
"Downloading": "Stahuje se",
"Edit": "Upravit",
"Edit Device": "Upravit zařízení",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Upravit složku",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Upravuje se {{path}}.",
"Enable Crash Reporting": "Povolit hlášení pádů",
"Enable NAT traversal": "Povolit průchod skrze NAT překlad",
@@ -122,6 +133,7 @@
"Folder Label": "Jmenovka složky",
"Folder Path": "Popis umístění složky",
"Folder Type": "Typ složky",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Složky",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Pokus o spuštění sledování změn v těchto složkách se nezdařil. Bude se to opětovně zkoušet každou minutu, takže se to možná brzo povede. Pokud ne, pokuste se najít příčinu. případně požádejte o pomoc.",
"Full Rescan Interval (s)": "Interval plného skenu (sek.)",
@@ -139,6 +151,7 @@
"Help": "Nápověda",
"Home page": "Domovská stránka",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Nicméně Vaše současná nastavení značí, že si nepřejete funkci povolit. Automatické hlášení pádů tedy bylo vypnuto.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Pokud chcete ostatním uživatelům tohoto počítače zabránit v přístupu k Syncthing (a skrze něj tedy ke svým souborům), zvažte nastavení ověřování se.",
"Ignore": "Ignorovat",
"Ignore Patterns": "Vzory ignorovaného",
@@ -187,6 +200,7 @@
"No File Versioning": "Neuchovávat předchozí verze souborů",
"No files will be deleted as a result of this operation.": "Tato operace nesmaže žádné soubory.",
"No upgrades": "Žádné aktualizace",
"Not shared": "Not shared",
"Notice": "Oznámení",
"OK": "OK",
"Off": "Vypnuta",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Náhled hlášení o využívání",
"Quick guide to supported patterns": "Rychlá nápověda k podporovaným vzorům",
"Random": "Náhodné",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Pouze přijímací",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Nedávné změny",
"Reduced by ignore patterns": "Redukováno o ignorované vzory",
"Release Notes": "Poznámky k vydání",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Kandidáti na vydání obsahují nejnovější změny a opravy. Podobají se tradičním dvoutýdenním vydáním Syncthing.",
"Remote Devices": "Vzdálená zařízení",
"Remote GUI": "Remote GUI",
"Remove": "Odstranit",
"Remove Device": "Odebrat zařízení",
"Remove Folder": "Odebrat složku",
@@ -249,6 +266,7 @@
"Select All": "Vybrat vše",
"Select a version": "Vyberte verzi",
"Select additional devices to share this folder with.": "Vyberte další zařízení pro sdílení s touto složkou.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Vybrat nejnovější verzi",
"Select oldest version": "Vybrat nejstarší verzi",
"Select the folders to share with this device.": "Vybrat složky ke sdílení s tímto zařízením.",
@@ -259,6 +277,7 @@
"Share Folder": "Sdílet složku",
"Share Folders With Device": "Sdílet složky s tímto zařízením",
"Share this folder?": "Sdílet tuto složku?",
"Shared Folders": "Shared Folders",
"Shared With": "Sdíleno s",
"Sharing": "Sdílení",
"Show ID": "Zobrazit identifikátor",
@@ -281,6 +300,7 @@
"Start Browser": "Otevřít webový prohlížeč",
"Statistics": "Statistiky",
"Stopped": "Zastaveno",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Podpora",
"Support Bundle": "Balík podpory",
"Sync Protocol Listen Addresses": "Adresa, na které synchronizační protokol očekává spojení",
@@ -310,6 +330,7 @@
"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.": "Jsou použity následující intervaly: za první hodinu jsou ponechány verze pro každých 30 sekund, za první den jsou ponechány verze pro každou hodinu, za prvních 30 dní jsou ponechány verze pro každý den a do nejvyššího nastaveného stáří jsou ponechány verze pro každý týden.",
"The following items could not be synchronized.": "Následující položky nemohly být synchronizovány.",
"The following items were changed locally.": "Tyto položky byly změněny lokálně",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "Interval musí být kladný počet sekund.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Interval (v sekundách) pro spouštění čištění ve složce s verzemi. Nula pravidelné čištění vypíná.",
"The maximum age must be a number and cannot be blank.": "Nejvyšší stáří je třeba zadat v podobě čísla a nemůže být prázdné.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Je třeba, aby limit rychlosti bylo kladné číslo (0: bez limitu)",
"The rescan interval must be a non-negative number of seconds.": "Je třeba, aby interval opakování skenování bylo kladné číslo.",
"There are no devices to share this folder with.": "Nejsou žádná zařízení, se kterými lze sdílet tuto složku.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Nové pokusy o synchronizaci budou probíhat automaticky a položky budou synchronizovány jakmile bude chyba odstraněna.",
"This Device": "Toto zařízení",
"This can easily give hackers access to read and change any files on your computer.": "Toto může útočníkům jednoduše umožnit čtení a úpravy souborů na vašem počítači. ",
@@ -335,10 +357,14 @@
"Unavailable": "Nedostupné",
"Unavailable/Disabled by administrator or maintainer": "Není k dispozici / vypnuto správcem systému či balíčku",
"Undecided (will prompt)": "Nerozhodnuto (zeptá se)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Přestat ignorovat",
"Unknown": "Neznámý",
"Unshared": "Nesdílený",
"Unshared Devices": "Nesdílená zařízení",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Aktuální",
"Updated": "Aktualizováno",
"Upgrade": "Přechod na novější verzi",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Nemáte žádné ignorované složky.",
"You have unsaved changes. Do you really want to discard them?": "Máte neuložené změny. Opravdu je chcete zahodit?",
"You must keep at least one version.": "Je třeba ponechat alespoň jednu verzi.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dní",
"directories": "složky",
"files": "souborů",
@@ -381,5 +408,6 @@
"items": "položky",
"seconds": "sekund",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce sdílet složku „{{folder}}“.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce sdílet složku „{{folderlabel}}“ ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce sdílet složku „{{folderlabel}}“ ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,21 +18,23 @@
"Advanced": "Avanceret",
"Advanced Configuration": "Avanceret konfiguration",
"All Data": "Alt data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Tillad anonym brugerstatistik?",
"Allowed Networks": "Tilladte netværk",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "En ekstern kommando styrer versioneringen. Den skal fjerne filen fra den delte mappe. Hvis stien til programmet indeholder mellemrum, bør den sættes i anførselstegn.",
"Anonymous Usage Reporting": "Anonym brugerstatistik",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formatet for anonym brugerstatistik er ændret. Vil du flytte til det nye format?",
"Are you sure you want to permanently delete all these files?": "Slette valgte filer permanent?",
"Are you sure you want to remove device {%name%}?": "Er du sikker på, at du vil fjerne enheden {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Er du sikker på, at du vil fjerne mappen {{label}}?",
"Are you sure you want to restore {%count%} files?": "Er du sikker på, at du vil genskabe {{count}} filer?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Are you sure you want to upgrade?": "Opgradere?",
"Auto Accept": "Autoacceptér",
"Automatic Crash Reporting": "Automatisk nedbrud rapportering",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Den automatiske opdatering tilbyder nu valget mellem stabile udgivelser og udgivelseskandidater.",
"Automatic upgrades": "Automatisk opdatering",
"Automatic upgrades are always enabled for candidate releases.": "Automatic upgrades are always enabled for candidate releases.",
"Automatic upgrades are always enabled for candidate releases.": "Automatisk opgradering er altid aktiveret for kandidat udgivelser",
"Automatically create or share folders that this device advertises at the default path.": "Opret eller del automatisk mapper på standardstien, som denne enhed tilbyder.",
"Available debug logging facilities:": "Tilgængelige faciliteter for fejlretningslogning:",
"Be careful!": "Vær forsigtig!",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "i øjeblikket delt med enheder",
"Danger!": "Fare!",
"Debugging Facilities": "Faciliteter til fejlretning",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Standardmappesti",
"Defaults": "Defaults",
"Delete Unexpected Items": "Slet ikke forventede elementer ",
"Deleted": "Slettet",
"Deselect All": "Fravælg alle",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect devices to stop sharing this folder with.": "Fravælg enheder for at stoppe mappe deling.",
"Deselect folders to stop sharing with this device.": "Fravælg mapper for at stoppe deling med denne enhed.",
"Device": "Enhed",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Enheden “{{name}}” ({{device}} på {{address}}) vil gerne forbinde. Tilføj denne enhed?",
"Device ID": "Enheds-ID",
"Device Identification": "Enhedsidentifikation",
"Device Name": "Enhedsnavn",
"Device is untrusted, enter encryption password": "Enhed er ikke-troværdig, indtast krypteringsadgangskode",
"Device rate limits": "Enhedens hastighedsbegrænsning",
"Device that last modified the item": "Enhed, som sidst ændrede filen",
"Devices": "Enheder",
@@ -92,7 +101,9 @@
"Downloading": "Downloader",
"Edit": "Redigér",
"Edit Device": "Redigere enhed",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Redigere mappe",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Redigerer {{path}}.",
"Enable Crash Reporting": "Aktivere nedbrud rapportering",
"Enable NAT traversal": "Aktivér NAT-traversering",
@@ -122,6 +133,7 @@
"Folder Label": "Mappeetiket",
"Folder Path": "Mappesti",
"Folder Type": "Mappetype",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Mapper",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For de følgende mapper opstod en fejl ved start på overvågning af ændringer. Der prøves igen hvert minut, så fejlene går eventuelt væk snart. Hvis de forbliver, kan du prøve at rette den tilgrundliggende fejl eller spørge efter hjælp, hvis du ikke kan.",
"Full Rescan Interval (s)": "Interval for komplet genskan (sek.)",
@@ -139,6 +151,7 @@
"Help": "Hjælp",
"Home page": "Hjem",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "Hvis ikke troværdig, indtast krypteringsadgangskode",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignorér",
"Ignore Patterns": "Ignoreringsmønstre",
@@ -168,7 +181,7 @@
"Local State (Total)": "Lokal tilstand (total)",
"Locally Changed Items": "Lokalt ændrede filer",
"Log": "Logbog",
"Log tailing paused. Scroll to the bottom to continue.": "Log tailing paused. Scroll to the bottom to continue.",
"Log tailing paused. Scroll to the bottom to continue.": "Log sammenkædning er i pause. Rul til bunden for at fortsætte.",
"Logs": "Logbog",
"Major Upgrade": "Opgradering til ny hovedversion",
"Mass actions": "Massehandlinger",
@@ -187,6 +200,7 @@
"No File Versioning": "Ingen filversionering",
"No files will be deleted as a result of this operation.": "Ingen filer vil blive slettet som resultat af denne handling.",
"No upgrades": "Ingen opgraderinger",
"Not shared": "Ikke delte",
"Notice": "Bemærk",
"OK": "OK",
"Off": "Deaktiveret",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Forhåndsvisning af forbrugsrapport",
"Quick guide to supported patterns": "Kvikguide til understøttede mønstre",
"Random": "Tilfældig",
"Receive Encrypted": "Modtag krypteret",
"Receive Only": "Modtag kun",
"Received data is already encrypted": "Modtaget data er allerede krypteret",
"Recent Changes": "Nylige ændringer",
"Reduced by ignore patterns": "Reduceret af ignoreringsmønstre",
"Release Notes": "Udgivelsesnoter",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Udgivelseskandidater indeholder alle de nyeste funktioner og rettelser. De er det samme som de traditionelle tougers-udgivelser af Syncthing.",
"Remote Devices": "Fjernenheder ",
"Remote GUI": "Ekstern grafisk brugerflade",
"Remove": "Fjern",
"Remove Device": "Fjern enhed",
"Remove Folder": "Fjern mappe",
@@ -248,7 +265,8 @@
"See external versioning help for supported templated command line parameters.": "Se hjælp til ekstern versionering for understøttede kommandolinjeparametre.",
"Select All": "Vælg alle",
"Select a version": "Vælg en version",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional devices to share this folder with.": "Vælg yderligere enheder at dele denne mappe med.",
"Select additional folders to share with this device.": "Vælg yderligere mapper at dele med denne enhed.",
"Select latest version": "Vælg seneste version",
"Select oldest version": "Vælg ældste version",
"Select the folders to share with this device.": "Vælg hvilke mapper du vil dele med denne enhed.",
@@ -259,6 +277,7 @@
"Share Folder": "Del mappe",
"Share Folders With Device": "Del mappe med enhed",
"Share this folder?": "Del denne mappe?",
"Shared Folders": "Delte mapper",
"Shared With": "Delt med",
"Sharing": "Deler",
"Show ID": "Vis ID",
@@ -281,13 +300,14 @@
"Start Browser": "Start browser",
"Statistics": "Statistikker",
"Stopped": "Stoppet",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Støt",
"Support Bundle": "Støttepakke",
"Sync Protocol Listen Addresses": "Lytteadresser for synkroniseringsprotokol",
"Syncing": "Synkroniserer",
"Syncthing has been shut down.": "Syncthing er lukket ned.",
"Syncthing includes the following software or portions thereof:": "Syncthing indeholder følgende software eller dele heraf:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing is Free and Open Source Software licensed as MPL v2.0.",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing er fri og åben kildekode software licenseret som MPL v2.0.",
"Syncthing is restarting.": "Syncthing genstarter.",
"Syncthing is upgrading.": "Syncthing opgraderer.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.",
@@ -298,7 +318,7 @@
"The Syncthing Authors": "Syncthing udviklere",
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing-administationsfladen er sat op til at kunne fjernstyres uden adgangskode.",
"The aggregated statistics are publicly available at the URL below.": "Den indsamlede statistik er offentligt tilgængelig på den nedenstående URL.",
"The cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"The cleanup interval cannot be blank.": "Ryd op interval kan ikke være tom.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfigurationen er gemt, men ikke aktiveret. Syncthing skal genstarte for at aktivere den nye konfiguration.",
"The device ID cannot be blank.": "Enhedens ID må ikke være tom.",
"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).": "Det enheds-ID, som skal indtastes her, kan findes under menuen “Handlinger > Vis ID” på den anden enhed. Mellemrum og bindestreger er valgfri (ignoreres).",
@@ -310,8 +330,9 @@
"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.": "De følgende intervaller er brugt: Inden for den første time bliver en version gemt hvert 30. sekund, inden for den første dag bliver en version gemt hver time, inden for de første 30 dage bliver en version gemt hver dag, og indtil den maksimale alder bliver en version gemt hver uge.",
"The following items could not be synchronized.": "Følgende filer kunne ikke synkroniseres.",
"The following items were changed locally.": "De følgende filer er ændret lokalt.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The following unexpected items were found.": "Følgende ikke-forventet emner blev fundet.",
"The interval must be a positive number of seconds.": "Intervallet skal være et positivt antal sekunder.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Interval i sekunder for kørsel af oprydning i versionskatalog. Nul vil deaktivere periodisk rengøring.",
"The maximum age must be a number and cannot be blank.": "Maksimal alder skal være et tal og feltet må ikke være tomt.",
"The maximum time to keep a version (in days, set to 0 to keep versions forever).": "Den maksimale tid, en version skal gemmes (i dage; sæt lig med 0 for at beholde gamle versioner for altid).",
"The number of days must be a number and cannot be blank.": "Antallet af dage skal være et tal og feltet må ikke være tomt.",
@@ -321,7 +342,8 @@
"The path cannot be blank.": "Stien må ikke være tom.",
"The rate limit must be a non-negative number (0: no limit)": "Hastighedsbegrænsningen skal være et ikke-negativt tal (0: ingen begrænsning)",
"The rescan interval must be a non-negative number of seconds.": "Genskanningsintervallet skal være et ikke-negativt antal sekunder.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no devices to share this folder with.": "Der er ingen enheder at dele denne mappe med.",
"There are no folders to share with this device.": "Der er ingen mapper at dele med denne enhed.",
"They are retried automatically and will be synced when the error is resolved.": "De prøves igen automatisk og vil blive synkroniseret, når fejlen er løst.",
"This Device": "Denne enhed",
"This can easily give hackers access to read and change any files on your computer.": "Dette gør det nemt for hackere at få adgang til at læse og ændre filer på din computer.",
@@ -335,10 +357,14 @@
"Unavailable": "Ikke tilgængelig",
"Unavailable/Disabled by administrator or maintainer": "Ikke tilgængelig / deaktiveret af administrator eller vedligeholder",
"Undecided (will prompt)": "Ubestemt (du bliver spurgt)",
"Unexpected Items": "Ikke forventede elementer",
"Unexpected items have been found in this folder.": "Ikke-forventet emner blev fundet i denne mappe.",
"Unignore": "Fjern ignorering",
"Unknown": "Ukendt",
"Unshared": "Ikke delt",
"Unshared Devices": "Ikke delte enheder",
"Unshared Folders": "Ikke delte mapper",
"Untrusted": "Ikke troværdig",
"Up to Date": "Fuldt opdateret",
"Updated": "Opdateret",
"Upgrade": "Opgradér",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Du har ingen ignorerede mapper.",
"You have unsaved changes. Do you really want to discard them?": "Du har ændringer, som ikke er gemt. Er du sikker på, at du ikke vil beholde dem?",
"You must keep at least one version.": "Du skal beholde mindst én version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dage",
"directories": "kataloger",
"files": "filer",
@@ -381,5 +408,6 @@
"items": "filer",
"seconds": "sekunder",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker at dele mappen “{{folder}}”.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker at dele mappen “{{folderlabel}}” ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker at dele mappen “{{folderlabel}}” ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Erweitert",
"Advanced Configuration": "Erweiterte Konfiguration",
"All Data": "Alle Daten",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Alle Ordner, welche mit diesem Gerät geteilt werden müssen von einem Passwort geschützt werden, sodass die gesendeten Daten ohne Kenntnis des Passworts nicht gelesen werden können. ",
"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. If the path to the application contains spaces, it should be quoted.": "Ein externer Befehl behandelt die Versionierung. Die Datei aus dem freigegebenen Ordner muss entfernen werden. Wenn der Pfad der Anwendung Leerzeichen enthält, sollte dieser in Anführungszeichen stehen.",
"Anonymous Usage Reporting": "Anonymer Nutzungsbericht",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Das Format des anonymen Nutzungsberichts hat sich geändert. Möchten Sie auf das neue Format umsteigen?",
"Are you sure you want to permanently delete all these files?": "Sind Sie sicher, dass Sie all diese Dateien dauerhaft löschen möchten?",
"Are you sure you want to remove device {%name%}?": "Sind Sie sicher, dass sie das Gerät {{name}} entfernen möchten?",
"Are you sure you want to remove folder {%label%}?": "Sind Sie sicher, dass sie den Ordner {{label}} entfernen möchten?",
"Are you sure you want to restore {%count%} files?": "Sind Sie sicher, dass Sie {{count}} Dateien wiederherstellen möchten?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Derzeit mit Geräten geteilt",
"Danger!": "Achtung!",
"Debugging Facilities": "Debugging-Möglichkeiten",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Standardmäßiger Ordnerpfad",
"Defaults": "Defaults",
"Delete Unexpected Items": "Unerwartete Elemente löschen",
"Deleted": "Gelöscht",
"Deselect All": "Alle abwählen",
"Deselect devices to stop sharing this folder with.": "Die Geräte abwählen, für die dieser Ordner nicht mehr freigegeben werden soll.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Gerät",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Gerät \"{{name}}\" ({{device}} {{address}}) möchte sich verbinden. Gerät hinzufügen?",
"Device ID": "Gerätekennung",
"Device Identification": "Geräteidentifikation",
"Device Name": "Gerätename",
"Device is untrusted, enter encryption password": "Gerät wird nicht vertraut, Verschlüsselungspasswort eingeben",
"Device rate limits": "Gerät Datenratelimit",
"Device that last modified the item": "Gerät, das das Element zuletzt geändert hat",
"Devices": "Geräte",
@@ -92,7 +101,9 @@
"Downloading": "Lädt herunter",
"Edit": "Bearbeiten",
"Edit Device": "Gerät bearbeiten",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Ordner bearbeiten",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Bearbeite {{path}}.",
"Enable Crash Reporting": "Absturzmeldung aktivieren",
"Enable NAT traversal": "NAT-Durchdringung aktivieren",
@@ -122,6 +133,7 @@
"Folder Label": "Ordnerbezeichnung",
"Folder Path": "Ordnerpfad",
"Folder Type": "Ordnertyp",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Der Ordnertyp \"{{receiveEncrypted}}\" kann nach dem Hinzufügen nicht geändert werden. Sie müssen den Ordner entweder entfernen, löschen oder die Daten auf dem Speichermedium entschlüsseln und anschließend den Order wieder neu hinzufügen.",
"Folders": "Ordner",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Bei den folgenden Ordnern ist ein Fehler aufgetreten, während Sie nach Änderungen suchten. Es wird jede Minute erneut gesucht, damit die Fehler bald verschwinden. Falls die Fehler bestehen bleiben, versuchen Sie, das zugrunde liegende Problem zu beheben, und fragen Sie evtl. nach Hilfe.",
"Full Rescan Interval (s)": "Vollständiges Scanintervall (s)",
@@ -139,6 +151,7 @@
"Help": "Hilfe",
"Home page": "Homepage",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Ihre aktuellen Einstellungen weisen jedoch daraufhin, dass Sie die Aktivierung möglicherweise nicht wünschen. Wir haben die automatischen Absturzberichte für Sie deaktiviert.",
"If untrusted, enter encryption password": "Wenn nicht vertraut, geben Sie das Verschlüsselungspasswort ein",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Falls Sie andere Benutzer dieses Computers daran hindern möchten auf Syncthing und somit ihren Dateien Zugriff zu haben, setzen Sie bitte einen Benutzernamen und Passwort.",
"Ignore": "Ignorieren",
"Ignore Patterns": "Ignoriermuster",
@@ -187,6 +200,7 @@
"No File Versioning": "Keine Dateiversionierung",
"No files will be deleted as a result of this operation.": "Durch diesen Vorgang werden keine Dateien gelöscht.",
"No upgrades": "Keine Aktualisierungen",
"Not shared": "Nicht geteilt",
"Notice": "Hinweis",
"OK": "OK",
"Off": "Aus",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Vorschau des Nutzungsberichts",
"Quick guide to supported patterns": "Schnellanleitung zu den unterstützten Mustern",
"Random": "Zufall",
"Receive Encrypted": "Empfange verschlüsselt",
"Receive Only": "Nur empfangen",
"Received data is already encrypted": "Empfangene Daten sind bereits verschlüsselt",
"Recent Changes": "Letzte Änderungen",
"Reduced by ignore patterns": "Durch Ignoriermuster reduziert",
"Release Notes": "Veröffentlichungshinweise",
"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": "Externe Geräte",
"Remote GUI": "Remote GUI",
"Remove": "Entfernen",
"Remove Device": "Gerät entfernen",
"Remove Folder": "Ordner entfernen",
@@ -249,6 +266,7 @@
"Select All": "Alle auswählen",
"Select a version": "Wählen Sie eine Version",
"Select additional devices to share this folder with.": "Weitere Geräte auswählen, für die dieser Ordner geteilt werden soll.",
"Select additional folders to share with this device.": "Wählen Sie weitere Ordner, um sie mit diesem Gerät zu teilen.",
"Select latest version": "Letzte Version auswählen",
"Select oldest version": "Älteste Version auswählen",
"Select the folders to share with this device.": "Wähle Sie die Ordner aus, die Sie mit diesem Gerät teilen möchten.",
@@ -259,6 +277,7 @@
"Share Folder": "Ordner teilen",
"Share Folders With Device": "Ordner mit diesem Gerät teilen",
"Share this folder?": "Diesen Ordner teilen?",
"Shared Folders": "Geteilte Ordner",
"Shared With": "Geteilt mit",
"Sharing": "Teilen",
"Show ID": "Eigene Kennung",
@@ -281,6 +300,7 @@
"Start Browser": "Browser starten",
"Statistics": "Statistiken",
"Stopped": "Gestoppt",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Speichert und synchronisiert nur verschlüsselte Daten. Ordner auf allen verbundenen Geräten müssen mit dem selben Passwort eingerichtet werden oder vom Typ \"{{receiveEncrypted}}\" sein.",
"Support": "Support",
"Support Bundle": "Supportpaket",
"Sync Protocol Listen Addresses": "Adresse(n) für das Synchronisierungsprotokoll",
@@ -310,6 +330,7 @@
"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.": "Es wird in folgenden Abständen versioniert: In der ersten Stunde wird alle 30 Sekunden eine Version behalten, am ersten Tag eine jede Stunde, in den ersten 30 Tagen eine jeden Tag. Danach wird bis zum angegebenen Höchstalter eine Version pro Woche behalten.",
"The following items could not be synchronized.": "Die folgenden Elemente konnten nicht synchronisiert werden.",
"The following items were changed locally.": "Die folgenden Elemente wurden lokal geändert.",
"The following unexpected items were found.": "Die folgenden unerwarteten Elemente wurden gefunden.",
"The interval must be a positive number of seconds.": "Das Intervall muss eine positive Zahl von Sekunden sein.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Das Intervall, in Sekunden, zwischen den Bereinigungen im Versionsverzeichnis. 0 um das regelmäßige Bereinigen zu deaktivieren.",
"The maximum age must be a number and cannot be blank.": "Das Höchstalter muss angegeben werden und eine Zahl sein.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Das Datenratelimit muss eine nicht negative Zahl sein (0 = kein Limit).",
"The rescan interval must be a non-negative number of seconds.": "Das Scanintervall muss eine nicht negative Anzahl (in Sekunden) sein.",
"There are no devices to share this folder with.": "Es gibt keine Geräte, mit denen dieser Ordner geteilt werden kann.",
"There are no folders to share with this device.": "Es gibt keine Ordner, die mit diesem Gerät geteilt werden können.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": " Nicht verfügbar",
"Unavailable/Disabled by administrator or maintainer": "Nicht verfügbar/durch Administrator oder Betreuer deaktiviert",
"Undecided (will prompt)": "Unentschlossen (wird nachgefragt)",
"Unexpected Items": "Unerwartete Elemente",
"Unexpected items have been found in this folder.": "In diesem Ordner wurden unerwartete Elemente gefunden.",
"Unignore": "Beachten",
"Unknown": "Unbekannt",
"Unshared": "Ungeteilt",
"Unshared Devices": "Ungeteilte Geräte",
"Unshared Devices": "Nicht geteilte Geräte",
"Unshared Folders": "Nicht geteilte Ordner",
"Untrusted": "Nicht vertraut",
"Up to Date": "Aktuell",
"Updated": "Aktualisiert",
"Upgrade": "Aktualisierung",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Sie haben keine ignorierten Ordner.",
"You have unsaved changes. Do you really want to discard them?": "Sie haben nicht gespeicherte Änderungen. Wollen sie diese wirklich verwerfen?",
"You must keep at least one version.": "Du musst mindestens eine Version behalten.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Sie sollten nie etwas im \"{{receiveEncrypted}}\" Ordner lokal ändern oder hinzufügen.",
"days": "Tage",
"directories": "Verzeichnisse",
"files": "Dateien",
@@ -381,5 +408,6 @@
"items": "Elemente",
"seconds": "Sekunden",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} möchte den Ordner \"{{folder}}\" teilen.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} möchte den Ordner \"{{folderlabel}}\" ({{folder}}) teilen."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} möchte den Ordner \"{{folderlabel}}\" ({{folder}}) teilen.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} könnte dieses Gerät wieder einführen."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Προχωρημένες",
"Advanced Configuration": "Προχωρημένες ρυθμίσεις",
"All Data": "Όλα τα δεδομένα",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Να επιτρέπεται η αποστολή ανώνυμων στοιχείων χρήσης;",
"Allowed Networks": "Επιτρεπόμενα δίκτυα",
"Alphabetic": "Αλφαβητικά",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Μια εξωτερική εντολή χειρίζεται την τήρηση εκδόσεων και αναλαμβάνει να αφαιρέσει το αρχείο από τον συγχρονισμένο φάκελο. Αν η διαδρομή προς την εφαρμογή περιέχει διαστήματα, πρέπει να εσωκλείεται σε εισαγωγικά. ",
"Anonymous Usage Reporting": "Ανώνυμα στοιχεία χρήσης",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Η μορφή της αναφοράς ανώνυμων στοιχείων χρήσης έχει αλλάξει. Επιθυμείτε να μεταβείτε στη νέα μορφή;",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Σίγουρα επιθυμείτε να αφαιρέσετε τη συσκευή {{name}};",
"Are you sure you want to remove folder {%label%}?": "Σίγουρα επιθυμείτε να αφαιρέσετε τον φάκελο {{label}};",
"Are you sure you want to restore {%count%} files?": "Σίγουρα επιθυμείτε να επαναφέρετε {{count}} αρχεία;",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Διαμοιράζεται με αυτές τις συσκευές",
"Danger!": "Προσοχή!",
"Debugging Facilities": "Εργαλεία αποσφαλμάτωσης",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Προκαθορισμένη διαδρομή φακέλων",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Διαγραμμένα",
"Deselect All": "Αποεπιλογή όλων",
"Deselect devices to stop sharing this folder with.": "Αποεπιλέξτε συσκευές για να σταματήσει ο διαμοιρασμός του φακέλου με αυτές.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Συσκευή",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Η συσκευή \"{{name}}\" ({{device}} στη διεύθυνση {{address}}) επιθυμεί να συνδεθεί. Προσθήκη της νέας συσκευής;",
"Device ID": "Ταυτότητα συσκευής",
"Device Identification": "Ταυτότητα συσκευής",
"Device Name": "Όνομα συσκευής",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Όρια ταχύτητας συσκευών",
"Device that last modified the item": "Συσκευή από την οποία πραγματοποιήθηκε η τελευταία τροποποίηση του στοιχείου",
"Devices": "Συσκευές",
@@ -92,7 +101,9 @@
"Downloading": "Λήψη",
"Edit": "Επεξεργασία",
"Edit Device": "Επεξεργασία συσκευής",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Επεξεργασία φακέλου",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Επεξεργασία του {{path}}.",
"Enable Crash Reporting": "Ενεργοποίηση αναφοράς σφαλμάτων",
"Enable NAT traversal": "Ενεργοποίηση διάσχισης NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Ετικέτα φακέλου",
"Folder Path": "Μονοπάτι φακέλου",
"Folder Type": "Τύπος φακέλου",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Φάκελοι",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Στους παρακάτω φακέλους εμφανίστηκε σφάλμα κατά την ενεργοποίηση της επιτήρησης αλλαγών. Καθώς θα γίνεται νέα προσπάθεια κάθε λεπτό, ενδέχεται αυτά τα σφάλματα να διορθωθούν από μόνα τους. Αν παραμείνουν, προσπαθήστε να επιλύσετε το βασικό αίτιο ή ζητήστε βοήθεια αν δεν μπορείτε.",
"Full Rescan Interval (s)": "Διάστημα πλήρων επανασαρώσεων (s)",
@@ -139,6 +151,7 @@
"Help": "Βοήθεια",
"Home page": "Αρχική σελίδα",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Ωστόσο, σύμφωνα με τις τρέχουσες ρυθμίσεις σας, μάλλον δεν επιθυμείτε αυτή τη λειτουργία. Οι αναφορές σφαλμάτων απενεργοποιήθηκαν.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Αγνόησε",
"Ignore Patterns": "Πρότυπο για αγνόηση",
@@ -187,6 +200,7 @@
"No File Versioning": "Να μην τηρούνται εκδόσεις",
"No files will be deleted as a result of this operation.": "Δεν πρόκειται να διαγραφούν αρχεία με αυτή την ενέργεια.",
"No upgrades": "Απενεργοποιημένες",
"Not shared": "Not shared",
"Notice": "Σημείωση",
"OK": "OK",
"Off": "Απενεργοποιημένο",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Προεπισκόπηση αναφοράς χρήσης",
"Quick guide to supported patterns": "Σύντομη βοήθεια σχετικά με τα πρότυπα αναζήτησης που υποστηρίζονται",
"Random": "Τυχαία",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Μόνο λήψη",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Πρόσφατες αλλαγές",
"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": "Απομακρυσμένες συσκευές",
"Remote GUI": "Remote GUI",
"Remove": "Αφαίρεση",
"Remove Device": "Αφαίρεση συσκευής",
"Remove Folder": "Αφαίρεση φακέλου",
@@ -249,6 +266,7 @@
"Select All": "Επιλογή όλων",
"Select a version": "Επιλογή έκδοσης",
"Select additional devices to share this folder with.": "Επιλέξτε επιπλέον συσκευές με τις οποίες θα διαμοιράζεται αυτός ο φάκελος.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Επιλογή τελευταίας έκδοσης",
"Select oldest version": "Επιλογή παλαιότερης έκδοσης",
"Select the folders to share with this device.": "Διάλεξε ποιοι φάκελοι θα διαμοιράζονται προς αυτή τη συσκευή.",
@@ -259,6 +277,7 @@
"Share Folder": "Διαμοίραση φακέλου",
"Share Folders With Device": "Διαμοίρασε τους φακέλους προς αυτή τη συσκευή",
"Share this folder?": "Να διαμοιραστεί αυτός ο φάκελος;",
"Shared Folders": "Shared Folders",
"Shared With": "Διαμοιράζεται με",
"Sharing": "Διαμοιρασμός",
"Show ID": "Εμφάνιση ταυτότητας",
@@ -281,6 +300,7 @@
"Start Browser": "Εκκίνηση προγράμματος περιήγησης",
"Statistics": "Στατιστικά",
"Stopped": "Απενεργοποιημένο",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Υποστήριξη",
"Support Bundle": "Πακέτο υποστήριξης",
"Sync Protocol Listen Addresses": "Διευθύνσεις για το πρωτόκολλο συγχρονισμού",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "Τα παρακάτω στοιχεία τροποποιήθηκαν τοπικά.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Η μέγιστη ηλικία πρέπει να είναι αριθμός και σίγουρα όχι κενό.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Το όριο ταχύτητας πρέπει να είναι ένας μη-αρνητικός αριθμός (0: χωρίς όριο)",
"The rescan interval must be a non-negative number of seconds.": "Ο χρόνος επανελέγχου για αλλαγές είναι σε δευτερόλεπτα (δηλ. θετικός αριθμός).",
"There are no devices to share this folder with.": "Δεν υπάρχουν συσκευές με τις οποίες διαμοιράζεται αυτός ο φάκελος.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "Αυτό μπορεί εύκολα να δώσει πρόσβαση ανάγνωσης και επεξεργασίας αρχείων του υπολογιστή σας σε χάκερς.",
@@ -335,10 +357,14 @@
"Unavailable": "Μη διαθέσιμο",
"Unavailable/Disabled by administrator or maintainer": "Μη διαθέσιμο/απενεργοποιημένο από τον διαχειριστή ή υπεύθυνο διανομής",
"Undecided (will prompt)": "Μη καθορισμένη (θα γίνει ερώτηση)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Αναίρεση αγνόησης",
"Unknown": "Άγνωστο",
"Unshared": "Δε μοιράζεται",
"Unshared Devices": "Συσκευές χωρίς διαμοιρασμό",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Ενημερωμένη",
"Updated": "Ενημερωμένο",
"Upgrade": "Αναβάθμιση",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Δεν έχετε αγνοηθέντες φακέλους.",
"You have unsaved changes. Do you really want to discard them?": "Έχετε μη αποθηκευμένες αλλαγές. Σίγουρα επιθυμείτε να τις απορρίψετε;",
"You must keep at least one version.": "Πρέπει να τηρήσεις τουλάχιστον μια έκδοση.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "Μέρες",
"directories": "κατάλογοι",
"files": "αρχεία",
@@ -381,5 +408,6 @@
"items": "εγγραφές",
"seconds": "δευτερόλεπτα",
"{%device%} wants to share folder \"{%folder%}\".": "Η συσκευή {{device}} θέλει να μοιράσει τον φάκελο «{{folder}}».",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "Η συσκευή {{device}} επιθυμεί να διαμοιράσει τον φάκελο \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "Η συσκευή {{device}} επιθυμεί να διαμοιράσει τον φάκελο \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -0,0 +1,413 @@
{
"A device with that ID is already added.": "A device with that ID is already added.",
"A negative number of days doesn't make sense.": "A negative number of days doesn't make sense.",
"A new major version may not be compatible with previous versions.": "A new major version may not be compatible with previous versions.",
"API Key": "API Key",
"About": "About",
"Action": "Action",
"Actions": "Actions",
"Add": "Add",
"Add Device": "Add Device",
"Add Folder": "Add 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?": "Add new folder?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.",
"Address": "Address",
"Addresses": "Addresses",
"Advanced": "Advanced",
"Advanced Configuration": "Advanced Configuration",
"All Data": "All Data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"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?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Are you sure you want to remove device {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Are you sure you want to remove folder {{label}}?",
"Are you sure you want to restore {%count%} files?": "Are you sure you want to restore {{count}} files?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Auto Accept": "Auto Accept",
"Automatic Crash Reporting": "Automatic Crash Reporting",
"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",
"Automatic upgrades are always enabled for candidate releases.": "Automatic upgrades are always enabled for candidate releases.",
"Automatically create or share folders that this device advertises at the default path.": "Automatically create or share folders that this device advertises at the default path.",
"Available debug logging facilities:": "Available debug logging facilities:",
"Be careful!": "Be careful!",
"Bugs": "Bugs",
"Changelog": "Changelog",
"Clean out after": "Clean out after",
"Cleaning Versions": "Cleaning Versions",
"Cleanup Interval": "Cleanup Interval",
"Click to see discovery failures": "Click to see discovery failures",
"Close": "Close",
"Command": "Command",
"Comment, when used at the start of a line": "Comment, when used at the start of a line",
"Compression": "Compression",
"Configured": "Configured",
"Connected (Unused)": "Connected (Unused)",
"Connection Error": "Connection Error",
"Connection Type": "Connection Type",
"Connections": "Connections",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that fewer full scans are required.",
"Copied from elsewhere": "Copied from elsewhere",
"Copied from original": "Copied from original",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Creating ignore patterns, overwriting an existing file at {{path}}.",
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Danger!",
"Debugging Facilities": "Debugging Facilities",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Default Folder Path",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Deleted",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"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": "Device ID",
"Device Identification": "Device Identification",
"Device Name": "Device Name",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Device that last modified the item",
"Devices": "Devices",
"Disable Crash Reporting": "Disable Crash Reporting",
"Disabled": "Disabled",
"Disabled periodic scanning and disabled watching for changes": "Disabled periodic scanning and disabled watching for changes",
"Disabled periodic scanning and enabled watching for changes": "Disabled periodic scanning and enabled watching for changes",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).",
"Discard": "Discard",
"Disconnected": "Disconnected",
"Disconnected (Unused)": "Disconnected (Unused)",
"Discovered": "Discovered",
"Discovery": "Discovery",
"Discovery Failures": "Discovery Failures",
"Do not restore": "Do not restore",
"Do not restore all": "Do not restore all",
"Do you want to enable watching for changes for all your folders?": "Do you want to enable watching for changes for all your folders?",
"Documentation": "Documentation",
"Download Rate": "Download Rate",
"Downloaded": "Downloaded",
"Downloading": "Downloading",
"Edit": "Edit",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Editing {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable NAT traversal": "Enable NAT traversal",
"Enable Relaying": "Enable Relaying",
"Enabled": "Enabled",
"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.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Error": "Error",
"External File Versioning": "External File Versioning",
"Failed Items": "Failed Items",
"Failed to setup, retrying": "Failed to setup, retrying",
"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": "File Pull Order",
"File Versioning": "File Versioning",
"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 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "Files are synchronised from the cluster, but any changes made locally will not be sent to other devices.",
"Filesystem Watcher Errors": "Filesystem Watcher Errors",
"Filter by date": "Filter by date",
"Filter by name": "Filter by name",
"Folder": "Folder",
"Folder ID": "Folder ID",
"Folder Label": "Folder Label",
"Folder Path": "Folder Path",
"Folder Type": "Folder Type",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Folders",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Full Rescan Interval (s)",
"GUI": "GUI",
"GUI Authentication Password": "GUI Authentication Password",
"GUI Authentication User": "GUI Authentication User",
"GUI Authentication: Set User and Password": "GUI Authentication: Set User and Password",
"GUI Listen Address": "GUI Listen Address",
"GUI Theme": "GUI Theme",
"General": "General",
"Generate": "Generate",
"Global Discovery": "Global Discovery",
"Global Discovery Servers": "Global Discovery Servers",
"Global State": "Global State",
"Help": "Help",
"Home page": "Home page",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignore",
"Ignore Patterns": "Ignore Patterns",
"Ignore Permissions": "Ignore Permissions",
"Ignored Devices": "Ignored Devices",
"Ignored Folders": "Ignored Folders",
"Ignored at": "Ignored at",
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Incorrect configuration may damage your folder contents and render Syncthing inoperable.",
"Introduced By": "Introduced By",
"Introducer": "Introducer",
"Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)",
"Keep Versions": "Keep Versions",
"LDAP": "LDAP",
"Largest First": "Largest First",
"Last Scan": "Last Scan",
"Last seen": "Last seen",
"Latest Change": "Latest Change",
"Learn more": "Learn more",
"Limit": "Limit",
"Listeners": "Listeners",
"Loading data...": "Loading data...",
"Loading...": "Loading...",
"Local Additions": "Local Additions",
"Local Discovery": "Local Discovery",
"Local State": "Local State",
"Local State (Total)": "Local State (Total)",
"Locally Changed Items": "Locally Changed Items",
"Log": "Log",
"Log tailing paused. Scroll to the bottom to continue.": "Log tailing paused. Scroll to the bottom to continue.",
"Logs": "Logs",
"Major Upgrade": "Major Upgrade",
"Mass actions": "Mass actions",
"Maximum Age": "Maximum Age",
"Metadata Only": "Metadata Only",
"Minimum Free Disk Space": "Minimum Free Disk Space",
"Mod. Device": "Mod. Device",
"Mod. Time": "Mod. Time",
"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 files will be deleted as a result of this operation.": "No files will be deleted as a result of this operation.",
"No upgrades": "No upgrades",
"Not shared": "Not shared",
"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 new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {{tilde}}.",
"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).",
"Pause": "Pause",
"Pause All": "Pause All",
"Paused": "Paused",
"Paused (Unused)": "Paused (Unused)",
"Pending changes": "Pending changes",
"Periodic scanning at given interval and disabled watching for changes": "Periodic scanning at given interval and disabled watching for changes",
"Periodic scanning at given interval and enabled watching for changes": "Periodic scanning at given interval and enabled watching for changes",
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:",
"Permissions": "Permissions",
"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",
"Preparing to Sync": "Preparing to Sync",
"Preview": "Preview",
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
"Random": "Random",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Receive Only",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Recent Changes",
"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",
"Remote GUI": "Remote GUI",
"Remove": "Remove",
"Remove Device": "Remove Device",
"Remove Folder": "Remove Folder",
"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",
"Rescans": "Rescans",
"Restart": "Restart",
"Restart Needed": "Restart Needed",
"Restarting": "Restarting",
"Restore": "Restore",
"Restore Versions": "Restore Versions",
"Resume": "Resume",
"Resume All": "Resume All",
"Reused": "Reused",
"Revert Local Changes": "Revert Local Changes",
"Save": "Save",
"Scan Time Remaining": "Scan Time Remaining",
"Scanning": "Scanning",
"See external versioning help for supported templated command line parameters.": "See external versioning help for supported templated command line parameters.",
"Select All": "Select All",
"Select a version": "Select a version",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Select latest version",
"Select oldest version": "Select oldest version",
"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 this folder?": "Share this folder?",
"Shared Folders": "Shared Folders",
"Shared With": "Shared With",
"Sharing": "Sharing",
"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",
"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)",
"Size": "Size",
"Smallest First": "Smallest First",
"Some items could not be restored:": "Some items could not be restored:",
"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",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Support",
"Support Bundle": "Support Bundle",
"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 Free and Open Source Software licensed as MPL v2.0.": "Syncthing is Free and Open Source Software licensed as MPL v2.0.",
"Syncthing is restarting.": "Syncthing is restarting.",
"Syncthing is upgrading.": "Syncthing is upgrading.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.",
"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.",
"Take me back": "Take me back",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.",
"The Syncthing Authors": "The Syncthing Authors",
"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 cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"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 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 synchronised.",
"The following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"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 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 bin. 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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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",
"Time the item was last modified": "Time the item was last modified",
"Trash Can File Versioning": "Bin File Versioning",
"Type": "Type",
"UNIX Permissions": "UNIX Permissions",
"Unavailable": "Unavailable",
"Unavailable/Disabled by administrator or maintainer": "Unavailable/Disabled by administrator or maintainer",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"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",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Username/Password has not been set for the GUI authentication. Please consider setting it up.",
"Version": "Version",
"Versions": "Versions",
"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.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"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}}).",
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "Warning: If you are using an external watcher like {{syncthingInotify}}, you should make sure it is deactivated.",
"Watch for Changes": "Watch for Changes",
"Watching for Changes": "Watching for Changes",
"Watching for changes discovers most changes without periodic scanning.": "Watching for changes discovers most changes without periodic scanning.",
"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 have no ignored devices.": "You have no ignored devices.",
"You have no ignored folders.": "You have no ignored folders.",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You must keep at least one version.": "You must keep at least one version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "days",
"directories": "directories",
"files": "files",
"full documentation": "full documentation",
"items": "items",
"seconds": "seconds",
"{%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}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Advanced",
"Advanced Configuration": "Advanced Configuration",
"All Data": "All Data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"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?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Are you sure you want to remove device {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Are you sure you want to remove folder {{label}}?",
"Are you sure you want to restore {%count%} files?": "Are you sure you want to restore {{count}} files?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Danger!",
"Debugging Facilities": "Debugging Facilities",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Default Folder Path",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Deleted",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"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": "Device ID",
"Device Identification": "Device Identification",
"Device Name": "Device Name",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Device that last modified the item",
"Devices": "Devices",
@@ -92,7 +101,9 @@
"Downloading": "Downloading",
"Edit": "Edit",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Editing {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable NAT traversal": "Enable NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Folder Label",
"Folder Path": "Folder Path",
"Folder Type": "Folder Type",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Folders",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Full Rescan Interval (s)",
@@ -139,6 +151,7 @@
"Help": "Help",
"Home page": "Home page",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignore",
"Ignore Patterns": "Ignore Patterns",
@@ -187,6 +200,7 @@
"No File Versioning": "No File Versioning",
"No files will be deleted as a result of this operation.": "No files will be deleted as a result of this operation.",
"No upgrades": "No upgrades",
"Not shared": "Not shared",
"Notice": "Notice",
"OK": "OK",
"Off": "Off",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
"Random": "Random",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Receive Only",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Recent Changes",
"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 fortnightly Syncthing releases.",
"Remote Devices": "Remote Devices",
"Remote GUI": "Remote GUI",
"Remove": "Remove",
"Remove Device": "Remove Device",
"Remove Folder": "Remove Folder",
@@ -249,6 +266,7 @@
"Select All": "Select All",
"Select a version": "Select a version",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Select latest version",
"Select oldest version": "Select oldest version",
"Select the folders to share with this device.": "Select the folders to share with this device.",
@@ -259,6 +277,7 @@
"Share Folder": "Share Folder",
"Share Folders With Device": "Share Folders With Device",
"Share this folder?": "Share this folder?",
"Shared Folders": "Shared Folders",
"Shared With": "Shared With",
"Sharing": "Sharing",
"Show ID": "Show ID",
@@ -281,6 +300,7 @@
"Start Browser": "Start Browser",
"Statistics": "Statistics",
"Stopped": "Stopped",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Support",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
@@ -310,6 +330,7 @@
"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 synchronised.",
"The following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.",
@@ -322,6 +343,7 @@
"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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": "Unavailable",
"Unavailable/Disabled by administrator or maintainer": "Unavailable/Disabled by administrator or maintainer",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "You have no ignored folders.",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You must keep at least one version.": "You must keep at least one version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "days",
"directories": "directories",
"files": "files",
@@ -381,5 +408,6 @@
"items": "items",
"seconds": "seconds",
"{%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}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Advanced",
"Advanced Configuration": "Advanced Configuration",
"All Data": "All Data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
"Allowed Networks": "Allowed Networks",
"Alphabetic": "Alphabetic",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"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?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Are you sure you want to remove device {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Are you sure you want to remove folder {{label}}?",
"Are you sure you want to restore {%count%} files?": "Are you sure you want to restore {{count}} files?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Danger!",
"Debugging Facilities": "Debugging Facilities",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Default Folder Path",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Deleted",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"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": "Device ID",
"Device Identification": "Device Identification",
"Device Name": "Device Name",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Device that last modified the item",
"Devices": "Devices",
@@ -92,7 +101,9 @@
"Downloading": "Downloading",
"Edit": "Edit",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Editing {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable NAT traversal": "Enable NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Folder Label",
"Folder Path": "Folder Path",
"Folder Type": "Folder Type",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Folders",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Full Rescan Interval (s)",
@@ -139,6 +151,7 @@
"Help": "Help",
"Home page": "Home page",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignore",
"Ignore Patterns": "Ignore Patterns",
@@ -187,6 +200,7 @@
"No File Versioning": "No File Versioning",
"No files will be deleted as a result of this operation.": "No files will be deleted as a result of this operation.",
"No upgrades": "No upgrades",
"Not shared": "Not shared",
"Notice": "Notice",
"OK": "OK",
"Off": "Off",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Preview Usage Report",
"Quick guide to supported patterns": "Quick guide to supported patterns",
"Random": "Random",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Receive Only",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Recent Changes",
"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",
"Remote GUI": "Remote GUI",
"Remove": "Remove",
"Remove Device": "Remove Device",
"Remove Folder": "Remove Folder",
@@ -249,6 +266,7 @@
"Select All": "Select All",
"Select a version": "Select a version",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Select latest version",
"Select oldest version": "Select oldest version",
"Select the folders to share with this device.": "Select the folders to share with this device.",
@@ -259,6 +277,7 @@
"Share Folder": "Share Folder",
"Share Folders With Device": "Share Folders With Device",
"Share this folder?": "Share this folder?",
"Shared Folders": "Shared Folders",
"Shared With": "Shared With",
"Sharing": "Sharing",
"Show ID": "Show ID",
@@ -281,6 +300,7 @@
"Start Browser": "Start Browser",
"Statistics": "Statistics",
"Stopped": "Stopped",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Support",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "The maximum age must be a number and cannot be blank.",
@@ -322,6 +343,7 @@
"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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": "Unavailable",
"Unavailable/Disabled by administrator or maintainer": "Unavailable/Disabled by administrator or maintainer",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Unknown",
"Unshared": "Unshared",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Up to Date",
"Updated": "Updated",
"Upgrade": "Upgrade",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "You have no ignored folders.",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You must keep at least one version.": "You must keep at least one version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "days",
"directories": "directories",
"files": "files",
@@ -381,5 +408,6 @@
"items": "items",
"seconds": "seconds",
"{%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}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wants to share folder \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Altnivela",
"Advanced Configuration": "Altnivela Agordo",
"All Data": "Ĉiuj Datumoj",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Permesi Anoniman Raporton de Uzado?",
"Allowed Networks": "Permesitaj Retoj",
"Alphabetic": "Alfabeta",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Ekstera komando manipulas la version. Ĝi devas forigi la dosieron el la komunigita dosierujo. Se la vojo al la apliko elhavas blankoj, ĝi devas esti inter citiloj.",
"Anonymous Usage Reporting": "Anonima Raporto de Uzado",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formato de anonima raporto de uzado ŝanĝis. Ĉu vi ŝatus transiri al la nova formato?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Ĉu vi certas, ke vi volas forigi aparaton {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Ĉu vi certas, ke vi volas forigi dosierujon {{label}}?",
"Are you sure you want to restore {%count%} files?": "Ĉu vi certas, ke vi volas restarigi {{count}} dosierojn?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Nune komunigita kun aparatoj",
"Danger!": "Danĝero!",
"Debugging Facilities": "Elpurigadiloj",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Defaŭlta Dosieruja Vojo",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Forigita",
"Deselect All": "Malelekti Ĉiujn",
"Deselect devices to stop sharing this folder with.": "Malelekti aparatojn por ĉesi komunigi tiun ĉi dosierujon kun ili.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Aparato",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Aparato \"{{name}}\" ({{device}} ĉe {{address}}) volas konekti. Aldoni la novan aparaton?",
"Device ID": "Aparato ID",
"Device Identification": "Identigo de Aparato",
"Device Name": "Nomo de Aparato",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Limoj de rapideco de aparato",
"Device that last modified the item": "Aparato kiu laste modifis la eron",
"Devices": "Aparatoj",
@@ -92,7 +101,9 @@
"Downloading": "Elŝutado",
"Edit": "Redakti",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Redaktado de {{path}}.",
"Enable Crash Reporting": "Ŝalti raportadon de kraŝoj",
"Enable NAT traversal": "Ŝaltu trairan NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Dosieruja Etikedo",
"Folder Path": "Dosieruja Vojo",
"Folder Type": "Dosieruja Tipo",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Dosierujoj",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Por la sekvantaj dosierujoj eraro okazis dum komencado de rigardado je ŝanĝoj. Provante denove ĉiuminute, do eraroj eble foriros baldaŭ. Se ili persistas, provu ripari subkuŝantan problemon kaj petu helpon, se vi ne povas.",
"Full Rescan Interval (s)": "Plena Reskana Intervalo (s)",
@@ -139,6 +151,7 @@
"Help": "Helpo",
"Home page": "Hejma paĝo",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignoru",
"Ignore Patterns": "Ignorantaj Ŝablonoj",
@@ -187,6 +200,7 @@
"No File Versioning": "Sen Dosiera Versionado",
"No files will be deleted as a result of this operation.": "Neniuj dosieroj estos forigitaj rezulte de ĉi tiu ago.",
"No upgrades": "Sen ĝisdatigoj",
"Not shared": "Not shared",
"Notice": "Avizo",
"OK": "Bone",
"Off": "Malŝata",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Antaŭrigardo Uzada Raporto",
"Quick guide to supported patterns": "Rapida gvidilo pri subtenata ŝablonoj",
"Random": "Hazarda",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Nur Ricevi",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Lastatempaj Ŝanĝoj",
"Reduced by ignore patterns": "Malpliigita per ignorantaj ŝablonoj",
"Release Notes": "Notoj de Eldono",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Kandidataj eldonoj enhavas la lastajn trajtojn kaj korektojn. Ili estas similaj al la tradiciaj dusemajnaj Syncthing eldonoj.",
"Remote Devices": "Foraj Aparatoj",
"Remote GUI": "Remote GUI",
"Remove": "Forigu",
"Remove Device": "Forigi Aparaton",
"Remove Folder": "Forigi Dosierujon",
@@ -249,6 +266,7 @@
"Select All": "Elekti Ĉiujn",
"Select a version": "Elekti version",
"Select additional devices to share this folder with.": "Elektu pliajn aparatojn por komunigi tiun ĉi dosierujon kun ili.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Elekti plej novan version",
"Select oldest version": "Elekti plej malnovan version",
"Select the folders to share with this device.": "Elekti la dosierujojn por komunigi kun ĉi tiu aparato.",
@@ -259,6 +277,7 @@
"Share Folder": "Komunigu Dosierujon",
"Share Folders With Device": "Dosierujoj Komunigitaj Kun Aparato",
"Share this folder?": "Komunigi ĉi tiun dosierujon?",
"Shared Folders": "Shared Folders",
"Shared With": "Komunigita Kun",
"Sharing": "Komunigo",
"Show ID": "Montru ID",
@@ -281,6 +300,7 @@
"Start Browser": "Startu Retumilon",
"Statistics": "Statistikoj",
"Stopped": "Haltita",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Subteno",
"Support Bundle": "Pakaĵo por subteno",
"Sync Protocol Listen Addresses": "Aŭskultado Adresoj de Sinkprotokolo",
@@ -310,6 +330,7 @@
"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.": "La jenaj intervaloj estas uzataj: dum la unua horo version restas dum ĉiuj 30 sekundoj, dum la unua tago versio restas konservita dum ĉiu horo, dum la unuaj 30 tagoj versio estas konservita dum ĉiu tago, ĝis la maksimume aĝa versio restas konservita dum ĉiu semajno.",
"The following items could not be synchronized.": "La sekvantaj eroj ne povas esti sinkronigitaj.",
"The following items were changed locally.": "La sekvantaj eroj estis ŝanĝitaj loke.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "La maksimuma aĝo devas esti nombro kaj ne povas esti malplena.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "La rapideca limo devas esti pozitiva nombro (0: senlimo)",
"The rescan interval must be a non-negative number of seconds.": "La intervalo de reskano devas esti pozitiva nombro da sekundoj.",
"There are no devices to share this folder with.": "Estas neniu aparato kun kiu komunigi tiun ĉi dosierujon.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Ili estas reprovitaj aŭtomate kaj estos sinkronigitaj kiam la eraro estas solvita.",
"This Device": "Ĉi Tiu Aparato",
"This can easily give hackers access to read and change any files on your computer.": "Ĉi tio povas facile doni al kodumuloj atingon por legi kaj ŝanĝi ajnajn dosierojn en via komputilo.",
@@ -335,10 +357,14 @@
"Unavailable": "Ne disponebla",
"Unavailable/Disabled by administrator or maintainer": "Ne disponebla/Malebligita de administranto aŭ subtenanto",
"Undecided (will prompt)": "Hezitema (demandos)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Malignoru",
"Unknown": "Nekonata",
"Unshared": "Nekomunigita",
"Unshared Devices": "Malkomunigitaj aparatoj",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Ĝisdata",
"Updated": "Ĝisdatigita",
"Upgrade": "Altgradigo",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Vi havas neniujn ignoritajn dosierujojn.",
"You have unsaved changes. Do you really want to discard them?": "Vi havas ne konservitaj ŝanĝoj. Ĉu vi vere volas forĵeti ilin?",
"You must keep at least one version.": "Vi devas konservi almenaŭ unu version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "tagoj",
"directories": "directories",
"files": "dosieroj",
@@ -381,5 +408,6 @@
"items": "eroj",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} volas komunigi dosierujon \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} volas komunigi dosierujon \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} volas komunigi dosierujon \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,16 +18,18 @@
"Advanced": "Avanzado",
"Advanced Configuration": "Configuración Avanzada",
"All Data": "Todos los datos",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Todos las carpetas compartidas con este equipo deben ser protegidas con una contraseña, de manera que todos los datos enviados sean ilegibles sin la contraseña dada.",
"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. If the path to the application contains spaces, it should be quoted.": "Un comando externo maneja el versionado. Tiene que eliminar el fichero de la carpeta compartida. Si la ruta a la aplicación contiene espacios, hay que escribirla entre comillas.",
"Anonymous Usage Reporting": "Informe anónimo de uso",
"Anonymous usage report format has changed. Would you like to move to the new format?": "El formato del informe anónimo de uso ha cambiado. ¿Quieres cambiar al nuevo formato?",
"Are you sure you want to permanently delete all these files?": "¿Esta seguro(a) de que desea eliminar permanentemente todos estos archivos?",
"Are you sure you want to remove device {%name%}?": "¿Estás seguro de que quieres quitar el dispositivo {{name}}?",
"Are you sure you want to remove folder {%label%}?": "¿Estás seguro de que quieres quitar la carpeta {{label}}?",
"Are you sure you want to restore {%count%} files?": "¿Estás seguro de que quieres restaurar {{count}} ficheros?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Are you sure you want to upgrade?": "¿Está seguro(a) de que desea actualizar?",
"Auto Accept": "Auto aceptar",
"Automatic Crash Reporting": "Informe automático de errores",
"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.",
@@ -39,15 +41,15 @@
"Bugs": "Errores",
"Changelog": "Registro de cambios",
"Clean out after": "Limpiar tras",
"Cleaning Versions": "Cleaning Versions",
"Cleanup Interval": "Cleanup Interval",
"Cleaning Versions": "Limpiando Versiones",
"Cleanup Interval": "Intervalo de Limpieza",
"Click to see discovery failures": "Clica para ver fallos de descubrimiento.",
"Close": "Cerrar",
"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",
"Connected (Unused)": "Connected (Unused)",
"Connected (Unused)": "Conectado (Sin uso)",
"Connection Error": "Error de conexión",
"Connection Type": "Tipo de conexión",
"Connections": "Conexiones",
@@ -56,18 +58,25 @@
"Copied from original": "Copiado del original",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 los siguientes Colaboradores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Crear patrones a ignorar, sobreescribiendo un fichero existente en {{path}}.",
"Currently Shared With Devices": "Currently Shared With Devices",
"Currently Shared With Devices": "Actualmente Compartida Con Los Equipos",
"Danger!": "¡Peligro!",
"Debugging Facilities": "Ayudas a la depuración",
"Default Configuration": "Configuración Por Defecto",
"Default Device": "Equipo Por Defecto",
"Default Folder": "Carpeta Por Defecto",
"Default Folder Path": "Ruta de la carpeta por defecto",
"Defaults": "Valores Por Defecto",
"Delete Unexpected Items": "Borrar Elementos Inesperados",
"Deleted": "Eliminado",
"Deselect All": "Deseleccionar Todo",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect devices to stop sharing this folder with.": "Deseleccione los equipos con los cuales dejar de compartir esta carpeta.",
"Deselect folders to stop sharing with this device.": "Deseleccione las carpetas para dejar de compartir con este equipo.",
"Device": "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",
"Device is untrusted, enter encryption password": "Se desconfía del equipo, ingrese la contraseña de cifrado.",
"Device rate limits": "Límites de la tasa del dispositivo",
"Device that last modified the item": "Último dispositivo que cambió el objeto",
"Devices": "Dispositivos",
@@ -76,10 +85,10 @@
"Disabled periodic scanning and disabled watching for changes": "Desactivados el escaneo periódico y la vigilancia de cambios",
"Disabled periodic scanning and enabled watching for changes": "Desactivado el escaneo periódico y activada la vigilancia de cambios",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Desactivado el escaneo periódico y falló la activación de la vigilancia de cambios, reintentando cada 1 minuto:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Desactiva la comparación y sincronización de los permisos de los archivos. Útil en sistemas con permisos inexistentes o personalizados (por ejemplo, FAT, exFAT, Synology, Android).",
"Discard": "Descartar",
"Disconnected": "Desconectado",
"Disconnected (Unused)": "Disconnected (Unused)",
"Disconnected (Unused)": "Desconectado (Sin uso)",
"Discovered": "Descubierto",
"Discovery": "Descubrimiento",
"Discovery Failures": "Fallos de Descubrimiento",
@@ -91,8 +100,10 @@
"Downloaded": "Descargado",
"Downloading": "Descargando",
"Edit": "Editar",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "Editar Equipo",
"Edit Device Defaults": "Editar Valores Por Defecto del Equipo",
"Edit Folder": "Editar Carpeta",
"Edit Folder Defaults": "Editar Valores Por Defecto de la Carpeta",
"Editing {%path%}.": "Editando {{path}}.",
"Enable Crash Reporting": "Permitir informe de errores",
"Enable NAT traversal": "Permitir NAT transversal",
@@ -102,7 +113,7 @@
"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.": "Introducir direcciones separadas por coma (\"tcp://ip:port\", \"tcp://host:port\") o dinámicas para realizar el descubrimiento automático de la dirección.",
"Enter ignore patterns, one per line.": "Introducir patrones a ignorar, uno por línea.",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Enter up to three octal digits.": "Ingrese hasta tres dígitos octales.",
"Error": "Error",
"External File Versioning": "Versionado externo de fichero",
"Failed Items": "Elementos fallidos",
@@ -122,13 +133,14 @@
"Folder Label": "Etiqueta de la Carpeta",
"Folder Path": "Ruta de la carpeta",
"Folder Type": "Tipo de carpeta",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "El tipo de carpeta \"{{receiveEncrypted}}\" no se puede cambiar después de añadir la carpeta. Es necesario eliminar la carpeta, borrar o descifrar los datos en el disco y volver a añadir la carpeta.",
"Folders": "Carpetas",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Para las siguientes carpetas ocurrió un error cuando se empezó a vigilar los cambios. Se reintentará cada minuto, así que puede ser que los errores desaparezcan pronto. Si persisten, intenta solucionar el problema subyacente y pide ayuda en el caso de que no puedas.",
"Full Rescan Interval (s)": "Intervalo para el reescaneo completo (s)",
"GUI": "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 Authentication: Set User and Password": "GUI Authentication: Set User and Password",
"GUI Authentication: Set User and Password": "Autenticación de la GUI: Establezca el Usuario y la Contraseña.",
"GUI Listen Address": "Dirección de Escucha del GUI.",
"GUI Theme": "Tema GUI",
"General": "General",
@@ -139,7 +151,8 @@
"Help": "Ayuda",
"Home page": "Página de inicio",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Sin embargo, su configuración actual indica que puede no querer habilitarlo. Hemos deshabilitado el informe automático de errores por usted.",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"If untrusted, enter encryption password": "Si no es de confianza, ingrese la contraseña de cifrado.",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Si quiere impedirle a otros usuarios de esta computadora acceder a Syncthing y, a través de este, a sus archivos, considere establecer la autenticación.",
"Ignore": "Ignorar",
"Ignore Patterns": "Patrones a ignorar",
"Ignore Permissions": "Permisos a ignorar",
@@ -162,7 +175,7 @@
"Listeners": "Oyentes",
"Loading data...": "Cargando datos...",
"Loading...": "Cargando...",
"Local Additions": "Local Additions",
"Local Additions": "Adiciones Locales",
"Local Discovery": "Descubrimiento local",
"Local State": "Estado local",
"Local State (Total)": "Estado Local (Total)",
@@ -187,6 +200,7 @@
"No File Versioning": "Sin versionado de fichero",
"No files will be deleted as a result of this operation.": "No se borraron ficheros como resultado de esta operación",
"No upgrades": "Sin actualizaciones",
"Not shared": "No compartida",
"Notice": "Aviso",
"OK": "OK",
"Off": "Desconectar",
@@ -204,7 +218,7 @@
"Pause": "Pausar",
"Pause All": "Pausar todo",
"Paused": "Pausado",
"Paused (Unused)": "Paused (Unused)",
"Paused (Unused)": "Pausado(a) (Sin uso)",
"Pending changes": "Cambios pendientes",
"Periodic scanning at given interval and disabled watching for changes": "Escaneo periódico en un intervalo determinado y desactivada la vigilancia de cambios",
"Periodic scanning at given interval and enabled watching for changes": "Escaneo periódico en un intervalo determinado y activada la vigilancia de cambios",
@@ -215,17 +229,20 @@
"Please wait": "Por favor, espere",
"Prefix indicating that the file can be deleted if preventing directory removal": "El prefijo indica que el fichero puede ser borrado si se previene la eliminación de directorios",
"Prefix indicating that the pattern should be matched without case sensitivity": "El prefijo indica que el patrón se comparará sin tener en cuenta las mayúsculas",
"Preparing to Sync": "Preparing to Sync",
"Preparing to Sync": "Preparándose para Sincronizar",
"Preview": "Vista previa",
"Preview Usage Report": "Informe de uso de vista previa",
"Quick guide to supported patterns": "Guía rápida de patrones soportados",
"Random": "Aleatorio",
"Receive Encrypted": "Recibir Cifrado",
"Receive Only": "Solo recibir",
"Received data is already encrypted": "Los datos recibidos ya están cifrados",
"Recent Changes": "Cambios recientes",
"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",
"Remote GUI": "GUI Remota",
"Remove": "Eliminar",
"Remove Device": "Quitar dispositivo",
"Remove Folder": "Quitar carpeta",
@@ -248,7 +265,8 @@
"See external versioning help for supported templated command line parameters.": "Consultar la ayuda externa del versionado para ver las plantillas de los parámetros de línea de comandos",
"Select All": "Seleccionar Todo",
"Select a version": "Selecciona una versión",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional devices to share this folder with.": "Seleccione equipos adicionales con los cuales compartir esta carpeta",
"Select additional folders to share with this device.": "Seleccione carpetas adicionales para compartir con este equipo.",
"Select latest version": "Selecciona la última versión",
"Select oldest version": "Selecciona la versión más antigua",
"Select the folders to share with this device.": "Selecciona las carpetas para compartir con este dispositivo.",
@@ -259,6 +277,7 @@
"Share Folder": "Compartir carpeta",
"Share Folders With Device": "Compartir carpetas con dispositivo",
"Share this folder?": "¿Deseas compartir esta carpeta?",
"Shared Folders": "Carpetas Compartidas",
"Shared With": "Compartir con",
"Sharing": "Compartiendo",
"Show ID": "Mostrar ID",
@@ -281,6 +300,7 @@
"Start Browser": "Iniciar el navegador",
"Statistics": "Estadísticas",
"Stopped": "Detenido",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Solo almacena y sincroniza datos cifrados. Las carpetas de todos los equipos conectados tienen que ser configuradas con la misma contraseña o ser del tipo \"{{receiveEncrypted}}\" también.",
"Support": "Forum",
"Support Bundle": "Lote de Soporte",
"Sync Protocol Listen Addresses": "Direcciones de escucha del protocolo de sincronización",
@@ -295,10 +315,10 @@
"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.",
"Take me back": "Llévame atrás",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "La dirección del GUI es sobreescrita por las opciones de arranque. Los cambios de aquí no tendrán efecto mientras la sobreescritura esté activa.",
"The Syncthing Authors": "The Syncthing Authors",
"The Syncthing Authors": "Los Autores de Syncthing",
"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 cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"The cleanup interval cannot be blank.": "El intervalo de limpieza no puede ser nulo.",
"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).",
@@ -310,8 +330,9 @@
"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 following items were changed locally.": "Los siguientes ítems fueron cambiados localmente.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The following unexpected items were found.": "Los siguientes elementos inesperados fueron encontrados.",
"The interval must be a positive number of seconds.": "El intervalo debe ser un número positivo de segundos.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "El intervalo, en segundos, para realizar la limpieza del directorio de versiones. Cero para desactivar la limpieza periódica.",
"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 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.",
@@ -321,7 +342,8 @@
"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 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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no devices to share this folder with.": "No hay equipos con los cuales compartir esta carpeta.",
"There are no folders to share with this device.": "No hay carpetas para compartir con este equipo.",
"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 podría permitir fácilmente el acceso a hackers para leer y modificar cualquier fichero de tu equipo.",
@@ -331,14 +353,18 @@
"Time the item was last modified": "Tiempo en el que se modificó el ítem por última vez",
"Trash Can File Versioning": "Versionado de archivos de la papelera",
"Type": "Tipo",
"UNIX Permissions": "UNIX Permissions",
"UNIX Permissions": "Permisos de UNIX",
"Unavailable": "No disponible",
"Unavailable/Disabled by administrator or maintainer": "No disponible/Desactivado por el administrador o el mantenedor",
"Undecided (will prompt)": "Aún no decidido (se preguntará al usuario)",
"Unexpected Items": "Elementos Inesperados",
"Unexpected items have been found in this folder.": "Se han encontrado Elementos Inesperados en esta carpeta.",
"Unignore": "Designorar",
"Unknown": "Desconocido",
"Unshared": "No compartido",
"Unshared Devices": "Unshared Devices",
"Unshared Devices": "Equipos no Compartidos",
"Unshared Folders": "Carpetas no Compartidas",
"Untrusted": "No Confiable",
"Up to Date": "Actualizado",
"Updated": "Actualizado",
"Upgrade": "Actualizar",
@@ -348,14 +374,14 @@
"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)",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Username/Password has not been set for the GUI authentication. Please consider setting it up.",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Usuario/Contraseña no establecida para la autenticación de la GUI. Por favor, considere establecerla.",
"Version": "Versión",
"Versions": "Versiones",
"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.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"Waiting to Clean": "Esperando para Limpiar",
"Waiting to Scan": "Esperando para Escanear",
"Waiting to Sync": "Esperando para Sincronizar",
"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}}\".",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "No tienes carpetas ignoradas.",
"You have unsaved changes. Do you really want to discard them?": "Tienes cambios sin guardar. ¿Quieres descartarlos?",
"You must keep at least one version.": "Debes mantener al menos una versión.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Nunca debe agregar o cambiar nada localmente en una carpeta \"{{receiveEncrypted}}\".",
"days": "días",
"directories": "directories",
"directories": "directorios",
"files": "archivos",
"full documentation": "Documentación completa",
"items": "Elementos",
"seconds": "seconds",
"seconds": "segundos",
"{%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}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quiere compartir la carpeta \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} puede reintroducir este equipo."
}

View File

@@ -18,68 +18,77 @@
"Advanced": "Avanzado",
"Advanced Configuration": "Configuración Avanzada",
"All Data": "Todos los datos",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Todas las carpetas compartidas con este dispositivo deben estar protegidas por una contraseña, de forma que todos los datos enviados sean ilegibles sin la contraseña indicada.",
"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. If the path to the application contains spaces, it should be quoted.": "Un comando externo maneja las versiones. Tienes que eliminar el archivo de la carpeta compartida. Si la ruta a la aplicación contiene espacios, ésta debe estar entre comillas.",
"Anonymous Usage Reporting": "Informe anónimo de uso",
"Anonymous usage report format has changed. Would you like to move to the new format?": "El formato del informe de uso anónimo a cambiado. ¿Desearía usar el nuevo formato?",
"Are you sure you want to permanently delete all these files?": "¿Está seguro de que desea eliminar permanente todos estos archivos?",
"Are you sure you want to remove device {%name%}?": "¿Está seguro que desea eliminar el dispositivo {{name}}?",
"Are you sure you want to remove folder {%label%}?": "¿Está seguro que desea eliminar la carpeta {{label}}?",
"Are you sure you want to restore {%count%} files?": "¿Está seguro que desea restaurar {{count}} archivos?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Are you sure you want to upgrade?": "¿Está seguro(a) de que desea actualizar?",
"Auto Accept": "Aceptar automáticamente",
"Automatic Crash Reporting": "Automatic Crash Reporting",
"Automatic Crash Reporting": "Informe Automático de Fallos",
"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",
"Automatic upgrades are always enabled for candidate releases.": "Automatic upgrades are always enabled for candidate releases.",
"Automatic upgrades are always enabled for candidate releases.": "Las actualizaciones automáticas siempre están activadas para las versiones candidatas.",
"Automatically create or share folders that this device advertises at the default path.": "Crear o compartir automáticamente carpetas que este dispositivo anuncia en la ruta por defecto.",
"Available debug logging facilities:": "Funciones de registro de depuración disponibles:",
"Be careful!": "¡Ten cuidado!",
"Bugs": "Errores",
"Changelog": "Registro de cambios",
"Clean out after": "Limpiar tras",
"Cleaning Versions": "Cleaning Versions",
"Cleanup Interval": "Cleanup Interval",
"Cleaning Versions": "Limpiando Versiones",
"Cleanup Interval": "Intervalo de Limpieza",
"Click to see discovery failures": "Clica para ver fallos de descubrimiento.",
"Close": "Cerrar",
"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",
"Connected (Unused)": "Connected (Unused)",
"Connected (Unused)": "Conectado (Sin Uso)",
"Connection Error": "Error de conexión",
"Connection Type": "Tipo de conexión",
"Connections": "Conexiones",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Ahora está disponible en Syncthing la búsqueda continua de cambios. Se detectarán los cambios en disco y se hará un escaneado sólo en las rutas modificadas. Los beneficios son que los cambios se propagan más rápido y que se requieren menos escaneos completos.",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Ahora está disponible en Syncthing el control de cambios continuo. Se detectarán los cambios en disco y se hará un escaneado sólo en las rutas modificadas. Los beneficios son que los cambios se propagan más rápido y que se requieren menos escaneos completos.",
"Copied from elsewhere": "Copiado de otro sitio",
"Copied from original": "Copiado del original",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 the following Contributors:",
"Copyright © 2014-2019 the following Contributors:": "Derechos de Autor © 2014-2019 los siguientes colaboradores:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Crear patrones a ignorar, sobreescribiendo un fichero existente en {{path}}.",
"Currently Shared With Devices": "Currently Shared With Devices",
"Currently Shared With Devices": "Actualmente Compartida con los Dispositivos",
"Danger!": "¡Peligro!",
"Debugging Facilities": "Servicios de depuración",
"Default Configuration": "Configuración Predeterminada",
"Default Device": "Dispositivo Predeterminado",
"Default Folder": "Carpeta Predeterminada",
"Default Folder Path": "Ruta de la carpeta por defecto",
"Defaults": "Valores Predeterminados",
"Delete Unexpected Items": "Borrar Elementos Inesperados",
"Deleted": "Eliminado",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect All": "Deseleccionar Todo",
"Deselect devices to stop sharing this folder with.": "Deseleccionar dispositivos con los cuales dejar de compartir esta carpeta.",
"Deselect folders to stop sharing with this device.": "Deseleccionar carpetas para dejar de compartir con este dispositivo.",
"Device": "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",
"Device is untrusted, enter encryption password": "El dispositivo no es de confianza, introduzca la contraseña de cifrado",
"Device rate limits": "Límites de velocidad del dispositivo",
"Device that last modified the item": "Dispositivo que modificó por última vez el ítem",
"Devices": "Dispositivos",
"Disable Crash Reporting": "Disable Crash Reporting",
"Disable Crash Reporting": "Desactivar Informes de Fallos",
"Disabled": "Deshabilitado",
"Disabled periodic scanning and disabled watching for changes": "Se desactivó el escaneo periódico y se desactivó el control de cambios",
"Disabled periodic scanning and enabled watching for changes": "Se desactivó el escaneo periódico y se activó el control de cambios",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Se desactivó el escaneo periódico y falló la configuración para detectar cambios, volviendo a intentarlo cada 1 m:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Desactiva la comparación y sincronización de los permisos de los archivos. Útil en sistemas con permisos inexistentes o personalizados (por ejemplo, FAT, exFAT, Synology, Android).",
"Discard": "Descartar",
"Disconnected": "Desconectado",
"Disconnected (Unused)": "Disconnected (Unused)",
"Disconnected (Unused)": "Desconectado (Sin Uso)",
"Discovered": "Descubierto",
"Discovery": "Descubrimiento",
"Discovery Failures": "Fallos de Descubrimiento",
@@ -91,18 +100,20 @@
"Downloaded": "Descargado",
"Downloading": "Descargando",
"Edit": "Editar",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "Editar Dispositivo",
"Edit Device Defaults": "Editar Valores Predeterminados del Dispositivo",
"Edit Folder": "Editar Carpeta",
"Edit Folder Defaults": "Editar Valores Predeterminados de la Carpeta",
"Editing {%path%}.": "Editando {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable Crash Reporting": "Activar Informes de Fallos",
"Enable NAT traversal": "Permitir NAT transversal",
"Enable Relaying": "Habilitar Retransmisión",
"Enabled": "Activado",
"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.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Introduzca direcciones separadas por comas (\"tcp://ip:port\", \"tcp://host:port\") o \"dynamic\" para realizar el descubrimiento automático de la dirección.",
"Enter ignore patterns, one per line.": "Introducir patrones a ignorar, uno por línea.",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Enter up to three octal digits.": "Introduzca hasta tres dígitos octales.",
"Error": "Error",
"External File Versioning": "Versionado externo de fichero",
"Failed Items": "Elementos fallidos",
@@ -122,13 +133,14 @@
"Folder Label": "Etiqueta de la Carpeta",
"Folder Path": "Ruta de la carpeta",
"Folder Type": "Tipo de carpeta",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "El tipo de carpeta \"{{receiveEncrypted}}\" no se puede cambiar después de añadir la carpeta. Es necesario eliminar la carpeta, borrar o descifrar los datos en el disco y volver a añadir la carpeta.",
"Folders": "Carpetas",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "En las siguientes carpetas se ha producido un error al empezar a buscar cambios. Se volverá a intentar cada minuto, por lo que los errores podrían solucionarse pronto. Si persisten, trata de arreglar el problema subyacente y pide ayuda si no puedes.",
"Full Rescan Interval (s)": "Intervalo de rescaneo completo (s)",
"GUI": "GUI",
"GUI Authentication Password": "Password de la Interfaz Gráfica de Usuario (GUI)",
"GUI Authentication Password": "Contraseña de la Interfaz Gráfica de Usuario (GUI)",
"GUI Authentication User": "Autentificación de usuario de la Interfaz Gráfica de Usuario (GUI)",
"GUI Authentication: Set User and Password": "GUI Authentication: Set User and Password",
"GUI Authentication: Set User and Password": "Autenticación de la GUI: Establezca el Usuario y Contraseña",
"GUI Listen Address": "Dirección de Escucha del GUI.",
"GUI Theme": "Tema GUI",
"General": "General",
@@ -138,8 +150,9 @@
"Global State": "Estado global",
"Help": "Ayuda",
"Home page": "Página de inicio",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Sin embargo, su configuración actual indica que puede no quererla activa. Hemos desactivado los informes automáticos de fallos por usted.",
"If untrusted, enter encryption password": "Si no es de confianza, introduzca la contraseña de cifrado",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Si desea evitar que otros usuarios de esta computadora accedan a Syncthing y, a través de él, a sus archivos, considere establecer la autenticación.",
"Ignore": "Ignorar",
"Ignore Patterns": "Patrones a ignorar",
"Ignore Permissions": "Permisos a ignorar",
@@ -158,17 +171,17 @@
"Last seen": "Visto por última vez",
"Latest Change": "Último Cambio",
"Learn more": "Saber más",
"Limit": "Limit",
"Limit": "Límite",
"Listeners": "Oyentes",
"Loading data...": "Cargando datos...",
"Loading...": "Cargando...",
"Local Additions": "Local Additions",
"Local Additions": "Adiciones Locales",
"Local Discovery": "Descubrimiento local",
"Local State": "Estado local",
"Local State (Total)": "Estado Local (Total)",
"Locally Changed Items": "Locally Changed Items",
"Locally Changed Items": "Elementos Cambiados Localmente",
"Log": "Registro",
"Log tailing paused. Scroll to the bottom to continue.": "Log tailing paused. Scroll to the bottom to continue.",
"Log tailing paused. Scroll to the bottom to continue.": "Seguimiento del registro pausado. Desplácese hasta el final para continuar.",
"Logs": "Registros",
"Major Upgrade": "Actualización importante",
"Mass actions": "Acción masiva",
@@ -187,6 +200,7 @@
"No File Versioning": "Sin versionado de fichero",
"No files will be deleted as a result of this operation.": "Ningún archivo será eliminado como resultado de esta operación.",
"No upgrades": "Sin actualizaciones",
"Not shared": "No Compartido(a)",
"Notice": "Aviso",
"OK": "OK",
"Off": "Desconectar",
@@ -204,7 +218,7 @@
"Pause": "Pausar",
"Pause All": "Pausar todo",
"Paused": "Pausado",
"Paused (Unused)": "Paused (Unused)",
"Paused (Unused)": "Pausado(a) (Sin Uso)",
"Pending changes": "Cambios pendientes",
"Periodic scanning at given interval and disabled watching for changes": "Escaneando periódicamente a un intervalo dado y detección de cambios desactivada",
"Periodic scanning at given interval and enabled watching for changes": "Escaneando periódicamente a un intervalo dado y detección de cambios activada",
@@ -215,17 +229,20 @@
"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",
"Preparing to Sync": "Preparing to Sync",
"Preparing to Sync": "Preparándose para Sincronizar",
"Preview": "Vista previa",
"Preview Usage Report": "Informe de uso de vista previa",
"Quick guide to supported patterns": "Guía rápida de patrones soportados",
"Random": "Aleatorio",
"Receive Encrypted": "Recibir Encriptado(s)",
"Receive Only": "Solo Recibir",
"Received data is already encrypted": "Los datos recibidos ya están cifrados",
"Recent Changes": "Cambios recientes",
"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",
"Remote GUI": "GUI Remota",
"Remove": "Eliminar",
"Remove Device": "Eliminar dispositivo",
"Remove Folder": "Remover carpeta",
@@ -246,9 +263,10 @@
"Scan Time Remaining": "Tiempo Restante de Escaneo",
"Scanning": "Analizando",
"See external versioning help for supported templated command line parameters.": "Vea la ayuda del gestor de versiones externo para los parámetros de linea de comandos que usan una plantilla.",
"Select All": "Select All",
"Select All": "Seleccionar Todo",
"Select a version": "Seleccione una versión",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional devices to share this folder with.": "Seleccionar dispositivos adicionales con los cuales compartir esta carpeta.",
"Select additional folders to share with this device.": "Seleccionar carpetas adicionales para compartir con este dispositivo.",
"Select latest version": "Seleccione la última versión",
"Select oldest version": "Seleccione la versión más antigua",
"Select the folders to share with this device.": "Selecciona las carpetas para compartir con este dispositivo.",
@@ -259,6 +277,7 @@
"Share Folder": "Compartir carpeta",
"Share Folders With Device": "Compartir carpetas con dispositivo",
"Share this folder?": "¿Deseas compartir esta carpeta?",
"Shared Folders": "Carpetas Compartidas",
"Shared With": "Compartir con",
"Sharing": "Compartiendo",
"Show ID": "Mostrar ID",
@@ -281,24 +300,25 @@
"Start Browser": "Iniciar el navegador",
"Statistics": "Estadísticas",
"Stopped": "Detenido",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Almacena y sincroniza sólo los datos cifrados. Las carpetas de todos los dispositivos conectados deben estar configuradas con la misma contraseña o ser también del tipo \"{{receiveEncrypted}}\".",
"Support": "Forum",
"Support Bundle": "Paquete de Soporte",
"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 Free and Open Source Software licensed as MPL v2.0.": "Syncthing is Free and Open Source Software licensed as MPL v2.0.",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing es Software Libre y de Código Abierto con licencia MPL v2.0.",
"Syncthing is restarting.": "Syncthing se está reiniciando.",
"Syncthing is upgrading.": "Syncthing se está actualizando.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing ahora soporta el reportar automáticamente las fallas a los desarrolladores. Esta característica está habilitada por defecto.",
"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.",
"Take me back": "Llévame de vuelta",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "La dirección de la Interfaz Gráfica de Ususario (GUI) está sobreescrita por las opciones de inicio. Los cambios aquí no tendrán efecto mientras la sobreescritura esté activa.",
"The Syncthing Authors": "The Syncthing Authors",
"The Syncthing Authors": "Los Autores de Syncthing",
"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 cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"The cleanup interval cannot be blank.": "El intervalo de limpieza no puede ser nulo.",
"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).",
@@ -309,9 +329,10 @@
"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 following items were changed locally.": "The following items were changed locally.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The following items were changed locally.": "Los siguientes elementos fueron cambiados localmente.",
"The following unexpected items were found.": "Los siguientes elementos inesperados fueron encontrados.",
"The interval must be a positive number of seconds.": "El intervalo debe ser un número de segundos positivo.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "El intervalo, en segundos, para ejecutar la limpieza del directorio de versiones. Cero para desactivar la limpieza periódica.",
"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 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.",
@@ -321,7 +342,8 @@
"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 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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no devices to share this folder with.": "No hay dispositivos con los cuales compartir esta carpeta.",
"There are no folders to share with this device.": "No hay carpetas para compartir con este dispositivo.",
"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 podría permitir fácilmente el acceso a hackers para leer y modificar cualquier fichero de tu equipo.",
@@ -331,14 +353,18 @@
"Time the item was last modified": "Hora en que el ítem fue modificado por última vez",
"Trash Can File Versioning": "Versionado de archivos de la papelera",
"Type": "Tipo",
"UNIX Permissions": "UNIX Permissions",
"UNIX Permissions": "Permisos de UNIX",
"Unavailable": "No disponible",
"Unavailable/Disabled by administrator or maintainer": "No disponible/Deshabilitado por el administrador o mantenedor",
"Undecided (will prompt)": "No decidido (se preguntará)",
"Unexpected Items": "Elementos Inesperados",
"Unexpected items have been found in this folder.": "Se han encontrado Elementos Inesperados en esta carpeta.",
"Unignore": "Dejar de ignorar",
"Unknown": "Desconocido",
"Unshared": "No compartido",
"Unshared Devices": "Unshared Devices",
"Unshared Devices": "Dispositivos no Enlazados",
"Unshared Folders": "Carpetas no Compartidas",
"Untrusted": "No Confiable",
"Up to Date": "Actualizado",
"Updated": "Actualizado",
"Upgrade": "Actualizar",
@@ -348,14 +374,14 @@
"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)",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Username/Password has not been set for the GUI authentication. Please consider setting it up.",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "No se ha configurado el nombre de usuario/la contraseña para la autenticación de la GUI. Por favor, considere configurarlos.",
"Version": "Versión",
"Versions": "Versiones",
"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.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"Waiting to Clean": "Esperando para Limpiar",
"Waiting to Scan": "Esperando para Escanear",
"Waiting to Sync": "Esperando para Sincronizar",
"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}}\".",
@@ -363,7 +389,7 @@
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "Advertencia: Si estás utilizando un observador externo como {{syncthingInotify}}, debes asegurarte de que está desactivado.",
"Watch for Changes": "Vigila los cambios",
"Watching for Changes": "Vigilando los cambios",
"Watching for changes discovers most changes without periodic scanning.": "Watching for changes discovers most changes without periodic scanning.",
"Watching for changes discovers most changes without periodic scanning.": "El control de cambios descubre la mayoría de cambios sin el escaneo periódico.",
"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",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "No tienes carpetas ignoradas",
"You have unsaved changes. Do you really want to discard them?": "Tienes cambios sin guardar. ¿Quieres descartarlos realmente?",
"You must keep at least one version.": "Debes mantener al menos una versión.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Nunca debe agregar o cambiar nada localmente en una carpeta \"{{receiveEncrypted}}\".",
"days": "días",
"directories": "directories",
"directories": "directorios",
"files": "archivos",
"full documentation": "Documentación completa",
"items": "Elementos",
"seconds": "seconds",
"seconds": "segundos",
"{%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}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quiere compartir la carpeta \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} puede reintroducir este dispositivo."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Aitzinatua",
"Advanced Configuration": "Konfigurazio aitzinatua",
"All Data": "Datu guziak",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Gailu honekin partekatutako karpeta guztiak pasahitz baten bidez babestu behar dira, horrela, bidalitako datu guztiak irakurri ezinak izango dira emandako pasahitzik gabe.",
"Allow Anonymous Usage Reporting?": "Izenik gabeko erabiltze erreportak baimendu?",
"Allowed Networks": "Sare baimenduak",
"Alphabetic": "Alfabetikoa",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Kanpoko kontrolagailu batek fitxategien bertsioak kudeatzen ditu. Fitxategiak kendu behar ditu errepertorio sinkronizatuan. Aplikaziorako ibilbideak espazioak baditu, komatxo artean egon behar du.",
"Anonymous Usage Reporting": "Izenik gabeko erabiltze erreportak",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Erabilera anonimoko txostenaren formatua aldatu egin da. Formatu berria erabili nahi duzu?",
"Are you sure you want to permanently delete all these files?": "Ziur zaude fitxategi guzti hauek betirako ezabatu nahi dituzula?",
"Are you sure you want to remove device {%name%}?": "Ziur zaude {{name}} gailua ezabatu nahi duzula?",
"Are you sure you want to remove folder {%label%}?": "Ziur zaude {{label}} karpeta ezabatu nahi duzula?",
"Are you sure you want to restore {%count%} files?": "Ziur zaude {{count}} fitxategi berreskuratu nahi dituzula? ",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Gaur egun tresnekin partekatua",
"Danger!": "Lanjera !",
"Debugging Facilities": "Arazketa zerbitzuak",
"Default Configuration": "Konfigurazio lehenetsia",
"Default Device": "Gailu lehenetsia",
"Default Folder": "Karpeta lehenetsia",
"Default Folder Path": "Partekatzearen sustrai bide lehenetsia",
"Defaults": "Lehenetsiak",
"Delete Unexpected Items": "Ezabatu ustekabeko elementuak",
"Deleted": "Kendua",
"Deselect All": "Hautaketa guztia kendu",
"Deselect devices to stop sharing this folder with.": "Desautatu karpeta honekin partekatu nahi ez dituzun gailuak.",
"Deselect folders to stop sharing with this device.": "Desautatu karpetak gailu honekin partekatzeari uzteko.",
"Device": "Tresna",
"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",
"Device is untrusted, enter encryption password": "Gailua ez da fidagarria, idatzi enkriptatzeko pasahitza",
"Device rate limits": "Gailuaren abiadura mugak",
"Device that last modified the item": "Itema azkenekoz aldatu zuen gailua",
"Devices": "Tresnak",
@@ -92,7 +101,9 @@
"Downloading": "Deskargatzea",
"Edit": "Aldatu",
"Edit Device": "Tresna aldatzea",
"Edit Device Defaults": "Editatu gailu lehenetsiak",
"Edit Folder": "Editatu karpeta",
"Edit Folder Defaults": "Editatu karpeta lehenetsiak",
"Editing {%path%}.": "Muntatzea {{path}}",
"Enable Crash Reporting": "Aktibatu blokeatzeko txosten automatikoen bidalketa",
"Enable NAT traversal": "NAT translazioa aktibatu",
@@ -122,6 +133,7 @@
"Folder Label": "Partekatzearen izena",
"Folder Path": "Partekatzearen sustrai bidea",
"Folder Type": "Partekatze mota",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "\"{{ReceiveEncrypted}}\" karpeta mota ezin da aldatu karpeta gehitu ondoren. Karpeta kendu, diskoko datuak ezabatu edo deszifratu eta karpeta berriro gehitu behar duzu.",
"Folders": "Partekatzeak",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Hurrengo karpetetan errorea gertatu da aldaketak bilatzen hastean. Berriro saiatuko da minuturo, beraz, akatsak laster konpon daitezke. Jarraitzen badute, saiatu azpiko arazoa konpontzen eta eskatu laguntza, ezin baduzu.",
"Full Rescan Interval (s)": "Berriz eskaneatzeko tartea osatu da (s)",
@@ -139,6 +151,7 @@
"Help": "Laguntza",
"Home page": "Harrera",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Hala ere, zure ezarpenen arabera baliteke aktibatu nahi ez izatea. Txostenen bidalketa automatikoa desaktibatu dugu zuretzat.",
"If untrusted, enter encryption password": "Fidagarria ez bada, idatzi enkriptatzeko pasahitza",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Ordenagailu honetako beste erabiltzaile batzuk Syncthing-era eta haren bidez zure fitxategietara sartzea eragotzi nahi baduzu, kontuan izan autentifikazioa konfiguratu behar duzula.",
"Ignore": "Kontuan ez hartu",
"Ignore Patterns": "Baztertzeak",
@@ -187,6 +200,7 @@
"No File Versioning": "Fitxategi bersioen kontrolik ez",
"No files will be deleted as a result of this operation.": "Eragiketa horren ondorioz, ez da artxiborik ezabatuko.",
"No upgrades": "Eguneratzerik ez",
"Not shared": "Ez da partekatu",
"Notice": "Jakinaraztea",
"OK": "Ados",
"Off": "Desgaitu",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Erabiltze estatistika txostenaren aurrebista",
"Quick guide to supported patterns": "Eredu konpatibleen gidaliburuxka",
"Random": "Aleatorioa",
"Receive Encrypted": "Jaso enkriptatuak",
"Receive Only": "Jaso bakarrik",
"Received data is already encrypted": "Jasotako datuak jada enkriptaturik daude",
"Recent Changes": "Aldaketa berriak",
"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.": "Azken zuzenketak eta funtzionalitateak edukitzen dituzte aitzin-bertsioek. Bi hilabete guziz egiten diren eguneratzeen berdinak dira.",
"Remote Devices": "Beste tresnak",
"Remote GUI": "Urruneko GUI",
"Remove": "Kendu",
"Remove Device": "Tresna kendu",
"Remove Folder": "Karpeta kendu",
@@ -249,6 +266,7 @@
"Select All": "Hautatu guztia",
"Select a version": "Bertsio bat aukeratu",
"Select additional devices to share this folder with.": " Tresna gehigarriak hauta itzazu partekatze honekin sinkronizatzeko ",
"Select additional folders to share with this device.": "Aukeratu karpeta osagarriak gailu honekin partekatzeko.",
"Select latest version": "Aukeratu azken bertsioa",
"Select oldest version": "Aukeratu bertsio zaharrena",
"Select the folders to share with this device.": "Tresna honek erabiltzen dituen partekatzeak hauta itzazu",
@@ -259,6 +277,7 @@
"Share Folder": "Partekatzea",
"Share Folders With Device": "Tresnarekin partekatzeak",
"Share this folder?": "Partekatze hau onartzen duzu?",
"Shared Folders": "Partekatutako karpetak",
"Shared With": "...ekin partekatua",
"Sharing": "Partekatuz",
"Show ID": "Erakutsi ene ID-a",
@@ -281,6 +300,7 @@
"Start Browser": "Web nabigatzailea piztu",
"Statistics": "Estatistikak",
"Stopped": "Gelditua!",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Enkriptatutako datuak soilik gordetzen eta sinkronizatzen ditu. Konektatutako gailu guztietako karpetak pasahitz berarekin konfiguratu behar dira edo \"{{receiveEncrypted}}\" motakoak izan.",
"Support": "Foroa",
"Support Bundle": "Laguntza-sorta",
"Sync Protocol Listen Addresses": "Sinkronizatu protokoloaren entzun zuzenbideak",
@@ -310,6 +330,7 @@
"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.": "Hunako tarteak erabiliak dira: lehen orduan bertsio bat kontserbatua da 30 segundu guziz. Lehen egunean, bertsio bat ordu bakoitz, lehen 30 egunetan bertsio bat egunero. Handik harat, adinaren mugetan egonez, bertsio bat astero.",
"The following items could not be synchronized.": "Ondoko fitxero hauk ez dira sinkronizatuak ahal izan",
"The following items were changed locally.": "Elementu hauek tokiz aldatu dira.",
"The following unexpected items were found.": "Ustekabeko elementu hauek aurkitu dira.",
"The interval must be a positive number of seconds.": "Tarteak segundo kopuru positiboa izan behar du.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Bertsioen direktorioko garbiketa exekutatzeko tartea, segundotan. Zero aldizkako garbiketa desgaitzeko.",
"The maximum age must be a number and cannot be blank.": "Gehieneko adinak zenbaki bat behar du izan eta ez da hutsa izaiten ahal.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Ixuriaren emaria ez da negatiboa izaiten ahal (0 = mugarik gabekoa)",
"The rescan interval must be a non-negative number of seconds.": "Ikerketaren tartea ez da segundo kopuru negatiboa izaiten ahal",
"There are no devices to share this folder with.": "Ez dago partekatutako erabilera horri gehitzeko gailurik.",
"There are no folders to share with this device.": "Ez dago gailu honekin partekatzeko karpetarik.",
"They are retried automatically and will be synced when the error is resolved.": "Errorea zuzendua izanen delarik, automatikoki berriz entseatuak et sinkronizatuak izanen dira",
"This Device": "Tresna hau",
"This can easily give hackers access to read and change any files on your computer.": "Hunek errexki irakurtzen eta aldatzen uzten ahal du zure ordenagailuko edozein fitxero, nahiz eta sartu denak ez haizu izan!",
@@ -335,10 +357,14 @@
"Unavailable": "Ez dago erabilgarri",
"Unavailable/Disabled by administrator or maintainer": "Ez dago erabilgarri/administratzaileak edo mantentzaileak desgaitu du",
"Undecided (will prompt)": "Erabaki gabe (galdetuko da)",
"Unexpected Items": "Ustekabeko elementuak",
"Unexpected items have been found in this folder.": "Karpeta honetan ustekabeko elementuak aurkitu dira.",
"Unignore": "Ez ikusia egin",
"Unknown": "Ezezaguna",
"Unshared": "Partekatua ez dena",
"Unshared Devices": "Partekatzen ez diren gailuak",
"Unshared Folders": "Partekatu gabeko karpetak",
"Untrusted": "Ez da fidagarria",
"Up to Date": "Eguneratua",
"Updated": "Berritua",
"Upgrade": "Aktualizatu",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Ez duzu bazter utzitako karpetarik",
"You have unsaved changes. Do you really want to discard them?": "Gorde gabeko aldaketak dituzu. Ziur baztertu nahi dituzula?",
"You must keep at least one version.": "Bertsio bat bederen behar duzu atxiki",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Ez zenuke inoiz ezer gehitu edo aldatu behar \"{{receiveEncrypted}}\" karpetan.",
"days": "Egunak",
"directories": "Karpetak",
"files": "Fitxategiak",
@@ -381,5 +408,6 @@
"items": "Elementuak",
"seconds": "segunduak",
"{%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."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}}k \"{{folderlabel}}\" ({{folder}}) hontan gomitatzen zaitu.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} -ek gailu hau birsar lezake."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Lisäasetukset",
"Advanced Configuration": "Kehittyneet asetukset",
"All Data": "Kaikki data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Salli anonyymi käyttöraportointi?",
"Allowed Networks": "Sallitut verkot",
"Alphabetic": "Aakkosellinen",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Ulkoinen komento hallitsee versionnin. Sen täytyy poistaa tiedosto synkronoidusta kansiosta. Mikäli ohjelman polussa on välilyöntejä se on laitettava lainausmerkkeihin.",
"Anonymous Usage Reporting": "Anonyymi käyttöraportointi",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Anonyymi käyttöraportti on muuttunut. Haluatko vaihtaa uuteen muotoon?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Oletko varma, että haluat postaa laitteen {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Oletko varma, että haluat poistaa kansion {{label}}?",
"Are you sure you want to restore {%count%} files?": "Haluatko varmasti palauttaa {{count}} tiedostoa?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Vaara!",
"Debugging Facilities": "Debug -luokat",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Oletuspolku kansioille",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Poistettu",
"Deselect All": "Poista valinnat",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Laite",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Laite \"{{name}}\" {{device}} osoitteessa ({{address}}) haluaa yhdistää. Lisää uusi laite?",
"Device ID": "Laitteen ID",
"Device Identification": "Laitteen tunniste",
"Device Name": "Laitteen nimi",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Laitteen siirtonopeuden rajoitus",
"Device that last modified the item": "Laite, joka viimeisimmäksi muokkasi kohdetta",
"Devices": "Laitteet",
@@ -92,7 +101,9 @@
"Downloading": "Ladataan",
"Edit": "Muokkaa",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Muokkaa {{path}}.",
"Enable Crash Reporting": "Ota kaatumisraportointi käyttöön",
"Enable NAT traversal": "Aktivoi osoitteenmuunnoksen kierto",
@@ -122,6 +133,7 @@
"Folder Label": "Kansion nimi",
"Folder Path": "Kansion polku",
"Folder Type": "Kansion tyyppi",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Kansiot",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Seuraavien kansioiden valvonnan aloitus epäonnistui. Yritetään uudelleen minuutin välein, joten virhe saattaa poistua pian. Mikäli virheet jäävät pysyviksi, yritä korjata taustaongelma tai kysy apua foorumilta, mikäli et onnistu.",
"Full Rescan Interval (s)": "Täydellisen uudelleenskannauksen aikaväli (s)",
@@ -139,6 +151,7 @@
"Help": "Apua",
"Home page": "Kotisivu",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ohita",
"Ignore Patterns": "Ohituslausekkeet",
@@ -187,6 +200,7 @@
"No File Versioning": "Ei tiedostoversiointia",
"No files will be deleted as a result of this operation.": "Yhtään tiedostoa ei poisteta tämän toimenpiteen jälkeen.",
"No upgrades": "Ei päivityksiä",
"Not shared": "Not shared",
"Notice": "Huomautus",
"OK": "OK",
"Off": "Pois",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Esikatsele käyttöraportti",
"Quick guide to supported patterns": "Tuettujen lausekkeiden pikaohje",
"Random": "Satunnainen",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Vain vastaanotto",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Viimeisimmät muutokset",
"Reduced by ignore patterns": "Vähennetty ohituslausekkeiden perusteella",
"Release Notes": "Julkaisutiedot",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Julkaisuehdokkaat \"Release candidate\" sisältää viimeisimmät ominaisuudet ja korjaukset. Ne vastaavat perinteistä joka toisen viikon Syncthing -julkaisua.",
"Remote Devices": "Laitteet",
"Remote GUI": "Remote GUI",
"Remove": "Poista",
"Remove Device": "Poista laite",
"Remove Folder": "Poista kansio",
@@ -249,6 +266,7 @@
"Select All": "Valitse kaikki",
"Select a version": "Valitse versio",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Valitse viimeisin versio",
"Select oldest version": "Valitse vanhin versio",
"Select the folders to share with this device.": "Valitse kansiot jaettavaksi tämän laitteen kanssa.",
@@ -259,6 +277,7 @@
"Share Folder": "Jaa kansio",
"Share Folders With Device": "Jaa kansioita laitteen kanssa",
"Share this folder?": "Jaa tämä kansio?",
"Shared Folders": "Shared Folders",
"Shared With": "Jaettu seuraavien kanssa",
"Sharing": "Jakaminen",
"Show ID": "Näytä ID",
@@ -281,6 +300,7 @@
"Start Browser": "Käynnistä selain",
"Statistics": "Tilastot",
"Stopped": "Pysäytetty",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Tuki",
"Support Bundle": "Tukipaketti. (Tiedostot vianselvitystä varten.)",
"Sync Protocol Listen Addresses": "Synkronointiprotokollan kuunteluosoite",
@@ -310,6 +330,7 @@
"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.": "Seuraavat aikavälit ovat käytössä: ensimmäisen tunnin ajalta uusi versio säilytetään joka 30 sekunti, ensimmäisen päivän ajalta uusi versio säilytetään tunneittain ja ensimmäisen 30 päivän aikana uusi versio säilytetään päivittäin. Lopulta uusi versio säilytetään viikoittain, kunnes maksimi-ikä saavutetaan.",
"The following items could not be synchronized.": "Seuraavia nimikkeitä ei voitu synkronoida.",
"The following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Maksimi-iän tulee olla numero, eikä se voi olla tyhjä.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Nopeusrajan tulee olla positiivinen luku tai nolla. (0: ei rajaa)",
"The rescan interval must be a non-negative number of seconds.": "Uudelleenskannauksen aikavälin tulee olla ei-negatiivinen numero sekunteja.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Niiden synkronointia yritetään uudelleen automaattisesti.",
"This Device": "Tämä laite",
"This can easily give hackers access to read and change any files on your computer.": "Tämä voi helposti sallia vihamielisille tahoille pääsyn lukea ja muokata kaikkia tiedostojasi",
@@ -335,10 +357,14 @@
"Unavailable": "Ei saatavilla",
"Unavailable/Disabled by administrator or maintainer": "Ei saatavilla / ylläpitäjän estämä.",
"Undecided (will prompt)": "Ei päätetty (kysytään myöhemmin)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Poista ohitus",
"Unknown": "Tuntematon",
"Unshared": "Jakamaton",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Ajan tasalla",
"Updated": "Päivitetty",
"Upgrade": "Päivitys",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Sinulla ei ole ohitettuja kansioita.",
"You have unsaved changes. Do you really want to discard them?": "Sinulla on tallentamattomia muutoksia. Tahdotko hylätä ne?",
"You must keep at least one version.": "Sinun tulee säilyttää ainakin yksi versio.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "päivää",
"directories": "directories",
"files": "tiedostot",
@@ -381,5 +408,6 @@
"items": "kohteet",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} haluaa jakaa kansion \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} haluaa jakaa kansion \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} haluaa jakaa kansion \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avancé",
"Advanced Configuration": "Configuration avancée",
"All Data": "Toutes les données",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Tous les partages pour cet appareil doivent être protégés par mot de passe, de sorte que les données envoyées soient illisibles sans le mot de passe.",
"Allow Anonymous Usage Reporting?": "Autoriser l'envoi de statistiques d'utilisation anonymisées ?",
"Allowed Networks": "Réseaux autorisés",
"Alphabetic": "Alphabétique",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Une commande externe gère les versions de fichiers. Il lui incombe de supprimer les fichiers du répertoire partagé. Si le chemin contient des espaces, il doit être spécifié entre guillemets.",
"Anonymous Usage Reporting": "Rapport anonyme de statistiques d'utilisation",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Le format du rapport anonyme d'utilisation a changé. Voulez-vous passer au nouveau format ?",
"Are you sure you want to permanently delete all these files?": "Êtes-vous sûrs de vouloir définitivement supprimer tous ces fichiers ?",
"Are you sure you want to remove device {%name%}?": "Êtes-vous sûr de vouloir supprimer l'appareil {{name}} ?",
"Are you sure you want to remove folder {%label%}?": "Êtes-vous sûr de vouloir supprimer le partage {{label}} ?",
"Are you sure you want to restore {%count%} files?": "Êtes-vous sûr de vouloir restaurer {{count}} fichiers ?",
@@ -33,7 +35,7 @@
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Le système de mise à jour automatique propose le choix entre versions stables et versions préliminaires.",
"Automatic upgrades": "Mises à jour automatiques",
"Automatic upgrades are always enabled for candidate releases.": "Les mises à jour automatiques sont toujours activées pour les versions préliminaires (-rc.N).",
"Automatically create or share folders that this device advertises at the default path.": "ATTENTION !!! Créer ou partager automatiquement dans le chemin par défaut les partages que cet appareil annonce.",
"Automatically create or share folders that this device advertises at the default path.": "ATTENTION, risque de sécurité/confidentialité !!! Créer ou partager automatiquement dans le chemin par défaut les partages auxquels cet appareil m'invite à participer. N'accordez ce privilège, éventuellement temporaire le temps de l'établissement, qu'à vos propres appareils.",
"Available debug logging facilities:": "Outils de débogage disponibles :",
"Be careful!": "Faites attention !",
"Bugs": "Bugs",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Appareils membres actuels de ce partage :",
"Danger!": "Attention !",
"Debugging Facilities": "Outils de débogage",
"Default Configuration": "Personnalisation des créations",
"Default Device": "Définir comme référence pour les réglages",
"Default Folder": "Définir comme référence pour les réglages",
"Default Folder Path": "Chemin parent par défaut pour les nouveaux partages",
"Defaults": "Personnalisation",
"Delete Unexpected Items": "Supprimer les éléments inattendus",
"Deleted": "Supprimé",
"Deselect All": "Tout déselectionner",
"Deselect devices to stop sharing this folder with.": "Désélectionnez les appareils avec lesquels vous ne souhaitez plus partager ce dossier.",
"Deselect devices to stop sharing this folder with.": "Désélectionnez les appareils avec lesquels vous ne souhaitez plus partager ces données.",
"Deselect folders to stop sharing with this device.": "Désélectionnez les partages auxquels cet appareil doit plus participer.",
"Device": "Appareil",
"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 convivial local de l'appareil",
"Device is untrusted, enter encryption password": "Confiance retirée, entrez un mot de passe de chiffrement",
"Device rate limits": "Limitations de débit",
"Device that last modified the item": "Dernier appareil modificateur",
"Devices": "Appareils",
@@ -92,7 +101,9 @@
"Downloading": "Réception",
"Edit": "Gérer...",
"Edit Device": "Gérer l'appareil",
"Edit Device Defaults": "Pour les nouveaux appareils",
"Edit Folder": "Gérer le partage",
"Edit Folder Defaults": "Pour les nouveaux partages",
"Editing {%path%}.": "Modification de {{path}}.",
"Enable Crash Reporting": "Activer l'envoi des rapports de plantage automatiques",
"Enable NAT traversal": "Activer la translation d'adresses (NAT)",
@@ -122,6 +133,7 @@
"Folder Label": "Nom du partage",
"Folder Path": "Chemin racine du partage",
"Folder Type": "Type de partage",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Un partage de type \"{{receiveEncrypted}}\" ne peut pas être modifié après sa création. Il vous faut le supprimer, supprimer ou déchiffrer les données du disque, puis recréer le partage.",
"Folders": "Partages",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Une erreur s'est produite pour les partages suivants lors du démarrage de la surveillance des changements. Une nouvelle tentative a lieu toutes les minutes, et les erreurs devraient disparaître rapidement. Si elles persistent, essayez de corriger le problème sous-jacent et demandez de l'aide si vous n'y parvenez pas.",
"Full Rescan Interval (s)": "Intervalle de réanalyse complète (s)",
@@ -139,6 +151,7 @@
"Help": "Aide (en anglais)",
"Home page": "Page d'accueil",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Cependant, vos réglages indiquent que vous pourriez souhaiter ne pas l'activer. Nous avons désactivé pour vous l'envoi automatique des rapports.",
"If untrusted, enter encryption password": "Entrez un mot de passe pour chiffrer",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Si vous voulez empêcher d'autres utilisateurs de cet appareil à accéder à Syncthing, et via Syncthing à vos fichiers, prenez quelques secondes pour régler l'authentification. ",
"Ignore": "Refuser",
"Ignore Patterns": "Exclusions...",
@@ -166,7 +179,7 @@
"Local Discovery": "Découverte locale",
"Local State": "État local",
"Local State (Total)": "État local (Total)",
"Locally Changed Items": "Éléments modifiés localement",
"Locally Changed Items": "Élément(s) modifié(s) localement",
"Log": "Journal",
"Log tailing paused. Scroll to the bottom to continue.": "Le défilement du journal est en pause. Faites défiler jusqu'en bas pour continuer.",
"Logs": "Journaux",
@@ -187,6 +200,7 @@
"No File Versioning": "Sans",
"No files will be deleted as a result of this operation.": "Aucun fichier ne sera supprimé à la suite de cette opération.",
"No upgrades": "Pas de mises à jour",
"Not shared": "Non partagé",
"Notice": "Notification",
"OK": "OK",
"Off": "Désactivée",
@@ -198,7 +212,7 @@
"Outgoing Rate Limit (KiB/s)": "Limite du débit d'envoi (Kio/s)",
"Override Changes": "Écraser les changements",
"Path": "Chemin",
"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": "Chemin vers le répertoire à partager dans l'appareil local. Il sera créé s'il n'existe pas. Vous pouvez entrer un chemin absolu (p.ex \"/home/moi/Sync/Exemple\") ou relatif à celui du programme (p.ex \"..\\Partages\\Exemple\" - utile pour installation portable). Le caractère tilde (~, ou ~+Espace sous Windows XP+Azerty) peut être utilisé comme raccourci vers",
"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": "Chemin vers le répertoire à partager dans l'appareil local. Il sera créé s'il n'existe pas. Vous pouvez entrer un chemin absolu (p.ex \"/home/moi/Sync/Exemple\") ou relatif à celui du programme (p.ex \"..\\Partages\\Exemple\" - utile pour installation portable). Le caractère tilde (~, ou ~+Espace sous Windows) peut être utilisé comme raccourci vers\nDans l'écran de \"Personnalisation\" des valeurs par défaut, ce champ indique le chemin dans lequel les partages acceptés automatiquement seront créés, ainsi que chemin de base suggéré lors de l'enregistrement des nouveaux partages. Le caractère tilde (~) est un raccourci pour {{tilde}}.",
"Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "Chemin dans lequel les partages acceptés automatiquement seront créés, ainsi que chemin suggéré lors de l'enregistrement des nouveaux partages via cette interface graphique. Le caractère tilde (~) est un raccourci pour {{tilde}}.",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Chemin où les versions seront conservées (laisser vide pour le chemin par défaut de .stversions (caché) dans le partage).\nChemin relatif ou absolu (recommandé), mais dans un répertoire non synchronisé (par masque ou hors du chemin du partage).\nSur la même partition ou système de fichiers (recommandé).",
"Pause": "Pause",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Aperçu du rapport de statistiques d'utilisation",
"Quick guide to supported patterns": "Guide rapide des masques compatibles ci-dessous",
"Random": "Aléatoire",
"Receive Encrypted": "Réception chiffrée",
"Receive Only": "Réception seulement",
"Received data is already encrypted": "Les données reçues sont déjà chiffrées",
"Recent Changes": "Changements récents...",
"Reduced by ignore patterns": "(Limité par des masques d'exclusion)",
"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",
"Remote GUI": "IHM distant",
"Remove": "Supprimer...",
"Remove Device": "Supprimer l'appareil",
"Remove Folder": "Supprimer le partage",
@@ -249,6 +266,7 @@
"Select All": "Tout sélectionner",
"Select a version": "Choisissez une version",
"Select additional devices to share this folder with.": "Sélectionnez des appareils membres supplémentaires pour ce partage.",
"Select additional folders to share with this device.": "Choisissez des partages supplémentaires pour cet appareil.",
"Select latest version": "Restaurer la dernière version",
"Select oldest version": "Restaurer la plus ancienne version",
"Select the folders to share with this device.": "Choisir les partages auxquels cet appareil doit participer :",
@@ -259,6 +277,7 @@
"Share Folder": "Partager",
"Share Folders With Device": "Participe à ces partages",
"Share this folder?": "Acceptez-vous ce partage ?",
"Shared Folders": "Partages",
"Shared With": "Participant(s)",
"Sharing": "Partages",
"Show ID": "Afficher mon ID",
@@ -281,6 +300,7 @@
"Start Browser": "Lancer le navigateur web",
"Statistics": "Statistiques",
"Stopped": "Arrêté",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Récupère seulement des données chiffrées. Ce partage sur tous les autres appareils doit aussi être du type \"{{receiveEncrypted}}\" ou bien être défini avec le même mot de passe.",
"Support": "Forum",
"Support Bundle": "Kit d'assistance",
"Sync Protocol Listen Addresses": "Adresses d'écoute du protocole de synchronisation",
@@ -310,6 +330,7 @@
"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.": "Les seuils de durée suivants définissent le nombre maximum de versions pour chaque fichier : pendant la première heure une version est conservée toutes les 30 secondes. Le premier jour, une version par heure - des versions de la première heure sont alors progressivement effacées pour finir par n'en garder que la dernière. Pour les 30 jours passés, une version par jour - des versions horaires du premier jour sont alors progressivement effacées pour n'en garder qu'une par jour. Au-delà et jusqu'à la limite d'âge, une version est conservée par semaine - des versions journalières du premier mois sont alors progressivement effacées pour n'en garder qu'une.",
"The following items could not be synchronized.": "Les fichiers suivants n'ont pas pu être synchronisés.",
"The following items were changed locally.": "Les éléments suivants ont été modifiés localement.",
"The following unexpected items were found.": "Les éléments inattendus suivants ont été détectés.",
"The interval must be a positive number of seconds.": "L'intervalle doit être un nombre positif exprimé en secondes",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "L'intervalle, en secondes, de l'exécution du nettoyage du répertoire des versions. Définir à 0 pour désactiver la purge périodique (Dans ce cas, elle n'est effectuée qu'au démarrage).",
"The maximum age must be a number and cannot be blank.": "L'âge maximum doit être un nombre et ne peut être vide.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "La limite de débit ne doit pas être négative (0 = pas de limite)",
"The rescan interval must be a non-negative number of seconds.": "L'intervalle d'analyse ne doit pas être un nombre négatif de secondes.",
"There are no devices to share this folder with.": "Il n'y a aucun appareil à ajouter à ce partage.",
"There are no folders to share with this device.": "Il n'y a aucun partage disponible.",
"They are retried automatically and will be synced when the error is resolved.": "Ils seront automatiquement retentés et synchronisés quand l'erreur sera résolue.",
"This Device": "Cet appareil",
"This can easily give hackers access to read and change any files on your computer.": "Ceci peut aisément permettre à un intrus de lire et modifier n'importe quel fichier de votre ordinateur.",
@@ -335,10 +357,14 @@
"Unavailable": "Indisponible",
"Unavailable/Disabled by administrator or maintainer": "Indisponible/Désactivé par l'administrateur ou le mainteneur",
"Undecided (will prompt)": "Non défini (Choisir plus tard)",
"Unexpected Items": "Éléments inattendus.",
"Unexpected items have been found in this folder.": "Des éléments inattendus ont été détectés dans ce partage. ",
"Unignore": "Reprendre",
"Unknown": "Inconnu",
"Unshared": "Non partagé",
"Unshared Devices": "Appareils non membres de ce partage :",
"Unshared Folders": "Non partagés",
"Untrusted": "Retirer la confiance (chiffrer tous les partages)",
"Up to Date": "À jour",
"Updated": "Mis à jour",
"Upgrade": "Mettre à jour",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "Aucun partage refusé.",
"You have unsaved changes. Do you really want to discard them?": "Vous avez des réglages non enregistrés. Voulez-vous vraiment les rejeter ?",
"You must keep at least one version.": "Vous devez garder au minimum une version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Vous ne devriez jamais ajouter ou modifier localement le contenu d'un partage de type \"{{receiveEncrypted}}\".",
"days": "Jours",
"directories": "répertoires",
"files": "Fichiers",
"full documentation": "Documentation complète ici",
"items": "éléments",
"items": "élément(s)",
"seconds": "secondes",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vous invite au partage \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vous invite au partage \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vous invite au partage \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} pourrait ré-enrôler cet appareil."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avansearre",
"Advanced Configuration": "Avansearre konfiguraasje",
"All Data": "Alle data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Anonime brûkensrapportaazje tastean?",
"Allowed Networks": "Tasteane Netwurken",
"Alphabetic": "Alfabetysk",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "In ekstern kommando soarget foar it ferzjebehear. It moat de triem út de dielde map fuortsmite. As it paad nei de applikaasje romtes hat, moat it tusken oanheltekens sette wurden.",
"Anonymous Usage Reporting": "Anonym brûkensrapportaazje",
"Anonymous usage report format has changed. Would you like to move to the new format?": "It formaat fan de rapportaazje fan anonime gebrûksynformaasje is feroare. Wolle jo op dit nije formaat oerstappe?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Bist der wis fan datsto apparaat {{name}} fuortsmite wolst?",
"Are you sure you want to remove folder {%label%}?": "Bist der wis fan datsto map {{label}} fuortsmite wolst?",
"Are you sure you want to restore {%count%} files?": "Bist der wis fan datsto {{count}} triemen weromsette wolst?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Op dit stuit Dielt mei Apparaten",
"Danger!": "Gefaar!",
"Debugging Facilities": "Debug-foarsjennings",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Standert Map-paad",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Fuortsmiten",
"Deselect All": "Alles Deselektearje",
"Deselect devices to stop sharing this folder with.": "Kies de apparaten om dizze map net langer mei te dielen.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Apparaat",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Apparaat \"{{name}}\" {{device}} op ({{address}}) wol ferbining meitsje. Nij apparaat taheakje?",
"Device ID": "Apparaat-ID",
"Device Identification": "Apparaatidentifikaasje",
"Device Name": "Apparaatnamme",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Apparaatfluggenslimiet",
"Device that last modified the item": "Apparaat dat dit item it lêst oanpast hat",
"Devices": "Apparaten",
@@ -92,7 +101,9 @@
"Downloading": "Oan it downloaden",
"Edit": "Bewurkje",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "{{path}} wurd bewurke.",
"Enable Crash Reporting": "Automatyske Rapportaazje fan Fêstrinners Oansette",
"Enable NAT traversal": "NAT-trochkruse ynskeakelje",
@@ -122,6 +133,7 @@
"Folder Label": "Map-opskrift",
"Folder Path": "Map-paad",
"Folder Type": "Maptype",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Mappen",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "By it starten fan it sjen foar feroarings is der foar de folgende mappen is in flater ûnstean. It wurd eltse minuut opnij besike, dus de flaters koene wol ris gau fuortgean. At se der bliuwe, besykje dan it ûnderlizzende probleem te ferhelpen en freegje om help dat dit net slagget.",
"Full Rescan Interval (s)": "Folledich wersken ynterfal (s)",
@@ -139,6 +151,7 @@
"Help": "Help",
"Home page": "Hiemstee",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Lykwols, jo aktuele ynstellings litte sjen dat jo it miskien net oan sette wol. Wy hawwe automatysk rapportearjen fan fêstrinnen foar jo útsetten.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Negearje",
"Ignore Patterns": "Negear-patroanen",
@@ -187,6 +200,7 @@
"No File Versioning": "Gjin triemferzjebehear",
"No files will be deleted as a result of this operation.": "Der wurde gjin triemen fuortsmiten as gefolch fan dizze aksje.",
"No upgrades": "Gjin fernijings",
"Not shared": "Not shared",
"Notice": "Notysje",
"OK": "Okee",
"Off": "Ut",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Foarbyld fan brûkensrapport ",
"Quick guide to supported patterns": "Fluch-paadwizer foar stipe patroanen",
"Random": "Willekeurich",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Allinnich Untfange",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Resinte Feroarings",
"Reduced by ignore patterns": "Ferlytse troch negear-patroanen",
"Release Notes": "Utjeftenotysjes",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Ferzje kandidaten hawwe de lêste mooglikheden en ferbetterings. Se binne allyksa de tradisjonele twa-wyklikse Syncthing ferzjes.",
"Remote Devices": "Apparaten op Ofstân",
"Remote GUI": "Remote GUI",
"Remove": "Fuortsmite",
"Remove Device": "Apparaat Fuortsmite",
"Remove Folder": "Map Fourtsmite",
@@ -249,6 +266,7 @@
"Select All": "Alles Selektearje",
"Select a version": "Kies in ferzje",
"Select additional devices to share this folder with.": "Doch apparaten derby om dizze map mei te dielen.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Selektearje de nijste ferzje",
"Select oldest version": "Selektearje de âldste ferzje",
"Select the folders to share with this device.": "Sykje de mappen út om mei dit apparaat te dielen.",
@@ -259,6 +277,7 @@
"Share Folder": "Map diele",
"Share Folders With Device": "Map diele mei apparaat",
"Share this folder?": "Dizze map diele?",
"Shared Folders": "Shared Folders",
"Shared With": "Dielt mei",
"Sharing": "Dielen",
"Show ID": "ID sjen litte",
@@ -281,6 +300,7 @@
"Start Browser": "Browser iepenje wannear't Syncthing start",
"Statistics": "Statistiken",
"Stopped": "Stoppe",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Help (Forum)",
"Support Bundle": "Helpbundel",
"Sync Protocol Listen Addresses": "Sync-protokolharkadressen",
@@ -310,6 +330,7 @@
"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.": "De folgende yntervals wurd brûkt: foar it earste oere wurd eltse 30 sekonden in ferzje bewarre, foar de earste dei wurd eltse oere in ferzje bewarre, foar de earste 30 dagen wurd eltse dei in ferzje bewarre, oant ta de maksimale âldens wurd eltse wike in ferzje bewarre.",
"The following items could not be synchronized.": "De folgende items koene net syngronisearre wurde.",
"The following items were changed locally.": "De neikommende items binne lokaal feroare.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "De maksimale âldens moat in nûmer en net leech wêze.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "It fluggenslimyt moat in posityf nûmer wêze (0: gjin limyt)",
"The rescan interval must be a non-negative number of seconds.": "It wersken-ynterfal moat in posityf tal fan sekonden wêze.",
"There are no devices to share this folder with.": "Der binne gjin apparaten om dizze map mei te dielen.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Sy wurde automatysk opnij probearre en sille syngronisearre wurde wannear at de flater oplost is.",
"This Device": "Dit Apparaat",
"This can easily give hackers access to read and change any files on your computer.": "Dit kin samar ynkringers (hackers) tagong jaan om elke triem op jo kompjûter te besjen en te feroarjen.",
@@ -335,10 +357,14 @@
"Unavailable": "Net beskikber",
"Unavailable/Disabled by administrator or maintainer": "Net beskikber/Utsetten troch administrator of ûnderhâlder",
"Undecided (will prompt)": "Noch net beslist (wurd noch frege)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Net mear negeare",
"Unknown": "Unbekend",
"Unshared": "Net dielt",
"Unshared Devices": "Net-dielde Apparaten",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "By de tiid",
"Updated": "Fernijt",
"Upgrade": "Fernije",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Jo hawwe gjin negearde mappen.",
"You have unsaved changes. Do you really want to discard them?": "Jo hawwe noch net-opsleine feroarings. Wolle jo dizze echt fuortsmite?",
"You must keep at least one version.": "Jo moatte minstens ien ferzje bewarje.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dagen",
"directories": "directories",
"files": "triemmen",
@@ -381,5 +408,6 @@
"items": "items",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wol map \"{{folder}}\" diele.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wol map \"{{folderlabel}}\" ({{folder}}) diele."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wol map \"{{folderlabel}}\" ({{folder}}) diele.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Haladó",
"Advanced Configuration": "Haladó beállítások",
"All Data": "Minden adat",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Minden, ezzel az eszközzel megosztott mappát jelszóval kell védeni, így az összes elküldött adat olvashatatlan a megadott jelszó nélkül.",
"Allow Anonymous Usage Reporting?": "A névtelen felhasználási adatok elküldhetők?",
"Allowed Networks": "Engedélyezett hálózatok",
"Alphabetic": "ABC sorrendben",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Külső program kezeli a fájlverzió-követést. Az távolítja el a fájlt a megosztott mappából. Ha az alkalmazás útvonala szóközöket tartalmaz, zárójelezni szükséges az útvonalat.",
"Anonymous Usage Reporting": "Névtelen felhasználási adatok küldése",
"Anonymous usage report format has changed. Would you like to move to the new format?": "A névtelen használati jelentés formátuma megváltozott. Szeretnél áttérni az új formátumra?",
"Are you sure you want to permanently delete all these files?": "Biztos, hogy véglegesen törölhetőek mindezek a fájlok?",
"Are you sure you want to remove device {%name%}?": "Biztos, hogy el akarod távolítani az eszközt: {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Biztos, hogy el akarod távolítani a mappát: {{label}}?",
"Are you sure you want to restore {%count%} files?": "Biztos, hogy vissza akarod állítani a(z) {{count}} fájlt?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Eszközök, melyekkel jelenleg meg van osztva",
"Danger!": "Veszély!",
"Debugging Facilities": "Hibakeresési képességek",
"Default Configuration": "Alapértelmezett beállítások",
"Default Device": "Alapértelmezett eszköz",
"Default Folder": "Alapértelmezett mappa",
"Default Folder Path": "Alapértelmezett mappa útvonala",
"Defaults": "Alapértelmezések",
"Delete Unexpected Items": "Váratlan elemek törlése",
"Deleted": "Törölve",
"Deselect All": "Kijelölés megszüntetése",
"Deselect devices to stop sharing this folder with.": "Azon eszközök kijelölésének törlése, amelyekkel e mappa megosztása leállítandó.",
"Deselect folders to stop sharing with this device.": "Szüntesse meg a mappák kijelölését a mappák megosztásának leállításához ezzel az eszközzel.",
"Device": "Eszköz",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "\"{{name}}\" eszköz ({{device}} @ {{address}}) szeretne csatlakozni. Hozzáadható az új eszköz?",
"Device ID": "Eszközazonosító",
"Device Identification": "Eszközazonosító",
"Device Name": "Eszköz neve",
"Device is untrusted, enter encryption password": "Az eszköz nem megbízható, adjon meg titkosítási jelszót",
"Device rate limits": "Eszköz sávszélessége",
"Device that last modified the item": "Az eszköz, amely utoljára módosította az elemet",
"Devices": "Eszközök",
@@ -92,7 +101,9 @@
"Downloading": "Letöltés",
"Edit": "Szerkesztés",
"Edit Device": "Eszköz szerkesztése",
"Edit Device Defaults": "Eszköz alapértelmezéseinek szerkesztése",
"Edit Folder": "Mappa szerkesztése",
"Edit Folder Defaults": "Mappa alapértelmezéseinek szerkesztése",
"Editing {%path%}.": "{{path}} szerkesztése.",
"Enable Crash Reporting": "Összeomlás-jelentés engedélyezése",
"Enable NAT traversal": "NAT bejárás engedélyezése",
@@ -122,6 +133,7 @@
"Folder Label": "Mappacímke",
"Folder Path": "Mappa elérési útvonala",
"Folder Type": "Mappatípus",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "A „{{receiveEncrypted}}” mappa típusa nem változtatható meg a létrehozása után. El kell távolítani a mappát, az adatokat törölni kell vagy visszafejteni a lemezen és újra hozzáadni a mappát.",
"Folders": "Mappák",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Az alábbi mappák figyelésének indításakor hibák léptek fel. Minden percben megismétlődik a próbálkozás, így a hibák valószínűleg el fognak tűnni. Ha mégsem, meg kell próbálni javítani az előidéző hibát vagy segítséget kérni.",
"Full Rescan Interval (s)": "Teljes átnézési intervallum (mp)",
@@ -139,6 +151,7 @@
"Help": "Súgó",
"Home page": "Főoldal",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "A jelenlegi beállítások azonban azt jelzik, hogy nem kívánja engedélyezni. Az automatikus összeomlás-jelentés ezért letiltásra került.",
"If untrusted, enter encryption password": "Ha nem megbízható, adjon hozzá titkosítási jelszót",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Ha kívánatos, hogy a számítógép többi felhasználója ne tudja elérni a Syncthinget, sem annak fájljait, érdemes az azonosítást beállítani.",
"Ignore": "Mellőzés",
"Ignore Patterns": "Mellőzési minták",
@@ -168,7 +181,7 @@
"Local State (Total)": "Helyi állapot (teljes)",
"Locally Changed Items": "Helyileg változott elemek",
"Log": "Napló",
"Log tailing paused. Scroll to the bottom to continue.": "Napló utolsó sorainak figyelése leállítva. Görgetve lehet folytatni.",
"Log tailing paused. Scroll to the bottom to continue.": "Napló utolsó sorainak figyelése szüneteltetve. Alulra görgetve lehet folytatni.",
"Logs": "Naplófájlok",
"Major Upgrade": "Főverzió-frissítés",
"Mass actions": "Tömeges műveletek",
@@ -187,6 +200,7 @@
"No File Versioning": "Nincs fájlverzió-követés",
"No files will be deleted as a result of this operation.": "A művelet eredményeként egyetlen fájl sem lesz törölve.",
"No upgrades": "Nincsenek frissítések",
"Not shared": "Nem megosztott",
"Notice": "Megjegyzés",
"OK": "Rendben",
"Off": "Kikapcsolva",
@@ -201,9 +215,9 @@
"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": "A mappa elérési útvonala az eszközön. Amennyiben nem létezik, a program automatikusan létrehozza. A hullámvonal (~) a következő helyettesítésre használható: ",
"Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "Az útvonal, ahol létrejönnek az automatikusan elfogadott mappák, valamint a grafikus felületen létrehozott mappák esetén alapértelmezetten javasolt útvonal. A hullámvonal karakter (~) erre egészül ki: {{tilde}}",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "A verziók tárolására szolgáló elérési út (hagyd üresen a megasztott mappa alapértelmezett .stversions könyvtárának használatához)",
"Pause": "Szünet",
"Pause All": "Mindent szüneteltet",
"Paused": "Szünetel",
"Pause": "Szüneteltetés",
"Pause All": "Minden szüneteltetése",
"Paused": "Szüneteltetve",
"Paused (Unused)": "Szüneteltetve (használaton kívül)",
"Pending changes": "Várakozó módosítások",
"Periodic scanning at given interval and disabled watching for changes": "Periodikus átnézés a megadott időközönként és a változások keresése letiltva",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Használati jelentés áttekintése",
"Quick guide to supported patterns": "Rövid útmutató a használható mintákról",
"Random": "Véletlenszerű",
"Receive Encrypted": "Titkosított fogadás",
"Receive Only": "Csak fogadás",
"Received data is already encrypted": "A fogadott adatok már titkosítottak",
"Recent Changes": "Utolsó módosítások",
"Reduced by ignore patterns": "Mellőzési mintákkal csökkentve",
"Release Notes": "Kiadási megjegyzések",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Az előzetes kiadások tartalmazzák a legújabb fejlesztéseket és javításokat. Ezek hasonlóak a hagyományos, kétheti Syncthing kiadásokhoz.",
"Remote Devices": "Távoli eszközök",
"Remote GUI": "Távoli grafikus felület",
"Remove": "Eltávolítás",
"Remove Device": "Eszköz eltávolítás",
"Remove Folder": "Mappa eltávolítás",
@@ -249,6 +266,7 @@
"Select All": "Mindent kijelöl",
"Select a version": "Válassz egy verziót",
"Select additional devices to share this folder with.": "További eszközök, amelyekkel megosztandó a mappa.",
"Select additional folders to share with this device.": "Válasszon további ezzel az eszközzel megosztandó mappákat.",
"Select latest version": "Legfrissebb verzió kijelölése",
"Select oldest version": "Legrégebbi verzió kijelölése",
"Select the folders to share with this device.": "Mappák, amelyek megosztandók ezzel az eszközzel.",
@@ -259,6 +277,7 @@
"Share Folder": "Mappa megosztása",
"Share Folders With Device": "Mappák megosztása az eszközzel",
"Share this folder?": "Megosztható ez a mappa?",
"Shared Folders": "Megosztott mappák",
"Shared With": "Megosztva ezekkel:",
"Sharing": "Megosztás",
"Show ID": "Azonosító megjelenítése",
@@ -281,6 +300,7 @@
"Start Browser": "Böngésző indítása",
"Statistics": "Statisztika",
"Stopped": "Leállítva",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Csak titkosított adatokat tárol és szinkronizál. Minden kapcsolatban lévő eszközön a mappákat ugyanazzal a jelszóval kell védeni vagy „{{receiveEncrypted}}” típusúnak kell lenniük.",
"Support": "Támogatás",
"Support Bundle": "Támogatási csomag",
"Sync Protocol Listen Addresses": "Szinkronizációs protokoll címe",
@@ -310,6 +330,7 @@
"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.": "A következő intervallumokat használjuk: egy régi verziót őrzünk meg az első órában minden 30 másodpercben, az első nap minden órában, az első 30 napban minden nap, egészen addig amíg el nem érjük a maximálisan megtartható verziók számát minden héten.",
"The following items could not be synchronized.": "A következő elemek nem szinkronizálhatóak.",
"The following items were changed locally.": "A következő elemek változtak helyileg.",
"The following unexpected items were found.": "A következő váratlan elemek találhatóak.",
"The interval must be a positive number of seconds.": "A tisztítási intervallum egy pozitív számmal kifejezett másodperc kell legyen.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "A verziók mappáin futó tisztítási folyamat intervalluma másodpercekben kifejezve. A nullával letiltható az időszakos tisztítás.",
"The maximum age must be a number and cannot be blank.": "A maximális kornak számnak kell lenni és nem lehet üres.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "A sebességlimitnek pozitív számnak kell lennie (0: nincs limit)",
"The rescan interval must be a non-negative number of seconds.": "Az átnézési intervallum nullánál nagyobb másodperc érték kell legyen.",
"There are no devices to share this folder with.": "Nincsenek eszközök, amelyekkel megosztható lenne a mappa.",
"There are no folders to share with this device.": "Nincsenek mappák, amelyek megoszthatók ezzel az eszközzel.",
"They are retried automatically and will be synced when the error is resolved.": "A hiba javítása után automatikusan újra megpróbálja a szinkronizálást.",
"This Device": "Ez az eszköz",
"This can easily give hackers access to read and change any files on your computer.": "Így a hekkerek könnyedén hozzáférést szerezhetnek a gépen tárolt fájlok olvasásához és módosításához.",
@@ -335,10 +357,14 @@
"Unavailable": "Nem elérhető",
"Unavailable/Disabled by administrator or maintainer": "Nem elérhető/letiltva egy adminisztrátor vagy karbantartó által",
"Undecided (will prompt)": "Bizonytalan (kérdezni fogja)",
"Unexpected Items": "Váratlan elemek",
"Unexpected items have been found in this folder.": "Váratlan elemek találhatóak ebben a mappában.",
"Unignore": "Mellőzés visszavonása",
"Unknown": "Ismeretlen",
"Unshared": "Nincs megosztva",
"Unshared Devices": "Nem megosztott eszközök",
"Unshared Folders": "Nem megosztott mappák",
"Untrusted": "Nem megbízható",
"Up to Date": "Friss",
"Updated": "Frissítve",
"Upgrade": "Frissítés",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Nincsenek mellőzött mappák.",
"You have unsaved changes. Do you really want to discard them?": "Nincs minden beállítás elmentve. Valóban elvethetők?",
"You must keep at least one version.": "Legalább egy verziót meg kell tartani.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Soha ne adjon hozzá vagy módosítson helyileg semmit a „{{receiveEncrypted}}” mappában.",
"days": "nap",
"directories": "mappa",
"files": "fájl",
@@ -381,5 +408,6 @@
"items": "elem",
"seconds": "másodperc",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} szeretné megosztani a mappát: „{{folder}}”.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} szeretné megosztani a mappát: „{{folderlabel}}” ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} szeretné megosztani a mappát: „{{folderlabel}}” ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} újra bevezetheti ezt az eszközt."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avanzato",
"Advanced Configuration": "Configurazione Avanzata",
"All Data": "Tutti i Dati",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Tutte le cartelle condivise con questo dispositivo devono essere protette da una password, in modo tale che tutti i dati inviati siano illeggibili senza la password fornita.",
"Allow Anonymous Usage Reporting?": "Abilitare Statistiche Anonime di Utilizzo?",
"Allowed Networks": "Reti Consentite.",
"Alphabetic": "Alfabetico",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Il controllo versione è gestito da un comando esterno. Quest'ultimo deve rimuovere il file dalla cartella condivisa. Se il percorso dell'applicazione contiene spazi, deve essere indicato tra virgolette.",
"Anonymous Usage Reporting": "Statistiche Anonime di Utilizzo",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Il formato delle statistiche anonime di utilizzo è cambiato. Vuoi passare al nuovo formato?",
"Are you sure you want to permanently delete all these files?": "Sei sicuro di voler eliminare definitivamente tutti questi file?",
"Are you sure you want to remove device {%name%}?": "Sei sicuro di voler rimuovere il dispositivo {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Sei sicuro di voler rimuovere la cartella {{label}}?",
"Are you sure you want to restore {%count%} files?": "Sei sicuro di voler ripristinare {{count}} file?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Attualmente Condiviso Con Dispositivi",
"Danger!": "Pericolo!",
"Debugging Facilities": "Servizi di Debug",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Percorso Cartella di Default",
"Defaults": "Defaults",
"Delete Unexpected Items": "Elimina elementi imprevisti",
"Deleted": "Cancellato",
"Deselect All": "Deseleziona tutto",
"Deselect devices to stop sharing this folder with.": "Deseleziona i dispositivi con cui interrompere la condivisione di questa cartella.",
"Deselect folders to stop sharing with this device.": "Deseleziona le cartelle per interromperne la condivisione con questo dispositivo.",
"Device": "Dispositivo",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Il dispositivo \"{{name}}\" ({{device}} - {{address}}) chiede di connettersi. Aggiungere il nuovo dispositivo?",
"Device ID": "ID Dispositivo",
"Device Identification": "Identificazione Dispositivo",
"Device Name": "Nome Dispositivo",
"Device is untrusted, enter encryption password": "Il dispositivo non è attendibile, inserisci la password di crittografia",
"Device rate limits": "Limiti di velocità del dispositivo",
"Device that last modified the item": "Dispositivo che ha modificato l'elemento per ultimo",
"Devices": "Dispositivi",
@@ -92,7 +101,9 @@
"Downloading": "Scaricamento in corso",
"Edit": "Modifica",
"Edit Device": "Modifica Dispositivo",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Modifica Cartella",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Modifica di {{path}}.",
"Enable Crash Reporting": "Attiva la Segnalazione degli arresti anomali",
"Enable NAT traversal": "Abilita NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Etichetta per la Cartella",
"Folder Path": "Percorso Cartella",
"Folder Type": "Tipo di Cartella",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Il tipo di cartella \"{{receiveEncrypted}}\" non può essere modificato dopo aver aggiunto la cartella. È necessario rimuovere la cartella, eliminare o decrittografare i dati sul disco e aggiungere nuovamente la cartella.",
"Folders": "Cartelle",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Per le seguenti cartelle si è verificato un errore durante l'avvio della ricerca delle modifiche. Sarà ripetuto ogni minuto, quindi gli errori potrebbero risolversi presto. Se persistono, prova a risolvere il problema sottostante e chiedi aiuto se non puoi.",
"Full Rescan Interval (s)": "Intervallo di scansione completa (s)",
@@ -139,6 +151,7 @@
"Help": "Aiuto",
"Home page": "Pagina home",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Tuttavia, le impostazioni correnti indicano che potresti non volerla attiva. Abbiamo disattivato la segnalazione automatica degli arresti anomali per te.",
"If untrusted, enter encryption password": "Se non attendibile, immettere la password di crittografia",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Se vuoi impedire ad altri utenti di questo computer di accedere a Syncthing e attraverso di esso ai tuoi file, prendi in considerazione la configurazione dell'autenticazione.",
"Ignore": "Ignora",
"Ignore Patterns": "Schemi Esclusione File",
@@ -187,6 +200,7 @@
"No File Versioning": "Nessun Controllo Versione",
"No files will be deleted as a result of this operation.": "Nessun file verrà eliminato come risultato di questa operazione.",
"No upgrades": "Nessun aggiornamento",
"Not shared": "Non condiviso",
"Notice": "Avviso",
"OK": "OK",
"Off": "Disattiva",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Anteprima Statistiche di Utilizzo",
"Quick guide to supported patterns": "Guida veloce agli schemi supportati",
"Random": "Casuale",
"Receive Encrypted": "Ricevi crittografato",
"Receive Only": "Ricevi solo",
"Received data is already encrypted": "I dati ricevuti sono già crittografati",
"Recent Changes": "Cambiamenti Recenti",
"Reduced by ignore patterns": "Ridotto da schemi di esclusione",
"Release Notes": "Note di Rilascio",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Le versioni candidate al rilascio contengono le ultime funzionalità e aggiustamenti. Sono simili ai rilasci bisettimanali di Syncthing.",
"Remote Devices": "Dispositivi Remoti",
"Remote GUI": "Interfaccia remota",
"Remove": "Rimuovi",
"Remove Device": "Rimuovi Dispositivo",
"Remove Folder": "Rimuovi Cartella",
@@ -249,6 +266,7 @@
"Select All": "Seleziona Tutto",
"Select a version": "Seleziona una versione",
"Select additional devices to share this folder with.": "Seleziona altri dispositivi con cui condividere questa cartella.",
"Select additional folders to share with this device.": "Seleziona altre cartelle da condividere con questo dispositivo.",
"Select latest version": "Seleziona l'ultima versione",
"Select oldest version": "Seleziona la versione più vecchia",
"Select the folders to share with this device.": "Seleziona le cartelle da condividere con questo dispositivo.",
@@ -259,6 +277,7 @@
"Share Folder": "Condividi la Cartella",
"Share Folders With Device": "Condividi Cartelle con il Dispositivo",
"Share this folder?": "Vuoi condividere questa cartella?",
"Shared Folders": "Cartelle condivise",
"Shared With": "Condiviso Con",
"Sharing": "Condivisione",
"Show ID": "Mostra ID",
@@ -281,6 +300,7 @@
"Start Browser": "Avvia Browser",
"Statistics": "Statistiche",
"Stopped": "Fermato",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Memorizza e sincronizza solo i dati crittografati. Le cartelle su tutti i dispositivi collegati devono essere configurate con la stessa password o essere del tipo \"{{receiveEncrypted}}\".",
"Support": "Supporto",
"Support Bundle": "Pacchetto di supporto",
"Sync Protocol Listen Addresses": "Indirizzi del Protocollo di Sincronizzazione",
@@ -310,6 +330,7 @@
"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.": "Vengono utilizzati i seguenti intervalli temporali: per la prima ora viene mantenuta una versione ogni 30 secondi, per il primo giorno viene mantenuta una versione ogni ora, per i primi 30 giorni viene mantenuta una versione al giorno, successivamente viene mantenuta una versione ogni settimana fino al periodo massimo impostato.",
"The following items could not be synchronized.": "Non è stato possibile sincronizzare i seguenti elementi.",
"The following items were changed locally.": "I seguenti elementi sono stati modificati localmente.",
"The following unexpected items were found.": "Sono stati trovati i seguenti elementi imprevisti.",
"The interval must be a positive number of seconds.": "L'intervallo deve essere un numero positivo di secondi.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "L'intervallo, in secondi, per l'esecuzione della pulizia nella directory delle versioni. Zero per disabilitare la pulizia periodica.",
"The maximum age must be a number and cannot be blank.": "La durata massima dev'essere un numero e non può essere vuoto.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Il limite di banda deve essere un numero non negativo (0: nessun limite)",
"The rescan interval must be a non-negative number of seconds.": "L'intervallo di scansione deve essere un numero non negativo secondi.",
"There are no devices to share this folder with.": "Non ci sono dispositivi con cui condividere questa cartella.",
"There are no folders to share with this device.": "Non ci sono cartelle da condividere con questo dispositivo.",
"They are retried automatically and will be synced when the error is resolved.": "Verranno effettuati tentativi in automatico e verranno sincronizzati quando l'errore sarà risolto.",
"This Device": "Questo Dispositivo",
"This can easily give hackers access to read and change any files on your computer.": "Ciò potrebbe facilmente permettere agli hackers accesso alla lettura e modifica di qualunque file del tuo computer.",
@@ -335,10 +357,14 @@
"Unavailable": "Non disponibile",
"Unavailable/Disabled by administrator or maintainer": "Non disponibile/Disabilitato dall'amministratore o dal manutentore",
"Undecided (will prompt)": "Non deciso (verrà richiesto)",
"Unexpected Items": "Elementi imprevisti",
"Unexpected items have been found in this folder.": "Sono stati trovati elementi imprevisti in questa cartella.",
"Unignore": "Non ignorare",
"Unknown": "Sconosciuto",
"Unshared": "Non Condiviso",
"Unshared Devices": "Dispositivi non condivisi",
"Unshared Folders": "Cartelle non condivise",
"Untrusted": "Non attendibile",
"Up to Date": "Sincronizzato",
"Updated": "Aggiornato",
"Upgrade": "Aggiornamento",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Non ci sono cartelle ignorate.",
"You have unsaved changes. Do you really want to discard them?": "Hai modifiche non salvate. Vuoi davvero scartarle?",
"You must keep at least one version.": "È necessario mantenere almeno una versione.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Non si dovrebbe mai aggiungere o modificare nulla localmente in una cartella \"{{receiveEncrypted}}\".",
"days": "giorni",
"directories": "directory",
"files": "file",
@@ -381,5 +408,6 @@
"items": "elementi",
"seconds": "secondi",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vuole condividere la cartella \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vuole condividere la cartella \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vuole condividere la cartella \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} potrebbe reintrodurre questo dispositivo."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "高度な設定",
"Advanced Configuration": "高度な設定",
"All Data": "全てのデータ",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "匿名で使用状況をレポートすることを許可しますか?",
"Allowed Networks": "許可されているネットワーク",
"Alphabetic": "アルファベット順",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"Anonymous Usage Reporting": "匿名での使用状況レポート",
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名での使用状況レポートのフォーマットが変わりました。新形式でのレポートに移行しますか?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "デバイス {{name}} を削除してよろしいですか?",
"Are you sure you want to remove folder {%label%}?": "フォルダー {{label}} を削除してよろしいですか?",
"Are you sure you want to restore {%count%} files?": "Are you sure you want to restore {{count}} files?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "現在共有中のデバイス",
"Danger!": "危険!",
"Debugging Facilities": "デバッグ機能",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "デフォルトのフォルダーパス",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "削除",
"Deselect All": "すべて選択解除",
"Deselect devices to stop sharing this folder with.": "このフォルダの共有を停止したいデバイスがある場合は、当該デバイスの選択を解除してください。",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "デバイス",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "デバイス「{{name}}」 ({{address}} の {{device}}) が接続を求めています。新しいデバイスとして追加しますか?",
"Device ID": "デバイスID",
"Device Identification": "デバイスID",
"Device Name": "デバイス名",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "デバイス速度制限",
"Device that last modified the item": "Device that last modified the item",
"Devices": "デバイス",
@@ -92,7 +101,9 @@
"Downloading": "ダウンロード中",
"Edit": "編集",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "{{path}} を編集中",
"Enable Crash Reporting": "クラッシュレポートを有効にする",
"Enable NAT traversal": "NATトラバーサルを有効にする",
@@ -122,6 +133,7 @@
"Folder Label": "フォルダー名",
"Folder Path": "フォルダーパス",
"Folder Type": "フォルダーの種類",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "フォルダー",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "フルスキャンの間隔 (秒)",
@@ -139,6 +151,7 @@
"Help": "ヘルプ",
"Home page": "ホームページ",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "無視",
"Ignore Patterns": "無視するファイル名",
@@ -187,6 +200,7 @@
"No File Versioning": "バージョン管理をしない",
"No files will be deleted as a result of this operation.": "この操作を行っても、ファイルが削除されることはありません。",
"No upgrades": "アップグレードしない",
"Not shared": "Not shared",
"Notice": "通知",
"OK": "OK",
"Off": "オフ",
@@ -220,12 +234,15 @@
"Preview Usage Report": "使用状況レポートのプレビュー",
"Quick guide to supported patterns": "サポートされているパターンのクイックガイド",
"Random": "ランダム",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "受信のみ",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "最近の変更点",
"Reduced by ignore patterns": "無視パターン該当分を除く",
"Release Notes": "リリースノート",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "リリース候補版には最新の機能と修正が含まれます。これは従来の隔週リリースに近いものです。",
"Remote Devices": "接続先デバイス",
"Remote GUI": "Remote GUI",
"Remove": "除去",
"Remove Device": "デバイスを削除",
"Remove Folder": "フォルダーを削除",
@@ -249,6 +266,7 @@
"Select All": "すべて選択",
"Select a version": "バージョンを選択してください",
"Select additional devices to share this folder with.": "このフォルダの共有に追加したいデバイスがある場合は、当該デバイスを選択してください。",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "最も新しいバージョンを選択",
"Select oldest version": "最も古いバージョンを選択",
"Select the folders to share with this device.": "このデバイスと共有するフォルダーを選択してください。",
@@ -259,6 +277,7 @@
"Share Folder": "フォルダーを共有する",
"Share Folders With Device": "このデバイスと共有するフォルダー",
"Share this folder?": "このフォルダーを共有しますか?",
"Shared Folders": "Shared Folders",
"Shared With": "共有中のデバイス",
"Sharing": "共有",
"Show ID": "IDを表示",
@@ -281,6 +300,7 @@
"Start Browser": "起動時にウェブブラウザーで状態を表示する",
"Statistics": "統計情報",
"Stopped": "停止中",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "サポート",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "同期プロトコルの待ち受けアドレス",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "最大保存日数には数値を指定してください。空欄にはできません。",
@@ -322,6 +343,7 @@
"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秒以上で指定してください。",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "この設定のままでは、あなたのコンピューターにある任意のファイルを、他者が簡単に盗み見たり書き換えたりすることができます。",
@@ -335,10 +357,14 @@
"Unavailable": "Unavailable",
"Unavailable/Disabled by administrator or maintainer": "Unavailable/Disabled by administrator or maintainer",
"Undecided (will prompt)": "未決定(再確認する)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "無視を解除",
"Unknown": "不明",
"Unshared": "非共有",
"Unshared Devices": "非共有のデバイス",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "最新",
"Updated": "更新",
"Upgrade": "アップグレード",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "無視したフォルダーはありません。",
"You have unsaved changes. Do you really want to discard them?": "未保存の変更があります。本当に破棄してよろしいですか?",
"You must keep at least one version.": "少なくとも一つのバージョンを保持する必要があります。",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "日",
"directories": "directories",
"files": "個のファイル",
@@ -381,5 +408,6 @@
"items": "項目",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} がフォルダー \"{{folder}}\" を共有するよう求めています。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} がフォルダー「{{folderlabel}}」 ({{folder}}) を共有するよう求めています。"
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} がフォルダー「{{folderlabel}}」 ({{folder}}) を共有するよう求めています。",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "고급",
"Advanced Configuration": "고급 설정",
"All Data": "전체 데이터",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "익명 사용 보고서를 보내시겠습니까?",
"Allowed Networks": "허가된 네트워크",
"Alphabetic": "알파벳순",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "외부 커맨드가 파일 버전을 관리합니다. 공유된 폴더에서 파일을 삭제해야 합니다. 응용 프로그램의 경로에 공백이 있으면 따옴표로 묶어야합니다.",
"Anonymous Usage Reporting": "익명 사용 보고서",
"Anonymous usage report format has changed. Would you like to move to the new format?": "익명 사용 리포트의 형식이 변경되었습니다. 새 형식으로 이동 하시겠습니까?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "{{name}} 장치를 제거 하시겠습니까?",
"Are you sure you want to remove folder {%label%}?": "{{label}} 폴더를 제거 하시겠습니까?",
"Are you sure you want to restore {%count%} files?": "{{count}} 개의 파일을 복원 하시겠습니까?",
@@ -56,22 +58,29 @@
"Copied from original": "원본에서 복사됨",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 the following Contributors:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "무시 패턴 만들기, {{path}}에 존재하는 파일을 덮어쓰기 합니다",
"Currently Shared With Devices": "Currently Shared With Devices",
"Currently Shared With Devices": "현재 공유된 기기들",
"Danger!": "경고!",
"Debugging Facilities": "디버깅 기능",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "기본 폴더 경로",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "삭제됨",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "기기",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "다른 기기 {{device}} ({{address}}) 에서 접속을 요청했습니다. 새 장치를 추가하시겠습니까?",
"Device ID": "기기 ID",
"Device Identification": "기기 식별자",
"Device Name": "기기 이름",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "항목을 마지막으로 수정 한 기기",
"Devices": "기기",
"Disable Crash Reporting": "Disable Crash Reporting",
"Disable Crash Reporting": "충돌 보고 해제",
"Disabled": "비활성화",
"Disabled periodic scanning and disabled watching for changes": "주기적 스캔을 사용 중지하고 변경 사항을 감시하지 않음",
"Disabled periodic scanning and enabled watching for changes": "주기적 스캔을 사용 중지하고 변경 사항 감시 하기",
@@ -91,8 +100,10 @@
"Downloaded": "다운로드됨",
"Downloading": "다운로드 중",
"Edit": "편집",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "기기 수정",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "폴더 수정",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "{{path}} 수정하기.",
"Enable Crash Reporting": "충돌 보고 활성화",
"Enable NAT traversal": "NAT traversal 활성화",
@@ -102,7 +113,7 @@
"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.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "무시할 패턴을 한 줄에 하나씩 입력하세요.",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Enter up to three octal digits.": "최대 3자리의 8진수를 입력하세요.",
"Error": "오류",
"External File Versioning": "외부 파일 버전 관리",
"Failed Items": "실패한 항목",
@@ -122,6 +133,7 @@
"Folder Label": "폴더 라벨",
"Folder Path": "폴더 경로",
"Folder Type": "폴더 유형",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "폴더",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "전체 탐색 간격 (s)",
@@ -139,6 +151,7 @@
"Help": "도움말",
"Home page": "홈페이지",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "무시",
"Ignore Patterns": "패턴 무시",
@@ -187,6 +200,7 @@
"No File Versioning": "파일 버전 관리 안 함",
"No files will be deleted as a result of this operation.": "No files will be deleted as a result of this operation.",
"No upgrades": "업데이트 안함",
"Not shared": "Not shared",
"Notice": "공지",
"OK": "확인",
"Off": "꺼짐",
@@ -220,12 +234,15 @@
"Preview Usage Report": "사용 보고서 미리보기",
"Quick guide to supported patterns": "지원하는 패턴에 대한 빠른 도움말",
"Random": "무작위",
"Receive Only": "Receive Only",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "수신 전용",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "최근 변경",
"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": "원격 기기",
"Remote GUI": "Remote GUI",
"Remove": "삭제",
"Remove Device": "기기 제거",
"Remove Folder": "폴더 제거",
@@ -249,6 +266,7 @@
"Select All": "모두 선택",
"Select a version": "버전 선택",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "가장 최신 버전 선택",
"Select oldest version": "가장 오래된 버전 선택",
"Select the folders to share with this device.": "이 장치와 공유할 폴더를 선택합니다.",
@@ -259,6 +277,7 @@
"Share Folder": "폴더 공유",
"Share Folders With Device": "폴더를 공유할 기기",
"Share this folder?": "이 폴더를 공유하시겠습니까?",
"Shared Folders": "Shared Folders",
"Shared With": "~와 공유",
"Sharing": "Sharing",
"Show ID": "내 기기 ID",
@@ -281,6 +300,7 @@
"Start Browser": "브라우저 열기",
"Statistics": "통계",
"Stopped": "중지됨",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "지원",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "동기화 프로토콜 수신 주소",
@@ -310,7 +330,8 @@
"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초마다 유지되며, 첫 하루 동안은 매 시간, 첫 한 달 동안은 매 일마다 유지됩니다. 그리고 최대 날짜까지는 버전이 매 주마다 유지됩니다.",
"The following items could not be synchronized.": "이 항목들은 동기화 할 수 없습니다.",
"The following items were changed locally.": "The following items were changed locally.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "간격은 초 단위의 자연수여야 합니다.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"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을 입력하세요,",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "대역폭 제한 설정은 반드시 양수로 입력해야 합니다 (0: 무제한)",
"The rescan interval must be a non-negative number of seconds.": "재검색 간격은 초단위이며 양수로 입력해야 합니다.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "이 설정은 해커가 손쉽게 사용자 컴퓨터의 모든 파일을 읽고 변경할 수 있도록 할 수 있습니다.",
@@ -335,10 +357,14 @@
"Unavailable": "불가능",
"Unavailable/Disabled by administrator or maintainer": "운영자 또는 관리자에 의해 불가능/비활성화 됨",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "알 수 없음",
"Unshared": "공유되지 않음",
"Unshared Devices": "Unshared Devices",
"Unshared Devices": "공유되지 않은 기기들",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "최신 데이터",
"Updated": "업데이트 완료",
"Upgrade": "업데이트",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "You have no ignored folders.",
"You have unsaved changes. Do you really want to discard them?": "저장되지 않은 변경이 있습니다. 변경사항을 무시하시겠습니까?",
"You must keep at least one version.": "최소 한 개의 버전은 유지해야 합니다.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "일",
"directories": "directories",
"files": "파일",
@@ -381,5 +408,6 @@
"items": "항목",
"seconds": "초",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 에서 폴더 \\\"{{folder}}\\\" 를 공유하길 원합니다.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 에서 폴더 \"{{folderLabel}}\" ({{folder}})를 공유하길 원합니다."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 에서 폴더 \"{{folderLabel}}\" ({{folder}})를 공유하길 원합니다.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Išplėstiniai",
"Advanced Configuration": "Išplėstinė konfigūracija",
"All Data": "Visiems duomenims",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Siųsti anoniminę naudojimo ataskaitą?",
"Allowed Networks": "Leidžiami tinklai",
"Alphabetic": "Abėcėlės tvarka",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Išorinė komanda apdoroja versijų valdymą. Ji turi pašalinti failą iš bendrinamo aplanko. Jei kelyje į programą yra tarpų, jie turėtų būti imami į kabutes.",
"Anonymous Usage Reporting": "Anoniminė naudojimo ataskaita",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Anoniminės naudojimo ataskaitos formatas pasikeitė. Ar norėtumėte pereiti prie naujojo formato?",
"Are you sure you want to permanently delete all these files?": "Ar tikrai norite visam laikui ištrinti visus šiuos failus?",
"Are you sure you want to remove device {%name%}?": "Ar tikrai norite pašalinti įrenginį {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Ar tikrai norite pašalinti aplanką {{label}}?",
"Are you sure you want to restore {%count%} files?": "Ar tikrai norite atkurti {{count}} failų(-us)?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Šiuo metu bendrinama su įrenginiais",
"Danger!": "Pavojus!",
"Debugging Facilities": "Derinimo priemonės",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Numatytojo aplanko kelias",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Ištrinta",
"Deselect All": "Nuimti žymėjimą nuo visų",
"Deselect devices to stop sharing this folder with.": "Panaikinti įrenginių pasirinkimą, kad su jais būtų nustota bendrinti šį aplanką. ",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Įrenginys",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Įrenginys \"{{name}}\" ({{device}} {{address}}) nori prisijungti. Pridėti naują įrenginį?",
"Device ID": "Įrenginio ID",
"Device Identification": "Įrenginio identifikacija",
"Device Name": "Įrenginio pavadinimas",
"Device is untrusted, enter encryption password": "Įrenginys yra nepatikimas, įveskite šifravimo slaptažodį",
"Device rate limits": "Įrenginio spartos apribojimai",
"Device that last modified the item": "Įrenginys, kuris paskutinis modifikavo elementą",
"Devices": "Įrenginiai",
@@ -91,8 +100,10 @@
"Downloaded": "Parsisiųstas",
"Downloading": "Siunčiama",
"Edit": "Redaguoti",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "Taisyti įrenginį",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Taisyti aplanką",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Redaguojama {{path}}.",
"Enable Crash Reporting": "Įjungti automatines ataskaitas apie strigtis",
"Enable NAT traversal": "Leisti kirsti NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Aplanko etiketė",
"Folder Path": "Kelias iki aplanko",
"Folder Type": "Aplanko tipas",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Aplankai",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Pradėjus stebėti pakeitimus, šiuose aplankuose atsirado klaidų. Kiekvieną minutę bus bandoma iš naujo, taigi, klaidos gali išnykti. Jeigu jos neišnyks, pabandykite išspręsti slypinčią problemą, o jeigu neįstengiate, paprašykite pagalbos.",
"Full Rescan Interval (s)": "Pilno nuskaitymo iš naujo intervalas (s)",
@@ -139,6 +151,7 @@
"Help": "Pagalba",
"Home page": "Pagrindinis puslapis",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Vis dėlto, jūsų esami nustatymai nurodo, kad jūs, greičiausiai, nenorite turėti jas įjungtas. Mes jums išjungėme automatines ataskaitas apie strigtis.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Jei norite neleisti kitiems šio kompiuterio vartotojams gauti prieigą prie Syncthing, o per ją, prieigą prie jūsų failų, tuomet apsvarstykite galimybę nusistatyti tapatybės nustatymą.",
"Ignore": "Nepaisyti",
"Ignore Patterns": "Nepaisyti šablonų",
@@ -187,6 +200,7 @@
"No File Versioning": "Nėra versijų valdymo",
"No files will be deleted as a result of this operation.": "Šios operacijos rezultate nebus pašalinti jokie failai.",
"No upgrades": "Be atnaujinimų",
"Not shared": "Not shared",
"Notice": "Įspėjimas",
"OK": "Gerai",
"Off": "Netaikoma",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Naudojimo ataskaitos peržiūra",
"Quick guide to supported patterns": "Trumpas leistinų šablonų vadovas",
"Random": "Atsitiktinė",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Tik gauti",
"Received data is already encrypted": "Gauti duomenys jau yra šifruoti",
"Recent Changes": "Paskiausi keitimai",
"Reduced by ignore patterns": "Sumažinta pagal nepaisomus šablonus",
"Release Notes": "Laidos Informacija",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Kandidatinėse versijose yra naujausios ypatybės ir pataisymai. Šios versijos yra panašios į tradicines, du kartus per mėnesį išleidžiamas Syncthing versijas.",
"Remote Devices": "Nuotoliniai įrenginiai",
"Remote GUI": "Remote GUI",
"Remove": "Pašalinti",
"Remove Device": "Šalinti įrenginį",
"Remove Folder": "Šalinti aplanką",
@@ -249,6 +266,7 @@
"Select All": "Žymėti visus",
"Select a version": "Pasirinkti versiją",
"Select additional devices to share this folder with.": "Pasirinkti papildomus įrenginius, su kuriais bendrinti šį aplanką.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Pasirinkti paskiausią versiją",
"Select oldest version": "Pasirinkti seniausią versiją",
"Select the folders to share with this device.": "Pasirinkite aplankus kuriais norite dalintis su šiuo įrenginiu.",
@@ -259,6 +277,7 @@
"Share Folder": "Dalintis aplanku",
"Share Folders With Device": "Dalintis aplankalais su šiuo įrenginiu",
"Share this folder?": "Dalintis šiuo aplanku?",
"Shared Folders": "Shared Folders",
"Shared With": "Dalinamasi su",
"Sharing": "Dalinamasis",
"Show ID": "Rodyti ID",
@@ -281,6 +300,7 @@
"Start Browser": "Paleisti naršyklę",
"Statistics": "Statistika",
"Stopped": "Sustabdyta",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Pagalba",
"Support Bundle": "Palaikymo paketas",
"Sync Protocol Listen Addresses": "Sutapatinimo taisyklių adresas",
@@ -298,7 +318,7 @@
"The Syncthing Authors": "Syncthing autoriai",
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing administratoriaus sąsaja yra sukonfigūruota taip, kad be slaptažodžio leistų nuotolinę prieigą.",
"The aggregated statistics are publicly available at the URL below.": "Naudojimosi ataskaitą galite peržiūrėti žemiau nurodytu URL adresu.",
"The cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"The cleanup interval cannot be blank.": "Išvalymo intervalas negali būti tuščias.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Nauji nustatymai išsaugoti, bet neaktyvuoti. Perleiskite Syncthing programą iš naujo norėdami įgalinti naujus nustatymus.",
"The device ID cannot be blank.": "Įrenginio ID negali būti tuščias.",
"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).": "Įrenginio ID, kurį čia reikia įvesti, galite rasti „Veiksmai > Rodyti ID“ dialoge kitame įrenginyje. Tarpai ir brūkšneliai nebūtini (ignoruojami).",
@@ -310,6 +330,7 @@
"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.": "Šie pertraukų nustatymai naudojami: pirmą valandą versijos laikomos 30 sekundžių, pirmą dieną versijos laikomos valandą, pirmas 30 dienų versijos laikomos parą, kol nebus viršytas nustatytas maksimalus amžius.",
"The following items could not be synchronized.": "Nepavyko parsiųsti šių failų.",
"The following items were changed locally.": "Šie elementai buvo pakeisti vietoje.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Maksimalus amžius turi būti skaitmuo ir negali būti tuščias laukelis.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Srauto maksimalus greitis privalo būti ne neigiamas skaičius (0: nėra apribojimo)",
"The rescan interval must be a non-negative number of seconds.": "Nuskaitymo dažnis negali būti neigiamas skaičius.",
"There are no devices to share this folder with.": "Nėra įrenginių su kuriais bendrinti šį aplanką.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Failus bus automatiškai bandoma parsiųsti dar kartą kai išspręsite klaidas.",
"This Device": "Šis įrenginys",
"This can easily give hackers access to read and change any files on your computer.": "Tai gali suteikti programišiams lengvą prieigą skaityti ir keisti bet kokius failus jūsų kompiuteryje.",
@@ -335,10 +357,14 @@
"Unavailable": "Neprieinama",
"Unavailable/Disabled by administrator or maintainer": "Neprieinama/Išjungta administratoriaus ar prižiūrėtojo",
"Undecided (will prompt)": "Nenuspręsta (bus klausiama)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Nustoti nepaisyti",
"Unknown": "Nežinoma",
"Unshared": "Nesidalinama",
"Unshared Devices": "Nebedrinami įrenginiai",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Atnaujinta",
"Updated": "Atnaujinta",
"Upgrade": "Atnaujinimas",
@@ -353,7 +379,7 @@
"Versions": "Versijos",
"Versions Path": "Kelias iki versijos",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Versijos ištrinamos jei senesnės už nustatyta maksimalų amžių arba jei viršytas maksimalus failų skaičius per nustatytą laiko tarpą.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Clean": "Laukiama išvalymo",
"Waiting to Scan": "Laukiama nuskaityti",
"Waiting to Sync": "Laukiama sinchronizuoti",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Įspėjimas, šis kelias yra esamo aplanko \"{{otherFolder}}\" virškatalogis.",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "Jūs neturite jokių nepaisomų aplankų.",
"You have unsaved changes. Do you really want to discard them?": "Turite neįrašytų pakeitimų. Ar tikrai norite juos atmesti?",
"You must keep at least one version.": "Būtina saugoti bent vieną versiją.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dienos",
"directories": "directories",
"directories": "katalogai",
"files": "failai",
"full documentation": "pilna dokumentacija",
"items": "įrašai",
"seconds": "seconds",
"seconds": "sek.",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} nori dalintis aplanku \"{{folder}}\"",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} nori dalintis aplanku \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} nori dalintis aplanku \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avansert",
"Advanced Configuration": "Avanserte innstillinger",
"All Data": "Alle data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Tillat anonym innsamling av brukerdata?",
"Allowed Networks": "Tillatte nettverk",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "En ekstern kommando tar hånd om versjoneringen. Den må fjerne filen fra den delte mappen. Hvis stien til programmet inneholder mellomrom, må den siteres.",
"Anonymous Usage Reporting": "Anonym innsamling av brukerdata",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Det anonyme bruksrapportformatet har endret seg. Ønsker du å gå over til det nye formatet?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Er du sikker på at du ønsker å fjerne enheten {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Er du sikker på at du ønsker å fjerne mappen {{label}}?",
"Are you sure you want to restore {%count%} files?": "Er du sikker på at du ønsker å gjenopprette {{count}} filer?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Fare!",
"Debugging Facilities": "Feilrettingsverktøy",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Forvalgt mappeplassering",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Slettet",
"Deselect All": "Fjern alle markeringer",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Enhet",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Enhet \"{{name}}\" ({{device}} på {{address}}) ønsker å koble til. Legge til ny enhet?",
"Device ID": "Enhets-ID",
"Device Identification": "Enhetskjennemerke",
"Device Name": "Navn på enhet",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "enhetshastighetsgrense",
"Device that last modified the item": "Enheten som sist endret elementet",
"Devices": "Enheter",
@@ -92,7 +101,9 @@
"Downloading": "Laster ned",
"Edit": "Rediger",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Redigerer {{path}}.",
"Enable Crash Reporting": "Skru på krasjrapportering",
"Enable NAT traversal": "Slå på NAT-traversering",
@@ -122,6 +133,7 @@
"Folder Label": "Merkelapp for mappe",
"Folder Path": "Mappeplassering",
"Folder Type": "Mappetype",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Mapper",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Intervall for fullstendig omskanning (s)",
@@ -139,6 +151,7 @@
"Help": "Hjelp",
"Home page": "Hjemmeside",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignorer",
"Ignore Patterns": "Utelatelsesmønster",
@@ -187,6 +200,7 @@
"No File Versioning": "Ingen versjonskontroll",
"No files will be deleted as a result of this operation.": "Ingen filer vil bli slettet som følge av denne operasjonen.",
"No upgrades": "Ingen oppgraderinger",
"Not shared": "Not shared",
"Notice": "Merknader",
"OK": "OK",
"Off": "Av",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Forhåndsvisning av datainnsamling",
"Quick guide to supported patterns": "Kjapp innføring i godkjente mønstre",
"Random": "Tilfeldig",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Bare motta",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Nylige endringer",
"Reduced by ignore patterns": "Reduser med utelatelsesmønster",
"Release Notes": "Utgivelsesnotat",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Utgivelseskandidater inneholder de seneste problemfiksene og funksjonene. De ligner på de tradisjonelle Syncthing-utgivelsene som kom hver andre uke.",
"Remote Devices": "Andre enheter",
"Remote GUI": "Remote GUI",
"Remove": "Fjern",
"Remove Device": "Fjern enhet",
"Remove Folder": "Fjern mappe",
@@ -249,6 +266,7 @@
"Select All": "Velg alle",
"Select a version": "Velg en versjon",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Velg siste versjon",
"Select oldest version": "Velg eldste versjon",
"Select the folders to share with this device.": "Velg hvilke mapper som skal deles med denne enheten.",
@@ -259,6 +277,7 @@
"Share Folder": "Del mappe",
"Share Folders With Device": "Del mapper med enhet",
"Share this folder?": "Del denne mappa?",
"Shared Folders": "Shared Folders",
"Shared With": "Delt med",
"Sharing": "Deling",
"Show ID": "Vis ID",
@@ -281,6 +300,7 @@
"Start Browser": "Start nettleser",
"Statistics": "Statistikk",
"Stopped": "Stoppet",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Brukerstøtte",
"Support Bundle": "Støttebunt",
"Sync Protocol Listen Addresses": "Lytteadresse for synkroniseringsprotokoll",
@@ -310,6 +330,7 @@
"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.": "Følgende intervall blir brukt: Den første timen blir en versjon lagret hvert 30. sekund, den første dagen blir en versjon lagret hver time, de første 30 dagene blir en versjon lagret hver dag, og inntil maksimal levetid blir en versjon lagret hver uke.",
"The following items could not be synchronized.": "Følgende filer kunne ikke synkroniseres.",
"The following items were changed locally.": "Følgende elementer ble endret lokalt.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Maksimal levetid må være et tall og kan ikke være tomt.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Hastighetsbegrensningen kan ikke være et negativt tall (0: ingen begrensing)",
"The rescan interval must be a non-negative number of seconds.": "Antall sekund for intervallet kan ikke være negativt.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Disse hentes automatisk og vil synkroniseres når feilen er blitt utbedret.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": "Utilgjengelig",
"Unavailable/Disabled by administrator or maintainer": "Utilgjengelig/avskrudd av administrator eller vedlikeholder",
"Undecided (will prompt)": "Ikke bestemt (vil spørre)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Ikke ignorer",
"Unknown": "Ukjent",
"Unshared": "Ikke delt",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Oppdatert",
"Updated": "Oppdatert",
"Upgrade": "Oppgradere",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Du har ingen ignorerte mapper.",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You must keep at least one version.": "Du må beholde minst én versjon",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dager",
"directories": "directories",
"files": "filer",
@@ -381,5 +408,6 @@
"items": "elementer",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} ønsker å dele mappa \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker å dele mappa \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} ønsker å dele mappa \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Geavanceerd",
"Advanced Configuration": "Geavanceerde configuratie",
"All Data": "Alle gegevens",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Alle mappen die gedeeld worden met dit apparaat moeten beschermd worden met een wachtwoord zodat alle verzonden gegevens onleesbaar zijn zonder het opgegeven wachtwoord.",
"Allow Anonymous Usage Reporting?": "Versturen van anonieme gebruikersstatistieken toestaan?",
"Allowed Networks": "Toegestane netwerken",
"Alphabetic": "Alfabetisch",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Een externe opdracht regelt het versiebeheer. Hij moet het bestand verwijderen uit de gedeelde map. Als het pad naar de toepassing spaties bevat, moet dit tussen aanhalingstekens geplaatst worden.",
"Anonymous Usage Reporting": "Anonieme gebruikersstatistieken",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Het formaat voor anonieme gebruikersrapporten is gewijzigd. Wilt u naar het nieuwe formaat overschakelen?",
"Are you sure you want to permanently delete all these files?": "Weet u zeker dat u al deze bestanden permanent wilt verwijderen?",
"Are you sure you want to remove device {%name%}?": "Weet u zeker dat u apparaat {{name}} wilt verwijderen?",
"Are you sure you want to remove folder {%label%}?": "Weet u zeker dat u map {{label}} wilt verwijderen?",
"Are you sure you want to restore {%count%} files?": "Weet u zeker dat u {{count}} bestanden wilt herstellen?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Momenteel gedeeld met apparaten",
"Danger!": "Let op!",
"Debugging Facilities": "Debugmogelijkheden",
"Default Configuration": "Standaardconfiguratie",
"Default Device": "Standaardapparaat",
"Default Folder": "Standaardmap",
"Default Folder Path": "Standaardmaplocatie",
"Defaults": "Standaardwaarden",
"Delete Unexpected Items": "Onverwachte items verwijderen",
"Deleted": "Verwijderd",
"Deselect All": "Alles deselecteren",
"Deselect devices to stop sharing this folder with.": "Deselecteer apparaten om er deze map niet meer mee te delen.",
"Deselect folders to stop sharing with this device.": "Deselecteer mappen om te stoppen met delen met dit apparaat.",
"Device": "Apparaat",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Apparaat \"{{name}}\" ({{device}} op {{address}}) wil verbinden. Nieuw apparaat toevoegen?",
"Device ID": "Apparaat-ID",
"Device Identification": "Apparaat-identificatie",
"Device Name": "Naam apparaat",
"Device is untrusted, enter encryption password": "Apparaat wordt niet vertrouwd. Versleutelingswachtwoord opgeven",
"Device rate limits": "Snelheidsbegrenzingen apparaat",
"Device that last modified the item": "Apparaat dat het item laatst gewijzigd heeft",
"Devices": "Apparaten",
@@ -92,7 +101,9 @@
"Downloading": "Downloaden",
"Edit": "Bewerken",
"Edit Device": "Apparaat bewerken",
"Edit Device Defaults": "Standaardwaarden van apparaat bewerken",
"Edit Folder": "Map bewerken",
"Edit Folder Defaults": "Standaardwaarden van map bewerken",
"Editing {%path%}.": "{{path}} bewerken.",
"Enable Crash Reporting": "Crashrapportage inschakelen",
"Enable NAT traversal": "NAT traversal inschakelen",
@@ -122,6 +133,7 @@
"Folder Label": "Maplabel",
"Folder Path": "Maplocatie",
"Folder Type": "Soort map",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Maptype \"{{receiveEncrypted}}\" kan niet gewijzigd worden na het toevoegen van de map. U moet de map verwijderen, de gegevens op schijf verwijderen of ontsleutelen en daarna de map opnieuw toevoegen.",
"Folders": "Mappen",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Voor de volgende mappen trad een fout op tijdens het beginnen opvolgen van wijzigingen. Er zal elke minuut opnieuw geprobeerd worden, dus de fouten kunnen snel verdwijnen. Als ze blijven voorkomen, probeer dan het onderliggende probleem op te lossen en vraag om hulp als u dat niet kunt.",
"Full Rescan Interval (s)": "Interval voor volledig opnieuw scannen (s)",
@@ -139,6 +151,7 @@
"Help": "Help",
"Home page": "Startpagina",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Uw huidige instellingen geven echter aan dat u het misschien niet wilt inschakelen. We hebben de automatische crashrapportage voor u uitgeschakeld.",
"If untrusted, enter encryption password": "Indien niet vertrouwd, versleutelingswachtwoord opgeven",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Als u wilt voorkomen dat andere gebruikers op deze computer toegang krijgen tot Syncthing en daardoor uw bestanden, kunt u overwegen om authenticatie in te stellen.",
"Ignore": "Negeren",
"Ignore Patterns": "Negeerpatronen",
@@ -187,6 +200,7 @@
"No File Versioning": "Geen versiebeheer",
"No files will be deleted as a result of this operation.": "Deze handeling zal geen bestanden verwijderen.",
"No upgrades": "Geen upgrades",
"Not shared": "Niet gedeeld",
"Notice": "Mededeling",
"OK": "Ok",
"Off": "Uit",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Voorbeeld van gebruiksrapport",
"Quick guide to supported patterns": "Snelgids voor ondersteunde patronen",
"Random": "Willekeurig",
"Receive Encrypted": "Versleuteld ontvangen",
"Receive Only": "Alleen ontvangen",
"Received data is already encrypted": "Ontvangen gegevens zijn al versleuteld",
"Recent Changes": "Recente wijzigingen",
"Reduced by ignore patterns": "Verminderd door negeerpatronen",
"Release Notes": "Release-opmerkingen",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates bevatten de laatste functies en oplossingen voor problemen. Ze lijken op de traditionele tweewekelijkse Syncthing-releases.",
"Remote Devices": "Externe apparaten",
"Remote GUI": "Externe GUI",
"Remove": "Verwijderen",
"Remove Device": "Apparaat verwijderen",
"Remove Folder": "Map verwijderen",
@@ -249,6 +266,7 @@
"Select All": "Alles selecteren",
"Select a version": "Selecteer een versie",
"Select additional devices to share this folder with.": "Selecteer extra apparaten om deze map mee te delen.",
"Select additional folders to share with this device.": "Selecteer aanvullende mappen om te delen met dit apparaat.",
"Select latest version": "Laatste versie selecteren",
"Select oldest version": "Oudste versie selecteren",
"Select the folders to share with this device.": "Selecteer de mappen om te delen met dit apparaat.",
@@ -259,6 +277,7 @@
"Share Folder": "Map delen",
"Share Folders With Device": "Mappen delen met apparaat",
"Share this folder?": "Deze map delen?",
"Shared Folders": "Gedeelde mappen",
"Shared With": "Gedeeld met",
"Sharing": "Delen",
"Show ID": "ID weergeven",
@@ -281,6 +300,7 @@
"Start Browser": "Browser starten",
"Statistics": "Statistieken",
"Stopped": "Gestopt",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Bewaart en synchroniseert alleen versleutelde gegevens. Mappen op alle verbonden apparaten moeten met hetzelfde wachtwoord ingesteld worden of ook van het type \"{{receiveEncrypted}}\" zijn.",
"Support": "Ondersteuning",
"Support Bundle": "Ondersteuningspakket",
"Sync Protocol Listen Addresses": "Luisteradressen synchronisatieprotocol",
@@ -310,6 +330,7 @@
"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.": "De volgende intervallen worden gebruikt: het eerste uur worden versies iedere 30 seconden bewaard, de eerste dag worden versies ieder uur bewaard, de eerste 30 dagen worden versies iedere dag bewaard, tot de maximale leeftijd worden versies iedere week bewaard.",
"The following items could not be synchronized.": "De volgende items konden niet gesynchroniseerd worden.",
"The following items were changed locally.": "De volgende items werden lokaal gewijzigd.",
"The following unexpected items were found.": "De volgende onverwachte items zijn teruggevonden.",
"The interval must be a positive number of seconds.": "Het interval moet een positief aantal seconden zijn.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Het interval, in seconden, voor het uitvoeren van opruiming in de versie-map. Nul om de regelmatige schoonmaak uit te schakelen.",
"The maximum age must be a number and cannot be blank.": "De maximumleeftijd moet een getal zijn en mag niet leeg zijn.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "De snelheidsbegrenzing moet een positief getal zijn (0: geen begrenzing)",
"The rescan interval must be a non-negative number of seconds.": "Het interval voor opnieuw scannen moet een positief aantal seconden zijn.",
"There are no devices to share this folder with.": "Er zijn geen apparaten om deze map mee te delen.",
"There are no folders to share with this device.": "Er zijn geen mappen om te delen met dit apparaat.",
"They are retried automatically and will be synced when the error is resolved.": "Ze worden automatisch opnieuw geprobeerd en zullen gesynchroniseerd worden wanneer de fout opgelost is.",
"This Device": "Dit apparaat",
"This can easily give hackers access to read and change any files on your computer.": "Dit kan hackers eenvoudig toegang geven om bestanden op uw computer te lezen en te wijzigen.",
@@ -329,16 +351,20 @@
"This setting controls the free space required on the home (i.e., index database) disk.": "Deze instelling bepaalt de benodigde vrije ruimte op de home-schijf (d.w.z. de indexdatabase).",
"Time": "Tijd",
"Time the item was last modified": "Tijdstip waarop het item laatst gewijzigd is",
"Trash Can File Versioning": "Versiebeheer prullenbak",
"Trash Can File Versioning": "Prullenbak-versiebeheer",
"Type": "Type",
"UNIX Permissions": "UNIX-machtigingen",
"Unavailable": "Niet beschikbaar",
"Unavailable/Disabled by administrator or maintainer": "Niet beschikbaar of uitgeschakeld door administrator of beheerder",
"Undecided (will prompt)": "Onbeslist (zal bevestiging vragen)",
"Unexpected Items": "Onverwachte items",
"Unexpected items have been found in this folder.": "Er zijn onverwachte items teruggevonden in deze map.",
"Unignore": "Niet negeren",
"Unknown": "Onbekend",
"Unshared": "Niet gedeeld",
"Unshared Devices": "Niet-gedeelde apparaten",
"Unshared Folders": "Niet-gedeelde mappen",
"Untrusted": "Niet vertrouwd",
"Up to Date": "Bijgewerkt",
"Updated": "Bijgewerkt",
"Upgrade": "Bijwerken",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "U hebt geen genegeerde mappen.",
"You have unsaved changes. Do you really want to discard them?": "U hebt niet-opgeslagen wijzigingen. Wilt u ze echt verwerpen?",
"You must keep at least one version.": "U moet minstens één versie bewaren.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "U mag lokaal nooit iets toevoegen of wijzigen in een \"{{receiveEncrypted}}\"-map.",
"days": "dagen",
"directories": "mappen",
"files": "bestanden",
@@ -381,5 +408,6 @@
"items": "items",
"seconds": "seconden",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} wil map \"{{folder}}\" delen.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wil map \"{{folderlabel}}\" ({{folder}}) delen."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} wil map \"{{folderlabel}}\" ({{folder}}) delen.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} kan dit apparaat mogelijk opnieuw introduceren."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Zaawansowane",
"Advanced Configuration": "Konfiguracja zaawansowana",
"All Data": "Wszystkie dane",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Zezwalaj na anonimowe statystyki użycia?",
"Allowed Networks": "Dozwolone sieci",
"Alphabetic": "Alfabetycznie",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Zewnętrzne polecenie obsługuje wersjonowanie. Musi ono usunąć plik z dzielonego foldeur. Jeśli ścieżka do aplikacji zawiera odstępy (spacje), powinna być zamknięta w cudzysłowie.",
"Anonymous Usage Reporting": "Anonimowe statystyki użycia",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Format anonimowego raportu zużycia uległ zmianie.\nCzy chcesz przejść na nowy format?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Czy na pewno chcesz usunąć urządzenie {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Czy na pewno chcesz usunąć folder {{label}}?",
"Are you sure you want to restore {%count%} files?": "Czy na pewno chcesz przywrócić {{count}} plików?",
@@ -39,7 +41,7 @@
"Bugs": "Błędy",
"Changelog": "Historia zmian",
"Clean out after": "Uporządkuj",
"Cleaning Versions": "Cleaning Versions",
"Cleaning Versions": "Wyczyść wersje",
"Cleanup Interval": "Cleanup Interval",
"Click to see discovery failures": "Kliknij aby zobaczyć błędy odnajdywania",
"Close": "Zamknij",
@@ -47,7 +49,7 @@
"Comment, when used at the start of a line": "Komentarz, jeżeli użyty na początku linii",
"Compression": "Kompresja",
"Configured": "Skonfigurowane",
"Connected (Unused)": "Connected (Unused)",
"Connected (Unused)": "Połączone (nieużywane)",
"Connection Error": "Błąd połączenia",
"Connection Type": "Rodzaj połączenia",
"Connections": "Połączenia",
@@ -56,18 +58,25 @@
"Copied from original": "Skopiowane z oryginału",
"Copyright © 2014-2019 the following Contributors:": "Wszelkie prawa zastrzeżone © 2014-2019 dla twórców:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Ustawienie wzorów ignorowania, nadpisze istniejący plik w {{path}}.",
"Currently Shared With Devices": "Currently Shared With Devices",
"Currently Shared With Devices": "Aktualnie udostępniane między urządzeniami",
"Danger!": "Niebezpieczne!",
"Debugging Facilities": "Odpluskwianie",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Domyślna ścieżka folderu",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Usunięto",
"Deselect All": "Odznacz wszystko",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Urządzenie",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Urządzenie \"{{name}}\" {{device}} ({{address}}) chce się połączyć. Dodać nowe urządzenie?",
"Device ID": "ID urządzenia",
"Device Identification": "Identyfikator urządzenia",
"Device Name": "Nazwa urządzenia",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Limity transferu urządzenia",
"Device that last modified the item": "Urządzenie, które jako ostatnie zmodyfikowało element",
"Devices": "Urządzenia",
@@ -79,7 +88,7 @@
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).",
"Discard": "Odrzuć",
"Disconnected": "Rozłączony",
"Disconnected (Unused)": "Disconnected (Unused)",
"Disconnected (Unused)": "Rozłączono (nieużywane)",
"Discovered": "Odkryte",
"Discovery": "Odnajdywanie",
"Discovery Failures": "Błędy odnajdowania",
@@ -91,8 +100,10 @@
"Downloaded": "Pobrane",
"Downloading": "Pobieranie",
"Edit": "Edytuj",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "Edytuj urządzenie",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edytuj folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Edytowanie {{path}}.",
"Enable Crash Reporting": "Włącz raportowanie błędów",
"Enable NAT traversal": "Włącz trawersowanie NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Etykieta folderu",
"Folder Path": "Ścieżka folderu",
"Folder Type": "Rodzaj folderu",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Foldery",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "W przypadku następujących folderów wystąpił błąd podczas rozpoczynania monitorowania zmian. Akcja będzie ponawiana co minutę, więc błędy mogą zniknąć. Jeśli nie uda się pozbyć błędów, spróbuj naprawić zasadniczy problem lub poproś o pomoc, jeśli nie możesz tego zrobić.",
"Full Rescan Interval (s)": "Interwał pełnego skanowania (s)",
@@ -139,6 +151,7 @@
"Help": "Pomoc",
"Home page": "Strona domowa",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Twoje aktualne ustawienia wskazują iż być może nie chciał(a)byś wysyłać raportów. Wyłączyliśmy automatyczne raportowanie awarii.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignoruj",
"Ignore Patterns": "Wzorce ignorowania",
@@ -187,6 +200,7 @@
"No File Versioning": "Bez wersjonowania pliku",
"No files will be deleted as a result of this operation.": "W wyniku tej operacji żadne pliki nie zostaną usunięte.",
"No upgrades": "Brak aktualizacji",
"Not shared": "Not shared",
"Notice": "Wskazówka",
"OK": "OK",
"Off": "Wyłącz",
@@ -204,7 +218,7 @@
"Pause": "Zatrzymaj",
"Pause All": "Zatrzymaj wszystkie",
"Paused": "Zatrzymany",
"Paused (Unused)": "Paused (Unused)",
"Paused (Unused)": "Wstrzymane (nieużywane)",
"Pending changes": "Oczekujące zmiany",
"Periodic scanning at given interval and disabled watching for changes": "Okresowe skanowanie w podanym przedziale czasu i wyłączone obserwowanie zmian",
"Periodic scanning at given interval and enabled watching for changes": "Okresowe skanowanie w podanym przedziale czasu i włączone obserwowanie zmian",
@@ -215,17 +229,20 @@
"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",
"Preparing to Sync": "Preparing to Sync",
"Preparing to Sync": "Przygotowanie do synchronizacji",
"Preview": "Podgląd",
"Preview Usage Report": "Podgląd raportu użycia.",
"Quick guide to supported patterns": "Krótki przewodnik po obsługiwanych wzorcach",
"Random": "Losowo",
"Receive Encrypted": "Odbieraj zaszyfrowane",
"Receive Only": "Tylko odbieraj",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Ostatnie zmiany",
"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.": "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",
"Remote GUI": "Remote GUI",
"Remove": "Usuń",
"Remove Device": "Usuń urządzenie",
"Remove Folder": "Usuń folder",
@@ -241,7 +258,7 @@
"Resume": "Wznów",
"Resume All": "Wznów wszystkie",
"Reused": "Ponownie użyte",
"Revert Local Changes": "Przywróć zmiany lokalne",
"Revert Local Changes": "Odrzuć zmiany lokalne",
"Save": "Zapisz",
"Scan Time Remaining": "Pozostały czas skanowania",
"Scanning": "Skanowanie",
@@ -249,6 +266,7 @@
"Select All": "Zaznacz wszystko",
"Select a version": "Wybierz wersję",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Wybierz najnowszą wersję",
"Select oldest version": "Wybierz najstarszą wersję",
"Select the folders to share with this device.": "Wybierz foldery do współdzielenia z tym urządzeniem.",
@@ -259,6 +277,7 @@
"Share Folder": "Udostępnij folder",
"Share Folders With Device": "Udostępnij foldery między urządzeniami",
"Share this folder?": "Udostępnić ten folder?",
"Shared Folders": "Udostępnione foldery",
"Shared With": "Współdzielony z",
"Sharing": "Współdzielenie",
"Show ID": "Pokaż ID",
@@ -281,6 +300,7 @@
"Start Browser": "Uruchom przeglądarkę",
"Statistics": "Statystyki",
"Stopped": "Zatrzymany",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Wsparcie",
"Support Bundle": "Wsparcie",
"Sync Protocol Listen Addresses": "Adres nasłuchu protokołu synchronizacji",
@@ -295,7 +315,7 @@
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing nie może przetworzyć twojego zapytania. Proszę przeładuj stronę lub zrestartuj Syncthing, jeśli problem pozostanie.",
"Take me back": "Zabierz mnie z powrotem",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "Adres GUI jest nadpisywany przez opcje uruchamiania. Zmiany tutaj nie będą obowiązywać, dopóki ta opcja uruchamiania jest używana.",
"The Syncthing Authors": "The Syncthing Authors",
"The Syncthing Authors": "Autorzy Syncthing",
"The Syncthing admin interface is configured to allow remote access without a password.": "Interfejs administracyjny Syncthing jest skonfigurowany w sposób pozwalający na zdalny dostęp bez hasła.",
"The aggregated statistics are publicly available at the URL below.": "Zebrane statystyki są publicznie dostępne pod poniższym linkiem.",
"The cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
@@ -310,6 +330,7 @@
"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.": "Następujący interwał jest używany: dla pierwszej godziny wersja jest zachowywana co 30 sekund, dla pierwszego dnia wersja jest zachowywana co godzinę, dla pierwszego miesiąca wersja jest zachowywana codziennie, aż do maksymalnego odstępu zapisywania wersji co tydzień.",
"The following items could not be synchronized.": "Następujące elementy nie mogły zostać zsynchronizowane.",
"The following items were changed locally.": "Następujące elementy zostały zmienione lokalnie.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Maksymalny wiek musi być liczbą i nie może być pusty.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Ograniczenie prędkości powinno być nieujemną liczbą całkowitą (0: brak ograniczeń)",
"The rescan interval must be a non-negative number of seconds.": "Interwał skanowania musi być niezerową liczbą sekund.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Ponowne próby zachodzą automatycznie, synchronizacja nastąpi po usunięciu usterki.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": "Niedostępne",
"Unavailable/Disabled by administrator or maintainer": "Niedostępne/Wyłączone przez administratora lub opiekuna",
"Undecided (will prompt)": "Jeszcze nie zdecydowałem (przypomnij później)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Wyłącz ignorowanie",
"Unknown": "Nieznany",
"Unshared": "Nieudostępnione",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Nieudostępnione foldery",
"Untrusted": "Niezaufane",
"Up to Date": "Aktualny",
"Updated": "Zaktualizowano",
"Upgrade": "Aktualizacja",
@@ -354,8 +380,8 @@
"Versions Path": "Ścieżka wersji",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "Wersje zostają automatycznie usunięte jeżeli są starsze niż maksymalny wiek lub przekraczają liczbę dopuszczalnych wersji.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"Waiting to Scan": "Oczekiwanie na skanowanie",
"Waiting to Sync": "Oczekiwanie na synchronizację",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Uwaga, ta ścieżka jest nadrzędnym folderem istniejącego folderu \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Uwaga, ten folder jest nadfolderem istniejącego folderu \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Uwaga, ta ścieżka to podkatalog istniejącego folderu \"{{otherFolder}}\".",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Nie posiadasz zignorowanych katalogów.",
"You have unsaved changes. Do you really want to discard them?": "Masz niezapisane zmiany. Czy naprawdę chcesz je odrzucić?",
"You must keep at least one version.": "Musisz posiadać przynajmniej jedną wersję",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dni",
"directories": "directories",
"files": "pliki",
@@ -381,5 +408,6 @@
"items": "pozycji",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} chce udostępnić folder \"{{folder}}\"",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce udostępnić folder \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce udostępnić folder \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avançado",
"Advanced Configuration": "Configuração avançada",
"All Data": "Todos os dados",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anônimos de uso?",
"Allowed Networks": "Redes permitidas",
"Alphabetic": "Alfabética",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"Anonymous Usage Reporting": "Relatórios anônimos de uso",
"Anonymous usage report format has changed. Would you like to move to the new format?": "O formato do relatório anônimo de uso mudou. Gostaria de usar o formato novo?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Deseja mesmo remover o dispositivo {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Deseja mesmo remover a pasta {{name}}?",
"Are you sure you want to restore {%count%} files?": "Deseja mesmo restaurar {{count}} arquivo(s)?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Compartilhado com outros dispositivos",
"Danger!": "Perigo!",
"Debugging Facilities": "Facilidades de depuração",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Caminho padrão da pasta",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Apagado",
"Deselect All": "Deselect All",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Dispositivo",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Dispositivo \"{{name}}\" ({{device}} em {{address}}) quer se conectar. Adicionar novo dispositivo?",
"Device ID": "ID do dispositivo",
"Device Identification": "Identificação do dispositivo",
"Device Name": "Nome do dispositivo",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Dispositivo que modificou o item pela última vez",
"Devices": "Dispositivos",
@@ -92,7 +101,9 @@
"Downloading": "Recebendo",
"Edit": "Editar",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Editando {{path}}.",
"Enable Crash Reporting": "Habilitar relatório de falhas",
"Enable NAT traversal": "Habilitar NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Rótulo da pasta",
"Folder Path": "Caminho da pasta",
"Folder Type": "Tipo da pasta",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Pastas",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Full Rescan Interval (s)",
@@ -139,6 +151,7 @@
"Help": "Ajuda",
"Home page": "Página inicial",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignorar",
"Ignore Patterns": "Filtros",
@@ -187,6 +200,7 @@
"No File Versioning": "Desligado",
"No files will be deleted as a result of this operation.": "Nenhum arquivo será apagado como resultado desta operação",
"No upgrades": "Sem atualizações",
"Not shared": "Not shared",
"Notice": "Aviso",
"OK": "OK",
"Off": "Desligada",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Visualizar relatório de uso",
"Quick guide to supported patterns": "Guia rápido dos padrões suportados",
"Random": "Aleatória",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Receive Only",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Mudanças recentes",
"Reduced by ignore patterns": "Reduzido por filtros",
"Release Notes": "Notas de lançamento",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Versões candidatas ao lançamento possuem os recursos e correções mais recentes. Elas são similares às tradicionais versões quinzenais.",
"Remote Devices": "Dispositivos remotos",
"Remote GUI": "Remote GUI",
"Remove": "Remover",
"Remove Device": "Remover dispositivo",
"Remove Folder": "Remover pasta",
@@ -249,6 +266,7 @@
"Select All": "Selecionar tudo",
"Select a version": "Selecione uma versão",
"Select additional devices to share this folder with.": "Selecione outros dispositivos com os quais a pasta será compartilhada.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Escolher a última versão",
"Select oldest version": "Escolher a versão mais antiga",
"Select the folders to share with this device.": "Selecione as pastas a serem compartilhadas com este dispositivo.",
@@ -259,6 +277,7 @@
"Share Folder": "Compartilhar pasta",
"Share Folders With Device": "Compartilhar pastas com o dispositivo",
"Share this folder?": "Compartilhar esta pasta?",
"Shared Folders": "Shared Folders",
"Shared With": "Compartilhada com",
"Sharing": "Compartilhamento",
"Show ID": "Mostrar ID",
@@ -281,6 +300,7 @@
"Start Browser": "Iniciar navegador",
"Statistics": "Estatísticas",
"Stopped": "Parado",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Suporte",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Endereços de escuta do protocolo de sincronização",
@@ -310,6 +330,7 @@
"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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.",
"The following items could not be synchronized.": "Os itens a seguir não puderam ser sincronizados.",
"The following items were changed locally.": "The following items were changed locally.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "A idade máxima deve ser um valor numérico. O campo não pode ficar vazio.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade deve ser um número positivo (0: sem limite)",
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações deve ser um número positivo de segundos.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"They are retried automatically and will be synced when the error is resolved.": "Serão tentadas automaticamente e sincronizadas após o erro ter sido resolvido.",
"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.",
@@ -335,10 +357,14 @@
"Unavailable": "Não disponível",
"Unavailable/Disabled by administrator or maintainer": "Não disponível ou desabilitado pelo administrador ou mantenedor",
"Undecided (will prompt)": "Não tenho certeza (perguntar sempre)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Desconhecida",
"Unshared": "Não compartilhada",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Em sincronia",
"Updated": "Atualizado",
"Upgrade": "Atualização",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "You have no ignored folders.",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You must keep at least one version.": "Você deve manter pelo menos uma versão.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dias",
"directories": "directories",
"files": "arquivos",
@@ -381,5 +408,6 @@
"items": "itens",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer compartilhar a pasta \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quer compartilhar a pasta \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quer compartilhar a pasta \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Avançadas",
"Advanced Configuration": "Configuração avançada",
"All Data": "Todos os dados",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Todas as pastas partilhadas com este dispositivo têm de ser protegidas com uma senha, por forma a que todos os dados enviados sejam ilegíveis sem a senha dada.",
"Allow Anonymous Usage Reporting?": "Permitir envio de relatórios anónimos de utilização?",
"Allowed Networks": "Redes permitidas",
"Alphabetic": "Alfabética",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Um comando externo controla as versões. Esse comando tem que remover o ficheiro da pasta partilhada. Se o caminho para a aplicação contiver espaços, então terá de o escrever entre aspas.",
"Anonymous Usage Reporting": "Enviar relatórios anónimos de utilização",
"Anonymous usage report format has changed. Would you like to move to the new format?": "O formato do relatório anónimo de utilização foi alterado. Gostaria de mudar para o novo formato?",
"Are you sure you want to permanently delete all these files?": "Tem a certeza que quer eliminar permanentemente todos estes ficheiros?",
"Are you sure you want to remove device {%name%}?": "Tem a certeza que quer remover o dispositivo {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Tem a certeza que quer remover a pasta {{label}}?",
"Are you sure you want to restore {%count%} files?": "Tem a certeza que quer restaurar {{count}} ficheiros?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Dispositivos com os quais está partilhada",
"Danger!": "Perigo!",
"Debugging Facilities": "Recursos de depuração",
"Default Configuration": "Configuração predefinida",
"Default Device": "Dispositivo predefinido",
"Default Folder": "Pasta predefinida",
"Default Folder Path": "Caminho da pasta predefinida",
"Defaults": "Predefinições",
"Delete Unexpected Items": "Eliminar itens inesperados",
"Deleted": "Eliminado",
"Deselect All": "Retirar todas as selecções",
"Deselect devices to stop sharing this folder with.": "Retire a selecção para deixar de partilhar a pasta com esses dispositivos.",
"Deselect folders to stop sharing with this device.": "Retire a selecção das pastas para terminar a partilha com este dispositivo.",
"Device": "Dispositivo",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "O dispositivo \"{{name}}\" ({{device}} em {{address}}) quer conectar-se. Adiciono este novo dispositivo?",
"Device ID": "ID do dispositivo",
"Device Identification": "Identificação do dispositivo",
"Device Name": "Nome do dispositivo",
"Device is untrusted, enter encryption password": "Não existe uma relação de confiança com o dispositivo, insira senha de encriptação",
"Device rate limits": "Limites de velocidade do dispositivo",
"Device that last modified the item": "Último dispositivo a modificar o item",
"Devices": "Dispositivos",
@@ -92,7 +101,9 @@
"Downloading": "Recebendo",
"Edit": "Editar",
"Edit Device": "Editar dispositivo",
"Edit Device Defaults": "Editar as predefinições do dispositivo",
"Edit Folder": "Editar pasta",
"Edit Folder Defaults": "Editar as predefinições da pasta",
"Editing {%path%}.": "Editando {{path}}.",
"Enable Crash Reporting": "Activar Relatório de Estouro",
"Enable NAT traversal": "Activar travessia de NAT",
@@ -122,6 +133,7 @@
"Folder Label": "Etiqueta da pasta",
"Folder Path": "Caminho da pasta",
"Folder Type": "Tipo de pasta",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Pastas do tipo \"{{receiveEncrypted}}\" não podem ser modificadas depois de adicionar a pasta. Tem de remover a pasta, eliminar ou desencriptar os dados no disco e adicionar a pasta novamente.",
"Folders": "Pastas",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Nas pastas seguintes ocorreu um erro durante o arranque da vigilância de alterações. Será tentado novamente a cada minuto, por isso os erros poderão desaparecer brevemente. Se persistirem, tente resolver o erro subjacente e, caso não consiga, peça ajuda.",
"Full Rescan Interval (s)": "Intervalo entre verificações completas (s)",
@@ -139,6 +151,7 @@
"Help": "Ajuda",
"Home page": "Página do projecto",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Contudo, a sua configuração actual indica que pode não a querer activada. Nós desactivámos automaticamente o relatório de estouro para si.",
"If untrusted, enter encryption password": "Se não for fiável, insira uma senha de encriptação",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Se quiser evitar que outros utilizadores neste computador acedam ao Syncthing e, através dele, aos seus ficheiros, considere configurar a autenticação.",
"Ignore": "Ignorar",
"Ignore Patterns": "Padrões de exclusão",
@@ -187,6 +200,7 @@
"No File Versioning": "Nenhuma",
"No files will be deleted as a result of this operation.": "Nenhum ficheiro será eliminado como resultado desta operação.",
"No upgrades": "Sem actualizações",
"Not shared": "Não partilhada",
"Notice": "Avisos",
"OK": "OK",
"Off": "Desligada",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Pré-visualizar relatório de utilização",
"Quick guide to supported patterns": "Guia rápido dos padrões suportados",
"Random": "Aleatória",
"Receive Encrypted": "Receber encriptados",
"Receive Only": "Recebe apenas",
"Received data is already encrypted": "Os dados recebidos já estão encriptados",
"Recent Changes": "Alterações recentes",
"Reduced by ignore patterns": "Reduzido por padrões de exclusão",
"Release Notes": "Notas de lançamento",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Versões candidatas a lançamento contêm as funcionalidades e as correcções mais recentes. São semelhantes aos tradicionais lançamentos bi-semanais do Syncthing.",
"Remote Devices": "Dispositivos remotos",
"Remote GUI": "Interface gráfica remota",
"Remove": "Remover",
"Remove Device": "Remover dispositivo",
"Remove Folder": "Remover pasta",
@@ -249,6 +266,7 @@
"Select All": "Seleccionar tudo",
"Select a version": "Seleccione uma versão",
"Select additional devices to share this folder with.": "Seleccione outros dispositivos com os quais também pretende partilhar a pasta.",
"Select additional folders to share with this device.": "Seleccione pastas adicionais para partilhar com este dispositivo.",
"Select latest version": "Seleccionar a última versão",
"Select oldest version": "Seleccionar a versão mais antiga",
"Select the folders to share with this device.": "Seleccione as pastas a partilhar com este dispositivo.",
@@ -259,6 +277,7 @@
"Share Folder": "Partilhar pasta",
"Share Folders With Device": "Partilhar pastas com dispositivo",
"Share this folder?": "Partilhar esta pasta?",
"Shared Folders": "Pastas partilhadas",
"Shared With": "Partilhada com",
"Sharing": "Partilha",
"Show ID": "Mostrar ID",
@@ -281,6 +300,7 @@
"Start Browser": "Iniciar navegador",
"Statistics": "Estatísticas",
"Stopped": "Parado",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Armazena e sincroniza apenas dados encriptados. Pastas em todos os dispositivos conectados têm de ser configuradas com a mesma senha ou ser do tipo \"{{receiveEncrypted}}\" também.",
"Support": "Suporte",
"Support Bundle": "Pacote de suporte",
"Sync Protocol Listen Addresses": "Endereços de escuta do protocolo de sincronização",
@@ -310,6 +330,7 @@
"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.": "São utilizados os seguintes intervalos: na primeira hora é guardada uma versão a cada 30 segundos, no primeiro dia é guardada uma versão a cada hora, nos primeiros 30 dias é guardada uma versão por dia e, até que atinja a idade máxima, é guardada uma versão por semana.",
"The following items could not be synchronized.": "Não foi possível sincronizar os elementos seguintes.",
"The following items were changed locally.": "Os itens seguintes foram alterados localmente.",
"The following unexpected items were found.": "Foram encontrados os seguinte itens inesperados.",
"The interval must be a positive number of seconds.": "O intervalo tem que ser um número positivo de segundos.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "O intervalo, em segundos, para executar limpezas na pasta das versões. Coloque zero para desactivar a limpeza periódica.",
"The maximum age must be a number and cannot be blank.": "A idade máxima tem que ser um número e não pode estar vazia.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "O limite de velocidade tem que ser um número que não seja negativo (0: sem limite)",
"The rescan interval must be a non-negative number of seconds.": "O intervalo entre verificações tem que ser um valor não negativo de segundos.",
"There are no devices to share this folder with.": "Não existem quaisquer dispositivos com os quais se possa partilhar esta pasta.",
"There are no folders to share with this device.": "Não existem pastas para partilhar com este dispositivo.",
"They are retried automatically and will be synced when the error is resolved.": "Será tentado automaticamente e os itens serão sincronizados assim que o erro seja resolvido.",
"This Device": "Este dispositivo",
"This can easily give hackers access to read and change any files on your computer.": "Isso facilmente dará acesso aos piratas informáticos para lerem e modificarem quaisquer ficheiros no seu computador.",
@@ -335,10 +357,14 @@
"Unavailable": "Indisponível",
"Unavailable/Disabled by administrator or maintainer": "Indisponíveis ou desactivadas pelo administrador ou responsável de manutenção",
"Undecided (will prompt)": "Não definido (será inquirido na altura)",
"Unexpected Items": "Itens inesperados",
"Unexpected items have been found in this folder.": "Foram encontrados itens inesperados dentro desta pasta.",
"Unignore": "Deixar de ignorar",
"Unknown": "Desconhecido",
"Unshared": "Não partilhada",
"Unshared Devices": "Dispositivos sem partilhas",
"Unshared Folders": "Pastas não partilhadas",
"Untrusted": "Não fiável",
"Up to Date": "Em sincronia",
"Updated": "Actualizado",
"Upgrade": "Actualizar",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Não tem pastas ignoradas.",
"You have unsaved changes. Do you really want to discard them?": "Fez alterações que não foram guardadas. Quer mesmo descartá-las?",
"You must keep at least one version.": "Tem que manter pelo menos uma versão.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Nunca deve adicionar ou modificar algo localmente numa pasta \"{{receiveEncrypted}}\".",
"days": "dias",
"directories": "pastas",
"files": "ficheiros",
@@ -381,5 +408,6 @@
"items": "itens",
"seconds": "segundos",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} quer partilhar a pasta \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quer partilhar a pasta \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} quer partilhar a pasta \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} poderá reintroduzir este dispositivo"
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Дополнительно",
"Advanced Configuration": "Дополнительные настройки",
"All Data": "Все данные",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Разрешить анонимный отчет об использовании?",
"Allowed Networks": "Разрешённые сети",
"Alphabetic": "По алфавиту",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Для версионирования используется внешняя программа. Ей нужно удалить файл из общей папки. Если путь к приложению содержит пробелы, его нужно взять в кавычки.",
"Anonymous Usage Reporting": "Анонимный отчет об использовании",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Формат анонимных отчётов изменился. Вы хотите переключиться на новый формат?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Вы уверены, что хотите удалить устройство {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Вы уверены, что хотите удалить папку {{label}}?",
"Are you sure you want to restore {%count%} files?": "Вы уверены, что хотите восстановить {{count}} файлов?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "В настоящее время используется совместно с устройствами",
"Danger!": "Опасно!",
"Debugging Facilities": "Средства отладки",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Путь для папок",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Удалено",
"Deselect All": "Снять выделение",
"Deselect devices to stop sharing this folder with.": "Отмените выбор устройств, чтобы прекратить совместное использование этой папки.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Устройство",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Устройство «{{name}}» ({{device}} на {{address}}) хочет подключиться. Добавить новое устройство?",
"Device ID": "ID устройства",
"Device Identification": "Идентификация устройства",
"Device Name": "Имя устройства",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Ограничения скорости для устройства",
"Device that last modified the item": "Устройство, последним изменившее объект",
"Devices": "Устройства",
@@ -92,7 +101,9 @@
"Downloading": "Загрузка",
"Edit": "Редактировать",
"Edit Device": "Edit Device",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Edit Folder",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Правка {{path}}.",
"Enable Crash Reporting": "Включить отчёты о сбоях",
"Enable NAT traversal": "Включить NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Ярлык папки",
"Folder Path": "Путь к папке",
"Folder Type": "Тип папки",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Папки",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Для следующих папок произошла ошибка при запуске отслеживания изменений. Попытки будут повторяться раз в минуту, и ошибки скоро могут быть устранены. Если этого не произойдёт, попробуйте разобраться в причинах и попросите поддержки, если у вас не получится.",
"Full Rescan Interval (s)": "Интервал полного сканирования (в секундах)",
@@ -139,6 +151,7 @@
"Help": "Помощь",
"Home page": "Домашняя страница",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Однако, ваши текущие настройки указывают на то, что вы, возможно, не хотите, чтобы эта функция была включена. Мы отключили автоматическую отправку отчетов о сбоях для вас.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Если вы хотите запретить другим пользователям на этом компьютере доступ к Syncthing и через него к вашим файлам, подумайте о настройке аутентификации.",
"Ignore": "Игнорировать",
"Ignore Patterns": "Шаблоны игнорирования",
@@ -187,6 +200,7 @@
"No File Versioning": "Без управления версиями файлов",
"No files will be deleted as a result of this operation.": "В результате этой операции никакие файлы не будут удалены",
"No upgrades": "Нет обновлений",
"Not shared": "Not shared",
"Notice": "Внимание",
"OK": "ОК",
"Off": "Отключить",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Посмотреть отчёт об использовании",
"Quick guide to supported patterns": "Краткое руководство по поддерживаемым шаблонам",
"Random": "Случайно",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Только получить",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Последние изменения",
"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": "Удалённые устройства",
"Remote GUI": "Remote GUI",
"Remove": "Удалить",
"Remove Device": "Удалить устройство",
"Remove Folder": "Удалить папку",
@@ -249,6 +266,7 @@
"Select All": "Выбрать все",
"Select a version": "Выберите версию",
"Select additional devices to share this folder with.": "Выберите дополнительные устройства, для которых будет доступна эта папка.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Выбрать последнюю версию",
"Select oldest version": "Выбрать самую старую версию",
"Select the folders to share with this device.": "Выберите папки, которые будут доступны этому устройству.",
@@ -259,6 +277,7 @@
"Share Folder": "Предоставить доступ к папке",
"Share Folders With Device": "Предоставить доступ устройству к папкам",
"Share this folder?": "Предоставить доступ к этой папке?",
"Shared Folders": "Shared Folders",
"Shared With": "Доступ предоставлен",
"Sharing": "Предоставление доступа",
"Show ID": "Показать ID",
@@ -281,6 +300,7 @@
"Start Browser": "Запускать браузер",
"Statistics": "Статистика",
"Stopped": "Остановлено",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Поддержка",
"Support Bundle": "Данные для поддержки",
"Sync Protocol Listen Addresses": "Адрес протокола синхронизации",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "Следующие объекты были изменены локально",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Максимальный срок должен быть числом и не может быть пустым.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Скорость должна быть неотрицательным числом (0: нет ограничения)",
"The rescan interval must be a non-negative number of seconds.": "Интервал пересканирования должен быть неотрицательным количеством секунд.",
"There are no devices to share this folder with.": "Нет устройств, для которых будет доступна эта папка.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "Это может дать доступ хакерам для чтения и изменения любых файлов на вашем компьютере.",
@@ -335,10 +357,14 @@
"Unavailable": "Недоступно",
"Unavailable/Disabled by administrator or maintainer": "Недоступно или отключено администратором",
"Undecided (will prompt)": "Не определено (запрашивать каждый раз)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Не игнорировать",
"Unknown": "Неизвестно",
"Unshared": "Необщедоступно",
"Unshared Devices": "Устройства без общего доступа",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "В актуальном состоянии",
"Updated": "Обновлено",
"Upgrade": "Обновить",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "У вас нет игнорируемых папок.",
"You have unsaved changes. Do you really want to discard them?": "Есть несохранённые изменения. Вы действительно хотите отменить их?",
"You must keep at least one version.": "Вы должны хранить как минимум одну версию.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "дней",
"directories": "directories",
"files": "файлов",
@@ -381,5 +408,6 @@
"items": "элементы",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хочет поделиться папкой «{{folder}}».",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} хочет поделиться папкой «{{folderlabel}}» ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} хочет поделиться папкой «{{folderlabel}}» ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -12,24 +12,26 @@
"Add Remote Device": "Pridať vzdialené zariadenie",
"Add devices from the introducer to our device list, for mutually shared folders.": "Pre vzájomne zdieľané adresáre pridaj zariadenie od zavádzača do svojho zoznamu zariadení.",
"Add new folder?": "Pridať nový adresár?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Naviac interval plného skenovania bude navýšený (60krát, t.j. nová výchozia hodnota 1h). Môžete to nastaviť aj manuálne pre každý adresár ak zvolíte Nie.",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Navyše, interval plného skenovania bude navýšený (60krát, t.j. nová výchozia hodnota 1h). Môžete to nastaviť aj manuálne pre každý adresár ak zvolíte Nie.",
"Address": "Adresa",
"Addresses": "Adresy",
"Advanced": "Pokročilé",
"Advanced Configuration": "Pokročilá konfigurácia",
"All Data": "Všetky dáta",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"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. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"Anonymous Usage Reporting": "Anonymné hlásenie o používaní",
"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?",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Formát anonymného hlásenia o používaní sa zmenil. Chcete prejsť na nový formát?",
"Are you sure you want to permanently delete all these files?": "Určite chcete vymazať všetky tieto súbory?",
"Are you sure you want to remove device {%name%}?": "Určite chcete odobrať zariadenie {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Určite chcete odobrať adresár {{label}}?",
"Are you sure you want to restore {%count%} files?": "Určite chcete obnoviť {{count}} súborov?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Are you sure you want to upgrade?": "Určite chcete aktualizovať?",
"Auto Accept": "Automatické prijatie",
"Automatic Crash Reporting": "Automatic Crash Reporting",
"Automatic Crash Reporting": "Automatické hlásenie chýb",
"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",
"Automatic upgrades are always enabled for candidate releases.": "Automatic upgrades are always enabled for candidate releases.",
@@ -40,7 +42,7 @@
"Changelog": "Záznam zmien",
"Clean out after": "Vyčistenie po",
"Cleaning Versions": "Cleaning Versions",
"Cleanup Interval": "Cleanup Interval",
"Cleanup Interval": "Interval čistenia",
"Click to see discovery failures": "Kliknite pre zobrazenie zlyhaní zisťovania.",
"Close": "Zatvoriť",
"Command": "Príkaz",
@@ -51,7 +53,7 @@
"Connection Error": "Chyba pripojenia",
"Connection Type": "Typ pripojenia",
"Connections": "Spojenia",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Nepretržité sledovanie zmien je už dostupné. Tým sa skenovanie spustí iba pre zmenené súbory. Výhoda je, že týmto spôsobom sa rýchlejšie šíria zmeny a nie je potrebných toľko veľa úplných skenov.",
"Copied from elsewhere": "Skoprírované odinakiaľ",
"Copied from original": "Skopírované z originálu",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 nasledujúci prispievatelia:",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Currently Shared With Devices",
"Danger!": "Pozor!",
"Debugging Facilities": "Debugging Facilities",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Predvolená adresárová cesta",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Zmazané",
"Deselect All": "Odznačiť všetko",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Zariadenie",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Zariadenie \"{{name}}\" ({{device}} na {{address}}) sa chce pripojiť. Pridať nové zariadenie?",
"Device ID": "ID zariadenia",
"Device Identification": "Identifikácia zariadenia",
"Device Name": "Názov zariadenia",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Device rate limits",
"Device that last modified the item": "Zariadenie, ktoré naposledy pozmenilo položku",
"Devices": "Zariadenia",
@@ -91,10 +100,12 @@
"Downloaded": "Stiahnuté",
"Downloading": "Sťahovanie",
"Edit": "Upraviť",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "Upraviť zariadenie",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Upraviť priečinok",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Úprava {{path}}.",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable Crash Reporting": "Zapnúť hlásenie chýb",
"Enable NAT traversal": "Povoliť priechod NAT",
"Enable Relaying": "Povoliť prenosové uzly",
"Enabled": "Povolené",
@@ -102,11 +113,11 @@
"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.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "Zadaj ignorované vzory, jeden na riadok.",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Enter up to three octal digits.": "Zadajte max 3. číslice v osmičkovej sústave.",
"Error": "Chyba",
"External File Versioning": "Externé spracovanie verzií súborov",
"Failed Items": "Zlyhané položky",
"Failed to setup, retrying": "Failed to setup, retrying",
"Failed to setup, retrying": "Nepodarilo sa nastaviť, opakujem.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Zlyhanie pripojenia k IPv6 serverom je očakávané ak neexistujú žiadne IPv6 pripojenia.",
"File Pull Order": "Poradie sťahovania súborov",
"File Versioning": "Verzie súborov",
@@ -114,7 +125,7 @@
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Súbory premiestnené alebo zmazané aplikáciou Sycthing sú presunuté do verzií označených dátumov v adresári .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.": "Soubory sú chránené pred zmenami na ostatních zariadeniach, ale zmeny provedené z tohto zariadenia budú rozoslané na zvyšok klastra.",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.",
"Filesystem Watcher Errors": "Filesystem Watcher Errors",
"Filesystem Watcher Errors": "Chyby zo subsystému \"Filesystem watcher\"",
"Filter by date": "Filtrovanie podľa dátumu",
"Filter by name": "Filtrovanie podľa mena",
"Folder": "Adresár",
@@ -122,13 +133,14 @@
"Folder Label": "Označenie adresára",
"Folder Path": "Cesta k adresáru",
"Folder Type": "Typ adresára",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Adresáre",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "Full Rescan Interval (s)",
"Full Rescan Interval (s)": "Interval úplného skenu (s)",
"GUI": "GUI",
"GUI Authentication Password": "Prihlasovacie heslo do GUI",
"GUI Authentication User": "Prihlasovacie meno do GUI",
"GUI Authentication: Set User and Password": "GUI Authentication: Set User and Password",
"GUI Authentication: Set User and Password": "Autentifikácia do webového rozhrania: Nastavenie mena a hesla",
"GUI Listen Address": "Adresa pre prístup do GUI",
"GUI Theme": "Grafická téma GUI",
"General": "Všeobecné",
@@ -139,13 +151,14 @@
"Help": "Pomoc",
"Home page": "Domovská stránka",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If untrusted, enter encryption password": "Ak nie je dôveryhodný, uveďte heslo na dešifrovanie",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"Ignore": "Ignorovať",
"Ignore Patterns": "Ignorované vzory",
"Ignore Permissions": "Ignorované práva",
"Ignored Devices": "Ignorované zariadenia",
"Ignored Folders": "Ingorované priečinky",
"Ignored at": "Ignored at",
"Ignored at": "Ignorované na",
"Incoming Rate Limit (KiB/s)": "Limit pre sťahovanie (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Nesprávna konfigurácia môže poškodiť váš adresár a spôsobiť nefunkčnosť aplikácie Súbory.",
"Introduced By": "Uvedené",
@@ -187,6 +200,7 @@
"No File Versioning": "Bez verzií súbor",
"No files will be deleted as a result of this operation.": "Ako výsledok tejto operáciu nebudú zmazané žiadne súbory.",
"No upgrades": "Bez aktualizácií",
"Not shared": "Not shared",
"Notice": "Oznámenie",
"OK": "OK",
"Off": "Vypnúť",
@@ -215,17 +229,20 @@
"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.",
"Preparing to Sync": "Preparing to Sync",
"Preparing to Sync": "Príprava na Sync",
"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",
"Random": "Náhodne",
"Receive Encrypted": "Prijať šifrované",
"Receive Only": "Iba prijímanie",
"Received data is already encrypted": "Prijaté údaje sú už šifrované",
"Recent Changes": "Nedávne zmeny",
"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.": "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",
"Remote GUI": "Remote GUI",
"Remove": "Odstrániť",
"Remove Device": "Odstrániť zariadenie",
"Remove Folder": "Odstrániť adresár",
@@ -249,6 +266,7 @@
"Select All": "Vybrať všetko",
"Select a version": "Zvoliť verziu",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Zvoliť najnovšiu verziu",
"Select oldest version": "Zvoliť najstaršiu verziu",
"Select the folders to share with this device.": "Vyberte adresáre ktoré chcete zdieľať s týmto zariadením.",
@@ -259,6 +277,7 @@
"Share Folder": "Zdieľať adresár",
"Share Folders With Device": "Zdieľať adresáre so zariadením",
"Share this folder?": "Zdieľať tento adresár?",
"Shared Folders": "Zdieľané priečinky",
"Shared With": "Zdieľané s",
"Sharing": "Zdieľať",
"Show ID": "Zobraziť ID",
@@ -281,6 +300,7 @@
"Start Browser": "Spusti prehliadač",
"Statistics": "Štatistika",
"Stopped": "Zastavené",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Podpora",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Adresa načúvania synchronizačného protokolu",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "Tieto položky boli zmenené lokálne",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The maximum age must be a number and cannot be blank.": "Maximálny vek musí byť číslo a nemôže byť prázdne.",
@@ -322,6 +343,7 @@
"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.",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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": "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.",
@@ -335,10 +357,14 @@
"Unavailable": "Nedostupné",
"Unavailable/Disabled by administrator or maintainer": "Nedostupné/Zakázané administrátorom alebo správcom",
"Undecided (will prompt)": "Undecided (will prompt)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Unignore",
"Unknown": "Neznáme",
"Unshared": "Nezdieľané",
"Unshared Devices": "Unshared Devices",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Aktuálne",
"Updated": "Aktualizované",
"Upgrade": "Aktualizácia",
@@ -353,9 +379,9 @@
"Versions": "Verzie",
"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.",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"Waiting to Clean": "Čakám na čistenie",
"Waiting to Scan": "Čakám na sken",
"Waiting to Sync": "Čakám na Sync",
"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}}\".",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "Nemáte žiadne ignorované priečinky.",
"You have unsaved changes. Do you really want to discard them?": "Niektoré zmeny ste neuložili. Chcete ich skutočne zahodiť?",
"You must keep at least one version.": "Musíte ponechať aspoň jednu verziu",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "dní",
"directories": "directories",
"directories": "priečinky",
"files": "súbory",
"full documentation": "úplná dokumntácia",
"items": "položiek",
"seconds": "seconds",
"seconds": "send",
"{%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}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} chce zdieľať adresár \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -10,20 +10,22 @@
"Add Device": "Lägg till enhet",
"Add Folder": "Lägg till mapp",
"Add Remote Device": "Lägg till fjärrenhet",
"Add devices from the introducer to our device list, for mutually shared folders.": "Lägg enheter från introduktören till vår enhetslista för ömsesidigt delade mappar.",
"Add devices from the introducer to our device list, for mutually shared folders.": "Lägg till enheter från introduktören till vår enhetslista för ömsesidigt delade mappar.",
"Add new folder?": "Lägg till ny mapp?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Dessutom kommer det fullständiga återkommande skanningsintervallet att höjas (60 gånger, d.v.s. ny standard på 1h). Du kan också konfigurera det manuellt för varje mapp senare efter att du valt Nej.",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Dessutom kommer det fullständiga återkommande skanningsintervallet att höjas (60 gånger, d.v.s. ny standard på 1h). Du kan också konfigurera den manuellt för varje mapp senare efter att du har valt Nej.",
"Address": "Adress",
"Addresses": "Adresser",
"Advanced": "Avancerat",
"Advanced Configuration": "Avancerad konfiguration",
"All Data": "Alla data",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Alla mappar som delas med denna enhet måste skyddas av ett lösenord, så att alla data som skickas är oläsliga utan det angivna lösenordet.",
"Allow Anonymous Usage Reporting?": "Tillåt anonym användarstatistiksrapportering?",
"Allowed Networks": "Tillåtna nätverk",
"Alphabetic": "Alfabetisk",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Ett externt kommando hanterar versionen. Det måste ta bort filen från den delade mappen. Om sökvägen till applikationen innehåller mellanslag bör den citeras.",
"Anonymous Usage Reporting": "Anonym användarstatistiksrapportering",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Anonymt användningsrapportformat har ändrats. Vill du flytta till det nya formatet?",
"Are you sure you want to permanently delete all these files?": "Är du säker på att du vill ta bort alla dessa filer permanent?",
"Are you sure you want to remove device {%name%}?": "Är du säker på att du vill ta bort enheten {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Är du säker på att du vill ta bort mappen {{label}}?",
"Are you sure you want to restore {%count%} files?": "Är du säker på att du vill återställa {{count}} filer?",
@@ -33,7 +35,7 @@
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Automatisk uppgradering erbjuder nu valet mellan stabila utgåvor och utgåvskandidater.",
"Automatic upgrades": "Automatiska uppgraderingar",
"Automatic upgrades are always enabled for candidate releases.": "Automatiska uppgraderingar är alltid aktiverade för kandidatutgåvor.",
"Automatically create or share folders that this device advertises at the default path.": "Skapa eller dela automatiskt mappar som den här enheten annonserar på standardsökvägen.",
"Automatically create or share folders that this device advertises at the default path.": "Skapa eller dela automatiskt mappar som denna enhet annonserar på standardsökvägen.",
"Available debug logging facilities:": "Tillgängliga felsökningsfunktioner:",
"Be careful!": "Var aktsam!",
"Bugs": "Felrapporter",
@@ -51,38 +53,45 @@
"Connection Error": "Anslutningsproblem",
"Connection Type": "Anslutningstyp",
"Connections": "Anslutningar",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Kontinuerligt bevakning av ändringar är nu tillgängligt inom Syncthing. Detta kommer att upptäcka ändringar på disken och utfärda en skanning på endast de ändrade sökvägarna. Fördelarna är att förändringar sprids snabbare och att mindre fullständiga skanningar krävs.",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Kontinuerlig bevakning av ändringar är nu tillgängligt i Syncthing. Detta kommer att upptäcka ändringar på disken och utfärda en skanning på endast de ändrade sökvägarna. Fördelarna är att ändringar delas snabbare och att mindre fullständiga skanningar krävs.",
"Copied from elsewhere": "Kopierat från annanstans",
"Copied from original": "Kopierat från original",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 följande bidragsgivare:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "Skapa ignorera mönster, skriver över en existerande fil på {{path}}.",
"Currently Shared With Devices": "För närvarande delas med enheter",
"Danger!": "Fara!",
"Debugging Facilities": "Felsökningsanläggningar",
"Default Folder Path": "Standard mappsökväg",
"Debugging Facilities": "Felsökningsfunktioner",
"Default Configuration": "Standardkonfiguration",
"Default Device": "Standardenhet",
"Default Folder": "Standardmapp",
"Default Folder Path": "Standardmappsökväg",
"Defaults": "Standard",
"Delete Unexpected Items": "Ta bort oväntade objekt",
"Deleted": "Borttagna",
"Deselect All": "Avmarkera alla",
"Deselect devices to stop sharing this folder with.": "Avmarkera enheter för att sluta dela den här mappen med.",
"Deselect devices to stop sharing this folder with.": "Avmarkera enheter för att sluta dela denna mapp med.",
"Deselect folders to stop sharing with this device.": "Avmarkera mappar för att sluta dela med denna enhet.",
"Device": "Enhet",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Enhet \"{{name}}\" ({{device}} på {{address}}) vill ansluta. Lägg till ny enhet?",
"Device ID": "Enhets-ID",
"Device Identification": "Enhetens identifikation",
"Device Name": "Enhetsnamn",
"Device is untrusted, enter encryption password": "Enheten är otillförlitlig, ange krypteringslösenord",
"Device rate limits": "Enhetshastighetsgränser",
"Device that last modified the item": "Enhet som senast ändrade objektet",
"Devices": "Enheter",
"Disable Crash Reporting": "Inaktivera kraschrapportering",
"Disabled": "Inaktiverad",
"Disabled periodic scanning and disabled watching for changes": "Inaktiverad periodisk skanning och inaktiverad övervakning av ändringar",
"Disabled periodic scanning and enabled watching for changes": "Inaktiverad periodisk skanning och aktiverad övervakning av ändringar",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Inaktiverad periodisk skanning och misslyckades att ställa in övervakning av ändringar, försöker igen varje 1m:",
"Disabled periodic scanning and disabled watching for changes": "Inaktiverad periodisk skanning och inaktiverad bevakning av ändringar",
"Disabled periodic scanning and enabled watching for changes": "Inaktiverad periodisk skanning och aktiverad bevakning av ändringar",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "Inaktiverad periodisk skanning och misslyckades med att ställa in bevakning av ändringar, försöker igen var 1:e minut:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Inaktiverar att jämföra och synkronisera filbehörigheter. Användbart för system med obefintliga eller anpassade behörigheter (t.ex. FAT, exFAT, Synology, Android).",
"Discard": "Kasta",
"Disconnected": "Frånkopplad",
"Disconnected (Unused)": "Frånkopplad (oanvänd)",
"Discovered": "Upptäckt",
"Discovery": "Annonsering",
"Discovery Failures": "Upptäcktsmisslyckanden",
"Discovery Failures": "Annonseringsmisslyckanden",
"Do not restore": "Återställ inte",
"Do not restore all": "Återställ inte allt",
"Do you want to enable watching for changes for all your folders?": "Vill du aktivera bevakning av ändringar på alla dina mappar?",
@@ -92,10 +101,12 @@
"Downloading": "Hämtar",
"Edit": "Redigera",
"Edit Device": "Redigera enhet",
"Edit Device Defaults": "Redigera enhetsstandard",
"Edit Folder": "Redigera mapp",
"Edit Folder Defaults": "Redigera mappstandard",
"Editing {%path%}.": "Redigerar {{path}}.",
"Enable Crash Reporting": "Aktivera kraschrapportering",
"Enable NAT traversal": "Aktivera NAT traversering",
"Enable NAT traversal": "Aktivera NAT-genompassering",
"Enable Relaying": "Aktivera vidarebefordring",
"Enabled": "Aktiverad",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Ange ett icke-negativt antal (t.ex., \"2.35\") och välj en enhet. Procenttalen är som en del av den totala diskstorleken.",
@@ -107,12 +118,12 @@
"External File Versioning": "Extern filversionshantering",
"Failed Items": "Misslyckade objekt",
"Failed to setup, retrying": "Det gick inte att ställa in, försöker igen",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Misslyckande med att ansluta till IPv6-servrar förväntas om ingen IPv6-anslutning finns.",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "Det går inte att ansluta till IPv6-servrar om det inte finns någon IPv6-anslutning.",
"File Pull Order": "Filhämtningsprioritering",
"File Versioning": "Filversionshantering",
"Files are moved to .stversions directory when replaced or deleted by Syncthing.": "Filer flyttas till .stversions-mappen vid byte eller tas bort av Syncthing.",
"Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.": "Filer flyttas till datumstämplade versioner i en .stversions-mapp när de ersätts eller tas bort av 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.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på den här noden skickas till de andra klustermedlemmarna.",
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Filer skyddas från ändringar gjorda på andra enheter, men ändringar som görs på denna nod skickas till de andra klustermedlemmarna.",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "Filer synkroniseras från klustret, men alla ändringar som görs lokalt skickas inte till andra enheter.",
"Filesystem Watcher Errors": "Filsystem bevakarfel",
"Filter by date": "Filtrera efter datum",
@@ -122,15 +133,16 @@
"Folder Label": "Mappetikett",
"Folder Path": "Mappsökväg",
"Folder Type": "Mapptyp",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Mapptypen \"{{receiveEncrypted}}\" kan inte ändras efter att mappen har lagts till. Du måste ta bort mappen, ta bort eller dekryptera data på disken och lägga till mappen igen.",
"Folders": "Mappar",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "För följande mappar uppstod ett fel när du började bevaka ändringar. Det kommer att omförsökas varje minut, så felen kan försvinna snart. Om de fortsätter, försök att åtgärda det underliggande problemet och fråga om hjälp om du inte kan.",
"Full Rescan Interval (s)": "Fullständig återkommande skanningsintervall (s)",
"GUI": "Grafiskt gränssnitt",
"GUI Authentication Password": "Autentiseringslösenord för gränssnittet",
"GUI Authentication User": "Autentiseringsanvändare för gränssnittet",
"GUI Authentication: Set User and Password": "Autentisering för gränssnittets: Ställ in användare och lösenord",
"GUI Listen Address": "Lyssnaradress för gränssnittet",
"GUI Theme": "Tema för gränssnittet",
"Full Rescan Interval (s)": "Fullständigt återkommande skanningsintervall (s)",
"GUI": "Grafiskt användargränssnitt",
"GUI Authentication Password": "Autentiseringslösenord för gränssnitt",
"GUI Authentication User": "Autentiseringsanvändare för gränssnitt",
"GUI Authentication: Set User and Password": "Autentisering för det grafiska gränssnittet: Ställ in användare och lösenord",
"GUI Listen Address": "Lyssnaradress för gränssnitt",
"GUI Theme": "Tema för gränssnitt",
"General": "Allmänt",
"Generate": "Generera",
"Global Discovery": "Global annonsering",
@@ -139,7 +151,8 @@
"Help": "Hjälp",
"Home page": "Webbplats",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Dina aktuella inställningar visar dock att du kanske inte vill att den ska aktiveras. Vi har inaktiverat automatisk krasch rapportering för dig.",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Om du vill förhindra att andra användare på den här datorn får åtkomst till Syncthing och genom det dina filer, överväg att ställa in autentisering.",
"If untrusted, enter encryption password": "Om opålitlig, ange krypteringslösenord",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Om du vill förhindra att andra användare på denna dator får åtkomst till Syncthing och genom det dina filer, överväg att ställa in autentisering.",
"Ignore": "Ignorera",
"Ignore Patterns": "Ignorera mönster",
"Ignore Permissions": "Ignorera rättigheter",
@@ -182,15 +195,16 @@
"Never": "Aldrig",
"New Device": "Ny enhet",
"New Folder": "Ny mapp",
"Newest First": "Nyast först",
"Newest First": "Nyaste först",
"No": "Nej",
"No File Versioning": "Ingen filversionshantering",
"No files will be deleted as a result of this operation.": "Inga filer kommer att tas bort till följd av denna operation.",
"No upgrades": "Inga uppgraderingar",
"Not shared": "Inte delad",
"Notice": "Observera",
"OK": "OK",
"Off": "Av",
"Oldest First": "Äldst först",
"Oldest First": "Äldsta först",
"Optional descriptive label for the folder. Can be different on each device.": "Valfri beskrivande etikett för mappen. Kan vara olika på varje enhet.",
"Options": "Alternativ",
"Out of Sync": "Osynkroniserad",
@@ -199,33 +213,36 @@
"Override Changes": "Åsidosätt förändringar",
"Path": "Sökväg",
"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": "Sökväg till mappen på din dator. Kommer att skapas om det inte finns. Tecknet tilde (~) kan användas som en genväg för",
"Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "Sökvägen där nya automatiskt accepterade mappar kommer att skapas, liksom den föreslagna sökvägen när du lägger till nya mappar via gränssnittet. Tecknet tilde (~) expanderar till {{tilde}}.",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Sökväg där versioner ska lagras (lämna tomt för standard .stversions-mappen i den delade mappen).",
"Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "Sökväg där nya automatiskt accepterade mappar kommer att skapas, liksom föreslagen standardsökväg vid tilläggning av nya mappar via användargränssnittet. Tilde-tecknet (~) expanderar till {{tilde}}.",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "Sökväg där versioner ska lagras (lämna tomt för standardmappen .stversions i den delade mappen).",
"Pause": "Pausa",
"Pause All": "Pausa alla",
"Paused": "Pausad",
"Paused (Unused)": "Pausad (oanvänd)",
"Pending changes": "Väntar på ändringar",
"Periodic scanning at given interval and disabled watching for changes": "Periodisk skanning i givet intervall och inaktiverad övervakning av ändringar",
"Periodic scanning at given interval and enabled watching for changes": "Periodisk skanning i givet intervall och aktiverad övervakning av ändringar",
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "Periodisk skanning vid givna intervall och misslyckades med att ställa in bevakning av ändringar, försöker igen varje 1m:",
"Periodic scanning at given interval and disabled watching for changes": "Periodisk skanning vid givet intervall och inaktiverad bevakning av ändringar",
"Periodic scanning at given interval and enabled watching for changes": "Periodisk skanning vid givet intervall och aktiverad bevakning av ändringar",
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "Periodisk skanning vid givet intervall och misslyckades med att ställa in bevakning av ändringar, försöker igen var 1:e minut:",
"Permissions": "Behörigheter",
"Please consult the release notes before performing a major upgrade.": "Vänligen läs igenom versionsnyheterna innan du utför en större uppgradering.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Vänligen ange en användare och lösenord för autentisering för gränssnittet i inställningsdialogrutan.",
"Please set a GUI Authentication User and Password in the Settings dialog.": "Vänligen ställ in en autentiseringsanvändare och ett lösenord för det grafiska användargränssnittet i dialogrutan Inställningar.",
"Please wait": "Vänligen vänta",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix som indikerar att filen kan tas bort om det förhindrar mappborttagning",
"Prefix indicating that the file can be deleted if preventing directory removal": "Prefix som indikerar att filen kan tas bort om den förhindrar mappborttagning",
"Prefix indicating that the pattern should be matched without case sensitivity": "Prefix som indikerar att mönstret ska matchas utan skiftlägeskänslighet",
"Preparing to Sync": "Förberedelser för synkronisering",
"Preview": "Förhandsgranska",
"Preview Usage Report": "Förhandsgranska användningsrapport",
"Quick guide to supported patterns": "Snabb handledning till mönster som stöds",
"Random": "Slumpmässig",
"Receive Only": "Ta emot endast",
"Receive Encrypted": "Ta emot krypterade",
"Receive Only": "Ta endast emot",
"Received data is already encrypted": "Mottagna data är redan krypterade",
"Recent Changes": "Senaste ändringar",
"Reduced by ignore patterns": "Minskas med ignorera mönster",
"Release Notes": "Versionsanteckningar",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Utgåvskandidater innehåller de senaste funktionerna och korrigeringarna. De är lika de traditionella Syncthing-utgåvorna som kommer ut varannan vecka.",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Utgåvskandidater innehåller de senaste funktionerna och korrigeringarna. De liknar de traditionella Syncthing-utgåvorna som kommer ut varannan vecka.",
"Remote Devices": "Fjärrenheter",
"Remote GUI": "Fjärranslutet grafiskt användargränssnitt",
"Remove": "Ta bort",
"Remove Device": "Ta bort enhet",
"Remove Folder": "Ta bort mapp",
@@ -248,10 +265,11 @@
"See external versioning help for supported templated command line parameters.": "Se hjälp för extern version för stödda mallade kommandoradsparametrar.",
"Select All": "Markera alla",
"Select a version": "Välj en version",
"Select additional devices to share this folder with.": "Välj ytterligare enheter för att dela den här mappen med.",
"Select additional devices to share this folder with.": "Välj ytterligare enheter för att dela denna mapp med.",
"Select additional folders to share with this device.": "Välj ytterligare mappar att dela med denna enhet.",
"Select latest version": "Välj senaste versionen",
"Select oldest version": "Välj äldsta versionen",
"Select the folders to share with this device.": "Välj mapparna som ska delas med den här enheten.",
"Select the folders to share with this device.": "Välj mapparna som ska delas med denna enhet.",
"Send & Receive": "Skicka & ta emot",
"Send Only": "Skicka endast",
"Settings": "Inställningar",
@@ -259,50 +277,52 @@
"Share Folder": "Dela mapp",
"Share Folders With Device": "Dela mappar med enhet",
"Share this folder?": "Dela denna mapp?",
"Shared With": "Delad med",
"Shared Folders": "Delade mappar",
"Shared With": "Delas med",
"Sharing": "Delning",
"Show ID": "Visa ID",
"Show QR": "Visa QR",
"Show diff with previous version": "Visa skillnad med tidigare version",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Visas istället för enhets-ID i klusterstatusen. Skickas till andra enheter som ett alternativt förvalt namn.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Visas i stället för enhets-ID i klusterstatusen. Kommer att uppdateras till namnet enheten annonserar om det lämnas tomt.",
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Visas istället för enhets-ID i klusterstatus. Kommer att annonseras på andra enheter som ett valfritt standardnamn.",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Visas istället för enhets-ID i klusterstatus. Uppdateras till namnet som enheten annonserar om den lämnas tom.",
"Shutdown": "Stäng av",
"Shutdown Complete": "Avstängning klar",
"Simple File Versioning": "Enkel filversionshantering",
"Single level wildcard (matches within a directory only)": "Jokertecken som representerar noll eller fler godtyckliga tecken i ett filnamn.",
"Size": "Storlek",
"Smallest First": "Minst först",
"Smallest First": "Minsta först",
"Some items could not be restored:": "Vissa objekt kunde inte återställas:",
"Source Code": "Källkod",
"Stable releases and release candidates": "Stabila utgåvor och utgåvskandidater",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabila utgåvor är försenade med cirka två veckor. Under denna tid går de igenom tester som utgåvskandidater.",
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stabila utgåvor är försenade med cirka två veckor. Under denna tid går de igenom testning som utgåvskandidater.",
"Stable releases only": "Endast stabila utgåvor",
"Staggered File Versioning": "Filversionshantering i intervall",
"Start Browser": "Starta webbläsaren",
"Statistics": "Statistik",
"Stopped": "Stoppad",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Lagrar och synkroniserar endast krypterade data. Mappar på alla anslutna enheter måste ställas in med samma lösenord eller vara av typen \"{{receiveEncrypted}}\".",
"Support": "Support",
"Support Bundle": "Support Bundle",
"Sync Protocol Listen Addresses": "Lyssnaradresser för synkroniseringsprotokollets",
"Sync Protocol Listen Addresses": "Lyssnaradresser för synkroniseringsprotokoll",
"Syncing": "Synkroniserar",
"Syncthing has been shut down.": "Syncthing har stängts.",
"Syncthing includes the following software or portions thereof:": "Syncthing innehåller följande mjukvarupaket eller delar av dem:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing har fri och öppen källkod licensierad som MPL v2.0.",
"Syncthing is restarting.": "Syncthing startar om.",
"Syncthing is upgrading.": "Syncthing uppgraderas.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing stöder nu automatiskt kraschrapportering till utvecklarna. Den här funktionen är aktiverad som standard.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing stöder nu automatiskt kraschrapportering till utvecklarna. Denna funktion är aktiverad som standard.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "Syncthing verkar vara avstängd eller så är det problem med din internetanslutning. Försöker igen...",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "Syncthing verkar ha drabbats av ett problem med behandlingen av din förfrågan. Vänligen uppdatera sidan eller starta om Syncthing om problemet kvarstår.",
"Take me back": "Ta mig tillbaka",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "Adressen för det grafiska gränssnittets åsidosätts av startalternativ. Ändringar här träder inte i kraft så länge åsidosättandet är på plats.",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "Den grafiska gränssnittsadressen åsidosätts av startalternativ. Ändringar här träder inte i kraft så länge åsidosättningen är på plats.",
"The Syncthing Authors": "Syncthing-upphovsmän",
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing administratör gränssnittet är konfigurerat för att tillåta fjärrtillträde utan ett lösenord.",
"The Syncthing admin interface is configured to allow remote access without a password.": "Administratörsgränssnittet för Syncthing är konfigurerat för att möjliggöra fjärråtkomst utan lösenord.",
"The aggregated statistics are publicly available at the URL below.": "Den aggregerade statistiken är offentligt tillgänglig på webbadressen nedan.",
"The cleanup interval cannot be blank.": "Rensningsintervallet kan inte vara tomt.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "Konfigurationen har sparats men inte aktiverats. Syncthing måste startas om för att aktivera den nya konfigurationen.",
"The device ID cannot be blank.": "Enhets-ID kan inte vara tomt.",
"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).": "Enhets-ID som behövs här kan du hitta i \"Åtgärder > Visa ID\"-dialogrutan på den andra enheten. Mellanrum och bindestreck är valfria (ignoreras).",
"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.": "Den krypterade användningsrapporten skickas dagligen. Det används för att spåra vanliga plattformar, mappstorlekar och appversioner. Om den rapporterade datauppsättningen ändras kommer du att uppmanas med den här dialogrutan igen.",
"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).": "Enhets-ID som du anger här finns i dialogrutan \"Åtgärder > Visa ID\" på den andra enheten. Mellanslag och bindestreck är valfria (ignoreras).",
"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.": "Den krypterade användningsrapporten skickas dagligen. Det används för att spåra vanliga plattformar, mappstorlekar och appversioner. Om den rapporterade datauppsättningen ändras kommer du att uppmanas med denna dialogruta igen.",
"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.": "Det inmatade enhets-ID:t verkar inte vara korrekt. Det ska vara en 52 eller 56 teckensträng bestående av siffror och bokstäver, eventuellt med mellanrum och bindestreck.",
"The folder ID cannot be blank.": "Mapp-ID får inte vara tomt.",
"The folder ID must be unique.": "Mapp-ID måste vara unik.",
@@ -310,6 +330,7 @@
"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.": "De följande intervallen används: varje 30 sekunder under den första timmen; varje timme under den första dagen; varje dag för de första 30 dagarna; varje vecka tills den maximala åldersgränsen uppnås.",
"The following items could not be synchronized.": "Följande objekt kunde inte synkroniseras.",
"The following items were changed locally.": "Följande objekt ändrades lokalt.",
"The following unexpected items were found.": "Följande oväntade objekt hittades.",
"The interval must be a positive number of seconds.": "Intervallet måste vara ett positivt antal sekunder.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Intervallet, i sekunder, för att rensa i versionskatalogen. Noll för att inaktivera periodisk rensning.",
"The maximum age must be a number and cannot be blank.": "Åldersgränsen måste vara ett tal och kan inte lämnas tomt.",
@@ -321,24 +342,29 @@
"The path cannot be blank.": "Sökvägen kan inte vara tom.",
"The rate limit must be a non-negative number (0: no limit)": "Frekvensgränsen måste vara ett icke-negativt tal (0: ingen gräns)",
"The rescan interval must be a non-negative number of seconds.": "Förnyelseintervallet måste vara ett positivt antal sekunder",
"There are no devices to share this folder with.": "Det finns inga enheter att dela den här mappen med.",
"There are no devices to share this folder with.": "Det finns inga enheter att dela denna mapp med.",
"There are no folders to share with this device.": "Det finns inga mappar att dela med denna enhet.",
"They are retried automatically and will be synced when the error is resolved.": "De omprövas automatiskt och kommer att synkroniseras när felet är löst.",
"This Device": "Denna enhet",
"This can easily give hackers access to read and change any files on your computer.": "Detta kan lätt ge hackare tillgång till att läsa och ändra några filer på datorn.",
"This is a major version upgrade.": "Det här är en stor uppgradering.",
"This setting controls the free space required on the home (i.e., index database) disk.": "Denna inställning kontrollerar ledigt utrymme som krävs på home-disken (d.v.s. index-databasen).",
"This setting controls the free space required on the home (i.e., index database) disk.": "Denna inställning styr hur mycket ledigt utrymme som krävs på hemdisken (dvs. indexdatabasen).",
"Time": "Tid",
"Time the item was last modified": "Tidpunkten objektet var senast ändrad",
"Trash Can File Versioning": "Papperskorgs filversionshantering",
"Type": "Typ",
"UNIX Permissions": "UNIX-behörigheter",
"Unavailable": "Inte tillgänglig",
"Unavailable/Disabled by administrator or maintainer": "Inte tillgänglig/inaktiverad av administratör eller underhållare",
"Unavailable": "Otillgänglig",
"Unavailable/Disabled by administrator or maintainer": "Otillgänglig/inaktiverad av administratör eller underhållare",
"Undecided (will prompt)": "Obeslutad (kommer att skriva)",
"Unexpected Items": "Oväntade objekt",
"Unexpected items have been found in this folder.": "Oväntade objekt har hittats i denna mapp.",
"Unignore": "Sluta ignorera",
"Unknown": "Okänd",
"Unshared": "Inte delad",
"Unshared Devices": "Odelade enheter",
"Unshared Folders": "Odelade mappar",
"Untrusted": "Opålitlig",
"Up to Date": "Uppdaterad",
"Updated": "Uppdaterade",
"Upgrade": "Uppgradering",
@@ -347,8 +373,8 @@
"Upload Rate": "Sändningshastighet",
"Uptime": "Drifttid",
"Usage reporting is always enabled for candidate releases.": "Användningsrapportering är alltid aktiverad för kandidatutgåvor.",
"Use HTTPS for GUI": "Använd HTTPS för gränssnittet",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Användarnamn/lösenord har inte ställts in för autentisering för gränssnittet. Överväg att ställa in det.",
"Use HTTPS for GUI": "Använd HTTPS för gränssnitt",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Användarnamn/lösenord har inte ställts in för autentisering av det grafiska gränssnittet. Vänligen överväg att ställa in det.",
"Version": "Version",
"Versions": "Versioner",
"Versions Path": "Sökväg för versioner",
@@ -356,15 +382,15 @@
"Waiting to Clean": "Väntar på att rensa",
"Waiting to Scan": "Väntar på att skanna",
"Waiting to Sync": "Väntar på att synkronisera",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Varning, denna sökväg är en överordnad mapp av en befintlig mapp \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Varning, denna sökväg är en överordnad mapp av en befintlig mapp \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Varning, denna sökväg är en undermapp till en befintlig mapp \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Varning, denna sökväg är en undermapp av en befintlig mapp \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a parent directory of an existing folder \"{%otherFolder%}\".": "Varning, denna sökväg är en överordnad mapp för en befintlig mapp \"{{otherFolder}}\".",
"Warning, this path is a parent directory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Varning, denna sökväg är en överordnad mapp för en befintlig mapp \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolder%}\".": "Varning, denna sökväg är en undermapp för en befintlig mapp \"{{otherFolder}}\".",
"Warning, this path is a subdirectory of an existing folder \"{%otherFolderLabel%}\" ({%otherFolder%}).": "Varning, denna sökväg är en undermapp för en befintlig mapp \"{{otherFolderLabel}}\" ({{otherFolder}}).",
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "Varning: Om du använder en extern bevakare som {{syncthingInotify}}, bör du se till att den är inaktiverad.",
"Watch for Changes": "Bevaka ändringar",
"Watch for Changes": "Bevakning av ändringar",
"Watching for Changes": "Bevakar ändringar",
"Watching for changes discovers most changes without periodic scanning.": "Bevakar ändringar upptäcker de flesta ändringar utan periodisk skanning.",
"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å.",
"Watching for changes discovers most changes without periodic scanning.": "Bevakning av ändringar upptäcker de flesta ändringar utan periodisk skanning.",
"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 denna enhet 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:",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "Du har inga ignorerade mappar.",
"You have unsaved changes. Do you really want to discard them?": "Du har osparade ändringar. Vill du verkligen kasta dem?",
"You must keep at least one version.": "Du måste behålla åtminstone en version.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "Du ska aldrig lägga till eller ändra något lokalt i en \"{{receiveEncrypted}}\"-mapp.",
"days": "dagar",
"directories": "kataloger",
"directories": "mappar",
"files": "filer",
"full documentation": "fullständig dokumentation",
"items": "objekt",
"seconds": "sekunder",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} vill dela mapp \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vill dela mapp \"{{folderlabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} vill dela mapp \"{{folderlabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} kan återinföra denna enhet."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Gelişmiş",
"Advanced Configuration": "Gelişmiş Yapılandırma",
"All Data": "Tüm Veriler",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "Bu cihazla paylaşılan tüm klasörler bir parola ile korunmak zorundadır, böylece gönderilen tüm veriler verilen parola olmadan okunamaz.",
"Allow Anonymous Usage Reporting?": "İsimsiz Kullanım Bildirmeye İzin Verilsin Mi?",
"Allowed Networks": "İzin Verilen Ağlar",
"Alphabetic": "Alfabetik",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Harici bir komut sürümlendirmeyi gerçekleştirir. Dosyayı paylaşılan klasörden kaldırmak zorundadır. Eğer uygulama yolu boşluklar içeriyorsa, tırnak içine alınmalıdır.",
"Anonymous Usage Reporting": "İsimsiz Kullanım Bildirme",
"Anonymous usage report format has changed. Would you like to move to the new format?": "İsimsiz kullanım raporu biçimi değişti. Yeni biçime geçmek ister misiniz?",
"Are you sure you want to permanently delete all these files?": "Tüm bu dosyaları kalıcı olarak silmek istediğinize emin misiniz?",
"Are you sure you want to remove device {%name%}?": "\"{{name}}\" cihazını kaldırmak istediğinize emin misiniz?",
"Are you sure you want to remove folder {%label%}?": " \"{{label}}\" klasörünü kaldırmak istediğinize emin misiniz?",
"Are you sure you want to restore {%count%} files?": "{{count}} dosyayı geri yüklemek istediğinize emin misiniz?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "Şu Anda Paylaşıldığı Cihazlar",
"Danger!": "Tehlike!",
"Debugging Facilities": "Hata Ayıklama Olanakları",
"Default Configuration": "Varsayılan Yapılandırma",
"Default Device": "Varsayılan Cihaz",
"Default Folder": "Varsayılan Klasör",
"Default Folder Path": "Varsayılan Klasör Yolu",
"Defaults": "Varsayılanlar",
"Delete Unexpected Items": "Beklenmeyen Öğeleri Sil",
"Deleted": "Silinen",
"Deselect All": "Tüm Seçimi Kaldır",
"Deselect devices to stop sharing this folder with.": "Bu klasörün paylaşımının durdurulacağı cihazların seçimini kaldırın.",
"Deselect folders to stop sharing with this device.": "Bu cihazla paylaşımı durdurulacak klasörlerin seçimini kaldırın.",
"Device": "Cihaz",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "\"{{name}}\" ({{address}} adresindeki {{device}}) cihazı bağlanmak istiyor. Yeni cihaz eklensin mi?",
"Device ID": "Cihaz Kimliği",
"Device Identification": "Cihaz Kimliği",
"Device Name": "Cihaz Adı",
"Device is untrusted, enter encryption password": "Cihaz güvenilmez, şifreleme parolasını girin",
"Device rate limits": "Cihaz hız sınırları",
"Device that last modified the item": "Öğeyi son değiştiren cihaz",
"Devices": "Cihazlar",
@@ -92,7 +101,9 @@
"Downloading": "İndiriliyor",
"Edit": "Düzenle",
"Edit Device": "Düzenlenen Cihaz",
"Edit Device Defaults": "Cihaz Varsayılanlarını Düzenle",
"Edit Folder": "Düzenlenen Klasör",
"Edit Folder Defaults": "Klasör Varsayılanlarını Düzenle",
"Editing {%path%}.": "Düzenlenen {{path}}.",
"Enable Crash Reporting": "Çökme Bildirmeyi etkinleştir",
"Enable NAT traversal": "NAT geçişini etkinleştir",
@@ -122,6 +133,7 @@
"Folder Label": "Klasör Etiketi",
"Folder Path": "Klasör Yolu",
"Folder Type": "Klasör Türü",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Klasör türü \"{{receiveEncrypted}}\", klasör eklendikten sonra değiştirilemez. Klasörü kaldırmanız, diskteki verileri silmeniz veya şifresini çözmeniz ve klasörü tekrar eklemeniz gerekir.",
"Folders": "Klasörler",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Aşağıdaki klasörler için değişiklikleri izlemeye başlarken bir hata meydana geldi. Her dakika yeniden denenecektir, böylece hatalar kısa süre içinde ortadan kalkabilir. Devam ederse, altta yatan sorunu düzeltmeye çalışın ve yapamazsanız yardım isteyin.",
"Full Rescan Interval (s)": "Tam Yeniden Tarama Aralığı (s)",
@@ -139,6 +151,7 @@
"Help": "Yardım",
"Home page": "Ana Sayfa",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Ancak, şu anki ayarlarınız etkinleştirilmesini istemediğinizi gösterir. Sizin için otomatik çökme bildirmeyi etkisizleştirdik.",
"If untrusted, enter encryption password": "Eğer güvenilmezse, şifreleme parolasını girin",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Eğer bu bilgisayardaki diğer kullanıcıların Syncthing'e ve onun aracılığıyla dosyalarınıza erişmesini önlemek istiyorsanız, kimlik doğrulamasını ayarlamayı düşünün.",
"Ignore": "Yoksay",
"Ignore Patterns": "Yoksayma Şekilleri",
@@ -187,6 +200,7 @@
"No File Versioning": "Dosya Sürümlendirme Yok",
"No files will be deleted as a result of this operation.": "Bu işlem sonucunda hiçbir dosya silinmeyecektir.",
"No upgrades": "Yükseltmeler yok",
"Not shared": "Paylaşılmamış",
"Notice": "Uyarı",
"OK": "TAMAM",
"Off": "Kapalı",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Kullanım Raporunu önizle",
"Quick guide to supported patterns": "Desteklenen şekiller için hızlı rehber",
"Random": "Rastgele",
"Receive Encrypted": "Şifrelenmiş Al",
"Receive Only": "Yalnızca Al",
"Received data is already encrypted": "Alınan veriler zaten şifrelenmiş",
"Recent Changes": "Son Değişiklikler",
"Reduced by ignore patterns": "Yoksayılan şekiller tarafından azaltıldı",
"Release Notes": "Yayım Notları",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Yayım adayları en son özellikleri ve hata düzeltmelerini içerir. Bunlar, geleneksel iki haftada bir yapılan Syncthing yayımlarına benzerler.",
"Remote Devices": "Uzak Cihazlar",
"Remote GUI": "Uzak GKA",
"Remove": "Kaldır",
"Remove Device": "Cihazı Kaldır",
"Remove Folder": "Klasörü Kaldır",
@@ -249,6 +266,7 @@
"Select All": "Tümünü Seç",
"Select a version": "Bir sürüm seçin",
"Select additional devices to share this folder with.": "Bu klasörün paylaşılacağı ilave cihazları seçin.",
"Select additional folders to share with this device.": "Bu cihazla paylaşmak için ek klasörler seçin.",
"Select latest version": "En son sürümü seç",
"Select oldest version": "En eski sürümü seç",
"Select the folders to share with this device.": "Bu cihazla paylaşılacak klasörleri seçin.",
@@ -259,6 +277,7 @@
"Share Folder": "Paylaşım Klasörü",
"Share Folders With Device": "Klasörleri Cihazla Paylaş",
"Share this folder?": "Bu klasör paylaşılsın mı?",
"Shared Folders": "Paylaşılan Klasörler",
"Shared With": "Şununla Paylaşıldı",
"Sharing": "Paylaşma",
"Show ID": "Kimliği Göster",
@@ -281,6 +300,7 @@
"Start Browser": "Tarayıcıyı başlat",
"Statistics": "İstatistikler",
"Stopped": "Durduruldu",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Yalnızca şifrelenmiş verileri depolar ve eşitler. Tüm bağlı cihazlardaki klasörlerin de aynı parola ile ayarlanması veya \"{{receiveEncrypted}}\" türünde olması gerekir.",
"Support": "Destek",
"Support Bundle": "Destek Paketi",
"Sync Protocol Listen Addresses": "Eşitleme Protokolü Dinleme Adresleri",
@@ -310,6 +330,7 @@
"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.": "Şu aralıklar kullanılır: ilk saat için her 30 saniyede bir sürüm tutulur, ilk gün için her saat bir sürüm tutulur, ilk 30 gün için her gün bir sürüm tutulur, en fazla yaşa kadar her hafta bir sürüm tutulur.",
"The following items could not be synchronized.": "Aşağıdaki öğeler eşitlenemedi.",
"The following items were changed locally.": "Aşağıdaki öğeler yerel olarak değiştirildi.",
"The following unexpected items were found.": "Aşağıdaki beklenmeyen öğeler bulundu.",
"The interval must be a positive number of seconds.": "Aralık, pozitif bir saniye sayısı olmak zorundadır.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Sürüm dizininde temizlemeyi çalıştırmak için saniye olarak aralık değeri. Düzenli temizliği etkisizleştirmek için sıfır.",
"The maximum age must be a number and cannot be blank.": "En fazla yaş bir sayı olmak zorundadır ve boş bırakılamaz.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Hız sınırı negatif olmayan bir sayı olmak zorundadır (0: sınır yok)",
"The rescan interval must be a non-negative number of seconds.": "Yeniden tarama aralığı negatif olmayan bir saniye sayısı olmak zorundadır.",
"There are no devices to share this folder with.": "Bu klasörün paylaşılacağı cihazlar yok.",
"There are no folders to share with this device.": "Bu cihazla paylaşılacak klasörler yok.",
"They are retried automatically and will be synced when the error is resolved.": "Otomatik olarak yeniden denenirler ve hata çözüldüğünde eşitleneceklerdir.",
"This Device": "Bu Cihaz",
"This can easily give hackers access to read and change any files on your computer.": "Bu, bilgisayar korsanlarının bilgisayarınızdaki herhangi bir dosyayı okumasına ve değiştirmesine kolayca erişim sağlayabilir.",
@@ -335,10 +357,14 @@
"Unavailable": "Kullanılamaz",
"Unavailable/Disabled by administrator or maintainer": "Yönetici veya bakımcı tarafından kullanılamaz yapıldı/etkisizleştirildi",
"Undecided (will prompt)": "Kararsız (sorulacak)",
"Unexpected Items": "Beklenmeyen Öğeler",
"Unexpected items have been found in this folder.": "Bu klasörde beklenmeyen öğeler bulundu.",
"Unignore": "Yoksaymayı Kaldır",
"Unknown": "Bilinmiyor",
"Unshared": "Paylaşılmadı",
"Unshared Devices": "Paylaşılmayan Cihazlar",
"Unshared Folders": "Paylaşılmayan Klasörler",
"Untrusted": "Güvenilmez",
"Up to Date": "Güncel",
"Updated": "Güncellenen",
"Upgrade": "Yükselt",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Yoksayılan klasörleriniz yok.",
"You have unsaved changes. Do you really want to discard them?": "Kaydedilmemiş değişiklikler var. Gerçekten yoksaymak istiyor musunuz?",
"You must keep at least one version.": "En az bir sürümü tutmak zorundasınız.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "\"{{receiveEncrypted}}\" klasörüne yerel olarak hiçbir şey eklememeli veya değiştirmemelisiniz.",
"days": "gün",
"directories": "dizin",
"files": "dosya",
@@ -381,5 +408,6 @@
"items": "öğe",
"seconds": "saniye",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}}, \"{{folder}}\" klasörünü paylaşmak istiyor.",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}}, \"{{folderlabel}}\" ({{folder}}) klasörünü paylaşmak istiyor."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}}, \"{{folderlabel}}\" ({{folder}}) klasörünü paylaşmak istiyor.",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} bu cihazı yeniden tanıtabilir."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "Розширені",
"Advanced Configuration": "Розширена конфігурація",
"All Data": "Усі дані",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "Дозволити програмі збирати анонімну статистику використання?",
"Allowed Networks": "Дозволені мережі",
"Alphabetic": "За алфавітом",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "Зовнішня команда керування версіями. Вона має видалити файл із спільної директорії. Якщо шлях до програми містить пробіли, він буде взятий у лапки.",
"Anonymous Usage Reporting": "Анонімна статистика використання",
"Anonymous usage report format has changed. Would you like to move to the new format?": "Змінився формат анонімного звіту про користування. Бажаєте перейти на новий формат?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "Чи ви впевнені в необхідності видалити пристрій {{name}}?",
"Are you sure you want to remove folder {%label%}?": "Чи ви впевнені в необхідності видалити директорію {{label}}?",
"Are you sure you want to restore {%count%} files?": "Чи ви впевнені в необхідності відновити наступну к-сть файлів: {{count}} ?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "На даний момент є спільний доступ пристроїв",
"Danger!": "Небезпечно!",
"Debugging Facilities": "Засоби відладки",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "Шлях до директорії по замовчанню",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "Видалене",
"Deselect All": "Зняти вибір з усіх",
"Deselect devices to stop sharing this folder with.": "Зніміть вибір з пристроїв, які не матимуть доступу до цієї директорії.",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "Пристрій",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Пристрій \"{{name}}\" ({{device}} за адресою {{address}}) намагається під’єднатися. Додати новий пристрій?",
"Device ID": "ID пристрою",
"Device Identification": "Ідентифікатор пристрою",
"Device Name": "Назва пристрою",
"Device is untrusted, enter encryption password": "Device is untrusted, enter encryption password",
"Device rate limits": "Обмеження пристрою",
"Device that last modified the item": "Пристрій, що останнім змінив елемент",
"Devices": "Пристрої",
@@ -92,7 +101,9 @@
"Downloading": "Завантаження",
"Edit": "Редагувати",
"Edit Device": "Налаштування пристрою",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "Налаштування директорії",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "Редагування {{path}}.",
"Enable Crash Reporting": "Увімкнути звітування про збої",
"Enable NAT traversal": "Увімкнути NAT traversal",
@@ -122,6 +133,7 @@
"Folder Label": "Мітка директорії",
"Folder Path": "Шлях до директорії",
"Folder Type": "Тип директорії",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "Директорії",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "Сталася помилка при спробі відслідковувати зміни у вищенаведених папках. Їх доступність перевірятиметься щохвилини, доки помилка не зникне. Якщо помилки не зникають, спробуйте виправити права доступу або попросіть допомоги.",
"Full Rescan Interval (s)": "Інтервал повного пересканування (секунди)",
@@ -139,6 +151,7 @@
"Help": "Допомога",
"Home page": "Домашня сторінка",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Однак ваші поточні налаштування вказують, що ви, можливо, не хочете, щоб це було ввімкнено. Ми відключили автоматичне повідомлення про аварійне завершення роботи.",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "Якщо ви хочете заборонити іншим користувачам цього комп’ютера отримувати доступ до Syncthing і через нього до своїх файлів, подумайте про налаштування автентифікації.",
"Ignore": "Ігнорувати",
"Ignore Patterns": "Шаблони винятків",
@@ -187,6 +200,7 @@
"No File Versioning": "Версіонування вимкнено",
"No files will be deleted as a result of this operation.": "В результаті цієї операції не було видалено жодного файлу.",
"No upgrades": "Немає оновлень",
"Not shared": "Not shared",
"Notice": "Зауваження",
"OK": "Гаразд",
"Off": "Вимкнути",
@@ -220,12 +234,15 @@
"Preview Usage Report": "Попередній перегляд статистичного звіту",
"Quick guide to supported patterns": "Короткий посібник по шаблонам, що підтримуються",
"Random": "Випадково",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "Тільки отримувати",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "Останні зміни",
"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": "Віддалені пристрої",
"Remote GUI": "Remote GUI",
"Remove": "Видалити",
"Remove Device": "Видалити пристрій",
"Remove Folder": "Видалити директорію",
@@ -249,6 +266,7 @@
"Select All": "Обрати все",
"Select a version": "Обрати версію",
"Select additional devices to share this folder with.": "Оберіть додаткові пристрої, які матимуть доступ до цієї директорії.",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "Обрати найновішу версію",
"Select oldest version": "Обрати найстарішу версію",
"Select the folders to share with this device.": "Оберіть директорії до яких матиме доступ цей пристрій.",
@@ -259,6 +277,7 @@
"Share Folder": "Розповсюдити каталог",
"Share Folders With Device": "Розділити каталог з пристроєм",
"Share this folder?": "Розповсюдити цей каталог?",
"Shared Folders": "Shared Folders",
"Shared With": "Доступно для",
"Sharing": "Спільне використання",
"Show ID": "Показати ID",
@@ -281,6 +300,7 @@
"Start Browser": "Запустити браузер",
"Statistics": "Статистика",
"Stopped": "Зупинено",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "Підтримка",
"Support Bundle": "Пакетна підтримка",
"Sync Protocol Listen Addresses": "Адреса і вхідний порт протоколу синхронізації",
@@ -310,6 +330,7 @@
"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 following items were changed locally.": "Наступні об'єкти були змінені локально.",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "Інтервал повинен бути додатною кількістю секунд.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "Інтервал, в секундах, для запуску очищення в директорії версій. Нуль для вимкнення періодичної чистки.",
"The maximum age must be a number and cannot be blank.": "Максимальний термін повинен бути числом та не може бути пустим.",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "Швидкість має бути додатнім числом.",
"The rescan interval must be a non-negative number of seconds.": "Інтервал повторного сканування повинен бути неід’ємною величиною.",
"There are no devices to share this folder with.": "Відсутні пристрої, які мають доступ до цієї директорії.",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "Це легко може дати хакерам доступ до читання та зміни будь-яких файлів на вашому комп'ютері.",
@@ -335,10 +357,14 @@
"Unavailable": "Недоступно",
"Unavailable/Disabled by administrator or maintainer": "Недоступно/заборонено адміністратором або куратором",
"Undecided (will prompt)": "Невизначено (буде запитано)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "Не ігнорувати",
"Unknown": "Невідомо",
"Unshared": "Не розповсюджується",
"Unshared Devices": "Пристрої, що не розповсюджується",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "Актуальна версія",
"Updated": "Оновлено",
"Upgrade": "Оновлення",
@@ -374,6 +400,7 @@
"You have no ignored folders.": "Немає ігнорованих папок.",
"You have unsaved changes. Do you really want to discard them?": "Внесені зміни не збережено, чи дійсно відмовитись від змін?",
"You must keep at least one version.": "Ви повинні зберігати щонайменше одну версію.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "днів",
"directories": "директорії",
"files": "файли",
@@ -381,5 +408,6 @@
"items": "елементи",
"seconds": "секунд",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} хоче поділитися директорією \"{{folder}}\".",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} хоче поділитися директорією \"{{folderLabel}}\" ({{folder}})."
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} хоче поділитися директорією \"{{folderLabel}}\" ({{folder}}).",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -18,12 +18,14 @@
"Advanced": "高级",
"Advanced Configuration": "高级配置",
"All Data": "所有数据",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "允许匿名使用报告?",
"Allowed Networks": "允许的网络",
"Alphabetic": "字母顺序",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "外部命令接管了版本控制。该外部命令必须自行从共享文件夹中删除该文件。如果此应用程序的路径包含空格,应该用半角引号括起来。",
"Anonymous Usage Reporting": "匿名使用报告",
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名使用情况的报告格式已经变更。是否要迁移到新的格式?",
"Are you sure you want to permanently delete all these files?": "确认要永久删除这些文件吗?",
"Are you sure you want to remove device {%name%}?": "您确定要移除设备 {{name}} 吗?",
"Are you sure you want to remove folder {%label%}?": "您确定要移除文件夹 {{label}} 吗?",
"Are you sure you want to restore {%count%} files?": "您确定要恢复这 {{count}} 个文件吗?",
@@ -59,15 +61,22 @@
"Currently Shared With Devices": "当前设备已共享",
"Danger!": "危险!",
"Debugging Facilities": "调试功能",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "默认文件夹路径",
"Defaults": "Defaults",
"Delete Unexpected Items": "Delete Unexpected Items",
"Deleted": "已删除",
"Deselect All": "取消全选",
"Deselect devices to stop sharing this folder with.": "反选设备以停止共享此文件夹",
"Deselect folders to stop sharing with this device.": "Deselect folders to stop sharing with this device.",
"Device": "设备",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "设备 \"{{name}}\"(位于 {{address}} 的 {{device}})请求连接。是否添加新设备?",
"Device ID": "设备 ID",
"Device Identification": "设备标识",
"Device Name": "设备名",
"Device is untrusted, enter encryption password": "设备不可信,请输入加密密码",
"Device rate limits": "设备速率限制",
"Device that last modified the item": "最近修改该项的设备",
"Devices": "设备",
@@ -91,8 +100,10 @@
"Downloaded": "已下载",
"Downloading": "下载中",
"Edit": "选项",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "编辑设备",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "编辑文件夹",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "正在编辑 {{path}}。",
"Enable Crash Reporting": "启用自动发送崩溃报告",
"Enable NAT traversal": "启用 NAT 遍历",
@@ -122,6 +133,7 @@
"Folder Label": "文件夹标签",
"Folder Path": "文件夹路径",
"Folder Type": "文件夹类型",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "文件夹",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "开始监视下列文件夹时发生错误。由于每分钟都会重试,所以错误可能很快就消失。如果它们仍存在,请试着修复潜在问题,如不会则请求帮助。",
"Full Rescan Interval (s)": "完整扫描间隔",
@@ -139,6 +151,7 @@
"Help": "帮助",
"Home page": "主页",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "我们已经为您关闭了自动崩溃报告发送功能,因为您当前的设置显示您可能并不想启用该功能。",
"If untrusted, enter encryption password": "If untrusted, enter encryption password",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "如果要阻止此计算机上的其他用户访问Syncthing并通过它访问文件请考虑设置身份验证。",
"Ignore": "忽略",
"Ignore Patterns": "忽略模式",
@@ -187,6 +200,7 @@
"No File Versioning": "不启用版本控制",
"No files will be deleted as a result of this operation.": "此操作结果不会删除任何文件。",
"No upgrades": "无更新",
"Not shared": "Not shared",
"Notice": "提示",
"OK": "确定",
"Off": "关闭",
@@ -220,12 +234,15 @@
"Preview Usage Report": "预览使用报告",
"Quick guide to supported patterns": "支持的通配符的简单教程:",
"Random": "随机顺序",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "仅接收",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "最近更改",
"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": "远程设备",
"Remote GUI": "Remote GUI",
"Remove": "移除",
"Remove Device": "移除设备",
"Remove Folder": "移除文件夹",
@@ -249,6 +266,7 @@
"Select All": "全选",
"Select a version": "选择版本",
"Select additional devices to share this folder with.": "选择其他共享此文件夹的设备",
"Select additional folders to share with this device.": "Select additional folders to share with this device.",
"Select latest version": "选择最新的版本",
"Select oldest version": "选择最旧的版本",
"Select the folders to share with this device.": "选择与该设备共享的文件夹。",
@@ -259,6 +277,7 @@
"Share Folder": "共享文件夹",
"Share Folders With Device": "将指定文件夹共享给设备",
"Share this folder?": "是否共享该文件夹?",
"Shared Folders": "Shared Folders",
"Shared With": "共享给",
"Sharing": "共享",
"Show ID": "显示 ID",
@@ -281,6 +300,7 @@
"Start Browser": "启动浏览器",
"Statistics": "统计",
"Stopped": "已停止",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "支持",
"Support Bundle": "支持捆绑包",
"Sync Protocol Listen Addresses": "协议监听地址",
@@ -310,6 +330,7 @@
"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 were changed locally.": "下列项目存在本地更改。",
"The following unexpected items were found.": "The following unexpected items were found.",
"The interval must be a positive number of seconds.": "间隔必须为正数秒。",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "在版本目录中运行清理的间隔。0表示禁用定期清除。",
"The maximum age must be a number and cannot be blank.": "最长保留时间必须为数字,且不能为空。",
@@ -322,6 +343,7 @@
"The rate limit must be a non-negative number (0: no limit)": "传输速度限制为非负整数0 表示不限制)",
"The rescan interval must be a non-negative number of seconds.": "扫描间隔单位为秒,且不能为负数。",
"There are no devices to share this folder with.": "没有设备共享此文件夹",
"There are no folders to share with this device.": "There are no folders to share with this device.",
"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.": "这会让骇客能够轻而易举地访问及修改您的文件。",
@@ -335,10 +357,14 @@
"Unavailable": "无效",
"Unavailable/Disabled by administrator or maintainer": "无效/禁用(由管理员或维护者)",
"Undecided (will prompt)": "待定(将提示)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "Unexpected items have been found in this folder.",
"Unignore": "解除忽略",
"Unknown": "未知",
"Unshared": "未共享",
"Unshared Devices": "未共享设备",
"Unshared Folders": "Unshared Folders",
"Untrusted": "Untrusted",
"Up to Date": "同步完成",
"Updated": "已更新",
"Upgrade": "更新",
@@ -374,12 +400,14 @@
"You have no ignored folders.": "你没有已忽略的文件夹。",
"You have unsaved changes. Do you really want to discard them?": "你有未保存的更改。你真的要丢弃它们吗?",
"You must keep at least one version.": "您必须保留至少一个版本。",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "You should never add or change anything locally in a \"{{receiveEncrypted}}\" folder.",
"days": "天",
"directories": "directories",
"directories": "目录",
"files": "文件",
"full documentation": "完整文档",
"items": "条目",
"seconds": "秒",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想将 “{{folder}}” 文件夹共享给您。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要共享 \"{{folderlabel}}\" ({{folder}}) 文件夹给您。"
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要共享 \"{{folderlabel}}\" ({{folder}}) 文件夹给您。",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} might reintroduce this device."
}

View File

@@ -0,0 +1,413 @@
{
"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.": "重大更新可能與之前的版本之間無法兼容",
"API Key": "API Key",
"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?": "新增新文件夾?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "另外,完整重新掃瞄的間隔將增大(時間 60以新的默認 1 小時為例)。你也可以在選擇「否」後手動配置每個文件夾的時間。",
"Address": "地址",
"Addresses": "地址列表",
"Advanced": "高級",
"Advanced Configuration": "高級配置",
"All Data": "所有資料",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.",
"Allow Anonymous Usage Reporting?": "允許匿名使用報告?",
"Allowed Networks": "允許的網絡",
"Alphabetic": "字母順序",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "外部命令接管了版本控制。該外部命令必須自行從共享文件夾中刪除該文件。如果此應用程序的路徑包含空格,應該用半角引號括起來。",
"Anonymous Usage Reporting": "匿名使用報告",
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名使用情況的報告格式已經變更。是否要遷移到新的格式?",
"Are you sure you want to permanently delete all these files?": "Are you sure you want to permanently delete all these files?",
"Are you sure you want to remove device {%name%}?": "您確定要移除設備 {{name}} 嗎?",
"Are you sure you want to remove folder {%label%}?": "您確定要移除文件夾 {{label}} 嗎?",
"Are you sure you want to restore {%count%} files?": "您確定要恢復這 {{count}} 個文件嗎?",
"Are you sure you want to upgrade?": "你確定要升級嗎?",
"Auto Accept": "自動接受",
"Automatic Crash Reporting": "自動發送崩潰報告",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動升級現在提供了穩定版本和候選發佈版的選項。",
"Automatic upgrades": "自動升級",
"Automatic upgrades are always enabled for candidate releases.": "候選發佈版會一直啟用自動升級。",
"Automatically create or share folders that this device advertises at the default path.": "在本機默認文件夾中,自動地創建或共享這個設備共享出來的所有文件夾。",
"Available debug logging facilities:": "可用的調試日誌功能:",
"Be careful!": "小心!",
"Bugs": "問題回報",
"Changelog": "更新日誌",
"Clean out after": "在該時間後清除",
"Cleaning Versions": "清除版本",
"Cleanup Interval": "清除間隔",
"Click to see discovery failures": "點擊查看設備發現錯誤",
"Close": "關閉",
"Command": "命令",
"Comment, when used at the start of a line": "註釋,在行首使用",
"Compression": "壓縮",
"Configured": "已配置",
"Connected (Unused)": "已連接(未使用)",
"Connection Error": "連接出錯",
"Connection Type": "連接類型",
"Connections": "連接",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Syncthing 現在可以持續監視更改了。這將檢測磁盤上的更改,然後對有修改的路徑發起掃瞄。這樣的好處是更改可以更快地傳播,且需要的完整掃瞄會更少。",
"Copied from elsewhere": "從其他設備複製",
"Copied from original": "從源複製",
"Copyright © 2014-2019 the following Contributors:": "版權所有©2014-2019以下貢獻者",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "正在創建忽略模式,覆蓋位於 {{path}} 的已有文件。",
"Currently Shared With Devices": "當前設備已共享",
"Danger!": "危險!",
"Debugging Facilities": "調試功能",
"Default Configuration": "Default Configuration",
"Default Device": "Default Device",
"Default Folder": "Default Folder",
"Default Folder Path": "默認文件夾路徑",
"Defaults": "Defaults",
"Delete Unexpected Items": "刪除不需要項目",
"Deleted": "已刪除",
"Deselect All": "取消全選",
"Deselect devices to stop sharing this folder with.": "反選設備以停止共享此文件夾",
"Deselect folders to stop sharing with this device.": "停止選擇文件夾以停止與此設備共享。",
"Device": "設備",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "設備 \"{{name}}\"(位於 {{address}} 的 {{device}})請求連接。是否添加新設備?",
"Device ID": "設備 ID",
"Device Identification": "設備標識",
"Device Name": "設備名",
"Device is untrusted, enter encryption password": "設備不受信任,請輸入加密密碼",
"Device rate limits": "設備速率限制",
"Device that last modified the item": "最近修改該項的設備",
"Devices": "設備",
"Disable Crash Reporting": "禁用自動發送崩潰報告",
"Disabled": "已禁用",
"Disabled periodic scanning and disabled watching for changes": "已禁用定期掃瞄和更改監視",
"Disabled periodic scanning and enabled watching for changes": "已禁用定期掃瞄並啟用更改監視",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "已禁用定期掃瞄但設置更改監視失敗,正在以每 1m 一次重試:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "禁用比較和同步文件權限。 適用於不存在或自定義權限的系統例如FATexFATSynologyAndroid。",
"Discard": "丟棄",
"Disconnected": "連接已斷開",
"Disconnected (Unused)": "斷開連接(未使用)",
"Discovered": "已發現",
"Discovery": "設備發現",
"Discovery Failures": "設備發現錯誤",
"Do not restore": "不要恢復",
"Do not restore all": "不要全部恢復",
"Do you want to enable watching for changes for all your folders?": "您想要啟用對監視您所有文件夾的更改嗎?",
"Documentation": "文檔",
"Download Rate": "下載速度",
"Downloaded": "已下載",
"Downloading": "下載中",
"Edit": "選項",
"Edit Device": "編輯設備",
"Edit Device Defaults": "Edit Device Defaults",
"Edit Folder": "編輯文件夾",
"Edit Folder Defaults": "Edit Folder Defaults",
"Editing {%path%}.": "正在編輯 {{path}}。",
"Enable Crash Reporting": "啟用自動發送崩潰報告",
"Enable NAT traversal": "啟用 NAT 遍歷",
"Enable Relaying": "開啟中繼",
"Enabled": "已啟用",
"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.": "請輸入忽略模式,每行一條。",
"Enter up to three octal digits.": "最多輸入三個8進制數字",
"Error": "錯誤",
"External File Versioning": "外部版本控制",
"Failed Items": "失敗的項目",
"Failed to setup, retrying": "設置失敗,正在重試。",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "如果本機沒有配置IPv6則無法連接IPv6服務器是正常的。",
"File Pull Order": "文件拉取順序",
"File Versioning": "版本控制",
"Files are moved to .stversions directory 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.": "當某個文件在其他設備被替換或刪除時,本設備將在 .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.": "在其它設備中對該文件夾內文件的修改並不會被同步到本機,但是在本機上對其的修改,則會被同步到集群中的其它設備。",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "文件將從集群同步,但本地所作的任何更改都不會被發送到其他設備。",
"Filesystem Watcher Errors": "文件系統監視器錯誤",
"Filter by date": "按日期篩選",
"Filter by name": "按名稱篩選",
"Folder": "文件夾",
"Folder ID": "文件夾 ID",
"Folder Label": "文件夾標籤",
"Folder Path": "文件夾路徑",
"Folder Type": "文件夾類型",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "Folder type \"{{receiveEncrypted}}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.",
"Folders": "文件夾",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "開始監視下列文件夾時發生錯誤。由於每分鐘都會重試,所以錯誤可能很快就消失。如果它們仍存在,請試著修復潛在問題,如不會則請求幫助。",
"Full Rescan Interval (s)": "完整掃瞄間隔",
"GUI": "圖形用戶界面",
"GUI Authentication Password": "圖形管理界面密碼",
"GUI Authentication User": "圖形管理界面用戶名",
"GUI Authentication: Set User and Password": "GUI身份驗證設置用戶和密碼",
"GUI Listen Address": "GUI 監聽地址",
"GUI Theme": "GUI 主題",
"General": "常規",
"Generate": "生成",
"Global Discovery": "全球發現",
"Global Discovery Servers": "全球發現服務器",
"Global State": "全局狀態",
"Help": "幫助",
"Home page": "主頁",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "我們已經為您關閉了自動崩潰報告發送功能,因為您當前的設置顯示您可能並不想啟用該功能。",
"If untrusted, enter encryption password": "如果不受信任,請輸入加密密碼",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "如果要阻止此計算機上的其他用戶訪問Syncthing並通過它訪問文件請考慮設置身份驗證。",
"Ignore": "忽略",
"Ignore Patterns": "忽略模式",
"Ignore Permissions": "忽略文件權限",
"Ignored Devices": "已忽略的設備",
"Ignored Folders": "已忽略的文件夾",
"Ignored at": "已忽略於",
"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": "保留版本數量",
"LDAP": "LDAP",
"Largest First": "大文件優先",
"Last Scan": "最後掃瞄",
"Last seen": "最後可見",
"Latest Change": "最後更改",
"Learn more": "瞭解更多",
"Limit": "限制",
"Listeners": "偵聽程序",
"Loading data...": "正在載入數據…",
"Loading...": "正在載入…",
"Local Additions": "從本地添加",
"Local Discovery": "本地發現",
"Local State": "本地狀態",
"Local State (Total)": "本地狀態匯總",
"Locally Changed Items": "本地更改的項目",
"Log": "日誌",
"Log tailing paused. Scroll to the bottom to continue.": "已暫停日誌跟蹤。滾動到底部以繼續。",
"Logs": "日誌",
"Major Upgrade": "重大更新",
"Mass actions": "批量操作",
"Maximum Age": "最長保留時間",
"Metadata Only": "僅元數據",
"Minimum Free Disk Space": "最低可用磁盤空間",
"Mod. Device": "修改設備",
"Mod. Time": "修改時間",
"Move to top of queue": "移動到隊列頂端",
"Multi level wildcard (matches multiple directory levels)": "多級通配符(用以匹配多層文件夾)",
"Never": "從未",
"New Device": "新設備",
"New Folder": "新文件夾",
"Newest First": "新文件優先",
"No": "否",
"No File Versioning": "不啟用版本控制",
"No files will be deleted as a result of this operation.": "此操作結果不會刪除任何文件。",
"No upgrades": "無更新",
"Not shared": "未分享",
"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 new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "用於創建自動接受新文件夾的路徑,同時也是通過 UI 添加新文件夾時的默認值。波浪號 (~) 擴展成 {{tilde}}。",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "歷史版本儲存路徑(留空則會默認存儲在共享文件夾中的 .stversions 目錄)。",
"Pause": "暫停",
"Pause All": "全部暫停",
"Paused": "已暫停",
"Paused (Unused)": "已暫停(未使用)",
"Pending changes": "待定的更改",
"Periodic scanning at given interval and disabled watching for changes": "正以給定的間隔定期掃瞄並已禁用更改監視",
"Periodic scanning at given interval and enabled watching for changes": "正以給定的間隔定期掃瞄並已啟用更改監視",
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "正以給定的間隔定期掃瞄但設置更改監視失敗,正在以每 1m 一次重試:",
"Permissions": "權限",
"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": "此前綴表示,後面的模式在匹配時不區分大小寫",
"Preparing to Sync": "準備同步",
"Preview": "預覽",
"Preview Usage Report": "預覽使用報告",
"Quick guide to supported patterns": "支持的通配符的簡單教程:",
"Random": "隨機順序",
"Receive Encrypted": "Receive Encrypted",
"Receive Only": "僅接收",
"Received data is already encrypted": "Received data is already encrypted",
"Recent Changes": "最近更改",
"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": "遠程設備",
"Remote GUI": "Remote GUI",
"Remove": "移除",
"Remove Device": "移除設備",
"Remove Folder": "移除文件夾",
"Required identifier for the folder. Must be the same on all cluster devices.": "必需的文件夾唯一標識。同一個文件夾在集群中的所有設備上ID必須相同。",
"Rescan": "重新掃瞄",
"Rescan All": "全部重新掃瞄",
"Rescans": "重新掃瞄",
"Restart": "重啟 Syncthing",
"Restart Needed": "需要重啟 Syncthing",
"Restarting": "重啟中",
"Restore": "恢復",
"Restore Versions": "恢復歷史版本",
"Resume": "恢復",
"Resume All": "全部恢復",
"Reused": "復用",
"Revert Local Changes": "恢復本地更改",
"Save": "保存",
"Scan Time Remaining": "掃瞄剩餘時間",
"Scanning": "掃瞄中",
"See external versioning help for supported templated command line parameters.": "有關受支持的模板命令行參數,請參閱外部版本控制幫助。",
"Select All": "全選",
"Select a version": "選擇版本",
"Select additional devices to share this folder with.": "選擇其他共享此文件夾的設備",
"Select additional folders to share with this device.": "選擇其他文件夾與此設備共享。",
"Select latest version": "選擇最新的版本",
"Select oldest version": "選擇最舊的版本",
"Select the folders to share with this device.": "選擇與該設備共享的文件夾。",
"Send & Receive": "發送與接收",
"Send Only": "僅發送",
"Settings": "設置",
"Share": "共享",
"Share Folder": "共享文件夾",
"Share Folders With Device": "將指定文件夾共享給設備",
"Share this folder?": "是否共享該文件夾?",
"Shared Folders": "共享文件夾",
"Shared With": "共享給",
"Sharing": "共享",
"Show ID": "顯示 ID",
"Show QR": "顯示 QR 碼",
"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.": "在集群狀態中顯示該名稱,而不是設備 ID。將會作為當前設備的可選的默認名稱報告給所有其他設備。",
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "在集群狀態中顯示該名稱,而不是設備 ID。如果設置為空則會使用目標設備自報的默認名稱。",
"Shutdown": "關閉 Syncthing",
"Shutdown Complete": "關閉完成",
"Simple File Versioning": "簡易版本控制",
"Single level wildcard (matches within a directory only)": "單級通配符(僅匹配單層文件夾)",
"Size": "大小",
"Smallest First": "小文件優先",
"Some items could not be restored:": "有些項目無法被恢復:",
"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": "已停止",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "支持",
"Support Bundle": "支持捆綁包",
"Sync Protocol Listen Addresses": "協議監聽地址",
"Syncing": "同步中",
"Syncthing has been shut down.": "Syncthing 已關閉。",
"Syncthing includes the following software or portions thereof:": "Syncthing 使用了下列軟件或其中的一部分:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing 是個以 MPL v2.0 授權的免費開源軟件。",
"Syncthing is restarting.": "Syncthing 正在重啟。",
"Syncthing is upgrading.": "Syncthing 正在升級。",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "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。",
"Take me back": "帶我回去",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "GUI 地址已被啟動選項覆蓋。當覆蓋存在時,此處的更改就不會生效。",
"The Syncthing Authors": "Syncthing的作者",
"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 cleanup interval cannot be blank.": "清理間隔不能為空。",
"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 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 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.": "保留的歷史版本會遵循以下條件:最近一小時內的歷史版本,更新間隔小於三十秒的僅保留一份。最近一天內的歷史版本,更新間隔小於一小時的僅保留一份。最近一個月內的歷史版本,更新間隔小於一天的僅保留一份。距離現在超過一個月且小於最長保留時間的,更新間隔小於一周的僅保留一份。",
"The following items could not be synchronized.": "下列項目無法被同步。",
"The following items were changed locally.": "下列項目存在本地更改。",
"The following unexpected items were found.": "找到以下不需要項目。",
"The interval must be a positive number of seconds.": "間隔必須為正數秒。",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "在版本目錄中運行清理的間隔。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 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 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.": "掃瞄間隔單位為秒,且不能為負數。",
"There are no devices to share this folder with.": "沒有設備共享此文件夾",
"There are no folders to share with this device.": "沒有與此設備共享的文件夾。",
"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 is a major version upgrade.": "這是一個重大版本更新。",
"This setting controls the free space required on the home (i.e., index database) disk.": "此設置控制主(例如索引數據庫)磁盤上需要的可用空間。",
"Time": "時間",
"Time the item was last modified": "該項最近修改的時間",
"Trash Can File Versioning": "回收站式版本控制",
"Type": "類型",
"UNIX Permissions": "UNIX權限",
"Unavailable": "無效",
"Unavailable/Disabled by administrator or maintainer": "無效/禁用(由管理員或維護者)",
"Undecided (will prompt)": "待定(將提示)",
"Unexpected Items": "Unexpected Items",
"Unexpected items have been found in this folder.": "在此文件夾中發現了不需要的項目。",
"Unignore": "解除忽略",
"Unknown": "未知",
"Unshared": "未共享",
"Unshared Devices": "未共享設備",
"Unshared Folders": "未共享的文件夾",
"Untrusted": "不信任",
"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": "使用加密連接到圖形管理頁面",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "尚未為GUI身份驗證設置用戶名/密碼。 請考慮進行設置。",
"Version": "版本",
"Versions": "歷史版本",
"Versions Path": "歷史版本路徑",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "超過最長保留時間,或者不滿足下列條件的歷史版本,將會被刪除。",
"Waiting to Clean": "等待清除",
"Waiting to Scan": "等待掃瞄",
"Waiting to Sync": "等待同步",
"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}})的下級目錄。",
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "警告:如果你在使用外部的監視器如 {{syncthingInotify}},你應該確保它已經取消激活。",
"Watch for Changes": "監視更改",
"Watching for Changes": "正在監視更改",
"Watching for changes discovers most changes without periodic scanning.": "對更改的監視無需定期掃瞄就可以發現大多數更改。",
"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 have no ignored devices.": "你沒有已忽略的設備。",
"You have no ignored folders.": "你沒有已忽略的文件夾。",
"You have unsaved changes. Do you really want to discard them?": "你有未保存的更改。你真的要丟棄它們嗎?",
"You must keep at least one version.": "您必須保留至少一個版本。",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "您絕對不應在\"{{receiveEncrypted}}\"文件夾中本地添加或更改任何內容。",
"days": "天",
"directories": "目錄",
"files": "文件",
"full documentation": "完整文檔",
"items": "條目",
"seconds": "秒",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想將 「{{folder}}」 文件夾共享給您。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要共享 \"{{folderlabel}}\" ({{folder}}) 文件夾給您。",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} 可能會重新引入此設備。"
}

View File

@@ -1,85 +1,94 @@
{
"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.": "新的主要版本可能與前的版本不相容。",
"A new major version may not be compatible with previous versions.": "新的主要版本可能與前的版本不相容。",
"API Key": "API 金鑰",
"About": "關於",
"Action": "作",
"Action": "作",
"Actions": "操作",
"Add": "增",
"Add Device": "增裝置",
"Add Folder": "加資料夾",
"Add": "增",
"Add Device": "增裝置",
"Add Folder": "加資料夾",
"Add Remote Device": "新增遠端裝置",
"Add devices from the introducer to our device list, for mutually shared folders.": "對於共的資料夾,匯入引入者的裝置清單。",
"Add new folder?": "新增資料夾?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.",
"Add devices from the introducer to our device list, for mutually shared folders.": "對於共的資料夾,匯入引入者的裝置清單。",
"Add new folder?": "新增資料夾",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "另外,完整地重新掃瞄的間隔將增大(時間 60例如新的預設值為 1 小時)。您也可以在選擇「否」後,手動配置每個資料夾的時間間隔。",
"Address": "位址",
"Addresses": "位址",
"Advanced": "進階",
"Advanced Configuration": "進階配置",
"All Data": "全部資料",
"Allow Anonymous Usage Reporting?": "允許匿名的使用資訊回報?",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "所有與此裝置分享的資料夾必須使用密碼保護起來,如此一來,沒有提供密碼將無法閱覽資料。",
"Allow Anonymous Usage Reporting?": "允許回報匿名數據?",
"Allowed Networks": "允許的網路",
"Alphabetic": "字母順序",
"An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.": "An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.",
"Anonymous Usage Reporting": "匿名的使用資訊回報",
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名的使用資訊回報格式已經改變,你想要移至新格式嗎?",
"Anonymous Usage Reporting": "匿名數據回報",
"Anonymous usage report format has changed. Would you like to move to the new format?": "匿名數據回報格式已經變更,想要移至新格式嗎?",
"Are you sure you want to permanently delete all these files?": "確認永久刪除檔案?",
"Are you sure you want to remove device {%name%}?": "確定要移除 {{name}} 裝置?",
"Are you sure you want to remove folder {%label%}?": "確定要移除 {{label}} 資料夾?",
"Are you sure you want to restore {%count%} files?": "確定想要還原 {{count}} 個檔案?",
"Are you sure you want to upgrade?": "Are you sure you want to upgrade?",
"Are you sure you want to upgrade?": "確定想要更新?",
"Auto Accept": "自動接受",
"Automatic Crash Reporting": "Automatic Crash Reporting",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動更新目前有穩定發行版及發行候選版可供選擇。",
"Automatic upgrades": "自動升級",
"Automatic upgrades are always enabled for candidate releases.": "Automatic upgrades are always enabled for candidate releases.",
"Automatic Crash Reporting": "自動回傳當機報告",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "自動更新目前提供選項有穩定版及候選發行版。",
"Automatic upgrades": "自動更新",
"Automatic upgrades are always enabled for candidate releases.": "候選發行版永遠啟用自動更新。",
"Automatically create or share folders that this device advertises at the default path.": "自動在預設資料夾路徑建立或分享該裝置推薦的資料夾。",
"Available debug logging facilities:": "可用的除錯日誌工具:",
"Be careful!": "請小心!",
"Bugs": "程式錯誤",
"Changelog": "更新日誌",
"Clean out after": "於之後清空",
"Cleaning Versions": "Cleaning Versions",
"Cleanup Interval": "Cleanup Interval",
"Cleaning Versions": "正在清除歷史版本",
"Cleanup Interval": "清除間隔",
"Click to see discovery failures": "點擊以查閱失敗的探索",
"Close": "關閉",
"Command": "指令",
"Comment, when used at the start of a line": "註解,當輸入在一行的開頭時",
"Compression": "壓縮",
"Configured": "已設定",
"Connected (Unused)": "Connected (Unused)",
"Connected (Unused)": "已連線(未使用)",
"Connection Error": "連線錯誤",
"Connection Type": "連線類型",
"Connections": "連線",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Syncthing 現在能持續地監視變動了。此機制將偵測到磁碟上的變動並僅對修改過的項目發起掃描。好處是檔案的變動會傳播的更快,並且較不需要完整掃描。",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "Syncthing 現在能持續地監視變動了。此機制將偵測到磁碟上的變動並僅對修改過的項目發起掃描。優點是檔案的變動將更快地傳播,並且減少完整掃描的需求。",
"Copied from elsewhere": "從別處複製",
"Copied from original": "從原處複製",
"Copyright © 2014-2019 the following Contributors:": "Copyright © 2014-2019 下列貢獻者:",
"Creating ignore patterns, overwriting an existing file at {%path%}.": "建立忽略樣式,覆蓋已存在的 {{path}}。",
"Currently Shared With Devices": "Currently Shared With Devices",
"Currently Shared With Devices": "目前與裝置共享",
"Danger!": "危險!",
"Debugging Facilities": "除錯工具",
"Default Configuration": "預設配置",
"Default Device": "預設裝置",
"Default Folder": "預設資料夾",
"Default Folder Path": "預設資料夾路徑",
"Defaults": "預設",
"Delete Unexpected Items": "刪除不預期的項目",
"Deleted": "已刪除",
"Deselect All": "取消選取全部",
"Deselect devices to stop sharing this folder with.": "Deselect devices to stop sharing this folder with.",
"Deselect devices to stop sharing this folder with.": "取消選擇裝置以停用與其共享資料夾。",
"Deselect folders to stop sharing with this device.": "取消選擇資料夾以停用與此裝置共享。",
"Device": "裝置",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "裝置 \"{{name}}\" ({{device}} 位於 {{address}}) 想要連線。要加新裝置嗎?",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "裝置 \"{{name}}\" ({{device}} 位於 {{address}}) 想要連線。要加新裝置嗎?",
"Device ID": "裝置識別碼",
"Device Identification": "裝置識別",
"Device Name": "裝置名稱",
"Device is untrusted, enter encryption password": "裝置不受信任,輸入加密密碼",
"Device rate limits": "裝置速率限制",
"Device that last modified the item": "前次修改裝置",
"Devices": "裝置",
"Disable Crash Reporting": "Disable Crash Reporting",
"Disable Crash Reporting": "停用回傳當機報告",
"Disabled": "停用",
"Disabled periodic scanning and disabled watching for changes": "已停用定期掃描及觀察變動",
"Disabled periodic scanning and enabled watching for changes": "已停用定期掃描及啟用觀察變動",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "已停用定期掃描,無法設定觀察變動,每 1 分鐘重試:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "停用比較與同步檔案權限。在沒有或自定義權限的系統上很有用(例如FATexFATSynologyAndroid)。",
"Discard": "忽略",
"Disconnected": "斷線",
"Disconnected (Unused)": "Disconnected (Unused)",
"Disconnected (Unused)": "斷線(未使用)",
"Discovered": "已發現",
"Discovery": "探索",
"Discovery Failures": "探索失敗",
@@ -91,29 +100,31 @@
"Downloaded": "已下載",
"Downloading": "正在下載",
"Edit": "編輯",
"Edit Device": "Edit Device",
"Edit Folder": "Edit Folder",
"Edit Device": "編輯裝置",
"Edit Device Defaults": "編輯裝置 預設",
"Edit Folder": "編輯資料夾",
"Edit Folder Defaults": "編輯資料夾 預設",
"Editing {%path%}.": "正在編輯 {{path}} 。",
"Enable Crash Reporting": "Enable Crash Reporting",
"Enable Crash Reporting": "啟用回傳當機報告",
"Enable NAT traversal": "啟用 NAT 穿透",
"Enable Relaying": "啟用中繼",
"Enabled": "啟用",
"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.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "輸入忽略樣式,每行一種。",
"Enter up to three octal digits.": "Enter up to three octal digits.",
"Enter up to three octal digits.": "輸入最多三位八進位數字。",
"Error": "錯誤",
"External File Versioning": "外部的檔案版本控制",
"Failed Items": "失敗的項目",
"Failed to setup, retrying": "無法設定,正在重試",
"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": "檔案版本控制",
"Files are moved to .stversions directory 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 protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "其他裝置做的改變不會影響此裝置上的檔案,但在此裝置上的變動將被發送到叢集的其他部分。",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.",
"Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.": "檔案已從叢集同步,但任何本機的變更將無法傳送至其它裝置。",
"Filesystem Watcher Errors": "檔案系統監視器錯誤",
"Filter by date": "以日期篩選",
"Filter by name": "以名稱篩選",
@@ -122,13 +133,14 @@
"Folder Label": "資料夾標籤",
"Folder Path": "資料夾路徑",
"Folder Type": "資料夾類型",
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "資料夾類型 \"{{receiveEncrypted}}\" 無法在新增後變更。您需要移除資料夾、刪除或解密磁碟上的資料,並再次新增資料夾。",
"Folders": "資料夾",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.",
"Full Rescan Interval (s)": "完全重新掃描間隔 (秒)",
"GUI": "GUI",
"GUI Authentication Password": "GUI 證密碼",
"GUI Authentication User": "GUI 使用者認證名稱",
"GUI Authentication: Set User and Password": "GUI Authentication: Set User and Password",
"GUI Authentication Password": "GUI 證密碼",
"GUI Authentication User": "GUI 驗證使用者名稱",
"GUI Authentication: Set User and Password": "GUI 驗證:設定使用者名稱與密碼",
"GUI Listen Address": "GUI 監聽位址",
"GUI Theme": "主題",
"General": "一般",
@@ -138,8 +150,9 @@
"Global State": "全域狀態",
"Help": "說明",
"Home page": "首頁",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "但是,當前設定表明您可能不希望啟用它。我們為您停用了當機自動回報。",
"If untrusted, enter encryption password": "如未受信任,請輸入加密密碼",
"If you want to prevent other users on this computer from accessing Syncthing and through it your files, consider setting up authentication.": "如果您想防止在此電腦上的其他使用者存取 Syncthing 及其文件,請考慮設定身份驗證。",
"Ignore": "忽略",
"Ignore Patterns": "忽略樣式",
"Ignore Permissions": "忽略權限",
@@ -168,7 +181,7 @@
"Local State (Total)": "本機狀態 (總結)",
"Locally Changed Items": "本地變動項目",
"Log": "日誌",
"Log tailing paused. Scroll to the bottom to continue.": "Log tailing paused. Scroll to the bottom to continue.",
"Log tailing paused. Scroll to the bottom to continue.": "日誌自動滾動已暫停。滾動到底部以繼續。",
"Logs": "日誌",
"Major Upgrade": "重大更新",
"Mass actions": "大量操作",
@@ -187,6 +200,7 @@
"No File Versioning": "無檔案版本控制",
"No files will be deleted as a result of this operation.": "此操作將不會移除您的檔案。",
"No upgrades": "不更新",
"Not shared": "未共享",
"Notice": "注意",
"OK": "確定",
"Off": "關閉",
@@ -200,32 +214,35 @@
"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 new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.": "新自動接受的資料夾將會建立在此路徑下,從 UI 加入資料夾時也將預設推薦此路徑。波浪符字元 (~) 將被展開為 {{tilde}}。",
"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 directory in the shared folder).": "儲存歷史版本的路徑(共享資料夾中的預設 .stversions 目錄則留白)。",
"Pause": "暫停",
"Pause All": "全部暫停",
"Paused": "暫停",
"Paused (Unused)": "Paused (Unused)",
"Paused (Unused)": "暫停(未使用)",
"Pending changes": "等待中的變動",
"Periodic scanning at given interval and disabled watching for changes": "在一定的時間間隔,定期掃描及關閉觀察變動",
"Periodic scanning at given interval and enabled watching for changes": "在一定的時間間隔,定期掃描及啟用觀察變動",
"Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:": "在一定的時間間隔,定期掃描,無法設定觀察變動,每 1 分鐘重試:",
"Permissions": "權限",
"Please consult the release notes before performing a major upgrade.": "執行重大升級前請先參閱版本資訊。",
"Please set a GUI Authentication User and Password in the Settings dialog.": "請在設定對話框內設置 GUI 使用者認證名稱及密碼。",
"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": "前綴表示此樣式不區分大小寫",
"Preparing to Sync": "Preparing to Sync",
"Preparing to Sync": "正在準備同步",
"Preview": "預覽",
"Preview Usage Report": "預覽使用資訊報告",
"Preview Usage Report": "預覽數據報告",
"Quick guide to supported patterns": "可支援樣式的快速指南",
"Random": "隨機",
"Receive Encrypted": "接收已加密",
"Receive Only": "僅接收",
"Received data is already encrypted": "接收到的數據已經加密",
"Recent Changes": "最近變動",
"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 雙週發行版相似。",
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "候選發行版包含最新的功能及修補。與傳統 Syncthing 雙週發行版相似。",
"Remote Devices": "遠端裝置",
"Remote GUI": "遠端 GUI",
"Remove": "移除",
"Remove Device": "移除裝置",
"Remove Folder": "移除資料夾",
@@ -241,26 +258,28 @@
"Resume": "繼續",
"Resume All": "全部繼續",
"Reused": "重用",
"Revert Local Changes": "Revert Local Changes",
"Revert Local Changes": "撤銷本機變更",
"Save": "儲存",
"Scan Time Remaining": "剩餘掃描時間",
"Scanning": "正在掃描",
"See external versioning help for supported templated command line parameters.": "查看關於命令列模板參數請參閱外部版本管理說明。",
"Select All": "Select All",
"Select All": "選擇全部",
"Select a version": "選擇一個版本",
"Select additional devices to share this folder with.": "Select additional devices to share this folder with.",
"Select additional devices to share this folder with.": "選擇額外裝置與其共享此資料夾。",
"Select additional folders to share with this device.": "選擇額外資料夾以共享至此裝置。",
"Select latest version": "選擇最新的版本",
"Select oldest version": "選擇最舊的版本",
"Select the folders to share with this device.": "選擇要共享這個資料夾的裝置。",
"Send & Receive": "傳送及接收",
"Send Only": "僅傳送",
"Settings": "設定",
"Share": "享",
"Share Folder": "享資料夾",
"Share": "享",
"Share Folder": "享資料夾",
"Share Folders With Device": "與裝置共享資料夾",
"Share this folder?": "享此資料夾?",
"Share this folder?": "享此資料夾",
"Shared Folders": "已共享的資料夾",
"Shared With": "與誰共享",
"Sharing": "Sharing",
"Sharing": "正在共享",
"Show ID": "顯示識別碼",
"Show QR": "顯示 QR 碼",
"Show diff with previous version": "顯示與前一個版本的差異",
@@ -274,44 +293,46 @@
"Smallest First": "最小的優先",
"Some items could not be restored:": "有些項目無法被還原:",
"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 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": "已停止",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{{receiveEncrypted}}\" too.",
"Support": "支援",
"Support Bundle": "Support Bundle",
"Support Bundle": "支援包",
"Sync Protocol Listen Addresses": "同步通訊協定監聽位址",
"Syncing": "正在同步",
"Syncthing has been shut down.": "Syncthing 已經關閉。",
"Syncthing includes the following software or portions thereof:": "Syncthing 包括以下軟體或其中的一部分:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing is Free and Open Source Software licensed as MPL v2.0.",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing 為自由且開源授權條款為 MPL v2.0",
"Syncthing is restarting.": "Syncthing 正在重新啟動。",
"Syncthing is upgrading.": "Syncthing 正在進行升級。",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.",
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "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。",
"Take me back": "Take me back",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.",
"The Syncthing Authors": "The Syncthing Authors",
"The Syncthing Authors": "Syncthing 作者們",
"The Syncthing admin interface is configured to allow remote access without a password.": "Syncthing 管理介面被設定允許無密碼的遠端存取。",
"The aggregated statistics are publicly available at the URL below.": "匯總統計資訊可於下方網址取得。",
"The cleanup interval cannot be blank.": "The cleanup interval cannot be blank.",
"The cleanup interval cannot be blank.": "清除間隔不能為空白。",
"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 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 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 following items were changed locally.": "The following items were changed locally.",
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
"The following items were changed locally.": "以下項目在本機進行了變更。",
"The following unexpected items were found.": "找到以下不預期項目。",
"The interval must be a positive number of seconds.": "間隔秒數必須為正數。",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "間隔,以秒為單位,執行清除歷史版本目錄。如欲停用週期清除,設 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 number of days must be a number and cannot be blank.": "天數必須必須為一個數字且不得為空。",
@@ -321,7 +342,8 @@
"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.": "重新掃描間隔必須為一個非負數的秒數。",
"There are no devices to share this folder with.": "There are no devices to share this folder with.",
"There are no devices to share this folder with.": "沒有裝置可以共享此資料夾。",
"There are no folders to share with this device.": "沒有資料夾分享給此裝置。",
"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.": "這能給駭客輕易的來讀取、變更電腦中的任何檔案。",
@@ -331,31 +353,35 @@
"Time the item was last modified": "前次修改時間",
"Trash Can File Versioning": "垃圾筒式檔案版本控制",
"Type": "類型",
"UNIX Permissions": "UNIX Permissions",
"UNIX Permissions": "UNIX 權限",
"Unavailable": "無法使用",
"Unavailable/Disabled by administrator or maintainer": "無法使用 / 被系統管理員或維護者停用",
"Undecided (will prompt)": "未決定(將會提示)",
"Unignore": "Unignore",
"Unexpected Items": "不預期的項目",
"Unexpected items have been found in this folder.": "在此資料夾中發現不預期項目。",
"Unignore": "未忽略",
"Unknown": "未知",
"Unshared": "未共享",
"Unshared Devices": "Unshared Devices",
"Unshared Devices": "未共享的裝置",
"Unshared Folders": "未共享的資料夾",
"Untrusted": "不信任",
"Up to Date": "最新",
"Updated": "已更新",
"Upgrade": "升級",
"Upgrade To {%version%}": "升級至 {{version}}",
"Upgrade": "更新",
"Upgrade To {%version%}": "更新至 {{version}}",
"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",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "Username/Password has not been set for the GUI authentication. Please consider setting it up.",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "尚未設定GUI 驗證的使用者名稱/密碼。請考慮進行設定。",
"Version": "版本",
"Versions": "版本",
"Versions Path": "歷史版本路徑",
"Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.": "當檔案歷史版本的存留時間大於設定的最大值,或是其數量在一段時間內超出允許值時,則會被刪除。",
"Waiting to Clean": "Waiting to Clean",
"Waiting to Scan": "Waiting to Scan",
"Waiting to Sync": "Waiting to Sync",
"Waiting to Clean": "正在等待清除",
"Waiting to Scan": "正在等待掃描",
"Waiting to Sync": "正在等待同步",
"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}}\" 的下級目錄。",
@@ -363,7 +389,7 @@
"Warning: If you are using an external watcher like {%syncthingInotify%}, you should make sure it is deactivated.": "警告:如果您正在使用外部監視工具,如 {{syncthingInotify}},您應該確認已經將其關閉。",
"Watch for Changes": "監視變動",
"Watching for Changes": "正在監視變動",
"Watching for changes discovers most changes without periodic scanning.": "Watching for changes discovers most changes without periodic scanning.",
"Watching for changes discovers most changes without periodic scanning.": "監視變動會發現大多數變更,而無需定期掃描。",
"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": "是",
@@ -372,14 +398,16 @@
"You can read more about the two release channels at the link below.": "您可於下方連結閱讀更多關於發行頻道的說明。",
"You have no ignored devices.": "您沒有已忽略的裝置。\n",
"You have no ignored folders.": "您沒有已忽略的資料夾。\n",
"You have unsaved changes. Do you really want to discard them?": "You have unsaved changes. Do you really want to discard them?",
"You have unsaved changes. Do you really want to discard them?": "您有未儲存的變更。確認棄用嗎?",
"You must keep at least one version.": "您必須保留至少一個版本。",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "您不應該在 \"{{receiveEncrypted}}\" 資料夾中新增或變更任何內容。",
"days": "日",
"directories": "directories",
"directories": "目錄",
"files": "個檔案",
"full documentation": "完整說明文件",
"items": "個項目",
"seconds": "seconds",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要享資料夾 \"{{folder}}\"。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要享資料夾 \"{{folderlabel}}\" ({{folder}})。"
"seconds": "",
"{%device%} wants to share folder \"{%folder%}\".": "{{device}} 想要享資料夾 \"{{folder}}\"。",
"{%device%} wants to share folder \"{%folderlabel%}\" ({%folder%}).": "{{device}} 想要享資料夾 \"{{folderlabel}}\" ({{folder}})。",
"{%reintroducer%} might reintroduce this device.": "{{reintroducer}} 可能會重新引入此裝置。"
}

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","fy":"Western Frisian","hu":"Hungarian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ru":"Russian","sk":"Slovak","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","zh-CN":"Chinese (China)","zh-TW":"Chinese (Taiwan)"}
var langPrettyprint = {"bg":"Bulgarian","ca@valencia":"Catalan (Valencian)","cs":"Czech","da":"Danish","de":"German","el":"Greek","en":"English","en-AU":"English (Australia)","en-GB":"English (United Kingdom)","eo":"Esperanto","es":"Spanish","es-ES":"Spanish (Spain)","eu":"Basque","fi":"Finnish","fr":"French","fy":"Western Frisian","hu":"Hungarian","it":"Italian","ja":"Japanese","ko-KR":"Korean (Korea)","lt":"Lithuanian","nb":"Norwegian Bokmål","nl":"Dutch","pl":"Polish","pt-BR":"Portuguese (Brazil)","pt-PT":"Portuguese (Portugal)","ru":"Russian","sk":"Slovak","sv":"Swedish","tr":"Turkish","uk":"Ukrainian","zh-CN":"Chinese (China)","zh-HK":"Chinese (Hong Kong)","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","fy","hu","it","ja","ko-KR","lt","nb","nl","pl","pt-BR","pt-PT","ru","sk","sv","tr","uk","zh-CN","zh-TW"]
var validLangs = ["bg","ca@valencia","cs","da","de","el","en","en-AU","en-GB","eo","es","es-ES","eu","fi","fr","fy","hu","it","ja","ko-KR","lt","nb","nl","pl","pt-BR","pt-PT","ru","sk","sv","tr","uk","zh-CN","zh-HK","zh-TW"]

View File

File diff suppressed because it is too large Load Diff

View File

@@ -74,6 +74,15 @@ function deviceMap(l) {
return m;
}
function deviceList(m) {
var l = [];
for (var id in m) {
l.push(m[id]);
}
l.sort(deviceCompare);
return l;
}
function folderMap(l) {
var m = {};
l.forEach(function (r) {

View File

@@ -9,7 +9,7 @@
</h1>
<p class="text-center">
Build {{version.date | date:"yyyy-MM-dd"}}
<span ng-if="version.tags">({{version.tags.join(", ")}})</span>
<span ng-if="version.tags.length">({{version.tags.join(", ")}})</span>
<br />
Copyright &copy; 2014-{{version.date | date:"yyyy"}} the Syncthing Authors.
</p>
@@ -19,7 +19,7 @@
<h4 class="text-center" translate>The Syncthing Authors</h4>
<div class="row">
<div class="col-md-12" id="contributor-list">
Jakob Borg, Audrius Butkevicius, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, dependabot-preview[bot], greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Alessandro G., Alex Lindeman, Alex Xu, Aman Gupta, Andrew Dunham, Andrew Rabert, Andrey D, André Colomb, Anjan Momi, Antoine Lamielle, Aranjedeath, Arkadiusz Tymiński, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chris Howie, Chris Joel, Chris Tonkinson, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, Kalle Laine, Karol Różycki, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max Schulze, MaximAL, Maxime Thirouin, Michael Jephcote, Michael Rienstra, Michael Tilli, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Nicholas Rishel, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Suhas Gundimeda, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tomasz Wilczyński, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, Vladimir Rusinov, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, dependabot[bot], derekriemer, desbma, georgespatton, ghjklw, janost, jaseg, jelle van der Waa, klemens, marco-m, mv1005, otbutz, perewa, rubenbe, wangguoliang, xarx00, xjtdy888, 佛跳墙
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Tomasz Wilczyński, Wulf Weich, dependabot-preview[bot], greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Alessandro G., Alex Lindeman, Alex Xu, Aman Gupta, Andrew Dunham, Andrew Rabert, Andrey D, Anjan Momi, Antoine Lamielle, Aranjedeath, Arkadiusz Tymiński, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eric Lesiuta, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, Kalle Laine, Karol Różycki, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max Schulze, MaximAL, Maxime Thirouin, Michael Jephcote, Michael Rienstra, Michael Tilli, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Nicholas Rishel, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Suhas Gundimeda, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, Vladimir Rusinov, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, chenrui, chucic, dependabot[bot], derekriemer, desbma, georgespatton, ghjklw, janost, jaseg, jelle van der Waa, klemens, marco-m, mv1005, otbutz, perewa, rubenbe, wangguoliang, xarx00, xjtdy888, 佛跳墙
</div>
</div>
<hr />

View File

@@ -60,12 +60,14 @@ angular.module('syncthing.core')
DEVICE_CONNECTED: 'DeviceConnected', // Generated each time a connection to a device has been established
DEVICE_DISCONNECTED: 'DeviceDisconnected', // Generated each time a connection to a device has been terminated
DEVICE_DISCOVERED: 'DeviceDiscovered', // Emitted when a new device is discovered using local discovery
DEVICE_REJECTED: 'DeviceRejected', // Emitted when there is a connection from a device we are not configured to talk to
DEVICE_REJECTED: 'DeviceRejected', // DEPRECATED: Emitted when there is a connection from a device we are not configured to talk to
PENDING_DEVICES_CHANGED: 'PendingDevicesChanged', // Emitted when pending devices were added / updated (connection from unknown ID) or removed (device is ignored or added)
DEVICE_PAUSED: 'DevicePaused', // Emitted when a device has been paused
DEVICE_RESUMED: 'DeviceResumed', // Emitted when a device has been resumed
DOWNLOAD_PROGRESS: 'DownloadProgress', // Emitted during file downloads for each folder for each file
FOLDER_COMPLETION: 'FolderCompletion', //Emitted when the local or remote contents for a folder changes
FOLDER_REJECTED: 'FolderRejected', // Emitted when a device sends index information for a folder we do not have, or have but do not share with the device in question
FOLDER_REJECTED: 'FolderRejected', // DEPRECATED: Emitted when a device sends index information for a folder we do not have, or have but do not share with the device in question
PENDING_FOLDERS_CHANGED: 'PendingFoldersChanged', // Emitted when pending folders were added / updated (offered by some device, but not shared to them) or removed (folder ignored or added or no longer offered from the remote device)
FOLDER_SUMMARY: 'FolderSummary', // Emitted when folder contents have changed locally
ITEM_FINISHED: 'ItemFinished', // Generated when Syncthing ends synchronizing a file to a newer version
ITEM_STARTED: 'ItemStarted', // Generated when Syncthing begins synchronizing a file to a newer version

View File

File diff suppressed because it is too large Load Diff

View File

@@ -16,10 +16,7 @@ angular.module('syncthing.core')
}
});
//Prevents user from adding a duplicate ID
var matches = scope.devices.filter(function (n) {
return n.deviceID == viewValue;
}).length;
if (matches > 0) {
if (scope.devices.hasOwnProperty(viewValue)) {
ctrl.$setValidity('unique', false);
} else {
ctrl.$setValidity('unique', true);

View File

@@ -1,14 +1,14 @@
<modal id="editDevice" status="default" icon="{{editingExisting ? 'fas fa-pencil-alt' : 'fas fa-desktop'}}" heading="{{editingExisting ? 'Edit Device' : 'Add Device' | translate}} {{currentDevice.name}}" large="yes" closeable="yes">
<modal id="editDevice" status="default" icon="{{editDeviceModalIcon()}}" heading="{{editDeviceModalTitle()}}" large="yes" closeable="yes">
<div class="modal-body">
<form role="form" name="deviceEditor">
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(deviceEditor)">
<li class="active"><a data-toggle="tab" href="#device-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
<li><a data-toggle="tab" href="#device-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
<li ng-if="!editingDefaults"><a data-toggle="tab" href="#device-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
<li><a data-toggle="tab" href="#device-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
</ul>
<div class="tab-content">
<div id="device-general" class="tab-pane in active">
<div class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
<div ng-if="!editingDefaults" class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
<label translate for="deviceID">Device ID</label>
<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" />
@@ -38,7 +38,7 @@
<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>
</div>
<div id="device-sharing" class="tab-pane">
<div ng-if="!editingDefaults" id="device-sharing" class="tab-pane">
<div class="row">
<div class="col-md-6">
<div class="form-group">
@@ -65,21 +65,44 @@
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label translate for="folders">Share Folders With Device</label>
<div class="form-group" ng-if="currentSharing.shared.length">
<label translate for="folders">Shared Folders</label>
<p class="help-block">
<span translate>Select the folders to share with this device.</span>&emsp;
<small><a href="#" ng-click="selectAllFolders()" translate>Select All</a>&emsp;
<a href="#" ng-click="deSelectAllFolders()" translate>Deselect All</a></small>
<span translate>Deselect folders to stop sharing with this device.</span>&emsp;
<small><a href="#" ng-click="selectAllSharedFolders(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllSharedFolders(false)" translate>Deselect All</a></small>
</p>
<div class="row">
<div class="col-md-4" ng-repeat="folder in folderList()">
<div class="col-md-4" ng-repeat="folder in currentSharing.shared">
<div class="checkbox">
<label ng-if="folder.label.length == 0">
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]">&nbsp;{{folder.id}}
<input type="checkbox" ng-model="currentSharing.selected[folder.id]" />&nbsp;{{folder.id}}
</label>
<label ng-if="folder.label.length != 0">
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]">&nbsp; <span tooltip data-original-title="{{folder.id}}">{{folder.label}}</span>
<input type="checkbox" ng-model="currentSharing.selected[folder.id]" />&nbsp; <span tooltip data-original-title="{{folder.id}}">{{folder.label}}</span>
</label>
</div>
</div>
</div>
</div>
<div class="form-group" ng-if="currentSharing.unrelated.length || folderList().length == 0">
<label translate for="folders">Unshared Folders</label>
<p class="help-block" ng-if="folderList().length > 0">
<span translate>Select additional folders to share with this device.</span>&emsp;
<small><a href="#" ng-click="selectAllUnrelatedFolders(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllUnrelatedFolders(false)" translate>Deselect All</a></small>
</p>
<p class="help-block" ng-if="folderList().length == 0">
<span translate>There are no folders to share with this device.</span>
</p>
<div class="row">
<div class="col-md-4" ng-repeat="folder in currentSharing.unrelated">
<div class="checkbox">
<label ng-if="folder.label.length == 0">
<input type="checkbox" ng-model="currentSharing.selected[folder.id]">&nbsp;{{folder.id}}
</label>
<label ng-if="folder.label.length != 0">
<input type="checkbox" ng-model="currentSharing.selected[folder.id]">&nbsp; <span tooltip data-original-title="{{folder.id}}">{{folder.label}}</span>
</label>
</div>
</div>
@@ -141,17 +164,14 @@
<button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid">
<span class="fas fa-check"></span>&nbsp;<span translate>Save</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#idqr" ng-if="editingExisting || deviceEditor.deviceID.$valid">
<button ng-if="!editingDefaults" type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#idqr" ng-if="editingExisting || deviceEditor.deviceID.$valid">
<span class="fas fa-qrcode"></span>&nbsp;<span translate>Show QR</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
</button>
<div ng-if="editingExisting" class="pull-left">
<button type="button" class="btn btn-warning btn-sm disabled" ng-if="willBeReintroducedBy" tooltip data-original-title="This device will be reintroduced by {{ willBeReintroducedBy }}">
<span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
</button>
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#remove-device-confirmation" ng-if="!willBeReintroducedBy">
<div ng-if="editingExisting && !editingDefaults" class="pull-left">
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#remove-device-confirmation">
<span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
</button>
</div>

View File

@@ -3,6 +3,7 @@
<p ng-model="currentDevice.name" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<span translate translate-value-name="{{currentDevice.name}}">Are you sure you want to remove device {%name%}?</span>
</p>
<p ng-if="willBeReintroducedBy" translate translate-value-reintroducer="{{willBeReintroducedBy}}">{%reintroducer%} might reintroduce this device.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning pull-left btn-sm" data-dismiss="modal" ng-click="deleteDevice()">

View File

@@ -1,24 +1,24 @@
<modal id="editFolder" status="default" icon="{{editingExisting ? 'fas fa-pencil-alt' : 'fas fa-folder'}}" heading="{{editingExisting ? 'Edit Folder' : 'Add Folder' | translate}} ({{folderLabel(currentFolder.id)}})" large="yes" closeable="yes">
<modal id="editFolder" status="default" icon="{{editFolderModalIcon()}}" heading="{{editFolderModalTitle()}}" large="yes" closeable="yes">
<div class="modal-body">
<form role="form" name="folderEditor">
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(folderEditor)">
<li class="active"><a data-toggle="tab" href="#folder-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
<li><a data-toggle="tab" href="#folder-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
<li><a data-toggle="tab" href="#folder-versioning"><span class="fas fa-copy"></span> <span translate>File Versioning</span></a></li>
<li><a data-toggle="tab" href="#folder-ignores"><span class="fas fa-filter"></span> <span translate>Ignore Patterns</span></a></li>
<li ng-if="!editingDefaults"><a data-toggle="tab" href="#folder-ignores"><span class="fas fa-filter"></span> <span translate>Ignore Patterns</span></a></li>
<li><a data-toggle="tab" href="#folder-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
</ul>
<div class="tab-content">
<div id="folder-general" class="tab-pane in active">
<div class="form-group" ng-class="{'has-error': folderEditor.folderLabel.$invalid && folderEditor.folderLabel.$dirty}">
<div class="form-group" ng-class="{'has-error': folderEditor.folderLabel.$invalid && folderEditor.folderLabel.$dirty && !editingDefaults}">
<label for="folderLabel"><span translate>Folder Label</span></label>
<input name="folderLabel" id="folderLabel" class="form-control" type="text" ng-model="currentFolder.label" value="{{currentFolder.label}}" />
<p class="help-block">
<span translate ng-if="folderEditor.folderLabel.$valid || folderEditor.folderLabel.$pristine">Optional descriptive label for the folder. Can be different on each device.</span>
</p>
</div>
<div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
<div ng-if="!editingDefaults" 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="" aria-required="true" unique-folder value="{{currentFolder.id}}" />
<p class="help-block">
@@ -28,25 +28,27 @@
<span translate ng-show="!editingExisting">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.</span>
</p>
</div>
<div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty}">
<div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty && !editingDefaults}">
<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="" aria-required="true" path-is-sub-dir />
<input name="folderPath" ng-readonly="editingExisting && !editingDefaults" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" ng-required="!editingDefaults" ng-aria-required="!editingDefaults" path-is-sub-dir />
<datalist id="directory-list">
<option ng-repeat="directory in directoryList" value="{{ directory }}" />
</datalist>
<p class="help-block">
<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 translate ng-if="folderEditor.folderPath.$error.required && folderEditor.folderPath.$dirty && !editingDefaults">The folder path cannot be blank.</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>
<span ng-if="folderPathErrors.isParent && !editingDefaults">
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="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.otherLabel.length != 0">Warning, this path is a parent directory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
</span>
</p>
</div>
</div>
<div id="folder-sharing" class="tab-pane">
<div class="form-group" ng-if="currentFolder.sharedDevices.length">
<div class="form-group" ng-if="currentSharing.shared.length">
<label translate>Currently Shared With Devices</label>
<p class="help-block">
<span translate>Deselect devices to stop sharing this folder with.</span>&emsp;
@@ -54,16 +56,16 @@
<a href="#" ng-click="selectAllSharedDevices(false)" translate>Deselect All</a></small>
</p>
<div class="row">
<div class="col-md-4" ng-repeat="device in currentFolder.sharedDevices">
<div class="col-md-4" ng-repeat="device in currentSharing.shared">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]" /> {{deviceName(device)}}
<input type="checkbox" ng-model="currentSharing.selected[device.deviceID]" /> {{deviceName(device)}}
</label>
</div>
</div>
</div>
</div>
<div class="form-group" ng-if="currentFolder.unrelatedDevices.length || otherDevices().length <= 0">
<div class="form-group" ng-if="currentSharing.unrelated.length || otherDevices().length <= 0">
<label translate>Unshared Devices</label>
<p class="help-block" ng-if="otherDevices().length > 0">
<span translate>Select additional devices to share this folder with.</span>&emsp;
@@ -74,10 +76,10 @@
<span translate>There are no devices to share this folder with.</span>
</p>
<div class="row">
<div class="col-md-4" ng-repeat="device in currentFolder.unrelatedDevices">
<div class="col-md-4" ng-repeat="device in currentSharing.unrelated">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]" /> {{deviceName(device)}}
<input type="checkbox" ng-model="currentSharing.selected[device.deviceID]" /> {{deviceName(device)}}
</label>
</div>
</div>
@@ -88,7 +90,7 @@
<div id="folder-versioning" class="tab-pane">
<div class="form-group">
<label translate>File Versioning</label>&emsp;<a href="https://docs.syncthing.net/users/versioning.html" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Help</span></a>
<select class="form-control" ng-model="currentFolder.fileVersioningSelector">
<select class="form-control" ng-model="currentFolder._guiVersioning.selector">
<option value="none" translate>No File Versioning</option>
<option value="trashcan" translate>Trash Can File Versioning</option>
<option value="simple" translate>Simple File Versioning</option>
@@ -96,69 +98,69 @@
<option value="external" translate>External File Versioning</option>
</select>
</div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='trashcan' || currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.trashcanClean.$invalid && folderEditor.trashcanClean.$dirty}">
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='trashcan' || currentFolder._guiVersioning.selectorector=='simple'" ng-class="{'has-error': folderEditor._guiVersioning.trashcanClean.$invalid && folderEditor._guiVersioning.trashcanClean.$dirty}">
<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="" aria-required="true" min="0" />
<input name="trashcanClean" id="trashcanClean" class="form-control text-right" type="number" ng-model="currentFolder._guiVersioning.trashcanClean" required="" aria-required="true" min="0" />
<div class="input-group-addon" translate>days</div>
</div>
<p class="help-block">
<span translate ng-if="folderEditor.trashcanClean.$valid || folderEditor.trashcanClean.$pristine">The number of days to keep files in the trash can. Zero means forever.</span>
<span translate ng-if="folderEditor.trashcanClean.$error.required && folderEditor.trashcanClean.$dirty">The number of days must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor.trashcanClean.$error.min && folderEditor.trashcanClean.$dirty">A negative number of days doesn't make sense.</span>
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$valid || folderEditor._guiVersioning.trashcanClean.$pristine">The number of days to keep files in the trash can. Zero means forever.</span>
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$error.required && folderEditor._guiVersioning.trashcanClean.$dirty">The number of days must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$error.min && folderEditor._guiVersioning.trashcanClean.$dirty">A negative number of days doesn't make sense.</span>
</p>
</div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='simple'" ng-class="{'has-error': folderEditor._guiVersioning.simpleKeep.$invalid && folderEditor._guiVersioning.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="" aria-required="true" min="1" />
<input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentFolder._guiVersioning.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>
<span translate ng-if="folderEditor.simpleKeep.$error.min && folderEditor.simpleKeep.$dirty">You must keep at least one version.</span>
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$valid || folderEditor._guiVersioning.simpleKeep.$pristine">The number of old versions to keep, per file.</span>
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$error.required && folderEditor._guiVersioning.simpleKeep.$dirty">The number of versions must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$error.min && folderEditor._guiVersioning.simpleKeep.$dirty">You must keep at least one version.</span>
</p>
</div>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='staggered'" ng-class="{'has-error': folderEditor.staggeredMaxAge.$invalid && folderEditor.staggeredMaxAge.$dirty}">
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='staggered'" ng-class="{'has-error': folderEditor._guiVersioning.staggeredMaxAge.$invalid && folderEditor._guiVersioning.staggeredMaxAge.$dirty}">
<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="" aria-required="true" min="0" />
<input name="staggeredMaxAge" id="staggeredMaxAge" class="form-control" type="number" ng-model="currentFolder._guiVersioning.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>
<span translate ng-if="folderEditor.staggeredMaxAge.$error.min && folderEditor.staggeredMaxAge.$dirty">A negative number of days doesn't make sense.</span>
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$valid || folderEditor._guiVersioning.staggeredMaxAge.$pristine">The maximum time to keep a version (in days, set to 0 to keep versions forever).</span>
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$error.required && folderEditor._guiVersioning.staggeredMaxAge.$dirty">The maximum age must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$error.min && folderEditor._guiVersioning.staggeredMaxAge.$dirty">A negative number of days doesn't make sense.</span>
</p>
</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" />
<div class="form-group" ng-if="internalVersioningEnabled()">
<label translate for="fsPath">Versions Path</label>
<input name="fsPath" id="fsPath" class="form-control" type="text" ng-model="currentFolder.versioning.fsPath" />
<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}">
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='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. If the path to the application contains spaces, it should be quoted.</p>
<label translate for="externalCommand">Command</label>
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder.externalCommand" required="" aria-required="true" />
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder._guiVersioning.externalCommand" required="" aria-required="true" />
<p class="help-block">
<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>
<div class="form-group" ng-if="currentFolder.fileVersioningSelector != 'none'" ng-class="{'has-error': folderEditor.versioningCleanupIntervalS.$invalid && folderEditor.versioningCleanupIntervalS.$dirty}">
<div class="form-group" ng-if="internalVersioningEnabled()" ng-class="{'has-error': folderEditor._guiVersioning.cleanupIntervalS.$invalid && folderEditor._guiVersioning.cleanupIntervalS.$dirty}">
<label translate for="versioningCleanupIntervalS">Cleanup Interval</label>
<div class="input-group">
<input name="versioningCleanupIntervalS" id="versioningCleanupIntervalS" class="form-control text-right" type="number" ng-model="currentFolder.versioningCleanupIntervalS" required="" min="0" max="31536000" aria-required="true" />
<input name="versioningCleanupIntervalS" id="versioningCleanupIntervalS" class="form-control text-right" type="number" ng-model="currentFolder._guiVersioning.cleanupIntervalS" required="" min="0" max="31536000" aria-required="true" />
<div class="input-group-addon" translate>seconds</div>
</div>
<p class="help-block">
<span translate ng-if="folderEditor.versioningCleanupIntervalS.$valid || folderEditor.versioningCleanupIntervalS.$pristine"class="help-block">The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.</span>
<span translate ng-if="folderEditor.versioningCleanupIntervalS.$error.required && folderEditor.versioningCleanupIntervalS.$dirty">The cleanup interval cannot be blank.</span>
<span translate ng-if="folderEditor.versioningCleanupIntervalS.$error.min && folderEditor.versioningCleanupIntervalS.$dirty">The interval must be a positive number of seconds.</span>
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$valid || folderEditor._guiVersioning.cleanupIntervalS.$pristine"class="help-block">The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.</span>
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$error.required && folderEditor._guiVersioning.cleanupIntervalS.$dirty">The cleanup interval cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$error.min && folderEditor._guiVersioning.cleanupIntervalS.$dirty">The interval must be a positive number of seconds.</span>
</p>
</div>
</div>
<div id="folder-ignores" class="tab-pane">
<div ng-if="!editingDefaults" id="folder-ignores" class="tab-pane">
<p translate>Enter ignore patterns, one per line.</p>
<div ng-class="{'has-error': ignores.error != null}">
<textarea class="form-control" rows="5" ng-model="ignores.text" ng-disabled="ignores.disabled"></textarea>
@@ -280,7 +282,7 @@
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
</button>
<button type="button" class="btn btn-warning pull-left btn-sm" data-toggle="modal" data-target="#remove-folder-confirmation" ng-if="editingExisting">
<button type="button" class="btn btn-warning pull-left btn-sm" data-toggle="modal" data-target="#remove-folder-confirmation" ng-if="editingExisting && !editingDefaults">
<span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
</button>
</div>

View File

@@ -18,8 +18,8 @@
<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 | 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]" />
<input ng-if="inputTypeFor(key, value) == 'list'" id="guiInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.gui[key]" ng-list />
<input ng-if="inputTypeFor(key, value) != 'list'" id="guiInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.gui[key]" />
</div>
</div>
</form>
@@ -65,50 +65,113 @@
</div>
</div>
<div class="panel panel-default" ng-repeat="folder in advancedConfig.folders">
<div class="panel-heading" role="tab" id="folder{{$index}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#folder{{$index}}Config" aria-expanded="false" aria-controls="folder{{$index}}Config" style="cursor: pointer;">
<h4 ng-if="folder.label.length == 0" class="panel-title" tabindex="0">
<span translate>Folder</span> "{{folder.id}}"
</h4>
<h4 ng-if="folder.label.length != 0" class="panel-title" tabindex="0">
<span translate>Folder</span> "{{folder.label}}" ({{folder.id}})
</h4>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="advancedFoldersHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#advancedFolders" aria-expanded="false" aria-controls="advancedFolders" style="cursor: pointer;">
<h4 class="panel-title" translate>Folders</h4>
</div>
<div id="folder{{$index}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{$index}}Heading">
<div id="advancedFolders" class="panel-collapse collapse" role="tabpanel" aria-labelledby="advancedFoldersHeading">
<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 | 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]" />
<div class="panel panel-default" ng-repeat="folder in advancedConfig.folders" ng-init="folderIndex = $index">
<div class="panel-heading" role="tab" id="folder{{folderIndex}}Heading" data-toggle="collapse" data-parent="#advancedFolders" href="#folder{{folderIndex}}Config" aria-expanded="false" aria-controls="folder{{folderIndex}}Config" style="cursor: pointer;">
<h4 ng-if="folder.label.length == 0" class="panel-title" tabindex="0">
<span translate>Folder</span> "{{folder.id}}"
</h4>
<h4 ng-if="folder.label.length != 0" class="panel-title" tabindex="0">
<span translate>Folder</span> "{{folder.label}}" ({{folder.id}})
</h4>
</div>
<div id="folder{{folderIndex}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{folderIndex}}Heading">
<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{{folderIndex}}Input{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="folder{{folderIndex}}Input{{$index}}" class="form-control" type="text" ng-model="folder[key]" ng-list />
<input ng-if="inputTypeFor(key, value) != 'list'" id="folder{{folderIndex}}Input{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folder[key]" />
</div>
</div>
</form>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="panel panel-default" ng-repeat="device in advancedConfig.devices">
<div class="panel-heading" role="tab" id="device{{$index}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#device{{$index}}Config" aria-expanded="false" aria-controls="folder{{$index}}Config" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0">
<span translate>Device</span> "{{deviceName(device)}}"
</h4>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="advancedDevicesHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#advancedDevices" aria-expanded="false" aria-controls="advancedDevices" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0" translate>Devices</h4>
</div>
<div id="device{{$index}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="device{{$index}}Heading">
<div id="advancedDevices" class="panel-collapse collapse" role="tabpanel" aria-labelledby="advancedDevicesHeading">
<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 | 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]" />
<div class="panel panel-default" ng-repeat="device in advancedConfig.devices" ng-init="deviceIndex = $index">
<div class="panel-heading" role="tab" id="device{{deviceIndex}}Heading" data-toggle="collapse" data-parent="#advancedDevices" href="#device{{deviceIndex}}Config" aria-expanded="false" aria-controls="device{{deviceIndex}}Config" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0">
<span translate>Device</span> "{{deviceName(device)}}"
</h4>
</div>
<div id="device{{deviceIndex}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="device{{deviceIndex}}Heading">
<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{{deviceIndex}}Input{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="device{{deviceIndex}}Input{{$index}}" class="form-control" type="text" ng-model="device[key]" ng-list />
<input ng-if="inputTypeFor(key, value) != 'list'" id="device{{deviceIndex}}Input{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="device[key]" />
</div>
</div>
</form>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="advancedDefaultsHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#advancedDefaults" aria-expanded="false" aria-controls="advancedDefaults" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0" translate>Defaults</h4>
</div>
<div id="advancedDefaults" class="panel-collapse collapse" role="tabpanel" aria-labelledby="advancedDefaultsHeading">
<div class="panel-body">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="advancedDefaultFolderHeading" data-toggle="collapse" data-parent="#advancedDefaults" href="#advancedDefaultFolder" aria-expanded="false" aria-controls="advancedDefaultFolder" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0" translate>Default Folder</h4>
</div>
<div id="advancedDefaultFolder" class="panel-collapse collapse" role="tabpanel" aria-labelledby="advancedDefaultFolderHeading">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in advancedConfig.defaults.folder" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="advancedDefaultFolderInput{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="advancedDefaultFolderInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.defaults.folder[key]" ng-list />
<input ng-if="inputTypeFor(key, value) != 'list'" id="advancedDefaultFolderInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.defaults.folder[key]" />
</div>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="advancedDefaultDeviceHeading" data-toggle="collapse" data-parent="#advancedDefaults" href="#advancedDefaultDevice" aria-expanded="false" aria-controls="advancedDefaultDevice" style="cursor: pointer;">
<h4 class="panel-title" tabindex="0" translate>Default Device</h4>
</div>
<div id="advancedDefaultDevice" class="panel-collapse collapse" role="tabpanel" aria-labelledby="advancedDefaultDeviceHeading">
<form class="form-horizontal" role="form">
<div ng-repeat="(key, value) in advancedConfig.defaults.device" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
<label for="advancedDefaultDeviceInput{{$index}}" class="col-sm-4 control-label">{{key | uncamel}}</label>
<div class="col-sm-8">
<input ng-if="inputTypeFor(key, value) == 'list'" id="advancedDefaultDeviceInput{{$index}}" class="form-control" type="text" ng-model="advancedConfig.defaults.device[key]" ng-list />
<input ng-if="inputTypeFor(key, value) != 'list'" id="advancedDefaultDeviceInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="advancedConfig.defaults.device[key]" />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">

View File

@@ -100,13 +100,15 @@
</div>
</div>
</div>
<div class="form-group">
<label translate for="urVersion">Default Folder Path</label>
<input id="DefaultFolderPath" class="form-control" type="text" ng-model="tmpOptions.defaultFolderPath" />
<p class="help-block">
<span translate translate-value-tilde="{{system.tilde}}">
Path where new auto accepted folders will be created, as well as the default suggested path when adding new folders via the UI. Tilde character (~) expands to {%tilde%}.
</span>
<div>
<label translate>Default Configuration</label>
<p>
<button type="button" class="btn btn-default btn-secondary" ng-click="editFolderDefaults()">
<span translate>Edit Folder Defaults</span>
</button>
<button type="button" class="btn btn-default btn-secondary" ng-click="editDeviceDefaults()">
<span translate>Edit Device Defaults</span>
</button>
</p>
</div>
</div>

View File

@@ -0,0 +1,958 @@
<!DOCTYPE html>
<!--
// Copyright (C) 2014 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/.
-->
<html lang="en" ng-app="syncthing" ng-controller="SyncthingController">
<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"/>
<title ng-bind="thisDeviceName() + ' | Syncthing'"></title>
<link href="vendor/bootstrap/css/bootstrap.css" rel="stylesheet"/>
<link href="vendor/daterangepicker/daterangepicker.css" rel="stylesheet"/>
<link href="assets/font/raleway.css" rel="stylesheet"/>
<link href="vendor/fork-awesome/css/fork-awesome.css" rel="stylesheet"/>
<link href="vendor/fork-awesome/css/v5-compat.css" rel="stylesheet"/>
<link href="assets/css/overrides.css" rel="stylesheet"/>
<link href="assets/css/theme.css" rel="stylesheet"/>
<link href="vendor/fancytree/css/ui.fancytree.css" rel="stylesheet"/>
</head>
<body>
<noscript>
<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" alt=""/>
<img class="logo hidden visible-xs" src="assets/img/favicon-default.png" height="32" alt=""/>
</span>
</div>
</nav>
<div class="container content">
<div class="row">
<div class="col-md-12">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-exclamation-circle"></span>
</div>
Warning!
</h3>
</div>
<div class="panel-body">
<p>
The Syncthing admin interface requires JavaScript. Please enable JavaScript in your web browser and try again.
</p>
</div>
</div>
</div>
</div>
</div>
</noscript>
<div class="ng-cloak">
<script type="text/javascript" src="syncthing/development/logbar.js"></script>
<div ng-if="version.isBeta" 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" 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">
<li ng-if="upgradeInfo && upgradeInfo.newer" class="upgrade-newer">
<button type="button" class="btn navbar-btn btn-primary btn-sm" data-toggle="modal" data-target="#upgrade">
<span class="fas fa-arrow-circle-up"></span>
<span class="hidden-xs" translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span>
</button>
</li>
<li ng-if="upgradeInfo && upgradeInfo.majorNewer" class="upgrade-newer-major">
<button type="button" class="btn navbar-btn btn-danger btn-sm" data-toggle="modal" data-target="#majorUpgrade">
<span class="fas fa-arrow-circle-up"></span>
<span class="hidden-xs" translate translate-value-version="{{upgradeInfo.latest}}">Upgrade To {%version%}</span>
</button>
</li>
<li class="dropdown" language-select></li>
<li>
<a class="navbar-link" href="https://docs.syncthing.net/intro/gui.html" target="_blank">
<span class="fas fa-question-circle"></span>
<span class="hidden-xs" translate>Help</span>
</a>
</li>
<li class="dropdown action-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fas fa-cog"></span>
<span class="hidden-xs" translate>Actions</span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="" ng-click="showSettings()"><span class="fas fa-fw fa-cog"></span>&nbsp;<span translate>Settings</span></a></li>
<li><a href="" data-toggle="modal" data-target="#idqr" ng-click="currentDevice=thisDevice()"><span class="fas fa-fw fa-qrcode"></span>&nbsp;<span translate>Show ID</span></a></li>
<li class="divider" aria-hidden="true"></li>
<li><a href="" ng-click="shutdown()"><span class="fas fa-fw fa-power-off"></span>&nbsp;<span translate>Shutdown</span></a></li>
<li><a href="" ng-click="restart()"><span class="fas fa-fw fa-refresh"></span>&nbsp;<span translate>Restart</span></a></li>
<li class="divider" aria-hidden="true"></li>
<li class="visible-xs">
<a href="https://docs.syncthing.net/intro/gui.html" target="_blank">
<span class="fas fa-fw fa-question-circle"></span>&nbsp;<span translate>Help</span>
</a>
</li>
<li><a href="" data-toggle="modal" data-target="#about"><span class="far fa-fw fa-heart"></span>&nbsp;<span translate>About</span></a></li>
<li class="divider" aria-hidden="true"></li>
<li><a href="" ng-click="advanced()"><span class="fas fa-fw fa-cogs"></span>&nbsp;<span translate>Advanced</span></a></li>
<li><a href="" ng-click="logging.show()"><span class="far fa-fw fa-file-alt"></span>&nbsp;<span translate>Logs</span></a></li>
<li class="divider" aria-hidden="true" ng-if="config.gui.debugging"></li>
<li><a href="/rest/debug/support" target="_blank" ng-if="config.gui.debugging"><span class="fa fa-user-md"></span>&nbsp;<span translate>Support Bundle</span></a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div class="container content">
<!-- Panel: Open, no auth -->
<div ng-if="openNoAuth" class="row">
<div class="col-md-12">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-exclamation-circle"></span>
</div>
<span translate>Danger!</span>
</h3>
</div>
<div class="panel-body">
<p>
<span translate>The Syncthing admin interface is configured to allow remote access without a password.</span>
<b><span translate>This can easily give hackers access to read and change any files on your computer.</span></b>
<span translate>Please set a GUI Authentication User and Password in the Settings dialog.</span>
</p>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="showSettings()">
<span class="fas fa-cog"></span>&nbsp;<span translate>Settings</span>
</button>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<!-- Panel: Restart Needed -->
<div ng-if="!configInSync" class="row">
<div class="col-md-12">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-exclamation-circle"></span>
</div>
<span translate>Restart Needed</span>
</h3>
</div>
<div class="panel-body">
<p translate>The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.</p>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="restart()">
<span class="fas fa-refresh"></span>&nbsp;<span translate>Restart</span>
</button>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div ng-if="config">
<!-- Panel: Notifications -->
<div ng-if="config.options && config.options.unackedNotificationIDs" ng-include="'syncthing/core/notifications.html'"></div>
<!-- Panel: New Device -->
<div ng-repeat="(deviceID, pendingDevice) in pendingDevices" class="row">
<div class="col-md-12">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">
<identicon class="panel-icon" data-value="device"></identicon>
<span translate>New Device</span>
<span class="pull-right">{{ pendingDevice.time | date:"yyyy-MM-dd HH:mm:ss" }}</span>
</h3>
</div>
<div class="panel-body">
<p>
<span translate translate-value-device="{{ deviceID }}" translate-value-address="{{ pendingDevice.address }}" translate-value-name="{{ pendingDevice.name }}">
Device "{%name%}" ({%device%} at {%address%}) wants to connect. Add new device?
</span>
</p>
</div>
<div class="panel-footer clearfix">
<div class="pull-right">
<button type="button" class="btn btn-sm btn-success" ng-click="addDevice(deviceID, pendingDevice.name)">
<span class="fas fa-plus"></span>&nbsp;<span translate>Add Device</span>
</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="ignoreDevice(deviceID, pendingDevice)">
<span class="fas fa-times"></span>&nbsp;<span translate>Ignore</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Panel: New Folder -->
<div ng-repeat="(folderID, pendingFolder) in pendingFolders">
<div ng-repeat="(deviceID, offeringDevice) in pendingFolder.offeredBy" class="row reject">
<div class="col-md-12">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-folder"></span>
</div>
<span translate ng-if="!folders[folderID]">New Folder</span>
<span translate ng-if="folders[folderID]">Share Folder</span>
<span class="pull-right">{{ offeringDevice.time | date:"yyyy-MM-dd HH:mm:ss" }}</span>
</h3>
</div>
<div class="panel-body">
<p>
<span ng-if="offeringDevice.label.length == 0" translate translate-value-device="{{ deviceName(devices[deviceID]) }}" translate-value-folder="{{ folderID }}">
{%device%} wants to share folder "{%folder%}".
</span>
<span ng-if="offeringDevice.label.length != 0" translate translate-value-device="{{ deviceName(devices[deviceID]) }}" translate-value-folder="{{ folderID }}" translate-value-folderlabel="{{ offeringDevice.label }}">
{%device%} wants to share folder "{%folderlabel%}" ({%folder%}).
</span>
<span translate ng-if="folders[folderID]">Share this folder?</span>
<span translate ng-if="!folders[folderID]">Add new folder?</span>
</p>
</div>
<div class="panel-footer clearfix">
<div class="pull-right">
<button type="button" class="btn btn-sm btn-success" ng-click="addFolderAndShare(folderID, offeringDevice.label, deviceID)" ng-if="!folders[folderID]">
<span class="fas fa-check"></span>&nbsp;<span translate>Add</span>
</button>
<button type="button" class="btn btn-sm btn-success" ng-click="shareFolderWithDevice(folderID, deviceID)" ng-if="folders[folderID]">
<span class="fas fa-check"></span>&nbsp;<span translate>Share</span>
</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="ignoreFolder(deviceID, folderID, offeringDevice)">
<span class="fas fa-times"></span>&nbsp;<span translate>Ignore</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Panel: Notice -->
<div ng-if="errorList().length > 0" class="row">
<div class="col-md-12">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-exclamation-circle"></span>
</div>
<span translate>Notice</span>
</h3>
</div>
<div class="panel-body">
<p ng-repeat="err in errorList()">
<small>{{err.when | date:"yyyy-MM-dd HH:mm:ss"}}:</small>
<span ng-bind-html="friendlyDevices(err.message) | linky: '_blank'"></span>
</p>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="clearErrors()">
<span class="fas fa-check"></span>&nbsp;<span translate>OK</span>
</button>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<!-- Panel: FS watcher errors -->
<div ng-if="sizeOf(fsWatcherErrorMap()) > 0" class="row">
<div class="col-md-12">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">
<div class="panel-icon">
<span class="fas fa-exclamation-circle"></span>
</div>
<span translate>Filesystem Watcher Errors</span>
</h3>
</div>
<div class="panel-body">
<p>
<span translate>For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.</span>&emsp;<a href="https://forum.syncthing.net" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Support</span></a>
</p>
<table>
<tr ng-repeat="(id, err) in fsWatcherErrorMap()">
<td>{{folderLabel(id)}}</td><td>{{err}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- First regular row -->
<div class="row">
<!-- Folder list (top left) -->
<div class="col-md-6" aria-labelledby="folder_list" role="region" >
<h3 id="folder_list" translate>Folders</h3>
<div class="panel-group" id="folders">
<div class="panel panel-default" ng-repeat="folder in folderList()">
<button class="btn panel-heading" data-toggle="collapse" data-parent="#folders" data-target="#folder-{{$index}}" aria-expanded="false">
<div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id) | percent}}"></div>
<div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id) | percent}}"></div>
<h4 class="panel-title">
<div class="panel-icon hidden-xs">
<span ng-if="folder.type == 'sendreceive'" class="fas fa-fw fa-folder"></span>
<span ng-if="folder.type == 'sendonly'" class="fas fa-fw fa-upload"></span>
<span ng-if="folder.type == 'receiveonly'" class="fas fa-fw fa-download"></span>
<span ng-if="folder.type == 'receiveencrypted'" class="fas fa-fw fa-lock"></span>
</div>
<div class="panel-status pull-right text-{{folderClass(folder)}}" ng-switch="folderStatus(folder)">
<span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs" aria-label="{{'Paused' | translate}}"><i class="fas fa-fw fa-pause"></i></span></span>
<span ng-switch-when="unknown"><span class="hidden-xs" translate>Unknown</span><span class="visible-xs" aria-label="{{'Unknown' | translate}}"><i class="fas fa-fw fa-question-circle"></i></span></span>
<span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs" aria-label="{{'Unshared' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
<span ng-switch-when="scan-waiting"><span class="hidden-xs" translate>Waiting to Scan</span><span class="visible-xs" aria-label="{{'Waiting to Scan' | translate}}"><i class="fas fa-fw fa-hourglass-half"></i></span></span>
<span ng-switch-when="cleaning"><span class="hidden-xs" translate>Cleaning Versions</span><span class="visible-xs" aria-label="{{'Cleaning Versions' | translate}}"><i class="fas fa-fw fa-recycle"></i></span></span>
<span ng-switch-when="clean-waiting"><span class="hidden-xs" translate>Waiting to Clean</span><span class="visible-xs" aria-label="{{'Waiting to Clean' | translate}}"><i class="fas fa-fw fa-hourglass-half"></i></span></span>
<span ng-switch-when="stopped"><span class="hidden-xs" translate>Stopped</span><span class="visible-xs" aria-label="{{'Stopped' | translate}}"><i class="fas fa-fw fa-stop"></i></span></span>
<span ng-switch-when="scanning">
<span class="hidden-xs" translate>Scanning</span>
<span class="hidden-xs" ng-if="scanPercentage(folder.id) != undefined">
({{scanPercentage(folder.id) | percent}})
</span>
<span class="visible-xs" aria-label="{{'Scanning' | translate}}"><i class="fas fa-fw fa-search"></i></span>
</span>
<span ng-switch-when="idle"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
<span ng-switch-when="localadditions"><span class="hidden-xs" translate>Local Additions</span><span class="visible-xs" aria-label="{{'Local Additions' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
<span ng-switch-when="sync-waiting">
<span class="hidden-xs" translate>Waiting to Sync</span>
<span class="visible-xs" aria-label="{{'Waiting to Sync' | translate}}"><i class="fas fa-fw fa-hourglass-half"></i></span>
</span>
<span ng-switch-when="sync-preparing">
<span class="hidden-xs" translate>Preparing to Sync</span>
<span class="visible-xs" aria-label="{{'Preparing to Sync' | translate}}"><i class="fas fa-fw fa-hourglass-half"></i></span>
</span>
<span ng-switch-when="syncing">
<span class="hidden-xs" translate>Syncing</span>
<span>({{syncPercentage(folder.id) | percent}}, {{model[folder.id].needBytes | binary}}B)</span>
</span>
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs" aria-label="{{'Out of Sync' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
<span ng-switch-when="faileditems"><span class="hidden-xs" translate>Failed Items</span><span class="visible-xs" aria-label="{{'Failed Items' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
<span ng-switch-when="localunencrypted"><span class="hidden-xs">{{'Unexpected Items' | translate}}</span><span class="visible-xs" aria-label="{{'Unexpected Items' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
</div>
<div class="panel-title-text">
<span tooltip data-original-title="{{folder.label.length != 0 ? folder.id : ''}}">{{folder.label.length != 0 ? folder.label : folder.id}}</span>
</div>
</h4>
</button>
<div id="folder-{{$index}}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table table-condensed table-striped table-auto">
<tbody>
<tr ng-show="folder.label != undefined && folder.label.length > 0">
<th><span class="fas fa-fw fa-info-circle"></span>&nbsp;<span translate>Folder ID</span></th>
<td class="text-right no-overflow-ellipse">{{folder.id}}</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-folder-open"></span>&nbsp;<span translate>Folder Path</span></th>
<td class="text-right">
<span tooltip data-original-title="{{folder.path}}">{{folder.path}}</span>
</td>
</tr>
<tr ng-if="!folder.paused && (model[folder.id].invalid || model[folder.id].error)">
<th><span class="fas fa-fw fa-exclamation-triangle"></span>&nbsp;<span translate>Error</span></th>
<td class="text-right">{{model[folder.id].invalid || model[folder.id].error}}</td>
</tr>
<tr ng-if="!folder.paused">
<th><span class="fas fa-fw fa-globe"></span>&nbsp;<span translate>Global State</span></th>
<td class="text-right">
<span tooltip data-original-title="{{model[folder.id].globalFiles | alwaysNumber | localeNumber}} {{'files' | translate}}, {{model[folder.id].globalDirectories | alwaysNumber | localeNumber}} {{'directories' | translate}}, ~{{model[folder.id].globalBytes | binary}}B">
<span class="far fa-copy"></span>&nbsp;{{model[folder.id].globalFiles | alwaysNumber | localeNumber}}&ensp;
<span class="far fa-folder"></span>&nbsp;{{model[folder.id].globalDirectories | alwaysNumber | localeNumber}}&ensp;
<span class="far fa-hdd"></span>&nbsp;~{{model[folder.id].globalBytes | binary}}B
</span>
</td>
</tr>
<tr ng-if="!folder.paused">
<th><span class="fas fa-fw fa-home"></span>&nbsp;<span translate>Local State</span></th>
<td class="text-right">
<span tooltip data-original-title="{{model[folder.id].localFiles | alwaysNumber | localeNumber}} {{'files' | translate}}, {{model[folder.id].localDirectories | alwaysNumber | localeNumber}} {{'directories' | translate}}, ~{{model[folder.id].localBytes | binary}}B">
<span class="far fa-copy"></span>&nbsp;{{model[folder.id].localFiles | alwaysNumber | localeNumber}}&ensp;
<span class="far fa-folder"></span>&nbsp;{{model[folder.id].localDirectories | alwaysNumber | localeNumber}}&ensp;
<span class="far fa-hdd"></span>&nbsp;~{{model[folder.id].localBytes | binary}}B<!-- get rid of the annoying trailing whitespace
--><span ng-if="model[folder.id].ignorePatterns"><br/><i><small translate class="text-muted">Reduced by ignore patterns</small></i></span>
</span>
</td>
</tr>
<tr ng-if="model[folder.id].needTotalItems > 0">
<th><span class="fas fa-fw fa-cloud-download-alt"></span>&nbsp;<span translate>Out of Sync Items</span></th>
<td class="text-right">
<a href="" ng-click="showNeed(folder.id)">{{model[folder.id].needTotalItems | alwaysNumber | localeNumber}} <span translate>items</span>, ~{{model[folder.id].needBytes | binary}}B</a>
</td>
</tr>
<tr ng-if="folderStatus(folder) === 'scanning' && scanRate(folder.id) > 0">
<th><span class="fas fa-fw fa-hourglass-half"></span>&nbsp;<span translate>Scan Time Remaining</span></th>
<td class="text-right">
<span tooltip data-original-title="{{scanRate(folder.id) | binary}}B/s">~ {{scanRemaining(folder.id)}}</span>
</td>
</tr>
<tr ng-if="hasFailedFiles(folder.id)">
<th><span class="fas fa-fw fa-exclamation-circle"></span>&nbsp;<span translate>Failed Items</span></th>
<!-- Show the number of failed items as a link to bring up the list. -->
<td class="text-right">
<a href="" ng-click="showFailed(folder.id)">{{model[folder.id].pullErrors | alwaysNumber | localeNumber}}&nbsp;<span translate>items</span></a>
</td>
</tr>
<tr ng-if="hasReceiveOnlyChanged(folder)">
<th><span class="fas fa-fw fa-exclamation-circle"></span>&nbsp;<span translate>Locally Changed Items</span></th>
<td class="text-right">
<a href="" ng-click="showLocalChanged(folder.id, folder.type)">{{model[folder.id].receiveOnlyTotalItems | alwaysNumber | localeNumber}} <span translate>items</span>, ~{{model[folder.id].receiveOnlyChangedBytes | binary}}B</a>
</td>
</tr>
<tr ng-if="hasReceiveEncryptedItems(folder)">
<th><span class="fas fa-fw fa-exclamation-circle"></span>&nbsp;<span translate>Locally Changed Items</span></th>
<td class="text-right">
<a href="" ng-click="showLocalChanged(folder.id, folder.type)">{{receiveEncryptedItemsCount(folder) | alwaysNumber | localeNumber}} <span translate>items</span>, ~{{model[folder.id].receiveOnlyChangedBytes | binary}}B</a>
</td>
</tr>
<tr ng-if="folder.type != 'sendreceive'">
<th><span class="fas fa-fw fa-folder"></span>&nbsp;<span translate>Folder Type</span></th>
<td class="text-right">
<span ng-if="folder.type == 'sendonly'" translate>Send Only</span>
<span ng-if="folder.type == 'receiveonly'" translate>Receive Only</span>
<span ng-if="folder.type == 'receiveencrypted'" translate>Receive Encrypted</span>
</td>
</tr>
<tr ng-if="folder.ignorePerms">
<th><span class="far fa-fw fa-minus-square"></span>&nbsp;<span translate>Ignore Permissions</span></th>
<td class="text-right">
<span translate>Yes</span>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-refresh"></span>&nbsp;<span translate>Rescans</span></th>
<td class="text-right">
<div ng-if="folder.rescanIntervalS > 0">
<span ng-if="!folder.fsWatcherEnabled" tooltip data-original-title="{{'Periodic scanning at given interval and disabled watching for changes' | translate}}">
<span class="far fa-clock"></span>&nbsp;{{folder.rescanIntervalS | duration}}&ensp;
<span class="fas fa-eye-slash"></span>&nbsp;<span translate>Disabled</span>
</span>
<span ng-if="folder.fsWatcherEnabled && (!model[folder.id].watchError || folder.paused || folderStatus(folder) === 'stopped')" tooltip data-original-title="{{'Periodic scanning at given interval and enabled watching for changes' | translate}}">
<span class="far fa-clock"></span>&nbsp;{{folder.rescanIntervalS | duration}}&ensp;
<span class="fas fa-eye"></span>&nbsp;<span translate>Enabled</span>
</span>
<span ng-if="folder.fsWatcherEnabled && !folder.paused && folderStatus(folder) !== 'stopped' && model[folder.id].watchError" tooltip data-original-title="{{'Periodic scanning at given interval and failed setting up watching for changes, retrying every 1m:' | translate}}<br/>{{model[folder.id].watchError}}">
<span class="far fa-clock"></span>&nbsp;{{folder.rescanIntervalS | duration}}&ensp;
<span class="fas fa-eye-slash"></span>&nbsp;<span translate>Failed to setup, retrying</span>
</span>
</div>
<div ng-if="folder.rescanIntervalS <= 0">
<span ng-if="!folder.fsWatcherEnabled" tooltip data-original-title="{{'Disabled periodic scanning and disabled watching for changes' | translate}}">
<span class="far fa-clock"></span>&nbsp;<span translate>Disabled</span>&ensp;
<span class="fas fa-eye-slash"></span>&nbsp;<span translate>Disabled</span>
</span>
<span ng-if="folder.fsWatcherEnabled && (!model[folder.id].watchError || folder.paused || folderStatus(folder) === 'stopped')" tooltip data-original-title="{{'Disabled periodic scanning and enabled watching for changes' | translate}}">
<span class="far fa-clock"></span>&nbsp;<span translate>Disabled</span>&ensp;
<span class="fas fa-eye"></span>&nbsp;<span translate>Enabled</span>
</span>
<span ng-if="folder.fsWatcherEnabled && !folder.paused && folderStatus(folder) !== 'stopped' && model[folder.id].watchError" tooltip data-original-title="{{'Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:' | translate}}<br/>{{model[folder.id].watchError}}">
<span class="far fa-clock"></span>&nbsp;<span translate>Disabled</span>&ensp;
<span class="fas fa-eye-slash"></span>&nbsp;<span translate>Failed to setup, retrying</span>
</span>
</div>
</td>
</tr>
<tr ng-if="folder.order != 'random' && folder.type != 'sendonly'">
<th><span class="fas fa-fw fa-sort"></span>&nbsp;<span translate>File Pull Order</span></th>
<td class="text-right" ng-switch="folder.order">
<span ng-switch-when="random" translate>Random</span>
<span ng-switch-when="alphabetic" translate>Alphabetic</span>
<span ng-switch-when="smallestFirst" translate>Smallest First</span>
<span ng-switch-when="largestFirst" translate>Largest First</span>
<span ng-switch-when="oldestFirst" translate>Oldest First</span>
<span ng-switch-when="newestFirst" translate>Newest First</span>
</td>
</tr>
<tr ng-if="folder.versioning.type">
<th><span class="far fa-fw fa-copy"></span>&nbsp;<span translate>File Versioning</span></th>
<td class="text-right" ng-switch="folder.versioning.type">
<span ng-switch-when="trashcan" translate>Trash Can File Versioning</span>
<span ng-switch-when="staggered" translate>Staggered File Versioning</span>
<span ng-switch-when="simple" translate>Simple File Versioning</span>
<span ng-switch-when="external" translate>External File Versioning</span>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-share-alt"></span>&nbsp;<span translate>Shared With</span></th>
<td class="text-right" ng-attr-title="{{sharesFolder(folder)}}">{{sharesFolder(folder)}}</td>
</tr>
<tr ng-if="folderStats[folder.id].lastScan">
<th><span class="far fa-fw fa-clock"></span>&nbsp;<span translate>Last Scan</span></th>
<td translate ng-if="folderStats[folder.id].lastScanDays >= 365" class="text-right">Never</td>
<td ng-if="folderStats[folder.id].lastScanDays < 365" class="text-right">
<span>{{folderStats[folder.id].lastScan | date:'yyyy-MM-dd HH:mm:ss'}}</span>
</td>
</tr>
<tr ng-if="folder.type != 'sendonly' && folder.type != 'receiveencrypted' && folderStats[folder.id].lastFile && folderStats[folder.id].lastFile.filename">
<th><span class="fas fa-fw fa-exchange-alt"></span>&nbsp;<span translate>Latest Change</span></th>
<td class="text-right">
<span tooltip data-original-title="{{folderStats[folder.id].lastFile.filename}} @ {{folderStats[folder.id].lastFile.at | date:'yyyy-MM-dd HH:mm:ss'}}">
<span translate ng-if="!folderStats[folder.id].lastFile.deleted">Updated</span>
<span translate ng-if="folderStats[folder.id].lastFile.deleted">Deleted</span>
{{folderStats[folder.id].lastFile.filename | basename}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-danger pull-left" ng-click="override(folder.id)" ng-if="folderStatus(folder) == 'outofsync' && folder.type == 'sendonly'">
<span class="fas fa-arrow-circle-up"></span>&nbsp;<span translate>Override Changes</span>
</button>
<button type="button" class="btn btn-sm btn-danger pull-left" ng-click="revert(folder.id)" ng-if="hasReceiveOnlyChanged(folder)">
<span class="fa fa-arrow-circle-down"></span>&nbsp;<span translate>Revert Local Changes</span>
</button>
<button type="button" class="btn btn-sm btn-danger pull-left" ng-click="deleteEncryptionModal(folder.id)" ng-if="hasReceiveEncryptedItems(folder)">
<span class="fa fa-arrow-lock"></span>&nbsp;<span translate>Delete Unexpected Items</span>
</button>
<span class="pull-right">
<button ng-if="!folder.paused" type="button" class="btn btn-sm btn-default" ng-click="setFolderPause(folder.id, true)">
<span class="fas fa-pause"></span>&nbsp;<span translate>Pause</span>
</button>
<button ng-if="folder.paused" type="button" class="btn btn-sm btn-default" ng-click="setFolderPause(folder.id, false)">
<span class="fas fa-play"></span>&nbsp;<span translate>Resume</span>
</button>
<button type="button" class="btn btn-default btn-sm" ng-click="restoreVersions.show(folder.id)" ng-if="folder.versioning.type && folder.versioning.type != 'external'">
<span class="fas fa-undo"></span>&nbsp;<span translate>Versions</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="rescanFolder(folder.id)" ng-disabled="['idle', 'stopped', 'unshared', 'outofsync', 'faileditems', 'localadditions'].indexOf(folderStatus(folder)) < 0">
<span class="fas fa-refresh"></span>&nbsp;<span translate>Rescan</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="editFolderExisting(folder)">
<span class="fas fa-pencil-alt"></span>&nbsp;<span translate>Edit</span>
</button>
</span>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<span class="pull-right">
<button type="button" class="btn btn-sm btn-default" ng-click="setAllFoldersPause(true)" ng-if="isAtleastOneFolderPausedStateSetTo(false)">
<span class="fas fa-pause"></span>&nbsp;<span translate>Pause All</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="setAllFoldersPause(false)" ng-if="isAtleastOneFolderPausedStateSetTo(true)">
<span class="fas fa-play"></span>&nbsp;<span translate>Resume All</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="rescanAllFolders()" ng-if="folderList().length > 0" ng-disabled="!isAtleastOneFolderPausedStateSetTo(false)">
<span class="fas fa-refresh"></span>&nbsp;<span translate>Rescan All</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="addFolder()">
<span class="fas fa-plus"></span>&nbsp;<span translate>Add Folder</span>
</button>
</span>
<div class="clearfix"></div>
<hr class="visible-sm"/>
</div>
<!-- Device list (top right) -->
<!-- This device -->
<div class="col-md-6" aria-label="{{'Devices' | translate}}" role="region">
<h3 translate>This Device</h3>
<div class="panel panel-default" ng-repeat="deviceCfg in [thisDevice()]">
<button class="btn panel-heading" data-toggle="collapse" data-target="#device-this" aria-expanded="true">
<h4 class="panel-title">
<identicon class="panel-icon" data-value="deviceCfg.deviceID"></identicon>
<div class="panel-title-text">{{deviceName(deviceCfg)}}</div>
</h4>
</button>
<div id="device-this" class="panel-collapse collapse in">
<div class="panel-body">
<table class="table table-condensed table-striped table-auto">
<tbody>
<tr>
<th><span class="fas fa-fw fa-cloud-download-alt"></span>&nbsp;<span translate>Download Rate</span></th>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connectionsTotal.inbps | binary}}B/s</span>
<span ng-if="metricRates">{{connectionsTotal.inbps*8 | metric}}bps</span>
({{connectionsTotal.inBytesTotal | binary}}B)
<small ng-if="config.options.maxRecvKbps > 0"><br/>
<i class="text-muted"><span translate>Limit</span>:
<span ng-if="!metricRates">{{config.options.maxRecvKbps*1024 | binary}}B/s</span>
<span ng-if="metricRates">{{config.options.maxRecvKbps*1024*8 | metric}}bps</span>
</i>
</small>
</a>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-cloud-upload-alt"></span>&nbsp;<span translate>Upload Rate</span></th>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connectionsTotal.outbps | binary}}B/s</span>
<span ng-if="metricRates">{{connectionsTotal.outbps*8 | metric}}bps</span>
({{connectionsTotal.outBytesTotal | binary}}B)
<small ng-if="config.options.maxSendKbps > 0"><br/>
<i class="text-muted"><span translate>Limit</span>:
<span ng-if="!metricRates">{{config.options.maxSendKbps*1024 | binary}}B/s</span>
<span ng-if="metricRates">{{config.options.maxSendKbps*1024*8 | metric}}bps</span>
</i>
</small>
</a>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-home"></span>&nbsp;<span translate>Local State (Total)</span></th>
<td class="text-right">
<span tooltip data-original-title="{{localStateTotal.files | alwaysNumber | localeNumber}} {{'files' | translate}}, {{ localStateTotal.directories | alwaysNumber | localeNumber}} {{'directories' | translate}}, ~{{ localStateTotal.bytes | binary}}B">
<span class="far fa-copy"></span>&nbsp;{{localStateTotal.files | alwaysNumber | localeNumber}}&ensp;
<span class="far fa-folder"></span>&nbsp;{{localStateTotal.directories| alwaysNumber | localeNumber}}&ensp;
<span class="far fa-hdd"></span>&nbsp;~{{localStateTotal.bytes | binary}}B
</span>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-sitemap"></span>&nbsp;<span translate>Listeners</span></th>
<td class="text-right">
<span ng-if="listenersFailed.length == 0" class="data text-success">
<span>{{listenersTotal}}/{{listenersTotal}}</span>
</span>
<span ng-if="listenersFailed.length != 0" class="data" ng-class="{'text-danger': listenersFailed.length == listenersTotal}">
<span popover data-trigger="hover" data-placement="bottom" data-html="true" data-content="{{listenersFailed.join('<br>\n')}}">
{{listenersTotal-listenersFailed.length}}/{{listenersTotal}}
</span>
</span>
</td>
</tr>
<tr ng-if="system.discoveryEnabled">
<th><span class="fas fa-fw fa-map-signs"></span>&nbsp;<span translate>Discovery</span></th>
<td class="text-right">
<span ng-if="discoveryFailed.length == 0" class="data text-success">
<span>{{discoveryTotal}}/{{discoveryTotal}}</span>
</span>
<span ng-if="discoveryFailed.length != 0" class="data" ng-class="{'text-danger': discoveryFailed.length == discoveryTotal}">
<span popover data-trigger="hover" data-placement="bottom" data-content="{{'Click to see discovery failures' | translate}}.">
<a href="" style="color:inherit" ng-click="showDiscoveryFailures()">{{discoveryTotal-discoveryFailed.length}}/{{discoveryTotal}}</a>
</span>
</span>
</td>
</tr>
<tr>
<th><span class="far fa-fw fa-clock"></span>&nbsp;<span translate>Uptime</span></th>
<td class="text-right">{{system.uptime | duration:"m"}}</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-tag"></span>&nbsp;<span translate>Version</span></th>
<td class="text-right">
<span tooltip data-original-title="{{versionString()}}">{{versionString()}}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Remote devices -->
<h3 translate>Remote Devices</h3>
<div class="panel-group" id="devices">
<div class="panel panel-default" ng-repeat="deviceCfg in otherDevices()">
<button class="btn panel-heading" data-toggle="collapse" data-parent="#devices" data-target="#device-{{$index}}" aria-expanded="false">
<div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | percent}}"></div>
<h4 class="panel-title">
<identicon class="panel-icon" data-value="deviceCfg.deviceID"></identicon>
<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" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
<span ng-switch-when="unused-insync"><span class="hidden-xs" translate>Connected (Unused)</span><span class="visible-xs" aria-label="{{'Connected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
<span ng-switch-when="syncing">
<span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | percent}}, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
</span>
<span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs" aria-label="{{'Paused' | translate}}"><i class="fas fa-fw fa-pause"></i></span></span>
<span ng-switch-when="unused-paused"><span class="hidden-xs" translate>Paused (Unused)</span><span class="visible-xs" aria-label="{{'Paused (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
<span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs" aria-label="{{'Disconnected' | translate}}"><i class="fas fa-fw fa-power-off"></i></span></span>
<span ng-switch-when="unused-disconnected"><span class="hidden-xs" translate>Disconnected (Unused)</span><span class="visible-xs" aria-label="{{'Disconnected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
</span>
<span>{{deviceName(deviceCfg)}}</span>
</h4>
</button>
<div id="device-{{$index}}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table table-condensed table-striped table-auto">
<tbody>
<tr ng-if="!connections[deviceCfg.deviceID].connected">
<th><span class="fas fa-fw fa-eye"></span>&nbsp;<span translate>Last seen</span></th>
<td translate ng-if="!deviceStats[deviceCfg.deviceID].lastSeenDays || deviceStats[deviceCfg.deviceID].lastSeenDays >= 365" class="text-right">Never</td>
<td ng-if="deviceStats[deviceCfg.deviceID].lastSeenDays < 365" class="text-right">{{deviceStats[deviceCfg.deviceID].lastSeen | date:"yyyy-MM-dd HH:mm:ss"}}</td>
</tr>
<tr ng-if="connections[deviceCfg.deviceID].connected">
<th><span class="fas fa-fw fa-cloud-download-alt"></span>&nbsp;<span translate>Download Rate</span></th>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connections[deviceCfg.deviceID].inbps | binary}}B/s</span>
<span ng-if="metricRates">{{connections[deviceCfg.deviceID].inbps*8 | metric}}bps</span>
({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)
<small ng-if="deviceCfg.maxRecvKbps > 0"><br/>
<i class="text-muted"><span translate>Limit</span>:
<span ng-if="!metricRates">{{deviceCfg.maxRecvKbps*1024 | binary}}B/s</span>
<span ng-if="metricRates">{{deviceCfg.maxRecvKbps*1024*8 | metric}}bps</span>
</i>
</small>
</a>
</td>
</tr>
<tr ng-if="connections[deviceCfg.deviceID].connected">
<th><span class="fas fa-fw fa-cloud-upload-alt"></span>&nbsp;<span translate>Upload Rate</span></th>
<td class="text-right">
<a href="#" class="toggler" ng-click="toggleUnits()">
<span ng-if="!metricRates">{{connections[deviceCfg.deviceID].outbps | binary}}B/s</span>
<span ng-if="metricRates">{{connections[deviceCfg.deviceID].outbps*8 | metric}}bps</span>
({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)
<small ng-if="deviceCfg.maxSendKbps > 0"><br/>
<i class="text-muted"><span translate>Limit</span>:
<span ng-if="!metricRates">{{deviceCfg.maxSendKbps*1024 | binary}}B/s</span>
<span ng-if="metricRates">{{deviceCfg.maxSendKbps*1024*8 | metric}}bps</span>
</i>
</small>
</a>
</td>
</tr>
<tr ng-if="deviceStatus(deviceCfg) == 'syncing'">
<th><span class="fas fa-fw fa-exchange-alt"></span>&nbsp;<span translate>Out of Sync Items</span></th>
<td class="text-right">
<a href="" ng-click="showRemoteNeed(deviceCfg)">{{completion[deviceCfg.deviceID]._needItems | alwaysNumber | localeNumber}} <span translate>items</span>, ~{{completion[deviceCfg.deviceID]._needBytes | binary}}B</a>
</td>
</tr>
<tr>
<th><span class="fas fa-fw fa-link"></span>&nbsp<span translate>Address</span></th>
<td ng-if="connections[deviceCfg.deviceID].connected" class="text-right">
<span tooltip data-original-title="{{ connections[deviceCfg.deviceID].type.indexOf('Relay') > -1 ? '' : connections[deviceCfg.deviceID].type }} {{ connections[deviceCfg.deviceID].crypto }}">
{{deviceAddr(deviceCfg)}}
</span>
</td>
<td ng-if="!connections[deviceCfg.deviceID].connected" class="text-right">
<span ng-repeat="addr in deviceCfg.addresses">
<span tooltip data-original-title="{{'Configured' | translate}}">{{addr}}</span><br>
<small ng-if="system.lastDialStatus[addr].error" tooltip data-original-title="{{system.lastDialStatus[addr].error}}" class="text-danger">{{abbreviatedError(addr)}}<br></small>
</span>
<span ng-repeat="addr in discoveryCache[deviceCfg.deviceID].addresses">
<span tooltip data-original-title="{{'Discovered' | translate}}">{{addr}}</span><br>
<small ng-if="system.lastDialStatus[addr].error" tooltip data-original-title="{{system.lastDialStatus[addr].error}}" class="text-danger">{{abbreviatedError(addr)}}<br></small>
</span>
</td>
</tr>
<tr ng-if="connections[deviceCfg.deviceID].connected && connections[deviceCfg.deviceID].type.indexOf('Relay') > -1" tooltip data-original-title="Connections via relays might be rate limited by the relay">
<th><span class="fas fa-fw fa-exclamation-triangle text-danger"></span>&nbsp;<span translate>Connection Type</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].type}}</td>
</tr>
<tr ng-if="deviceCfg.allowedNetworks.length > 0">
<th><span class="fas fa-fw fa-filter"></span>&nbsp;<span translate>Allowed Networks</span></th>
<td class="text-right">
<span>{{deviceCfg.allowedNetworks.join(", ")}}</span>
</td>
</tr>
<tr ng-if="deviceCfg.compression != 'metadata'">
<th><span class="fas fa-fw fa-compress"></span>&nbsp;<span translate>Compression</span></th>
<td class="text-right">
<span ng-if="deviceCfg.compression == 'always'" translate>All Data</span>
<span ng-if="deviceCfg.compression == 'never'" translate>Off</span>
</td>
</tr>
<tr ng-if="deviceCfg.introducer">
<th><span class="far fa-fw fa-thumbs-up"></span>&nbsp;<span translate>Introducer</span></th>
<td translate class="text-right">Yes</td>
</tr>
<tr ng-if="deviceCfg.introducedBy">
<th><span class="far fa-fw fa-handshake-o"></span>&nbsp;<span translate>Introduced By</span></th>
<td class="text-right">{{ deviceName(devices[deviceCfg.introducedBy]) || deviceCfg.introducedBy.substring(0, 5) }}</td>
</tr>
<tr ng-if="connections[deviceCfg.deviceID].clientVersion">
<th><span class="fas fa-fw fa-tag"></span>&nbsp;<span translate>Version</span></th>
<td class="text-right">{{connections[deviceCfg.deviceID].clientVersion}}</td>
</tr>
<tr ng-if="deviceFolders(deviceCfg).length > 0">
<th><span class="fas fa-fw fa-folder"></span>&nbsp;<span translate>Folders</span></th>
<td class="text-right" ng-attr-title="{{deviceFolders(deviceCfg).map(folderLabel).join(', ')}}">{{deviceFolders(deviceCfg).map(folderLabel).join(", ")}}</td>
</tr>
<tr ng-if="deviceCfg.remoteGUIPort > 0">
<th><span class="fas fa-fw fa-desktop"></span>&nbsp;<span translate>Remote GUI</span></th>
<td class="text-right" ng-attr-title="Port {{deviceCfg.remoteGUIPort}}">
<!-- Apply RFC6874 encoding for IPv6 link-local zone identifier -->
<a ng-if="hasRemoteGUIAddress(deviceCfg)" href="{{remoteGUIAddress(deviceCfg).replace('%', '%25')}}">{{remoteGUIAddress(deviceCfg)}}</a>
<span translate ng-if="!hasRemoteGUIAddress(deviceCfg)">Unknown</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-footer">
<span class="pull-right">
<button ng-if="!deviceCfg.paused" type="button" class="btn btn-sm btn-default" ng-click="setDevicePause(deviceCfg.deviceID, true)">
<span class="fas fa-pause"></span>&nbsp;<span translate>Pause</span>
</button>
<button ng-if="deviceCfg.paused" type="button" class="btn btn-sm btn-default" ng-click="setDevicePause(deviceCfg.deviceID, false)">
<span class="fas fa-play"></span>&nbsp;<span translate>Resume</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="editDeviceExisting(deviceCfg)">
<span class="fas fa-pencil-alt"></span>&nbsp;<span translate>Edit</span>
</button>
</span>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="form-group">
<span class="pull-right">
<button type="button" class="btn btn-sm btn-default" ng-click="setAllDevicesPause(true)" ng-if="isAtleastOneDevicePausedStateSetTo(false)">
<span class="fas fa-pause"></span>&nbsp;<span translate>Pause All</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="setAllDevicesPause(false)" ng-if="isAtleastOneDevicePausedStateSetTo(true)">
<span class="fas fa-play"></span>&nbsp;<span translate>Resume All</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="globalChanges()">
<span class="fas fa-fw fa-info-circle"></span>&nbsp;<span translate>Recent Changes</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="addDevice()">
<span class="fas fa-plus"></span>&nbsp;<span translate>Add Remote Device</span>
</button>
</span>
<div class="clearfix"></div>
</div>
</div>
</div> <!-- /row -->
</div> <!-- /container -->
</div> <!-- /ng-cloak -->
<!-- Bottom bar -->
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container">
<ul class="nav navbar-nav">
<li><a class="navbar-link" href="https://syncthing.net/" target="_blank"><span class="fas fa-home"></span>&nbsp;<span translate>Home page</span></a></li>
<li><a class="navbar-link" href="https://docs.syncthing.net/" target="_blank"><span class="fas fa-book"></span>&nbsp;<span translate>Documentation</span></a></li>
<li><a class="navbar-link" href="https://forum.syncthing.net" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Support</span></a></li>
<li><a class="navbar-link" href="https://data.syncthing.net/" target="_blank"><span class="fas fa-bar-chart"></span>&nbsp;<span translate>Statistics</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing/releases" target="_blank"><span class="far fa-file-alt"></span>&nbsp;<span translate>Changelog</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing/issues" target="_blank"><span class="fas fa-bug"></span>&nbsp;<span translate>Bugs</span></a></li>
<li><a class="navbar-link" href="https://github.com/syncthing/syncthing" target="_blank"><span class="fas fa-wrench"></span>&nbsp;<span translate>Source Code</span></a></li>
<li><a class="navbar-link" href="https://twitter.com/syncthing" target="_blank"><span class="fab fa-twitter"></span>&nbsp;Twitter</a></li>
</ul>
</div>
</nav>
<ng-include src="'syncthing/core/networkErrorDialogView.html'"></ng-include>
<ng-include src="'syncthing/core/httpErrorDialogView.html'"></ng-include>
<ng-include src="'syncthing/core/restartingDialogView.html'"></ng-include>
<ng-include src="'syncthing/core/upgradingDialogView.html'"></ng-include>
<ng-include src="'syncthing/core/shutdownDialogView.html'"></ng-include>
<ng-include src="'syncthing/device/idqrModalView.html'"></ng-include>
<ng-include src="'syncthing/device/editDeviceModalView.html'"></ng-include>
<ng-include src="'syncthing/device/globalChangesModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/editFolderModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/restoreVersionsModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/restoreVersionsConfirmation.html'"></ng-include>
<ng-include src="'syncthing/settings/settingsModalView.html'"></ng-include>
<ng-include src="'syncthing/settings/advancedSettingsModalView.html'"></ng-include>
<ng-include src="'syncthing/settings/discardChangesConfirmation.html'"></ng-include>
<ng-include src="'syncthing/usagereport/usageReportModalView.html'"></ng-include>
<ng-include src="'syncthing/usagereport/usageReportPreviewModalView.html'"></ng-include>
<ng-include src="'syncthing/transfer/neededFilesModalView.html'"></ng-include>
<ng-include src="'syncthing/transfer/failedFilesModalView.html'"></ng-include>
<ng-include src="'syncthing/transfer/remoteNeededFilesModalView.html'"></ng-include>
<ng-include src="'syncthing/transfer/localChangedFilesModalView.html'"></ng-include>
<ng-include src="'syncthing/core/upgradeModalView.html'"></ng-include>
<ng-include src="'syncthing/core/majorUpgradeModalView.html'"></ng-include>
<ng-include src="'syncthing/core/aboutModalView.html'"></ng-include>
<ng-include src="'syncthing/core/discoveryFailuresModalView.html'"></ng-include>
<ng-include src="'syncthing/folder/removeFolderDialogView.html'"></ng-include>
<ng-include src="'syncthing/folder/deleteEncryptionFolderDialogView.html'"></ng-include>
<ng-include src="'syncthing/device/removeDeviceDialogView.html'"></ng-include>
<ng-include src="'syncthing/core/logViewerModalView.html'"></ng-include>
<!-- vendor scripts -->
<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/moment/moment.js"></script>
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="vendor/daterangepicker/daterangepicker.js"></script>
<script type="text/javascript" src="vendor/fancytree/jquery.fancytree-all-deps.js"></script>
<!-- / vendor scripts -->
<!-- gui application code -->
<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/localeNumberFilter.js"></script>
<script type="text/javascript" src="syncthing/core/percentFilter.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/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>
</html>

View File

@@ -0,0 +1,40 @@
<div class="col-md-6 checkbox">
<label for="sharedwith-{{id}}">
<input id="sharedwith-{{id}}" ng-model="selected[id]" type="checkbox" />
<span tooltip data-original-title="{{id}}">{{label}}</span>
</label>
</div>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" ng-switch="folderType !== 'receiveencrypted' && !encryptionPasswords[id]">
<span ng-switch-when='true' class="fas fa-fw fa-unlock" />
<span ng-switch-default class="fas fa-fw fa-lock" />
</span>
<span ng-switch="folderType === 'receiveencrypted'">
<span ng-switch-when='true'>
<input class="form-control input-sm" type="password" placeholder="{{'Received data is already encrypted' | translate}}" disabled />
</span>
<span ng-switch-default ng-switch="selected[id]">
<span ng-switch-when='true' ng-switch="untrusted">
<span ng-switch-when='true' ng-class="{'has-error': !encryptionPasswords[id]}">
<input class="form-control input-sm" type="{{plain ? 'text' : 'password'}}" ng-model="encryptionPasswords[id]" required placeholder="{{'Device is untrusted, enter encryption password' | translate}}" />
</span>
<span ng-switch-default>
<input class="form-control input-sm" type="{{plain ? 'text' : 'password'}}" ng-model="encryptionPasswords[id]" placeholder="{{'If untrusted, enter encryption password' | translate}}" />
</span>
</span>
<span ng-switch-default>
<input class="form-control input-sm" type="password" placeholder="{{'Not shared' | translate}}" disabled />
</span>
</span>
</span>
<span ng-switch="selected[id] && folderType !== 'receiveencrypted'" class="input-group-addon">
<span ng-switch-when='true'>
<span class="button fas fa-fw fa-eye" ng-click="togglePasswordVisibility()" />
</span>
<span ng-switch-default>
<span class="button fas fa-fw fa-eye" disabled />
</span>
</span>
</div>
</div>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,166 @@
<modal id="editDevice" status="default" icon="{{editDeviceModalIcon()}}" heading="{{editDeviceModalTitle()}}" large="yes" closeable="yes">
<div class="modal-body">
<form role="form" name="deviceEditor">
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(deviceEditor)">
<li class="active"><a data-toggle="tab" href="#device-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
<li ng-if="!editingDefaults"><a data-toggle="tab" href="#device-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
<li><a data-toggle="tab" href="#device-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
</ul>
<div class="tab-content">
<div id="device-general" class="tab-pane in active">
<div ng-if="!editingDefaults" class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
<label translate for="deviceID">Device ID</label>
<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 && discovery.length !== 0">
<span translate>You can also select one of these nearby devices:</span>
<ul>
<li ng-repeat="id in discovery"><a href="#" 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>
</div>
<div class="form-group">
<label translate for="name">Device Name</label>
<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>
</div>
<div ng-if="!editingDefaults" id="device-sharing" class="tab-pane">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentDevice.introducer">
<span translate>Introducer</span>
<p translate class="help-block">Add devices from the introducer to our device list, for mutually shared folders.</p>
</label>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="currentDevice.autoAcceptFolders">
<span translate>Auto Accept</span>
<p translate class="help-block">Automatically create or share folders that this device advertises at the default path.</p>
</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="form-horizontal" ng-if="currentSharing.shared.length">
<label translate for="folders">Shared Folders</label>
<p class="help-block">
<span translate>Deselect folders to stop sharing with this device.</span>&emsp;
<small><a href="#" ng-click="selectAllSharedFolders(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllSharedFolders(false)" translate>Deselect All</a></small>
</p>
<div class="form-group" ng-repeat="folder in currentSharing.shared">
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabel(folder.id)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" />
</div>
</div>
<div class="form-horizontal" ng-if="currentSharing.unrelated.length">
<label translate for="folders">Unshared Folders</label>
<p class="help-block" ng-if="folderList().length > 0">
<span translate>Select additional folders to share with this device.</span>&emsp;
<small><a href="#" ng-click="selectAllUnrelatedFolders(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllUnrelatedFolders(false)" translate>Deselect All</a></small>
</p>
<p class="help-block" ng-if="folderList().length == 0">
<span translate>There are no folders to share with this device.</span>
</p>
<div class="form-group" ng-repeat="folder in currentSharing.unrelated">
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabel(folder.id)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" />
</div>
</div>
</div>
</div>
<div id="device-advanced" class="tab-pane">
<div class="row form-group">
<div class="col-md-6">
<div class="form-group">
<label translate for="addresses">Addresses</label>
<input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice._addressesStr"></input>
<p translate class="help-block">Enter comma separated ("tcp://ip:port", "tcp://host:port") addresses or "dynamic" to perform automatic discovery of the address.</p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label translate>Compression</label>
<select class="form-control" ng-model="currentDevice.compression">
<option value="always" translate>All Data</option>
<option value="metadata" translate>Metadata Only</option>
<option value="never" translate>Off</option>
</select>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<label translate>Device rate limits</label>
<div class="row">
<div class="col-md-6" ng-class="{'has-error': deviceEditor.maxRecvKbps.$invalid && deviceEditor.maxRecvKbps.$dirty}">
<div class="row">
<span class="col-md-8" translate>Incoming Rate Limit (KiB/s)</span>
<div class="col-md-4">
<input name="maxRecvKbps" id="maxRecvKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxRecvKbps" min="0" />
</div>
</div>
<p class="help-block" ng-if="!deviceEditor.maxRecvKbps.$valid && deviceEditor.maxRecvKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
</div>
<div class="col-md-6" ng-class="{'has-error': deviceEditor.maxSendKbps.$invalid && deviceEditor.maxSendKbps.$dirty}">
<div class="row">
<span class="col-md-8" translate>Outgoing Rate Limit (KiB/s)</span>
<div class="col-md-4">
<input name="maxSendKbps" id="maxSendKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxSendKbps" min="0" />
</div>
</div>
<p class="help-block" ng-if="!deviceEditor.maxSendKbps.$valid && deviceEditor.maxSendKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-6">
<input type="checkbox" id="untrusted" ng-model="currentDevice.untrusted" />
<label for="untrusted" translate>Untrusted</label>
<p translate class="help-block">All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.</p>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid">
<span class="fas fa-check"></span>&nbsp;<span translate>Save</span>
</button>
<button ng-if="!editingDefaults" type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#idqr" ng-if="editingExisting || deviceEditor.deviceID.$valid">
<span class="fas fa-qrcode"></span>&nbsp;<span translate>Show QR</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
</button>
<div ng-if="editingExisting && !editingDefaults" class="pull-left">
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#remove-device-confirmation">
<span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
</button>
</div>
</div>
</modal>

View File

@@ -0,0 +1,19 @@
<modal id="delete-encryption-confirmation" status="danger" icon="fas fa-question-circle" heading="{{'Delete Unexpected Items' | translate}}" large="no" closeable="yes">
<div class="modal-body">
<p>
<span translate>Unexpected items have been found in this folder.</span></br>
<span translate translate-value-receive-encrypted="{{'Receive Encrypted' | translate}}">You should never add or change anything locally in a "{%receiveEncrypted%}" folder.</span>
</p>
<p translate>
Are you sure you want to permanently delete all these files?
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger pull-left btn-sm" data-dismiss="modal" ng-click="revert(revertEncryptionFolder)">
<span class="fas fa-check"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>
</modal>

View File

@@ -0,0 +1,280 @@
<modal id="editFolder" status="default" icon="{{editFolderModalIcon()}}" heading="{{editFolderModalTitle()}}" large="yes" closeable="yes">
<div class="modal-body">
<form role="form" name="folderEditor">
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(folderEditor)">
<li class="active"><a data-toggle="tab" href="#folder-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
<li><a data-toggle="tab" href="#folder-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
<li><a data-toggle="tab" href="#folder-versioning"><span class="fas fa-copy"></span> <span translate>File Versioning</span></a></li>
<li ng-if="!editingDefaults"><a data-toggle="tab" href="#folder-ignores"><span class="fas fa-filter"></span> <span translate>Ignore Patterns</span></a></li>
<li><a data-toggle="tab" href="#folder-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
</ul>
<div class="tab-content">
<div id="folder-general" class="tab-pane in active">
<div class="form-group" ng-class="{'has-error': folderEditor.folderLabel.$invalid && folderEditor.folderLabel.$dirty && !editingDefaults}">
<label for="folderLabel"><span translate>Folder Label</span></label>
<input name="folderLabel" id="folderLabel" class="form-control" type="text" ng-model="currentFolder.label" value="{{currentFolder.label}}" />
<p class="help-block">
<span translate ng-if="folderEditor.folderLabel.$valid || folderEditor.folderLabel.$pristine">Optional descriptive label for the folder. Can be different on each device.</span>
</p>
</div>
<div ng-if="!editingDefaults" 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="" 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>
<span translate ng-if="folderEditor.folderID.$error.required && folderEditor.folderID.$dirty">The folder ID cannot be blank.</span>
<span translate ng-show="!editingExisting">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.</span>
</p>
</div>
<div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty && !editingDefaults}">
<label translate for="folderPath">Folder Path</label>
<input name="folderPath" ng-readonly="editingExisting && !editingDefaults" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" ng-required="!editingDefaults" ng-aria-required="!editingDefaults" path-is-sub-dir />
<datalist id="directory-list">
<option ng-repeat="directory in directoryList" value="{{ directory }}" />
</datalist>
<p class="help-block">
<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 && !editingDefaults">The folder path cannot be blank.</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 ng-if="folderPathErrors.isParent && !editingDefaults">
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="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.otherLabel.length != 0">Warning, this path is a parent directory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
</span>
</p>
</div>
</div>
<div id="folder-sharing" class="tab-pane">
<div class="form-horizontal" ng-if="currentSharing.shared.length">
<label translate>Currently Shared With Devices</label>
<p class="help-block">
<span translate>Deselect devices to stop sharing this folder with.</span>&emsp;
<small><a href="#" ng-click="selectAllSharedDevices(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllSharedDevices(false)" translate>Deselect All</a></small>
</p>
<div class="form-group" ng-repeat="device in currentSharing.shared">
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{device.deviceID}}" label="{{deviceName(device)}}" folder-type="{{currentFolder.type}}" untrusted="device.untrusted" />
</div>
</div>
<div class="form-horizontal" ng-if="currentSharing.unrelated.length || otherDevices().length <= 0">
<label translate>Unshared Devices</label>
<p class="help-block" ng-if="otherDevices().length > 0">
<span translate>Select additional devices to share this folder with.</span>&emsp;
<small><a href="#" ng-click="selectAllUnrelatedDevices(true)" translate>Select All</a>&emsp;
<a href="#" ng-click="selectAllUnrelatedDevices(false)" translate>Deselect All</a></small>
</p>
<p class="help-block" ng-if="otherDevices().length <= 0">
<span translate>There are no devices to share this folder with.</span>
</p>
<div class="form-group" ng-repeat="device in currentSharing.unrelated" ng-init="id = device.deviceID; folder = currentFolder">
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{device.deviceID}}" label="{{deviceName(device)}}" folder-type="{{currentFolder.type}}" untrusted="device.untrusted" />
</div>
</div>
</div>
<div id="folder-versioning" class="tab-pane">
<div class="form-group">
<label translate>File Versioning</label>&emsp;<a href="https://docs.syncthing.net/users/versioning.html" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Help</span></a>
<select class="form-control" ng-model="currentFolder._guiVersioning.selector">
<option value="none" translate>No File Versioning</option>
<option value="trashcan" translate>Trash Can File Versioning</option>
<option value="simple" translate>Simple File Versioning</option>
<option value="staggered" translate>Staggered File Versioning</option>
<option value="external" translate>External File Versioning</option>
</select>
</div>
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='trashcan' || currentFolder._guiVersioning.selectorector=='simple'" ng-class="{'has-error': folderEditor._guiVersioning.trashcanClean.$invalid && folderEditor._guiVersioning.trashcanClean.$dirty}">
<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._guiVersioning.trashcanClean" required="" aria-required="true" min="0" />
<div class="input-group-addon" translate>days</div>
</div>
<p class="help-block">
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$valid || folderEditor._guiVersioning.trashcanClean.$pristine">The number of days to keep files in the trash can. Zero means forever.</span>
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$error.required && folderEditor._guiVersioning.trashcanClean.$dirty">The number of days must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.trashcanClean.$error.min && folderEditor._guiVersioning.trashcanClean.$dirty">A negative number of days doesn't make sense.</span>
</p>
</div>
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='simple'" ng-class="{'has-error': folderEditor._guiVersioning.simpleKeep.$invalid && folderEditor._guiVersioning.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._guiVersioning.simpleKeep" required="" aria-required="true" min="1" />
<p class="help-block">
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$valid || folderEditor._guiVersioning.simpleKeep.$pristine">The number of old versions to keep, per file.</span>
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$error.required && folderEditor._guiVersioning.simpleKeep.$dirty">The number of versions must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.simpleKeep.$error.min && folderEditor._guiVersioning.simpleKeep.$dirty">You must keep at least one version.</span>
</p>
</div>
<div class="form-group" ng-if="currentFolder._guiVersioning.selector=='staggered'" ng-class="{'has-error': folderEditor._guiVersioning.staggeredMaxAge.$invalid && folderEditor._guiVersioning.staggeredMaxAge.$dirty}">
<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._guiVersioning.staggeredMaxAge" required="" aria-required="true" min="0" />
<p class="help-block">
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$valid || folderEditor._guiVersioning.staggeredMaxAge.$pristine">The maximum time to keep a version (in days, set to 0 to keep versions forever).</span>
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$error.required && folderEditor._guiVersioning.staggeredMaxAge.$dirty">The maximum age must be a number and cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.staggeredMaxAge.$error.min && folderEditor._guiVersioning.staggeredMaxAge.$dirty">A negative number of days doesn't make sense.</span>
</p>
</div>
<div class="form-group" ng-if="internalVersioningEnabled()">
<label translate for="fsPath">Versions Path</label>
<input name="fsPath" id="fsPath" class="form-control" type="text" ng-model="currentFolder.versioning.fsPath" />
<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._guiVersioning.selector=='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. If the path to the application contains spaces, it should be quoted.</p>
<label translate for="externalCommand">Command</label>
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder._guiVersioning.externalCommand" required="" aria-required="true" />
<p class="help-block">
<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>
<div class="form-group" ng-if="internalVersioningEnabled()" ng-class="{'has-error': folderEditor._guiVersioning.cleanupIntervalS.$invalid && folderEditor._guiVersioning.cleanupIntervalS.$dirty}">
<label translate for="versioningCleanupIntervalS">Cleanup Interval</label>
<div class="input-group">
<input name="versioningCleanupIntervalS" id="versioningCleanupIntervalS" class="form-control text-right" type="number" ng-model="currentFolder._guiVersioning.cleanupIntervalS" required="" min="0" max="31536000" aria-required="true" />
<div class="input-group-addon" translate>seconds</div>
</div>
<p class="help-block">
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$valid || folderEditor._guiVersioning.cleanupIntervalS.$pristine"class="help-block">The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.</span>
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$error.required && folderEditor._guiVersioning.cleanupIntervalS.$dirty">The cleanup interval cannot be blank.</span>
<span translate ng-if="folderEditor._guiVersioning.cleanupIntervalS.$error.min && folderEditor._guiVersioning.cleanupIntervalS.$dirty">The interval must be a positive number of seconds.</span>
</p>
</div>
</div>
<div ng-if="!editingDefaults" id="folder-ignores" class="tab-pane">
<p translate>Enter ignore patterns, one per line.</p>
<div ng-class="{'has-error': ignores.error != null}">
<textarea class="form-control" rows="5" ng-model="ignores.text" ng-disabled="ignores.disabled"></textarea>
<p class="help-block" ng-if="ignores.error">
{{ignores.error}}
</p>
</div>
<hr />
<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>
<dt><code>//</code></dt>
<dd><span translate>Comment, when used at the start of a line</span></dd>
</dl>
<hr />
<span translate ng-show="editingExisting" translate-value-path="{{currentFolder.path}}{{system.pathSeparator}}.stignore">Editing {%path%}.</span>
<span translate ng-show="!editingExisting" translate-value-path="{{currentFolder.path}}{{system.pathSeparator}}.stignore">Creating ignore patterns, overwriting an existing file at {%path%}.</span>
</div>
<div id="folder-advanced" class="tab-pane">
<div class="row form-group" ng-class="{'has-error': folderEditor.rescanIntervalS.$invalid && folderEditor.rescanIntervalS.$dirty}">
<div class="col-md-12">
<label translate>Scanning</label>
&nbsp;<a href="https://docs.syncthing.net/users/syncing.html#scanning" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Help</span></a></br>
<div class="row">
<div class="col-md-6">
<label>
<input type="checkbox" ng-model="currentFolder.fsWatcherEnabled" ng-change="fsWatcherToggled()" tooltip data-original-title="{{'Use notifications from the filesystem to detect changed items.' | translate }}">&nbsp;<span translate>Watch for Changes</span>
</label>
<p translate class="help-block">Watching for changes discovers most changes without periodic scanning.</p>
</div>
<div class="col-md-6">
<label for="rescanIntervalS" translate>Full Rescan Interval (s)</label>
<input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.rescanIntervalS" required="" aria-required="true" min="0" />
<p class="help-block" ng-if="!folderEditor.rescanIntervalS.$valid && folderEditor.rescanIntervalS.$dirty" translate>
The rescan interval must be a non-negative number of seconds.
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 form-group">
<label translate>Folder Type</label>
&nbsp;<a href="https://docs.syncthing.net/users/foldertypes.html" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Help</span></a>
<select class="form-control" ng-model="currentFolder.type" ng-disabled="editingExisting && currentFolder.type === 'receiveencrypted'">
<option value="sendreceive" translate>Send &amp; Receive</option>
<option value="sendonly" translate>Send Only</option>
<option value="receiveonly" translate>Receive Only</option>
<option value="receiveencrypted" ng-disabled="editingExisting" translate>Receive Encrypted</option>
</select>
<p ng-if="currentFolder.type == 'sendonly'" translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
<p ng-if="currentFolder.type == 'receiveonly'" translate class="help-block">Files are synchronized from the cluster, but any changes made locally will not be sent to other devices.</p>
<p ng-if="currentFolder.type == 'receiveencrypted'" translate class="help-block" translate-value-receive-encrypted="{{'Receive Encrypted' | translate}}">Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type "{%receiveEncrypted%}" too.</p>
<p ng-if="editingExisting" translate class="help-block" translate-value-receive-encrypted="{{'Receive Encrypted' | translate}}">Folder type "{%receiveEncrypted%}" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.</p>
</div>
<div class="col-md-6 form-group">
<label translate>File Pull Order</label>
<select class="form-control" ng-model="currentFolder.order" ng-if="currentFolder.type != 'sendonly'">
<option value="random" translate>Random</option>
<option value="alphabetic" translate>Alphabetic</option>
<option value="smallestFirst" translate>Smallest First</option>
<option value="largestFirst" translate>Largest First</option>
<option value="oldestFirst" translate>Oldest First</option>
<option value="newestFirst" translate>Newest First</option>
</select>
<select class="form-control" ng-if="currentFolder.type == 'sendonly'" disabled>
<option value="disabled" translate>Disabled</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6 form-group" ng-class="{'has-error': folderEditor.minDiskFree.$invalid && folderEditor.minDiskFree.$dirty}">
<label for="minDiskFree" translate>Minimum Free Disk Space</label><br />
<div class="row">
<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="form-control" ng-model="currentFolder.minDiskFree.unit">
<option value="%">%</option>
<option value="kB">kB</option>
<option value="MB">MB</option>
<option value="GB">GB</option>
<option value="TB">TB</option>
</select>
</div>
</div>
<p class="help-block" ng-show="folderEditor.minDiskFree.$invalid" translate>
Enter a non-negative number (e.g., "2.35") and select a unit. Percentages are as part of the total disk size.
</p>
</div>
<div class="col-md-6 form-group">
<label>
<input type="checkbox" ng-model="currentFolder.ignorePerms" /> <span translate>Ignore Permissions</span>
</label>
<p translate class="help-block">
Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).
</p>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="saveFolder()" ng-disabled="folderEditor.$invalid">
<span class="fas fa-check"></span>&nbsp;<span translate>Save</span>
</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
</button>
<button type="button" class="btn btn-warning pull-left btn-sm" data-toggle="modal" data-target="#remove-folder-confirmation" ng-if="editingExisting && !editingDefaults">
<span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
</button>
</div>
</modal>

View File

@@ -0,0 +1,35 @@
<modal id="localChanged" status="{{localChangedType === 'receiveencrypted' ? 'warning' : 'info'}}" icon="fas fa-exclamation-circle" heading="{{localChangedHeading(localChangedType)}}" large="yes" closeable="yes">
<div class="modal-body" ng-switch="localChangedType">
<p ng-switch-when="receiveonly" translate>
The following items were changed locally.
</p>
<p ng-switch-when="receiveencrypted">
<span translate>The following unexpected items were found.</span>
<span translate translate-value-receive-encrypted="{{'Receive Encrypted' | translate}}">You should never add or change anything locally in a "{%receiveEncrypted%}" folder.</span>
</p>
<table class="table table-striped">
<thead>
<tr>
<th translate>Path</th>
<th translate>Size</th>
</tr>
</thead>
<tr dir-paginate="file in localChanged.files | itemsPerPage: localChanged.perpage" current-page="localChanged.page" total-items="model[localChangedFolder].receiveOnlyTotalItems" pagination-id="localChanged">
<td class="file-path">{{file.name}}</td>
<td><span ng-hide="file.type == 'DIRECTORY'">{{file.size | binary}}B</span></td>
</tr>
</table>
<dir-pagination-controls on-page-change="refreshLocalChanged(newPageNumber, localChanged.perpage)" pagination-id="localChanged"></dir-pagination-controls>
<ul class="pagination pull-right">
<li ng-repeat="option in [10, 25, 50]" ng-class="{ active: localChanged.perpage == option }">
<a href="#" ng-click="refreshLocalChanged(localChanged.page, option)">{{option}}</a>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
<span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
</button>
</div>
</modal>

View File

@@ -31,10 +31,10 @@ import (
"strings"
"time"
"github.com/julienschmidt/httprouter"
metrics "github.com/rcrowley/go-metrics"
"github.com/thejerf/suture"
"github.com/thejerf/suture/v4"
"github.com/vitrun/qart/qr"
"golang.org/x/crypto/bcrypt"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
@@ -49,11 +49,11 @@ import (
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/svcutil"
"github.com/syncthing/syncthing/lib/sync"
"github.com/syncthing/syncthing/lib/tlsutil"
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/syncthing/syncthing/lib/ur"
"github.com/syncthing/syncthing/lib/util"
)
// matches a bcrypt hash and not too much else
@@ -65,6 +65,7 @@ const (
EventSubBufferSize = 1000
defaultEventTimeout = time.Minute
httpsCertLifetimeDays = 820
featureFlagUntrusted = "untrusted"
)
type service struct {
@@ -81,8 +82,6 @@ type service struct {
connectionsService connections.Service
fss model.FolderSummaryService
urService *ur.Service
systemConfigMut sync.Mutex // serializes posts to /rest/system/config
contr Controller
noUpgrade bool
tlsDefaultCommonName string
configChanged chan struct{} // signals intentional listener close due to config change
@@ -90,28 +89,23 @@ type service struct {
startedOnce chan struct{} // the service has started successfully at least once
startupErr error
listenerAddr net.Addr
exitChan chan *svcutil.FatalErr
guiErrors logger.Recorder
systemLog logger.Recorder
}
type Controller interface {
ExitUpgrading()
Restart()
Shutdown()
}
type Service interface {
suture.Service
config.Committer
WaitForStart() error
}
func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonName string, m model.Model, defaultSub, diskSub events.BufferedSubscription, evLogger events.Logger, discoverer discover.Manager, connectionsService connections.Service, urService *ur.Service, fss model.FolderSummaryService, errors, systemLog logger.Recorder, contr Controller, noUpgrade bool) Service {
s := &service{
func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonName string, m model.Model, defaultSub, diskSub events.BufferedSubscription, evLogger events.Logger, discoverer discover.Manager, connectionsService connections.Service, urService *ur.Service, fss model.FolderSummaryService, errors, systemLog logger.Recorder, noUpgrade bool) Service {
return &service{
id: id,
cfg: cfg,
statics: newStaticsServer(cfg.GUI().Theme, assetDir),
statics: newStaticsServer(cfg.GUI().Theme, assetDir, cfg.Options().FeatureFlag(featureFlagUntrusted)),
model: m,
eventSubs: map[events.EventType]events.BufferedSubscription{
DefaultEventMask: defaultSub,
@@ -123,17 +117,14 @@ func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonNam
connectionsService: connectionsService,
fss: fss,
urService: urService,
systemConfigMut: sync.NewMutex(),
guiErrors: errors,
systemLog: systemLog,
contr: contr,
noUpgrade: noUpgrade,
tlsDefaultCommonName: tlsDefaultCommonName,
configChanged: make(chan struct{}),
startedOnce: make(chan struct{}),
exitChan: make(chan *svcutil.FatalErr, 1),
}
s.Service = util.AsService(s.serve, s.String())
return s
}
func (s *service) WaitForStart() error {
@@ -212,7 +203,7 @@ func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
fmt.Fprintf(w, "%s\n", bs)
}
func (s *service) serve(ctx context.Context) {
func (s *service) Serve(ctx context.Context) error {
listener, err := s.getListener(s.cfg.GUI())
if err != nil {
select {
@@ -228,13 +219,13 @@ func (s *service) serve(ctx context.Context) {
s.startupErr = err
close(s.startedOnce)
}
return
return err
}
if listener == nil {
// Not much we can do here other than exit quickly. The supervisor
// will log an error at some point.
return
return nil
}
s.listenerAddr = listener.Addr()
@@ -243,60 +234,83 @@ func (s *service) serve(ctx context.Context) {
s.cfg.Subscribe(s)
defer s.cfg.Unsubscribe(s)
restMux := httprouter.New()
// The GET handlers
getRestMux := http.NewServeMux()
getRestMux.HandleFunc("/rest/db/completion", s.getDBCompletion) // [device] [folder]
getRestMux.HandleFunc("/rest/db/file", s.getDBFile) // folder file
getRestMux.HandleFunc("/rest/db/ignores", s.getDBIgnores) // folder
getRestMux.HandleFunc("/rest/db/need", s.getDBNeed) // folder [perpage] [page]
getRestMux.HandleFunc("/rest/db/remoteneed", s.getDBRemoteNeed) // device folder [perpage] [page]
getRestMux.HandleFunc("/rest/db/localchanged", s.getDBLocalChanged) // folder
getRestMux.HandleFunc("/rest/db/status", s.getDBStatus) // folder
getRestMux.HandleFunc("/rest/db/browse", s.getDBBrowse) // folder [prefix] [dirsonly] [levels]
getRestMux.HandleFunc("/rest/folder/versions", s.getFolderVersions) // folder
getRestMux.HandleFunc("/rest/folder/errors", s.getFolderErrors) // folder
getRestMux.HandleFunc("/rest/folder/pullerrors", s.getFolderErrors) // folder (deprecated)
getRestMux.HandleFunc("/rest/events", s.getIndexEvents) // [since] [limit] [timeout] [events]
getRestMux.HandleFunc("/rest/events/disk", s.getDiskEvents) // [since] [limit] [timeout]
getRestMux.HandleFunc("/rest/stats/device", s.getDeviceStats) // -
getRestMux.HandleFunc("/rest/stats/folder", s.getFolderStats) // -
getRestMux.HandleFunc("/rest/svc/deviceid", s.getDeviceID) // id
getRestMux.HandleFunc("/rest/svc/lang", s.getLang) // -
getRestMux.HandleFunc("/rest/svc/report", s.getReport) // -
getRestMux.HandleFunc("/rest/svc/random/string", s.getRandomString) // [length]
getRestMux.HandleFunc("/rest/system/browse", s.getSystemBrowse) // current
getRestMux.HandleFunc("/rest/system/config", s.getSystemConfig) // -
getRestMux.HandleFunc("/rest/system/config/insync", s.getSystemConfigInsync) // -
getRestMux.HandleFunc("/rest/system/connections", s.getSystemConnections) // -
getRestMux.HandleFunc("/rest/system/discovery", s.getSystemDiscovery) // -
getRestMux.HandleFunc("/rest/system/error", s.getSystemError) // -
getRestMux.HandleFunc("/rest/system/ping", s.restPing) // -
getRestMux.HandleFunc("/rest/system/status", s.getSystemStatus) // -
getRestMux.HandleFunc("/rest/system/upgrade", s.getSystemUpgrade) // -
getRestMux.HandleFunc("/rest/system/version", s.getSystemVersion) // -
getRestMux.HandleFunc("/rest/system/debug", s.getSystemDebug) // -
getRestMux.HandleFunc("/rest/system/log", s.getSystemLog) // [since]
getRestMux.HandleFunc("/rest/system/log.txt", s.getSystemLogTxt) // [since]
restMux.HandlerFunc(http.MethodGet, "/rest/cluster/pending/devices", s.getPendingDevices) // -
restMux.HandlerFunc(http.MethodGet, "/rest/cluster/pending/folders", s.getPendingFolders) // [device]
restMux.HandlerFunc(http.MethodGet, "/rest/db/completion", s.getDBCompletion) // [device] [folder]
restMux.HandlerFunc(http.MethodGet, "/rest/db/file", s.getDBFile) // folder file
restMux.HandlerFunc(http.MethodGet, "/rest/db/ignores", s.getDBIgnores) // folder
restMux.HandlerFunc(http.MethodGet, "/rest/db/need", s.getDBNeed) // folder [perpage] [page]
restMux.HandlerFunc(http.MethodGet, "/rest/db/remoteneed", s.getDBRemoteNeed) // device folder [perpage] [page]
restMux.HandlerFunc(http.MethodGet, "/rest/db/localchanged", s.getDBLocalChanged) // folder
restMux.HandlerFunc(http.MethodGet, "/rest/db/status", s.getDBStatus) // folder
restMux.HandlerFunc(http.MethodGet, "/rest/db/browse", s.getDBBrowse) // folder [prefix] [dirsonly] [levels]
restMux.HandlerFunc(http.MethodGet, "/rest/folder/versions", s.getFolderVersions) // folder
restMux.HandlerFunc(http.MethodGet, "/rest/folder/errors", s.getFolderErrors) // folder
restMux.HandlerFunc(http.MethodGet, "/rest/folder/pullerrors", s.getFolderErrors) // folder (deprecated)
restMux.HandlerFunc(http.MethodGet, "/rest/events", s.getIndexEvents) // [since] [limit] [timeout] [events]
restMux.HandlerFunc(http.MethodGet, "/rest/events/disk", s.getDiskEvents) // [since] [limit] [timeout]
restMux.HandlerFunc(http.MethodGet, "/rest/stats/device", s.getDeviceStats) // -
restMux.HandlerFunc(http.MethodGet, "/rest/stats/folder", s.getFolderStats) // -
restMux.HandlerFunc(http.MethodGet, "/rest/svc/deviceid", s.getDeviceID) // id
restMux.HandlerFunc(http.MethodGet, "/rest/svc/lang", s.getLang) // -
restMux.HandlerFunc(http.MethodGet, "/rest/svc/report", s.getReport) // -
restMux.HandlerFunc(http.MethodGet, "/rest/svc/random/string", s.getRandomString) // [length]
restMux.HandlerFunc(http.MethodGet, "/rest/system/browse", s.getSystemBrowse) // current
restMux.HandlerFunc(http.MethodGet, "/rest/system/connections", s.getSystemConnections) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/discovery", s.getSystemDiscovery) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/error", s.getSystemError) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/ping", s.restPing) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/status", s.getSystemStatus) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/upgrade", s.getSystemUpgrade) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/version", s.getSystemVersion) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/debug", s.getSystemDebug) // -
restMux.HandlerFunc(http.MethodGet, "/rest/system/log", s.getSystemLog) // [since]
restMux.HandlerFunc(http.MethodGet, "/rest/system/log.txt", s.getSystemLogTxt) // [since]
// The POST handlers
postRestMux := http.NewServeMux()
postRestMux.HandleFunc("/rest/db/prio", s.postDBPrio) // folder file [perpage] [page]
postRestMux.HandleFunc("/rest/db/ignores", s.postDBIgnores) // folder
postRestMux.HandleFunc("/rest/db/override", s.postDBOverride) // folder
postRestMux.HandleFunc("/rest/db/revert", s.postDBRevert) // folder
postRestMux.HandleFunc("/rest/db/scan", s.postDBScan) // folder [sub...] [delay]
postRestMux.HandleFunc("/rest/folder/versions", s.postFolderVersionsRestore) // folder <body>
postRestMux.HandleFunc("/rest/system/config", s.postSystemConfig) // <body>
postRestMux.HandleFunc("/rest/system/error", s.postSystemError) // <body>
postRestMux.HandleFunc("/rest/system/error/clear", s.postSystemErrorClear) // -
postRestMux.HandleFunc("/rest/system/ping", s.restPing) // -
postRestMux.HandleFunc("/rest/system/reset", s.postSystemReset) // [folder]
postRestMux.HandleFunc("/rest/system/restart", s.postSystemRestart) // -
postRestMux.HandleFunc("/rest/system/shutdown", s.postSystemShutdown) // -
postRestMux.HandleFunc("/rest/system/upgrade", s.postSystemUpgrade) // -
postRestMux.HandleFunc("/rest/system/pause", s.makeDevicePauseHandler(true)) // [device]
postRestMux.HandleFunc("/rest/system/resume", s.makeDevicePauseHandler(false)) // [device]
postRestMux.HandleFunc("/rest/system/debug", s.postSystemDebug) // [enable] [disable]
restMux.HandlerFunc(http.MethodPost, "/rest/db/prio", s.postDBPrio) // folder file [perpage] [page]
restMux.HandlerFunc(http.MethodPost, "/rest/db/ignores", s.postDBIgnores) // folder
restMux.HandlerFunc(http.MethodPost, "/rest/db/override", s.postDBOverride) // folder
restMux.HandlerFunc(http.MethodPost, "/rest/db/revert", s.postDBRevert) // folder
restMux.HandlerFunc(http.MethodPost, "/rest/db/scan", s.postDBScan) // folder [sub...] [delay]
restMux.HandlerFunc(http.MethodPost, "/rest/folder/versions", s.postFolderVersionsRestore) // folder <body>
restMux.HandlerFunc(http.MethodPost, "/rest/system/error", s.postSystemError) // <body>
restMux.HandlerFunc(http.MethodPost, "/rest/system/error/clear", s.postSystemErrorClear) // -
restMux.HandlerFunc(http.MethodPost, "/rest/system/ping", s.restPing) // -
restMux.HandlerFunc(http.MethodPost, "/rest/system/reset", s.postSystemReset) // [folder]
restMux.HandlerFunc(http.MethodPost, "/rest/system/restart", s.postSystemRestart) // -
restMux.HandlerFunc(http.MethodPost, "/rest/system/shutdown", s.postSystemShutdown) // -
restMux.HandlerFunc(http.MethodPost, "/rest/system/upgrade", s.postSystemUpgrade) // -
restMux.HandlerFunc(http.MethodPost, "/rest/system/pause", s.makeDevicePauseHandler(true)) // [device]
restMux.HandlerFunc(http.MethodPost, "/rest/system/resume", s.makeDevicePauseHandler(false)) // [device]
restMux.HandlerFunc(http.MethodPost, "/rest/system/debug", s.postSystemDebug) // [enable] [disable]
// Config endpoints
configBuilder := &configMuxBuilder{
Router: restMux,
id: s.id,
cfg: s.cfg,
}
configBuilder.registerConfig("/rest/config")
configBuilder.registerConfigInsync("/rest/config/insync")
configBuilder.registerFolders("/rest/config/folders")
configBuilder.registerDevices("/rest/config/devices")
configBuilder.registerFolder("/rest/config/folders/:id")
configBuilder.registerDevice("/rest/config/devices/:id")
configBuilder.registerDefaultFolder("/rest/config/defaults/folder")
configBuilder.registerDefaultDevice("/rest/config/defaults/device")
configBuilder.registerOptions("/rest/config/options")
configBuilder.registerLDAP("/rest/config/ldap")
configBuilder.registerGUI("/rest/config/gui")
// Deprecated config endpoints
configBuilder.registerConfigDeprecated("/rest/system/config") // POST instead of PUT
configBuilder.registerConfigInsync("/rest/system/config/insync")
// Debug endpoints, not for general use
debugMux := http.NewServeMux()
@@ -305,15 +319,15 @@ func (s *service) serve(ctx context.Context) {
debugMux.HandleFunc("/rest/debug/cpuprof", s.getCPUProf) // duration
debugMux.HandleFunc("/rest/debug/heapprof", s.getHeapProf)
debugMux.HandleFunc("/rest/debug/support", s.getSupportBundle)
getRestMux.Handle("/rest/debug/", s.whenDebugging(debugMux))
debugMux.HandleFunc("/rest/debug/file", s.getDebugFile)
restMux.Handler(http.MethodGet, "/rest/debug/*method", s.whenDebugging(debugMux))
// A handler that splits requests between the two above and disables
// caching
restMux := noCacheMiddleware(metricsMiddleware(getPostHandler(getRestMux, postRestMux)))
// A handler that disables caching
noCacheRestMux := noCacheMiddleware(metricsMiddleware(restMux))
// The main routing handler
mux := http.NewServeMux()
mux.Handle("/rest/", restMux)
mux.Handle("/rest/", noCacheRestMux)
mux.HandleFunc("/qr/", s.getQR)
// Serve compiled in assets unless an asset directory was set (for development)
@@ -391,6 +405,7 @@ func (s *service) serve(ctx context.Context) {
// Wait for stop, restart or error signals
err = nil
select {
case <-ctx.Done():
// Shutting down permanently
@@ -398,11 +413,20 @@ func (s *service) serve(ctx context.Context) {
case <-s.configChanged:
// Soft restart due to configuration change
l.Debugln("restarting (config changed)")
case <-serveError:
case err = <-s.exitChan:
case err = <-serveError:
// Restart due to listen/serve failure
l.Warnln("GUI/API:", err, "(restarting)")
}
srv.Close()
// Give it a moment to shut down gracefully, e.g. if we are restarting
// due to a config change through the API, let that finish successfully.
timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
if err := srv.Shutdown(timeout); err == timeout.Err() {
srv.Close()
}
return err
}
// Complete implements suture.IsCompletable, which signifies to the supervisor
@@ -432,7 +456,12 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
// No action required when this changes, so mask the fact that it changed at all.
from.GUI.Debugging = to.GUI.Debugging
if untrusted := to.Options.FeatureFlag(featureFlagUntrusted); untrusted != from.Options.FeatureFlag(featureFlagUntrusted) {
s.statics.setUntrusted(untrusted)
}
if to.GUI == from.GUI {
// No GUI changes, we're done here.
return true
}
@@ -446,17 +475,12 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
return true
}
func getPostHandler(get, post http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
get.ServeHTTP(w, r)
case "POST":
post.ServeHTTP(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
})
func (s *service) fatal(err *svcutil.FatalErr) {
// s.exitChan is 1-buffered and whoever is first gets handled.
select {
case s.exitChan <- err:
default:
}
}
func debugMiddleware(h http.Handler) http.Handler {
@@ -499,8 +523,8 @@ func corsMiddleware(next http.Handler, allowFrameLoading bool) http.Handler {
if r.Method == "OPTIONS" {
// Add a generous access-control-allow-origin header for CORS requests
w.Header().Add("Access-Control-Allow-Origin", "*")
// Only GET/POST Methods are supported
w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
// Only GET/POST/OPTIONS Methods are supported
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
// Only these headers can be set
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-API-Key")
// The request is meant to be cached 10 minutes
@@ -599,6 +623,33 @@ func (s *service) whenDebugging(h http.Handler) http.Handler {
})
}
func (s *service) getPendingDevices(w http.ResponseWriter, r *http.Request) {
devices, err := s.model.PendingDevices()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sendJSON(w, devices)
}
func (s *service) getPendingFolders(w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
device := qs.Get("device")
deviceID, err := protocol.DeviceIDFromString(device)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
folders, err := s.model.PendingFolders(deviceID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sendJSON(w, folders)
}
func (s *service) restPing(w http.ResponseWriter, r *http.Request) {
sendJSON(w, map[string]string{"ping": "pong"})
}
@@ -622,7 +673,7 @@ func (s *service) getSystemVersion(w http.ResponseWriter, r *http.Request) {
"isCandidate": build.IsCandidate,
"isRelease": build.IsRelease,
"date": build.Date,
"tags": build.Tags,
"tags": build.TagsList(),
"stamp": build.Stamp,
"user": build.User,
})
@@ -661,14 +712,19 @@ func (s *service) getDBBrowse(w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
folder := qs.Get("folder")
prefix := qs.Get("prefix")
dirsonly := qs.Get("dirsonly") != ""
dirsOnly := qs.Get("dirsonly") != ""
levels, err := strconv.Atoi(qs.Get("levels"))
if err != nil {
levels = -1
}
result, err := s.model.GlobalDirectoryTree(folder, prefix, levels, dirsOnly)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sendJSON(w, s.model.GlobalDirectoryTree(folder, prefix, levels, dirsonly))
sendJSON(w, result)
}
func (s *service) getDBCompletion(w http.ResponseWriter, r *http.Request) {
@@ -733,7 +789,11 @@ func (s *service) getDBNeed(w http.ResponseWriter, r *http.Request) {
page, perpage := getPagingParams(qs)
progress, queued, rest := s.model.NeedFolderFiles(folder, page, perpage)
progress, queued, rest, err := s.model.NeedFolderFiles(folder, page, perpage)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
// Convert the struct to a more loose structure, and inject the size.
sendJSON(w, map[string]interface{}{
@@ -758,13 +818,12 @@ func (s *service) getDBRemoteNeed(w http.ResponseWriter, r *http.Request) {
page, perpage := getPagingParams(qs)
snap, err := s.model.DBSnapshot(folder)
files, err := s.model.RemoteNeedFolderFiles(folder, deviceID, page, perpage)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
defer snap.Release()
files := snap.RemoteNeedFolderFiles(deviceID, page, perpage)
sendJSON(w, map[string]interface{}{
"files": toJsonFileInfoSlice(files),
"page": page,
@@ -779,13 +838,11 @@ func (s *service) getDBLocalChanged(w http.ResponseWriter, r *http.Request) {
page, perpage := getPagingParams(qs)
snap, err := s.model.DBSnapshot(folder)
files, err := s.model.LocalChangedFolderFiles(folder, page, perpage)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
defer snap.Release()
files := snap.LocalChangedFiles(page, perpage)
sendJSON(w, map[string]interface{}{
"files": toJsonFileInfoSlice(files),
@@ -837,60 +894,37 @@ func (s *service) getDBFile(w http.ResponseWriter, r *http.Request) {
})
}
func (s *service) getSystemConfig(w http.ResponseWriter, r *http.Request) {
sendJSON(w, s.cfg.RawCopy())
}
func (s *service) getDebugFile(w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
folder := qs.Get("folder")
file := qs.Get("file")
func (s *service) postSystemConfig(w http.ResponseWriter, r *http.Request) {
s.systemConfigMut.Lock()
defer s.systemConfigMut.Unlock()
to, err := config.ReadJSON(r.Body, s.id)
r.Body.Close()
snap, err := s.model.DBSnapshot(folder)
if err != nil {
l.Warnln("Decoding posted config:", err)
http.Error(w, err.Error(), http.StatusBadRequest)
http.Error(w, err.Error(), http.StatusNotFound)
return
}
if to.GUI.Password != s.cfg.GUI().Password {
if to.GUI.Password != "" && !bcryptExpr.MatchString(to.GUI.Password) {
hash, err := bcrypt.GenerateFromPassword([]byte(to.GUI.Password), 0)
if err != nil {
l.Warnln("bcrypting password:", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
lf, _ := snap.Get(protocol.LocalDeviceID, file)
gf, _ := snap.GetGlobal(file)
av := snap.Availability(file)
vl := snap.DebugGlobalVersions(file)
to.GUI.Password = string(hash)
}
}
// Activate and save. Wait for the configuration to become active before
// completing the request.
if wg, err := s.cfg.Replace(to); err != nil {
l.Warnln("Replacing config:", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} else {
wg.Wait()
}
if err := s.cfg.Save(); err != nil {
l.Warnln("Saving config:", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func (s *service) getSystemConfigInsync(w http.ResponseWriter, r *http.Request) {
sendJSON(w, map[string]bool{"configInSync": !s.cfg.RequiresRestart()})
sendJSON(w, map[string]interface{}{
"global": jsonFileInfo(gf),
"local": jsonFileInfo(lf),
"availability": av,
"globalVersions": vl.String(),
})
}
func (s *service) postSystemRestart(w http.ResponseWriter, r *http.Request) {
s.flushResponse(`{"ok": "restarting"}`, w)
go s.contr.Restart()
s.fatal(&svcutil.FatalErr{
Err: errors.New("restart initiated by rest API"),
Status: svcutil.ExitRestart,
})
}
func (s *service) postSystemReset(w http.ResponseWriter, r *http.Request) {
@@ -916,12 +950,18 @@ func (s *service) postSystemReset(w http.ResponseWriter, r *http.Request) {
s.flushResponse(`{"ok": "resetting folder `+folder+`"}`, w)
}
go s.contr.Restart()
s.fatal(&svcutil.FatalErr{
Err: errors.New("restart after db reset initiated by rest API"),
Status: svcutil.ExitRestart,
})
}
func (s *service) postSystemShutdown(w http.ResponseWriter, r *http.Request) {
s.flushResponse(`{"ok": "shutting down"}`, w)
go s.contr.Shutdown()
s.fatal(&svcutil.FatalErr{
Err: errors.New("shutdown initiated by rest API"),
Status: svcutil.ExitSuccess,
})
}
func (s *service) flushResponse(resp string, w http.ResponseWriter) {
@@ -1184,7 +1224,7 @@ func (s *service) getDBIgnores(w http.ResponseWriter, r *http.Request) {
folder := qs.Get("folder")
lines, patterns, err := s.model.GetIgnores(folder)
lines, patterns, err := s.model.LoadIgnores(folder)
if err != nil && !ignore.IsParseError(err) {
http.Error(w, err.Error(), 500)
return
@@ -1356,7 +1396,10 @@ func (s *service) postSystemUpgrade(w http.ResponseWriter, r *http.Request) {
}
s.flushResponse(`{"ok": "restarting"}`, w)
s.contr.ExitUpgrading()
s.fatal(&svcutil.FatalErr{
Err: errors.New("exit after upgrade initiated by rest API"),
Status: svcutil.ExitUpgrade,
})
}
}
@@ -1365,31 +1408,36 @@ func (s *service) makeDevicePauseHandler(paused bool) http.HandlerFunc {
var qs = r.URL.Query()
var deviceStr = qs.Get("device")
var cfgs []config.DeviceConfiguration
if deviceStr == "" {
for _, cfg := range s.cfg.Devices() {
cfg.Paused = paused
cfgs = append(cfgs, cfg)
var msg string
var status int
_, err := s.cfg.Modify(func(cfg *config.Configuration) {
if deviceStr == "" {
for i := range cfg.Devices {
cfg.Devices[i].Paused = paused
}
return
}
} else {
device, err := protocol.DeviceIDFromString(deviceStr)
if err != nil {
http.Error(w, err.Error(), 500)
msg = err.Error()
status = 500
return
}
cfg, ok := s.cfg.Devices()[device]
_, i, ok := cfg.Device(device)
if !ok {
http.Error(w, "not found", http.StatusNotFound)
msg = "not found"
status = http.StatusNotFound
return
}
cfg.Paused = paused
cfgs = append(cfgs, cfg)
}
cfg.Devices[i].Paused = paused
})
if _, err := s.cfg.SetDevices(cfgs); err != nil {
if msg != "" {
http.Error(w, msg, status)
} else if err != nil {
http.Error(w, err.Error(), 500)
}
}
@@ -1497,7 +1545,7 @@ func (s *service) postFolderVersionsRestore(w http.ResponseWriter, r *http.Reque
http.Error(w, err.Error(), 500)
return
}
sendJSON(w, ferr)
sendJSON(w, errorStringMap(ferr))
}
func (s *service) getFolderErrors(w http.ResponseWriter, r *http.Request) {
@@ -1791,6 +1839,14 @@ func shouldRegenerateCertificate(cert tls.Certificate) error {
return nil
}
func errorStringMap(errs map[string]error) map[string]*string {
out := make(map[string]*string, len(errs))
for s, e := range errs {
out[s] = errorString(e)
}
return out
}
func errorString(err error) *string {
if err != nil {
msg := err.Error()

View File

@@ -30,15 +30,17 @@ type staticsServer struct {
mut sync.RWMutex
theme string
lastThemeChange time.Time
untrusted bool
}
func newStaticsServer(theme, assetDir string) *staticsServer {
func newStaticsServer(theme, assetDir string, untrusted bool) *staticsServer {
s := &staticsServer{
assetDir: assetDir,
assets: auto.Assets(),
mut: sync.NewRWMutex(),
theme: theme,
lastThemeChange: time.Now().UTC(),
untrusted: untrusted,
}
seen := make(map[string]struct{})
@@ -60,6 +62,10 @@ func newStaticsServer(theme, assetDir string) *staticsServer {
}
}
if untrusted {
l.Infoln(`Feature flag "untrusted":`, untrusted)
}
return s
}
@@ -88,6 +94,7 @@ func (s *staticsServer) serveAsset(w http.ResponseWriter, r *http.Request) {
s.mut.RLock()
theme := s.theme
modificationTime := s.lastThemeChange
untrusted := s.untrusted
s.mut.RUnlock()
// If path starts with special prefix, get theme and file from path
@@ -105,44 +112,68 @@ func (s *staticsServer) serveAsset(w http.ResponseWriter, r *http.Request) {
}
// Check for an override for the current theme.
if s.assetDir != "" {
p := filepath.Join(s.assetDir, theme, filepath.FromSlash(file))
if _, err := os.Stat(p); err == nil {
mtype := assets.MimeTypeForFile(file)
if len(mtype) != 0 {
w.Header().Set("Content-Type", mtype)
}
http.ServeFile(w, r, p)
return
}
if untrusted && s.serveFromAssetDir(file, theme+"/untrusted", w, r) {
l.Debugln("serving", file, "from override untrusted")
return
}
if s.serveFromAssetDir(file, theme, w, r) {
return
}
// Check for a compiled in asset for the current theme.
as, ok := s.assets[theme+"/"+file]
if !ok {
// Check for an overridden default asset.
if s.assetDir != "" {
p := filepath.Join(s.assetDir, config.DefaultTheme, filepath.FromSlash(file))
if _, err := os.Stat(p); err == nil {
mtype := assets.MimeTypeForFile(file)
if len(mtype) != 0 {
w.Header().Set("Content-Type", mtype)
}
http.ServeFile(w, r, p)
return
}
}
// Check for a compiled in default asset.
as, ok = s.assets[config.DefaultTheme+"/"+file]
if !ok {
http.NotFound(w, r)
return
}
if untrusted && s.serveFromAssets(file, theme+"/untrusted", modificationTime, w, r) {
l.Debugln("serving", file, "from compiled untrusted")
return
}
if s.serveFromAssets(file, theme, modificationTime, w, r) {
return
}
// Check for an overridden default asset.
if untrusted && s.serveFromAssetDir(file, config.DefaultTheme+"/untrusted", w, r) {
l.Debugln("serving", file, "from override untrusted")
return
}
if s.serveFromAssetDir(file, config.DefaultTheme, w, r) {
return
}
// Check for a compiled in default asset.
if untrusted && s.serveFromAssets(file, config.DefaultTheme+"/untrusted", modificationTime, w, r) {
l.Debugln("serving", file, "from compiled untrusted")
return
}
if s.serveFromAssets(file, config.DefaultTheme, modificationTime, w, r) {
return
}
http.NotFound(w, r)
}
func (s *staticsServer) serveFromAssetDir(file, theme string, w http.ResponseWriter, r *http.Request) bool {
if s.assetDir == "" {
return false
}
p := filepath.Join(s.assetDir, theme, filepath.FromSlash(file))
if _, err := os.Stat(p); err != nil {
return false
}
mtype := assets.MimeTypeForFile(file)
if len(mtype) != 0 {
w.Header().Set("Content-Type", mtype)
}
http.ServeFile(w, r, p)
return true
}
func (s *staticsServer) serveFromAssets(file, theme string, modificationTime time.Time, w http.ResponseWriter, r *http.Request) bool {
as, ok := s.assets[theme+"/"+file]
if !ok {
return false
}
as.Modified = modificationTime
assets.Serve(w, r, as)
return true
}
func (s *staticsServer) serveThemes(w http.ResponseWriter, r *http.Request) {
@@ -158,6 +189,13 @@ func (s *staticsServer) setTheme(theme string) {
s.mut.Unlock()
}
func (s *staticsServer) setUntrusted(enabled bool) {
s.mut.Lock()
l.Infoln(`Feature flag "untrusted":`, enabled)
s.untrusted = enabled
s.mut.Unlock()
}
func (s *staticsServer) String() string {
return fmt.Sprintf("staticsServer@%p", s)
}

View File

@@ -9,6 +9,7 @@ package api
import (
"bytes"
"compress/gzip"
"context"
"encoding/json"
"fmt"
"io"
@@ -31,17 +32,23 @@ import (
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/svcutil"
"github.com/syncthing/syncthing/lib/sync"
"github.com/syncthing/syncthing/lib/tlsutil"
"github.com/syncthing/syncthing/lib/ur"
"github.com/thejerf/suture"
"github.com/thejerf/suture/v4"
)
var (
confDir = filepath.Join("testdata", "config")
token = filepath.Join(confDir, "csrftokens.txt")
dev1 protocol.DeviceID
)
func init() {
dev1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
}
func TestMain(m *testing.M) {
orig := locations.GetBaseDir(locations.ConfigBaseDir)
locations.SetBaseDir(locations.ConfigBaseDir, confDir)
@@ -106,17 +113,16 @@ func TestStopAfterBrokenConfig(t *testing.T) {
RawUseTLS: false,
},
}
w := config.Wrap("/dev/null", cfg, events.NoopLogger)
w := config.Wrap("/dev/null", cfg, protocol.LocalDeviceID, events.NoopLogger)
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
defer os.Remove(token)
srv.started = make(chan string)
sup := suture.New("test", suture.Spec{
PassThroughPanics: true,
})
sup := suture.New("test", svcutil.SpecWithDebugLogger(l))
sup.Add(srv)
sup.ServeBackground()
ctx, cancel := context.WithCancel(context.Background())
sup.ServeBackground(ctx)
<-srv.started
@@ -134,9 +140,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
t.Fatal("Verify config should have failed")
}
// Nonetheless, it should be fine to Stop() it without panic.
sup.Stop()
cancel()
}
func TestAssetsDir(t *testing.T) {
@@ -245,11 +249,11 @@ func TestAPIServiceRequests(t *testing.T) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
cases := []httpTestCase{
// /rest/db
@@ -396,6 +400,62 @@ func TestAPIServiceRequests(t *testing.T) {
Type: "text/plain",
Prefix: "",
},
// /rest/config
{
URL: "/rest/config",
Code: 200,
Type: "application/json",
Prefix: "",
},
{
URL: "/rest/config/folders",
Code: 200,
Type: "application/json",
Prefix: "",
},
{
URL: "/rest/config/folders/missing",
Code: 404,
Type: "text/plain",
Prefix: "",
},
{
URL: "/rest/config/devices",
Code: 200,
Type: "application/json",
Prefix: "",
},
{
URL: "/rest/config/devices/illegalid",
Code: 400,
Type: "text/plain",
Prefix: "",
},
{
URL: "/rest/config/devices/" + protocol.GlobalDeviceID.String(),
Code: 404,
Type: "text/plain",
Prefix: "",
},
{
URL: "/rest/config/options",
Code: 200,
Type: "application/json",
Prefix: "{",
},
{
URL: "/rest/config/gui",
Code: 200,
Type: "application/json",
Prefix: "{",
},
{
URL: "/rest/config/ldap",
Code: 200,
Type: "application/json",
Prefix: "{",
},
}
for _, tc := range cases {
@@ -458,11 +518,11 @@ func TestHTTPLogin(t *testing.T) {
cfg := new(mockedConfig)
cfg.gui.User = "üser"
cfg.gui.Password = "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq" // bcrypt of "räksmörgås" in UTF-8
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
// Verify rejection when not using authorization
@@ -520,7 +580,7 @@ func TestHTTPLogin(t *testing.T) {
}
}
func startHTTP(cfg *mockedConfig) (string, *suture.Supervisor, error) {
func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) {
m := new(mockedModel)
assetDir := "../../gui"
eventSub := new(mockedEventSub)
@@ -533,7 +593,7 @@ func startHTTP(cfg *mockedConfig) (string, *suture.Supervisor, error) {
// Instantiate the API service
urService := ur.New(cfg, m, connections, false)
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, nil, false).(*service)
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, false).(*service)
defer os.Remove(token)
svc.started = addrChan
@@ -542,23 +602,24 @@ func startHTTP(cfg *mockedConfig) (string, *suture.Supervisor, error) {
PassThroughPanics: true,
})
supervisor.Add(svc)
supervisor.ServeBackground()
ctx, cancel := context.WithCancel(context.Background())
supervisor.ServeBackground(ctx)
// Make sure the API service is listening, and get the URL to use.
addr := <-addrChan
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
supervisor.Stop()
return "", nil, fmt.Errorf("weird address from API service: %w", err)
cancel()
return "", cancel, fmt.Errorf("weird address from API service: %w", err)
}
host, _, _ := net.SplitHostPort(cfg.gui.RawAddress)
host, _, _ := net.SplitHostPort(cfg.GUI().RawAddress)
if host == "" || host == "0.0.0.0" {
host = "127.0.0.1"
}
baseURL := fmt.Sprintf("http://%s", net.JoinHostPort(host, strconv.Itoa(tcpAddr.Port)))
return baseURL, supervisor, nil
return baseURL, cancel, nil
}
func TestCSRFRequired(t *testing.T) {
@@ -567,11 +628,11 @@ func TestCSRFRequired(t *testing.T) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal("Unexpected error from getting base URL:", err)
}
defer sup.Stop()
defer cancel()
cli := &http.Client{
Timeout: time.Minute,
@@ -643,11 +704,11 @@ func TestRandomString(t *testing.T) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
cli := &http.Client{
Timeout: time.Second,
}
@@ -736,11 +797,11 @@ func testConfigPost(data io.Reader) (*http.Response, error) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
return nil, err
}
defer sup.Stop()
defer cancel()
cli := &http.Client{
Timeout: time.Second,
}
@@ -757,11 +818,11 @@ func TestHostCheck(t *testing.T) {
cfg := new(mockedConfig)
cfg.gui.RawAddress = "127.0.0.1:0"
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
// A normal HTTP get to the localhost-bound service should succeed
@@ -818,11 +879,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig)
cfg.gui.RawAddress = "127.0.0.1:0"
cfg.gui.InsecureSkipHostCheck = true
baseURL, sup, err = startHTTP(cfg)
baseURL, cancel, err = startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
// A request with a suspicious Host header should be allowed
@@ -842,11 +903,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig)
cfg.gui.RawAddress = "0.0.0.0:0"
cfg.gui.InsecureSkipHostCheck = true
baseURL, sup, err = startHTTP(cfg)
baseURL, cancel, err = startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
// A request with a suspicious Host header should be allowed
@@ -870,11 +931,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig)
cfg.gui.RawAddress = "[::1]:0"
baseURL, sup, err = startHTTP(cfg)
baseURL, cancel, err = startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
// A normal HTTP get to the localhost-bound service should succeed
@@ -965,11 +1026,11 @@ func TestAccessControlAllowOriginHeader(t *testing.T) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
cli := &http.Client{
Timeout: time.Second,
}
@@ -996,11 +1057,11 @@ func TestOptionsRequest(t *testing.T) {
const testAPIKey = "foobarbaz"
cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey
baseURL, sup, err := startHTTP(cfg)
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer sup.Stop()
defer cancel()
cli := &http.Client{
Timeout: time.Second,
}
@@ -1018,8 +1079,8 @@ func TestOptionsRequest(t *testing.T) {
if resp.Header.Get("Access-Control-Allow-Origin") != "*" {
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Origin: *' header")
}
if resp.Header.Get("Access-Control-Allow-Methods") != "GET, POST" {
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Methods: GET, POST' header")
if resp.Header.Get("Access-Control-Allow-Methods") != "GET, POST, PUT, PATCH, DELETE, OPTIONS" {
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS' header")
}
if resp.Header.Get("Access-Control-Allow-Headers") != "Content-Type, X-API-Key" {
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Headers: Content-Type, X-API-KEY' header")
@@ -1032,7 +1093,7 @@ func TestEventMasks(t *testing.T) {
cfg := new(mockedConfig)
defSub := new(mockedEventSub)
diskSub := new(mockedEventSub)
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
defer os.Remove(token)
if mask := svc.getEventMask(""); mask != DefaultEventMask {
@@ -1174,6 +1235,132 @@ func TestShouldRegenerateCertificate(t *testing.T) {
}
}
func TestConfigChanges(t *testing.T) {
t.Parallel()
const testAPIKey = "foobarbaz"
cfg := config.Configuration{
GUI: config.GUIConfiguration{
RawAddress: "127.0.0.1:0",
RawUseTLS: false,
APIKey: testAPIKey,
},
}
tmpFile, err := ioutil.TempFile("", "syncthing-testConfig-")
if err != nil {
panic(err)
}
defer os.Remove(tmpFile.Name())
w := config.Wrap(tmpFile.Name(), cfg, protocol.LocalDeviceID, events.NoopLogger)
tmpFile.Close()
if cfgService, ok := w.(suture.Service); ok {
cfgCtx, cfgCancel := context.WithCancel(context.Background())
go cfgService.Serve(cfgCtx)
defer cfgCancel()
}
baseURL, cancel, err := startHTTP(w)
if err != nil {
t.Fatal("Unexpected error from getting base URL:", err)
}
defer cancel()
cli := &http.Client{
Timeout: time.Minute,
}
do := func(req *http.Request, status int) *http.Response {
t.Helper()
req.Header.Set("X-API-Key", testAPIKey)
resp, err := cli.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != status {
t.Errorf("Expected status %v, got %v", status, resp.StatusCode)
}
return resp
}
mod := func(method, path string, data interface{}) {
t.Helper()
bs, err := json.Marshal(data)
if err != nil {
t.Fatal(err)
}
req, _ := http.NewRequest(method, baseURL+path, bytes.NewReader(bs))
do(req, http.StatusOK).Body.Close()
}
get := func(path string) *http.Response {
t.Helper()
req, _ := http.NewRequest(http.MethodGet, baseURL+path, nil)
return do(req, http.StatusOK)
}
dev1Path := "/rest/config/devices/" + dev1.String()
// Create device
mod(http.MethodPut, "/rest/config/devices", []config.DeviceConfiguration{{DeviceID: dev1}})
// Check its there
get(dev1Path).Body.Close()
// Modify just a single attribute
mod(http.MethodPatch, dev1Path, map[string]bool{"Paused": true})
// Check that attribute
resp := get(dev1Path)
var dev config.DeviceConfiguration
if err := unmarshalTo(resp.Body, &dev); err != nil {
t.Fatal(err)
}
if !dev.Paused {
t.Error("Expected device to be paused")
}
folder2Path := "/rest/config/folders/folder2"
// Create a folder and add another
mod(http.MethodPut, "/rest/config/folders", []config.FolderConfiguration{{ID: "folder1", Path: "folder1"}})
mod(http.MethodPut, folder2Path, config.FolderConfiguration{ID: "folder2", Path: "folder2"})
// Check they are there
get("/rest/config/folders/folder1").Body.Close()
get(folder2Path).Body.Close()
// Modify just a single attribute
mod(http.MethodPatch, folder2Path, map[string]bool{"Paused": true})
// Check that attribute
resp = get(folder2Path)
var folder config.FolderConfiguration
if err := unmarshalTo(resp.Body, &folder); err != nil {
t.Fatal(err)
}
if !dev.Paused {
t.Error("Expected folder to be paused")
}
// Delete folder2
req, _ := http.NewRequest(http.MethodDelete, baseURL+folder2Path, nil)
do(req, http.StatusOK)
// Check folder1 is still there and folder2 gone
get("/rest/config/folders/folder1").Body.Close()
req, _ = http.NewRequest(http.MethodGet, baseURL+folder2Path, nil)
do(req, http.StatusNotFound)
mod(http.MethodPatch, "/rest/config/options", map[string]int{"maxSendKbps": 50})
resp = get("/rest/config/options")
var opts config.OptionsConfiguration
if err := unmarshalTo(resp.Body, &opts); err != nil {
t.Fatal(err)
}
if opts.MaxSendKbps != 50 {
t.Error("Exepcted 50 for MaxSendKbps, got", opts.MaxSendKbps)
}
}
func equalStrings(a, b []string) bool {
if len(a) != len(b) {
return false

410
lib/api/confighandler.go Normal file
View File

@@ -0,0 +1,410 @@
// Copyright (C) 2020 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 api
import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
"github.com/julienschmidt/httprouter"
"golang.org/x/crypto/bcrypt"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/protocol"
)
type configMuxBuilder struct {
*httprouter.Router
id protocol.DeviceID
cfg config.Wrapper
}
func (c *configMuxBuilder) registerConfig(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.RawCopy())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustConfig(w, r)
})
}
func (c *configMuxBuilder) registerConfigDeprecated(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.RawCopy())
})
c.HandlerFunc(http.MethodPost, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustConfig(w, r)
})
}
func (c *configMuxBuilder) registerConfigInsync(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, map[string]bool{"configInSync": !c.cfg.RequiresRestart()})
})
}
func (c *configMuxBuilder) registerFolders(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.FolderList())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
var folders []config.FolderConfiguration
if err := unmarshalTo(r.Body, &folders); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetFolders(folders)
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
})
c.HandlerFunc(http.MethodPost, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustFolder(w, r, config.FolderConfiguration{}, false)
})
}
func (c *configMuxBuilder) registerDevices(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.DeviceList())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
var devices []config.DeviceConfiguration
if err := unmarshalTo(r.Body, &devices); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetDevices(devices)
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
})
c.HandlerFunc(http.MethodPost, path, func(w http.ResponseWriter, r *http.Request) {
var device config.DeviceConfiguration
if err := unmarshalTo(r.Body, &device); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.SetDevice(device)
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
})
}
func (c *configMuxBuilder) registerFolder(path string) {
c.Handle(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request, p httprouter.Params) {
folder, ok := c.cfg.Folder(p.ByName("id"))
if !ok {
http.Error(w, "No folder with given ID", http.StatusNotFound)
return
}
sendJSON(w, folder)
})
c.Handle(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
c.adjustFolder(w, r, config.FolderConfiguration{}, false)
})
c.Handle(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
folder, ok := c.cfg.Folder(p.ByName("id"))
if !ok {
http.Error(w, "No folder with given ID", http.StatusNotFound)
return
}
c.adjustFolder(w, r, folder, false)
})
c.Handle(http.MethodDelete, path, func(w http.ResponseWriter, _ *http.Request, p httprouter.Params) {
waiter, err := c.cfg.RemoveFolder(p.ByName("id"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
c.finish(w, waiter)
})
}
func (c *configMuxBuilder) registerDevice(path string) {
deviceFromParams := func(w http.ResponseWriter, p httprouter.Params) (config.DeviceConfiguration, bool) {
id, err := protocol.DeviceIDFromString(p.ByName("id"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return config.DeviceConfiguration{}, false
}
device, ok := c.cfg.Device(id)
if !ok {
http.Error(w, "No device with given ID", http.StatusNotFound)
return config.DeviceConfiguration{}, false
}
return device, true
}
c.Handle(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request, p httprouter.Params) {
if device, ok := deviceFromParams(w, p); ok {
sendJSON(w, device)
}
})
c.Handle(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
c.adjustDevice(w, r, config.DeviceConfiguration{}, false)
})
c.Handle(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
if device, ok := deviceFromParams(w, p); ok {
c.adjustDevice(w, r, device, false)
}
})
c.Handle(http.MethodDelete, path, func(w http.ResponseWriter, _ *http.Request, p httprouter.Params) {
id, err := protocol.DeviceIDFromString(p.ByName("id"))
waiter, err := c.cfg.RemoveDevice(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
c.finish(w, waiter)
})
}
func (c *configMuxBuilder) registerDefaultFolder(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.DefaultFolder())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustFolder(w, r, config.FolderConfiguration{}, true)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustFolder(w, r, c.cfg.DefaultFolder(), true)
})
}
func (c *configMuxBuilder) registerDefaultDevice(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.DefaultDevice())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustDevice(w, r, config.DeviceConfiguration{}, true)
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustDevice(w, r, c.cfg.DefaultDevice(), true)
})
}
func (c *configMuxBuilder) registerOptions(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.Options())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustOptions(w, r, config.OptionsConfiguration{})
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustOptions(w, r, c.cfg.Options())
})
}
func (c *configMuxBuilder) registerLDAP(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.LDAP())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustLDAP(w, r, config.LDAPConfiguration{})
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustLDAP(w, r, c.cfg.LDAP())
})
}
func (c *configMuxBuilder) registerGUI(path string) {
c.HandlerFunc(http.MethodGet, path, func(w http.ResponseWriter, _ *http.Request) {
sendJSON(w, c.cfg.GUI())
})
c.HandlerFunc(http.MethodPut, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustGUI(w, r, config.GUIConfiguration{})
})
c.HandlerFunc(http.MethodPatch, path, func(w http.ResponseWriter, r *http.Request) {
c.adjustGUI(w, r, c.cfg.GUI())
})
}
func (c *configMuxBuilder) adjustConfig(w http.ResponseWriter, r *http.Request) {
to, err := config.ReadJSON(r.Body, c.id)
r.Body.Close()
if err != nil {
l.Warnln("Decoding posted config:", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var errMsg string
var status int
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if to.GUI.Password, err = checkGUIPassword(cfg.GUI.Password, to.GUI.Password); err != nil {
l.Warnln("bcrypting password:", err)
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
*cfg = to
})
if errMsg != "" {
http.Error(w, errMsg, status)
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
func (c *configMuxBuilder) adjustFolder(w http.ResponseWriter, r *http.Request, folder config.FolderConfiguration, defaults bool) {
if err := unmarshalTo(r.Body, &folder); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if defaults {
cfg.Defaults.Folder = folder
} else {
cfg.SetFolder(folder)
}
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
func (c *configMuxBuilder) adjustDevice(w http.ResponseWriter, r *http.Request, device config.DeviceConfiguration, defaults bool) {
if err := unmarshalTo(r.Body, &device); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if defaults {
cfg.Defaults.Device = device
} else {
cfg.SetDevice(device)
}
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
func (c *configMuxBuilder) adjustOptions(w http.ResponseWriter, r *http.Request, opts config.OptionsConfiguration) {
if err := unmarshalTo(r.Body, &opts); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.Options = opts
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
func (c *configMuxBuilder) adjustGUI(w http.ResponseWriter, r *http.Request, gui config.GUIConfiguration) {
oldPassword := gui.Password
err := unmarshalTo(r.Body, &gui)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var errMsg string
var status int
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
if gui.Password, err = checkGUIPassword(oldPassword, gui.Password); err != nil {
l.Warnln("bcrypting password:", err)
errMsg = err.Error()
status = http.StatusInternalServerError
return
}
cfg.GUI = gui
})
if errMsg != "" {
http.Error(w, errMsg, status)
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
func (c *configMuxBuilder) adjustLDAP(w http.ResponseWriter, r *http.Request, ldap config.LDAPConfiguration) {
if err := unmarshalTo(r.Body, &ldap); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
waiter, err := c.cfg.Modify(func(cfg *config.Configuration) {
cfg.LDAP = ldap
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
c.finish(w, waiter)
}
// Unmarshals the content of the given body and stores it in to (i.e. to must be a pointer).
func unmarshalTo(body io.ReadCloser, to interface{}) error {
bs, err := ioutil.ReadAll(body)
body.Close()
if err != nil {
return err
}
return json.Unmarshal(bs, to)
}
func checkGUIPassword(oldPassword, newPassword string) (string, error) {
if newPassword == oldPassword {
return newPassword, nil
}
hash, err := bcrypt.GenerateFromPassword([]byte(newPassword), 0)
return string(hash), err
}
func (c *configMuxBuilder) finish(w http.ResponseWriter, waiter config.Waiter) {
waiter.Wait()
if err := c.cfg.Save(); err != nil {
l.Warnln("Saving config:", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

View File

@@ -38,11 +38,13 @@ func (c *mockedConfig) Options() config.OptionsConfiguration {
return config.OptionsConfiguration{}
}
func (c *mockedConfig) Replace(cfg config.Configuration) (config.Waiter, error) {
func (c *mockedConfig) Modify(config.ModifyFunction) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) Subscribe(cm config.Committer) {}
func (c *mockedConfig) Subscribe(cm config.Committer) config.Configuration {
return config.Configuration{}
}
func (c *mockedConfig) Unsubscribe(cm config.Committer) {}
@@ -54,12 +56,8 @@ func (c *mockedConfig) Devices() map[protocol.DeviceID]config.DeviceConfiguratio
return nil
}
func (c *mockedConfig) SetDevice(config.DeviceConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) SetDevices([]config.DeviceConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
func (c *mockedConfig) DeviceList() []config.DeviceConfiguration {
return nil
}
func (c *mockedConfig) Save() error {
@@ -78,14 +76,6 @@ func (c *mockedConfig) ConfigPath() string {
return ""
}
func (c *mockedConfig) SetGUI(gui config.GUIConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) SetOptions(opts config.OptionsConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) Folder(id string) (config.FolderConfiguration, bool) {
return config.FolderConfiguration{}, false
}
@@ -94,14 +84,13 @@ func (c *mockedConfig) FolderList() []config.FolderConfiguration {
return nil
}
func (c *mockedConfig) SetFolder(fld config.FolderConfiguration) (config.Waiter, error) {
func (c *mockedConfig) RemoveFolder(id string) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) SetFolders(folders []config.FolderConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
func (c *mockedConfig) FolderPasswords(device protocol.DeviceID) map[string]string {
return nil
}
func (c *mockedConfig) Device(id protocol.DeviceID) (config.DeviceConfiguration, bool) {
return config.DeviceConfiguration{}, false
}
@@ -114,10 +103,30 @@ func (c *mockedConfig) IgnoredDevice(id protocol.DeviceID) bool {
return false
}
func (c *mockedConfig) IgnoredDevices() []config.ObservedDevice {
return nil
}
func (c *mockedConfig) IgnoredFolder(device protocol.DeviceID, folder string) bool {
return false
}
func (c *mockedConfig) DefaultFolder() config.FolderConfiguration {
return config.FolderConfiguration{}
}
func (c *mockedConfig) SetDefaultFolder(config.FolderConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) DefaultDevice() config.DeviceConfiguration {
return config.DeviceConfiguration{}
}
func (c *mockedConfig) SetDefaultDevice(config.DeviceConfiguration) (config.Waiter, error) {
return noopWaiter{}, nil
}
func (c *mockedConfig) GlobalDiscoveryServers() []string {
return nil
}
@@ -126,6 +135,10 @@ func (c *mockedConfig) StunServers() []string {
return nil
}
func (c *mockedConfig) MyID() protocol.DeviceID {
return protocol.DeviceID{}
}
type noopWaiter struct{}
func (noopWaiter) Wait() {}

View File

@@ -7,6 +7,8 @@
package api
import (
"context"
"github.com/syncthing/syncthing/lib/connections"
)
@@ -24,9 +26,7 @@ func (m *mockedConnections) NATType() string {
return ""
}
func (m *mockedConnections) Serve() {}
func (m *mockedConnections) Stop() {}
func (m *mockedConnections) Serve(ctx context.Context) error { return nil }
func (m *mockedConnections) ExternalAddresses() []string { return nil }

View File

@@ -17,13 +17,10 @@ type mockedCachingMux struct{}
// from suture.Service
func (m *mockedCachingMux) Serve() {
func (m *mockedCachingMux) Serve(ctx context.Context) error {
select {}
}
func (m *mockedCachingMux) Stop() {
}
// from events.Finder
func (m *mockedCachingMux) Lookup(ctx context.Context, deviceID protocol.DeviceID) (direct []string, err error) {

View File

@@ -7,10 +7,10 @@
package api
import (
"context"
"net"
"time"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/protocol"
@@ -21,8 +21,8 @@ import (
type mockedModel struct{}
func (m *mockedModel) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly bool) map[string]interface{} {
return nil
func (m *mockedModel) GlobalDirectoryTree(folder, prefix string, levels int, dirsOnly bool) ([]*model.TreeEntry, error) {
return nil, nil
}
func (m *mockedModel) Completion(device protocol.DeviceID, folder string) model.FolderCompletion {
@@ -33,19 +33,31 @@ func (m *mockedModel) Override(folder string) {}
func (m *mockedModel) Revert(folder string) {}
func (m *mockedModel) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated) {
return nil, nil, nil
func (m *mockedModel) NeedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, []db.FileInfoTruncated, []db.FileInfoTruncated, error) {
return nil, nil, nil, nil
}
func (*mockedModel) RemoteNeedFolderFiles(folder string, device protocol.DeviceID, page, perpage int) ([]db.FileInfoTruncated, error) {
return nil, nil
}
func (*mockedModel) LocalChangedFolderFiles(folder string, page, perpage int) ([]db.FileInfoTruncated, error) {
return nil, nil
}
func (m *mockedModel) FolderProgressBytesCompleted(_ string) int64 {
return 0
}
func (m *mockedModel) NumConnections() int {
return 0
}
func (m *mockedModel) ConnectionStats() map[string]interface{} {
return nil
}
func (m *mockedModel) DeviceStatistics() (map[string]stats.DeviceStatistics, error) {
func (m *mockedModel) DeviceStatistics() (map[protocol.DeviceID]stats.DeviceStatistics, error) {
return nil, nil
}
@@ -68,7 +80,11 @@ func (m *mockedModel) Availability(folder string, file protocol.FileInfo, block
return nil
}
func (m *mockedModel) GetIgnores(folder string) ([]string, []string, error) {
func (m *mockedModel) LoadIgnores(folder string) ([]string, []string, error) {
return nil, nil, nil
}
func (m *mockedModel) CurrentIgnores(folder string) ([]string, []string, error) {
return nil, nil, nil
}
@@ -80,7 +96,7 @@ func (m *mockedModel) GetFolderVersions(folder string) (map[string][]versioner.F
return nil, nil
}
func (m *mockedModel) RestoreFolderVersions(folder string, versions map[string]time.Time) (map[string]string, error) {
func (m *mockedModel) RestoreFolderVersions(folder string, versions map[string]time.Time) (map[string]error, error) {
return nil, nil
}
@@ -105,7 +121,7 @@ func (m *mockedModel) ScanFolderSubdirs(folder string, subs []string) error {
func (m *mockedModel) BringToFront(folder, file string) {}
func (m *mockedModel) Connection(deviceID protocol.DeviceID) (connections.Connection, bool) {
func (m *mockedModel) Connection(deviceID protocol.DeviceID) (protocol.Connection, bool) {
return nil, false
}
@@ -116,6 +132,14 @@ func (m *mockedModel) State(folder string) (string, time.Time, error) {
func (m *mockedModel) UsageReportingStats(r *contract.Report, version int, preview bool) {
}
func (m *mockedModel) PendingDevices() (map[protocol.DeviceID]db.ObservedDevice, error) {
return nil, nil
}
func (m *mockedModel) PendingFolders(device protocol.DeviceID) (map[string]db.PendingFolder, error) {
return nil, nil
}
func (m *mockedModel) FolderErrors(folder string) ([]model.FileError, error) {
return nil, nil
}
@@ -124,8 +148,7 @@ func (m *mockedModel) WatchError(folder string) error {
return nil
}
func (m *mockedModel) Serve() {}
func (m *mockedModel) Stop() {}
func (m *mockedModel) Serve(ctx context.Context) error { return nil }
func (m *mockedModel) Index(deviceID protocol.DeviceID, folder string, files []protocol.FileInfo) error {
return nil
@@ -135,7 +158,7 @@ func (m *mockedModel) IndexUpdate(deviceID protocol.DeviceID, folder string, fil
return nil
}
func (m *mockedModel) Request(deviceID protocol.DeviceID, folder, name string, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (protocol.RequestResponse, error) {
func (m *mockedModel) Request(deviceID protocol.DeviceID, folder, name string, blockNo, size int32, offset int64, hash []byte, weakHash uint32, fromTemporary bool) (protocol.RequestResponse, error) {
return nil, nil
}
@@ -149,7 +172,7 @@ func (m *mockedModel) DownloadProgress(deviceID protocol.DeviceID, folder string
return nil
}
func (m *mockedModel) AddConnection(conn connections.Connection, hello protocol.Hello) {}
func (m *mockedModel) AddConnection(conn protocol.Connection, hello protocol.Hello) {}
func (m *mockedModel) OnHello(protocol.DeviceID, net.Addr, protocol.Hello) error {
return nil
@@ -167,9 +190,7 @@ func (m *mockedModel) DBSnapshot(_ string) (*db.Snapshot, error) {
type mockedFolderSummaryService struct{}
func (m *mockedFolderSummaryService) Serve() {}
func (m *mockedFolderSummaryService) Stop() {}
func (m *mockedFolderSummaryService) Serve(context.Context) error { return nil }
func (m *mockedFolderSummaryService) Summary(folder string) (map[string]interface{}, error) {
return map[string]interface{}{"mocked": true}, nil

View File

@@ -12,9 +12,9 @@ import (
"net"
"time"
"github.com/thejerf/suture"
"github.com/thejerf/suture/v4"
"github.com/syncthing/syncthing/lib/util"
"github.com/syncthing/syncthing/lib/svcutil"
)
type recv struct {
@@ -33,8 +33,8 @@ type Interface interface {
type cast struct {
*suture.Supervisor
name string
reader util.ServiceWithError
writer util.ServiceWithError
reader svcutil.ServiceWithError
writer svcutil.ServiceWithError
outbox chan recv
inbox chan []byte
stopped chan struct{}
@@ -44,24 +44,22 @@ type cast struct {
// caller needs to set reader and writer with the addReader and addWriter
// methods to get a functional implementation of Interface.
func newCast(name string) *cast {
return &cast{
Supervisor: suture.New(name, suture.Spec{
// Don't retry too frenetically: an error to open a socket or
// whatever is usually something that is either permanent or takes
// a while to get solved...
FailureThreshold: 2,
FailureBackoff: 60 * time.Second,
// Only log restarts in debug mode.
Log: func(line string) {
l.Debugln(line)
},
PassThroughPanics: true,
}),
name: name,
inbox: make(chan []byte),
outbox: make(chan recv, 16),
stopped: make(chan struct{}),
// Only log restarts in debug mode.
spec := svcutil.SpecWithDebugLogger(l)
// Don't retry too frenetically: an error to open a socket or
// whatever is usually something that is either permanent or takes
// a while to get solved...
spec.FailureThreshold = 2
spec.FailureBackoff = 60 * time.Second
c := &cast{
Supervisor: suture.New(name, spec),
name: name,
inbox: make(chan []byte),
outbox: make(chan recv, 16),
stopped: make(chan struct{}),
}
svcutil.OnSupervisorDone(c.Supervisor, func() { close(c.stopped) })
return c
}
func (c *cast) addReader(svc func(context.Context) error) {
@@ -74,18 +72,8 @@ func (c *cast) addWriter(svc func(ctx context.Context) error) {
c.Add(c.writer)
}
func (c *cast) createService(svc func(context.Context) error, suffix string) util.ServiceWithError {
return util.AsServiceWithError(func(ctx context.Context) error {
l.Debugln("Starting", c.name, suffix)
err := svc(ctx)
l.Debugf("Stopped %v %v: %v", c.name, suffix, err)
return err
}, fmt.Sprintf("%s/%s", c, suffix))
}
func (c *cast) Stop() {
c.Supervisor.Stop()
close(c.stopped)
func (c *cast) createService(svc func(context.Context) error, suffix string) svcutil.ServiceWithError {
return svcutil.AsService(svc, fmt.Sprintf("%s/%s", c, suffix))
}
func (c *cast) String() string {

View File

@@ -41,7 +41,7 @@ func writeBroadcasts(ctx context.Context, inbox <-chan []byte, port int) error {
select {
case bs = <-inbox:
case <-doneCtx.Done():
return nil
return doneCtx.Err()
}
intfs, err := net.Interfaces()
@@ -138,7 +138,7 @@ func readBroadcasts(ctx context.Context, outbox chan<- recv, port int) error {
select {
case outbox <- recv{c, addr}:
case <-doneCtx.Done():
return nil
return doneCtx.Err()
default:
l.Debugln("dropping message")
}

View File

@@ -56,7 +56,7 @@ func writeMulticasts(ctx context.Context, inbox <-chan []byte, addr string) erro
select {
case bs = <-inbox:
case <-doneCtx.Done():
return nil
return doneCtx.Err()
}
intfs, err := net.Interfaces()
@@ -87,7 +87,7 @@ func writeMulticasts(ctx context.Context, inbox <-chan []byte, addr string) erro
select {
case <-doneCtx.Done():
return nil
return doneCtx.Err()
default:
}
}
@@ -144,7 +144,7 @@ func readMulticasts(ctx context.Context, outbox chan<- recv, addr string) error
for {
select {
case <-doneCtx.Done():
return nil
return doneCtx.Err()
default:
}
n, _, addr, err := pconn.ReadFrom(bs)

View File

@@ -43,7 +43,6 @@ var (
"STHASHING",
"STNORESTART",
"STNOUPGRADE",
"USE_BADGER",
}
)
@@ -88,6 +87,13 @@ func LongVersionFor(program string) string {
date := Date.UTC().Format("2006-01-02 15:04:05 MST")
v := fmt.Sprintf(`%s %s "%s" (%s %s-%s) %s@%s %s`, program, Version, Codename, runtime.Version(), runtime.GOOS, runtime.GOARCH, User, Host, date)
if tags := TagsList(); len(tags) > 0 {
v = fmt.Sprintf("%s [%s]", v, strings.Join(tags, ", "))
}
return v
}
func TagsList() []string {
tags := strings.Split(Tags, ",")
if len(tags) == 1 && tags[0] == "" {
tags = tags[:0]
@@ -97,9 +103,7 @@ func LongVersionFor(program string) string {
tags = append(tags, strings.ToLower(envVar))
}
}
if len(tags) > 0 {
sort.Strings(tags)
v = fmt.Sprintf("%s [%s]", v, strings.Join(tags, ", "))
}
return v
sort.Strings(tags)
return tags
}

View File

@@ -41,10 +41,20 @@ func (validationError) String() string {
return "validationError"
}
func TestReplaceCommit(t *testing.T) {
t.Skip("broken, fails randomly, #3834")
func replace(t testing.TB, w Wrapper, to Configuration) {
t.Helper()
waiter, err := w.Modify(func(cfg *Configuration) {
*cfg = to
})
if err != nil {
t.Fatal(err)
}
waiter.Wait()
}
w := wrap("/dev/null", Configuration{Version: 0})
func TestReplaceCommit(t *testing.T) {
w := wrap("/dev/null", Configuration{Version: 0}, device1)
defer w.stop()
if w.RawCopy().Version != 0 {
t.Fatal("Config incorrect")
}
@@ -52,10 +62,7 @@ func TestReplaceCommit(t *testing.T) {
// Replace config. We should get back a clean response and the config
// should change.
_, err := w.Replace(Configuration{Version: 1})
if err != nil {
t.Fatal("Should not have a validation error:", err)
}
replace(t, w, Configuration{Version: 1})
if w.RequiresRestart() {
t.Fatal("Should not require restart")
}
@@ -69,11 +76,7 @@ func TestReplaceCommit(t *testing.T) {
sub0 := requiresRestart{committed: make(chan struct{}, 1)}
w.Subscribe(sub0)
_, err = w.Replace(Configuration{Version: 2})
if err != nil {
t.Fatal("Should not have a validation error:", err)
}
replace(t, w, Configuration{Version: 1})
<-sub0.committed
if !w.RequiresRestart() {
t.Fatal("Should require restart")
@@ -87,7 +90,9 @@ func TestReplaceCommit(t *testing.T) {
w.Subscribe(validationError{})
_, err = w.Replace(Configuration{Version: 3})
_, err := w.Modify(func(cfg *Configuration) {
*cfg = Configuration{Version: 3}
})
if err == nil {
t.Fatal("Should have a validation error")
}

View File

@@ -25,13 +25,12 @@ import (
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/util"
)
const (
OldestHandledVersion = 10
CurrentVersion = 32
CurrentVersion = 35
MaxRescanIntervalS = 365 * 24 * 60 * 60
)
@@ -105,8 +104,6 @@ func New(myID protocol.DeviceID) Configuration {
cfg.Options.UnackedNotificationIDs = []string{"authenticationUserAndPassword"}
util.SetDefaults(&cfg)
util.SetDefaults(&cfg.Options)
util.SetDefaults(&cfg.GUI)
// Can't happen.
if err := cfg.prepare(myID); err != nil {
@@ -152,8 +149,6 @@ func ReadXML(r io.Reader, myID protocol.DeviceID) (Configuration, int, error) {
var cfg xmlConfiguration
util.SetDefaults(&cfg)
util.SetDefaults(&cfg.Options)
util.SetDefaults(&cfg.GUI)
if err := xml.NewDecoder(r).Decode(&cfg); err != nil {
return Configuration{}, 0, err
@@ -171,8 +166,6 @@ func ReadJSON(r io.Reader, myID protocol.DeviceID) (Configuration, error) {
var cfg Configuration
util.SetDefaults(&cfg)
util.SetDefaults(&cfg.Options)
util.SetDefaults(&cfg.GUI)
bs, err := ioutil.ReadAll(r)
if err != nil {
@@ -211,9 +204,6 @@ func (cfg Configuration) Copy() Configuration {
newCfg.IgnoredDevices = make([]ObservedDevice, len(cfg.IgnoredDevices))
copy(newCfg.IgnoredDevices, cfg.IgnoredDevices)
newCfg.PendingDevices = make([]ObservedDevice, len(cfg.PendingDevices))
copy(newCfg.PendingDevices, cfg.PendingDevices)
return newCfg
}
@@ -230,38 +220,60 @@ func (cfg *Configuration) WriteXML(w io.Writer) error {
}
func (cfg *Configuration) prepare(myID protocol.DeviceID) error {
var myName string
cfg.ensureMyDevice(myID)
// Ensure this device is present in the config
for _, device := range cfg.Devices {
if device.DeviceID == myID {
goto found
}
}
myName, _ = os.Hostname()
cfg.Devices = append(cfg.Devices, DeviceConfiguration{
DeviceID: myID,
Name: myName,
})
found:
if err := cfg.clean(); err != nil {
existingDevices, err := cfg.prepareFoldersAndDevices(myID)
if err != nil {
return err
}
// Ensure that we are part of the devices
for i := range cfg.Folders {
cfg.Folders[i].Devices = ensureDevicePresent(cfg.Folders[i].Devices, myID)
}
cfg.GUI.prepare()
guiPWIsSet := cfg.GUI.User != "" && cfg.GUI.Password != ""
cfg.Options.prepare(guiPWIsSet)
cfg.prepareIgnoredDevices(existingDevices)
cfg.Defaults.prepare(myID, existingDevices)
cfg.removeDeprecatedProtocols()
util.FillNilExceptDeprecated(cfg)
// TestIssue1750 relies on migrations happening after preparing options.
cfg.applyMigrations()
return nil
}
func (cfg *Configuration) clean() error {
util.FillNilSlices(&cfg.Options)
func (cfg *Configuration) ensureMyDevice(myID protocol.DeviceID) {
for _, device := range cfg.Devices {
if device.DeviceID == myID {
return
}
}
myName, _ := os.Hostname()
cfg.Devices = append(cfg.Devices, DeviceConfiguration{
DeviceID: myID,
Name: myName,
})
}
func (cfg *Configuration) prepareFoldersAndDevices(myID protocol.DeviceID) (map[protocol.DeviceID]bool, error) {
existingDevices := cfg.prepareDeviceList()
sharedFolders, err := cfg.prepareFolders(myID, existingDevices)
if err != nil {
return nil, err
}
cfg.prepareDevices(sharedFolders)
return existingDevices, nil
}
func (cfg *Configuration) prepareDeviceList() map[protocol.DeviceID]bool {
// Ensure that the device list is
// - free from duplicates
// - no devices with empty ID
@@ -272,87 +284,62 @@ func (cfg *Configuration) clean() error {
return cfg.Devices[a].DeviceID.Compare(cfg.Devices[b].DeviceID) == -1
})
// Build a list of available devices
existingDevices := make(map[protocol.DeviceID]bool, len(cfg.Devices))
for _, device := range cfg.Devices {
existingDevices[device.DeviceID] = true
}
return existingDevices
}
func (cfg *Configuration) prepareFolders(myID protocol.DeviceID, existingDevices map[protocol.DeviceID]bool) (map[protocol.DeviceID][]string, error) {
// Prepare folders and check for duplicates. Duplicates are bad and
// dangerous, can't currently be resolved in the GUI, and shouldn't
// happen when configured by the GUI. We return with an error in that
// situation.
existingFolders := make(map[string]*FolderConfiguration)
sharedFolders := make(map[protocol.DeviceID][]string, len(cfg.Devices))
existingFolders := make(map[string]*FolderConfiguration, len(cfg.Folders))
for i := range cfg.Folders {
folder := &cfg.Folders[i]
folder.prepare()
if folder.ID == "" {
return errFolderIDEmpty
return nil, errFolderIDEmpty
}
if folder.Path == "" {
return fmt.Errorf("folder %q: %w", folder.ID, errFolderPathEmpty)
return nil, fmt.Errorf("folder %q: %w", folder.ID, errFolderPathEmpty)
}
if _, ok := existingFolders[folder.ID]; ok {
return fmt.Errorf("folder %q: %w", folder.ID, errFolderIDDuplicate)
return nil, fmt.Errorf("folder %q: %w", folder.ID, errFolderIDDuplicate)
}
folder.prepare(myID, existingDevices)
existingFolders[folder.ID] = folder
for _, dev := range folder.Devices {
sharedFolders[dev.DeviceID] = append(sharedFolders[dev.DeviceID], folder.ID)
}
}
cfg.Options.RawListenAddresses = util.UniqueTrimmedStrings(cfg.Options.RawListenAddresses)
cfg.Options.RawGlobalAnnServers = util.UniqueTrimmedStrings(cfg.Options.RawGlobalAnnServers)
if cfg.Version > 0 && cfg.Version < OldestHandledVersion {
l.Warnf("Configuration version %d is deprecated. Attempting best effort conversion, but please verify manually.", cfg.Version)
}
// Upgrade configuration versions as appropriate
migrations.apply(cfg)
// Build a list of available devices
existingDevices := make(map[protocol.DeviceID]bool)
for _, device := range cfg.Devices {
existingDevices[device.DeviceID] = true
}
// Ensure that the folder list is sorted by ID
sort.Slice(cfg.Folders, func(a, b int) bool {
return cfg.Folders[a].ID < cfg.Folders[b].ID
})
return sharedFolders, nil
}
// Ensure that in all folder configs
// - any loose devices are not present in the wrong places
// - there are no duplicate devices
// - the versioning configuration parameter map is not nil
sharedFolders := make(map[protocol.DeviceID][]string, len(cfg.Devices))
for i := range cfg.Folders {
cfg.Folders[i].Devices = ensureExistingDevices(cfg.Folders[i].Devices, existingDevices)
cfg.Folders[i].Devices = ensureNoDuplicateFolderDevices(cfg.Folders[i].Devices)
if cfg.Folders[i].Versioning.Params == nil {
cfg.Folders[i].Versioning.Params = map[string]string{}
}
sort.Slice(cfg.Folders[i].Devices, func(a, b int) bool {
return cfg.Folders[i].Devices[a].DeviceID.Compare(cfg.Folders[i].Devices[b].DeviceID) == -1
})
for _, dev := range cfg.Folders[i].Devices {
sharedFolders[dev.DeviceID] = append(sharedFolders[dev.DeviceID], cfg.Folders[i].ID)
}
}
func (cfg *Configuration) prepareDevices(sharedFolders map[protocol.DeviceID][]string) {
for i := range cfg.Devices {
cfg.Devices[i].prepare(sharedFolders[cfg.Devices[i].DeviceID])
}
}
// Very short reconnection intervals are annoying
if cfg.Options.ReconnectIntervalS < 5 {
cfg.Options.ReconnectIntervalS = 5
}
if cfg.GUI.APIKey == "" {
cfg.GUI.APIKey = rand.String(32)
}
func (cfg *Configuration) prepareIgnoredDevices(existingDevices map[protocol.DeviceID]bool) map[protocol.DeviceID]bool {
// The list of ignored devices should not contain any devices that have
// been manually added to the config.
var newIgnoredDevices []ObservedDevice
ignoredDevices := make(map[protocol.DeviceID]bool)
newIgnoredDevices := cfg.IgnoredDevices[:0]
ignoredDevices := make(map[protocol.DeviceID]bool, len(cfg.IgnoredDevices))
for _, dev := range cfg.IgnoredDevices {
if !existingDevices[dev.ID] {
ignoredDevices[dev.ID] = true
@@ -360,30 +347,10 @@ func (cfg *Configuration) clean() error {
}
}
cfg.IgnoredDevices = newIgnoredDevices
return ignoredDevices
}
// The list of pending devices should not contain devices that were added manually, nor should it contain
// ignored devices.
// Sort by time, so that in case of duplicates latest "time" is used.
sort.Slice(cfg.PendingDevices, func(i, j int) bool {
return cfg.PendingDevices[i].Time.Before(cfg.PendingDevices[j].Time)
})
var newPendingDevices []ObservedDevice
nextPendingDevice:
for _, pendingDevice := range cfg.PendingDevices {
if !existingDevices[pendingDevice.ID] && !ignoredDevices[pendingDevice.ID] {
// Deduplicate
for _, existingPendingDevice := range newPendingDevices {
if existingPendingDevice.ID == pendingDevice.ID {
continue nextPendingDevice
}
}
newPendingDevices = append(newPendingDevices, pendingDevice)
}
}
cfg.PendingDevices = newPendingDevices
func (cfg *Configuration) removeDeprecatedProtocols() {
// Deprecated protocols are removed from the list of listeners and
// device addresses. So far just kcp*.
for _, prefix := range []string{"kcp"} {
@@ -393,32 +360,26 @@ nextPendingDevice:
dev.Addresses = filterURLSchemePrefix(dev.Addresses, prefix)
}
}
}
// Initialize any empty slices
if cfg.Folders == nil {
cfg.Folders = []FolderConfiguration{}
func (cfg *Configuration) applyMigrations() {
if cfg.Version > 0 && cfg.Version < OldestHandledVersion {
l.Warnf("Configuration version %d is deprecated. Attempting best effort conversion, but please verify manually.", cfg.Version)
}
if cfg.IgnoredDevices == nil {
cfg.IgnoredDevices = []ObservedDevice{}
}
if cfg.PendingDevices == nil {
cfg.PendingDevices = []ObservedDevice{}
}
if cfg.Options.AlwaysLocalNets == nil {
cfg.Options.AlwaysLocalNets = []string{}
}
if cfg.Options.UnackedNotificationIDs == nil {
cfg.Options.UnackedNotificationIDs = []string{}
} else if cfg.GUI.User != "" && cfg.GUI.Password != "" {
for i, key := range cfg.Options.UnackedNotificationIDs {
if key == "authenticationUserAndPassword" {
cfg.Options.UnackedNotificationIDs = append(cfg.Options.UnackedNotificationIDs[:i], cfg.Options.UnackedNotificationIDs[i+1:]...)
break
}
// Upgrade configuration versions as appropriate
migrationsMut.Lock()
migrations.apply(cfg)
migrationsMut.Unlock()
}
func (cfg *Configuration) Device(id protocol.DeviceID) (DeviceConfiguration, int, bool) {
for i, device := range cfg.Devices {
if device.DeviceID == id {
return device, i, true
}
}
return nil
return DeviceConfiguration{}, 0, false
}
// DeviceMap returns a map of device ID to device configuration for the given configuration.
@@ -430,6 +391,80 @@ func (cfg *Configuration) DeviceMap() map[protocol.DeviceID]DeviceConfiguration
return m
}
func (cfg *Configuration) SetDevice(device DeviceConfiguration) {
cfg.SetDevices([]DeviceConfiguration{device})
}
func (cfg *Configuration) SetDevices(devices []DeviceConfiguration) {
inds := make(map[protocol.DeviceID]int, len(cfg.Devices))
for i, device := range cfg.Devices {
inds[device.DeviceID] = i
}
filtered := devices[:0]
for _, device := range devices {
if i, ok := inds[device.DeviceID]; ok {
cfg.Devices[i] = device
} else {
filtered = append(filtered, device)
}
}
cfg.Devices = append(cfg.Devices, filtered...)
}
func (cfg *Configuration) Folder(id string) (FolderConfiguration, int, bool) {
for i, folder := range cfg.Folders {
if folder.ID == id {
return folder, i, true
}
}
return FolderConfiguration{}, 0, false
}
// FolderMap returns a map of folder ID to folder configuration for the given configuration.
func (cfg *Configuration) FolderMap() map[string]FolderConfiguration {
m := make(map[string]FolderConfiguration, len(cfg.Folders))
for _, folder := range cfg.Folders {
m[folder.ID] = folder
}
return m
}
// FolderPasswords returns the folder passwords set for this device, for
// folders that have an encryption password set.
func (cfg Configuration) FolderPasswords(device protocol.DeviceID) map[string]string {
res := make(map[string]string, len(cfg.Folders))
nextFolder:
for _, folder := range cfg.Folders {
for _, dev := range folder.Devices {
if dev.DeviceID == device && dev.EncryptionPassword != "" {
res[folder.ID] = dev.EncryptionPassword
continue nextFolder
}
}
}
return res
}
func (cfg *Configuration) SetFolder(folder FolderConfiguration) {
cfg.SetFolders([]FolderConfiguration{folder})
}
func (cfg *Configuration) SetFolders(folders []FolderConfiguration) {
inds := make(map[string]int, len(cfg.Folders))
for i, folder := range cfg.Folders {
inds[folder.ID] = i
}
filtered := folders[:0]
for _, folder := range folders {
if i, ok := inds[folder.ID]; ok {
cfg.Folders[i] = folder
} else {
filtered = append(filtered, folder)
}
}
cfg.Folders = append(cfg.Folders, filtered...)
}
func ensureDevicePresent(devices []FolderDeviceConfiguration, myID protocol.DeviceID) []FolderDeviceConfiguration {
for _, device := range devices {
if device.DeviceID.Equals(myID) {
@@ -552,3 +587,19 @@ func getFreePort(host string, ports ...int) (int, error) {
c.Close()
return addr.Port, nil
}
func (defaults *Defaults) prepare(myID protocol.DeviceID, existingDevices map[protocol.DeviceID]bool) {
ensureZeroForNodefault(&FolderConfiguration{}, &defaults.Folder)
ensureZeroForNodefault(&DeviceConfiguration{}, &defaults.Device)
defaults.Folder.prepare(myID, existingDevices)
defaults.Device.prepare(nil)
}
func ensureZeroForNodefault(empty interface{}, target interface{}) {
util.CopyMatchingTag(empty, target, "nodefault", func(v string) bool {
if len(v) > 0 && v != "true" {
panic(fmt.Sprintf(`unexpected tag value: %s. expected untagged or "true"`, v))
}
return len(v) > 0
})
}

View File

@@ -24,14 +24,15 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type Configuration struct {
Version int `protobuf:"varint,1,opt,name=version,proto3,casttype=int" json:"version" xml:"version,attr"`
Folders []FolderConfiguration `protobuf:"bytes,2,rep,name=folders,proto3" json:"folders" xml:"folder"`
Devices []DeviceConfiguration `protobuf:"bytes,3,rep,name=devices,proto3" json:"devices" xml:"device"`
GUI GUIConfiguration `protobuf:"bytes,4,opt,name=gui,proto3" json:"gui" xml:"gui"`
LDAP LDAPConfiguration `protobuf:"bytes,5,opt,name=ldap,proto3" json:"ldap" xml:"ldap"`
Options OptionsConfiguration `protobuf:"bytes,6,opt,name=options,proto3" json:"options" xml:"options"`
IgnoredDevices []ObservedDevice `protobuf:"bytes,7,rep,name=ignored_devices,json=ignoredDevices,proto3" json:"remoteIgnoredDevices" xml:"remoteIgnoredDevice"`
PendingDevices []ObservedDevice `protobuf:"bytes,8,rep,name=pending_devices,json=pendingDevices,proto3" json:"pendingDevices" xml:"pendingDevice"`
Version int `protobuf:"varint,1,opt,name=version,proto3,casttype=int" json:"version" xml:"version,attr"`
Folders []FolderConfiguration `protobuf:"bytes,2,rep,name=folders,proto3" json:"folders" xml:"folder"`
Devices []DeviceConfiguration `protobuf:"bytes,3,rep,name=devices,proto3" json:"devices" xml:"device"`
GUI GUIConfiguration `protobuf:"bytes,4,opt,name=gui,proto3" json:"gui" xml:"gui"`
LDAP LDAPConfiguration `protobuf:"bytes,5,opt,name=ldap,proto3" json:"ldap" xml:"ldap"`
Options OptionsConfiguration `protobuf:"bytes,6,opt,name=options,proto3" json:"options" xml:"options"`
IgnoredDevices []ObservedDevice `protobuf:"bytes,7,rep,name=ignored_devices,json=ignoredDevices,proto3" json:"remoteIgnoredDevices" xml:"remoteIgnoredDevice"`
DeprecatedPendingDevices []ObservedDevice `protobuf:"bytes,8,rep,name=pending_devices,json=pendingDevices,proto3" json:"-" xml:"pendingDevice,omitempty"` // Deprecated: Do not use.
Defaults Defaults `protobuf:"bytes,9,opt,name=defaults,proto3" json:"defaults" xml:"defaults"`
}
func (m *Configuration) Reset() { *m = Configuration{} }
@@ -67,49 +68,94 @@ func (m *Configuration) XXX_DiscardUnknown() {
var xxx_messageInfo_Configuration proto.InternalMessageInfo
type Defaults struct {
Folder FolderConfiguration `protobuf:"bytes,1,opt,name=folder,proto3" json:"folder" xml:"folder"`
Device DeviceConfiguration `protobuf:"bytes,2,opt,name=device,proto3" json:"device" xml:"device"`
}
func (m *Defaults) Reset() { *m = Defaults{} }
func (m *Defaults) String() string { return proto.CompactTextString(m) }
func (*Defaults) ProtoMessage() {}
func (*Defaults) Descriptor() ([]byte, []int) {
return fileDescriptor_baadf209193dc627, []int{1}
}
func (m *Defaults) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Defaults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Defaults.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Defaults) XXX_Merge(src proto.Message) {
xxx_messageInfo_Defaults.Merge(m, src)
}
func (m *Defaults) XXX_Size() int {
return m.ProtoSize()
}
func (m *Defaults) XXX_DiscardUnknown() {
xxx_messageInfo_Defaults.DiscardUnknown(m)
}
var xxx_messageInfo_Defaults proto.InternalMessageInfo
func init() {
proto.RegisterType((*Configuration)(nil), "config.Configuration")
proto.RegisterType((*Defaults)(nil), "config.Defaults")
}
func init() { proto.RegisterFile("lib/config/config.proto", fileDescriptor_baadf209193dc627) }
var fileDescriptor_baadf209193dc627 = []byte{
// 547 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x93, 0x4f, 0x8b, 0xd3, 0x40,
0x18, 0xc6, 0x13, 0xbb, 0xdb, 0xba, 0xd9, 0x7f, 0x90, 0x15, 0x4d, 0x55, 0x32, 0x75, 0xa8, 0x52,
0x45, 0xbb, 0xb0, 0x5e, 0xc4, 0x9b, 0xb5, 0xb8, 0x14, 0x05, 0x65, 0x60, 0x45, 0xbd, 0x48, 0xdb,
0xcc, 0xa6, 0x03, 0xed, 0x4c, 0x49, 0xd2, 0xb2, 0x7e, 0x0b, 0xf1, 0x13, 0x78, 0xf5, 0x1b, 0xf8,
0x11, 0x7a, 0x6b, 0x8f, 0x9e, 0x06, 0xb6, 0xbd, 0xf5, 0x98, 0xa3, 0x27, 0x99, 0x7f, 0xdd, 0x44,
0xa2, 0xa7, 0xe6, 0x7d, 0x9f, 0xe7, 0xf9, 0xbd, 0x2f, 0x6f, 0x13, 0xe7, 0xd6, 0x90, 0xf4, 0x8e,
0xfb, 0x8c, 0x9e, 0x93, 0x50, 0xff, 0x34, 0xc7, 0x11, 0x4b, 0x98, 0x5b, 0x56, 0xd5, 0xed, 0x7a,
0xc6, 0x70, 0xce, 0x86, 0x01, 0x8e, 0x54, 0x31, 0x89, 0xba, 0x09, 0x61, 0x54, 0xb9, 0x73, 0xae,
0x00, 0x4f, 0x49, 0x1f, 0x17, 0xb9, 0xee, 0x65, 0x5c, 0xe1, 0x84, 0x14, 0x59, 0x60, 0xc6, 0x32,
0x0c, 0xba, 0xe3, 0x22, 0xcf, 0xfd, 0x8c, 0x87, 0x8d, 0x85, 0x10, 0x17, 0xd9, 0xaa, 0x59, 0x5b,
0x2f, 0xc6, 0xd1, 0x14, 0x07, 0x5a, 0xda, 0xc1, 0x17, 0x89, 0x7a, 0x84, 0x3f, 0xcb, 0xce, 0xfe,
0xcb, 0x6c, 0xda, 0x45, 0x4e, 0x65, 0x8a, 0xa3, 0x98, 0x30, 0xea, 0xd9, 0x35, 0xbb, 0xb1, 0xdd,
0x7a, 0xb6, 0xe6, 0xc0, 0xb4, 0x52, 0x0e, 0xdc, 0x8b, 0xd1, 0xf0, 0x39, 0xd4, 0xf5, 0xe3, 0x6e,
0x92, 0x44, 0xf0, 0x37, 0x07, 0x25, 0x42, 0x93, 0xf5, 0xbc, 0xbe, 0x97, 0xed, 0x23, 0x93, 0x72,
0xdf, 0x3b, 0x15, 0x75, 0xbc, 0xd8, 0xbb, 0x56, 0x2b, 0x35, 0x76, 0x4f, 0xee, 0x34, 0xf5, 0xb5,
0x5f, 0xc9, 0x76, 0x6e, 0x83, 0x16, 0x98, 0x71, 0x60, 0x89, 0xa1, 0x3a, 0x93, 0x72, 0xb0, 0x27,
0x87, 0xaa, 0x1a, 0x22, 0x23, 0x08, 0xae, 0x3a, 0x77, 0xec, 0x95, 0xf2, 0xdc, 0xb6, 0x6c, 0xff,
0x83, 0xab, 0x33, 0x1b, 0xae, 0xaa, 0x21, 0x32, 0x82, 0x8b, 0x9c, 0x52, 0x38, 0x21, 0xde, 0x56,
0xcd, 0x6e, 0xec, 0x9e, 0x78, 0x86, 0x79, 0x7a, 0xd6, 0xc9, 0x03, 0x1f, 0x08, 0xe0, 0x92, 0x83,
0xd2, 0xe9, 0x59, 0x67, 0xcd, 0x81, 0xc8, 0xa4, 0x1c, 0xec, 0x48, 0x66, 0x38, 0x21, 0xf0, 0xdb,
0xa2, 0x2e, 0x24, 0x24, 0x04, 0xf7, 0xa3, 0xb3, 0x25, 0xfe, 0x51, 0x6f, 0x5b, 0x42, 0xab, 0x06,
0xfa, 0xa6, 0xfd, 0xe2, 0x5d, 0x9e, 0xfa, 0x48, 0x53, 0xb7, 0x84, 0xb4, 0xe6, 0x40, 0xc6, 0x52,
0x0e, 0x1c, 0xc9, 0x15, 0x85, 0x00, 0x4b, 0x15, 0x49, 0xcd, 0xfd, 0xe0, 0x54, 0xf4, 0x8b, 0xe0,
0x95, 0x25, 0xfd, 0xae, 0xa1, 0xbf, 0x55, 0xed, 0xfc, 0x80, 0x9a, 0xb9, 0x83, 0x0e, 0xa5, 0x1c,
0xec, 0x4b, 0xb6, 0xae, 0x21, 0x32, 0x8a, 0xfb, 0xc3, 0x76, 0x0e, 0x49, 0x48, 0x59, 0x84, 0x83,
0xcf, 0xe6, 0xd2, 0x15, 0x79, 0xe9, 0x9b, 0x9b, 0x11, 0xfa, 0xdd, 0x52, 0x17, 0x6f, 0x0d, 0x34,
0xfc, 0x46, 0x84, 0x47, 0x2c, 0xc1, 0x1d, 0x15, 0x6e, 0x6f, 0x2e, 0x5e, 0x95, 0x93, 0x0a, 0x44,
0xb8, 0x9e, 0xd7, 0x8f, 0x0a, 0xfa, 0xe9, 0xbc, 0x5e, 0xc8, 0x42, 0x07, 0x24, 0x57, 0xbb, 0xd4,
0x39, 0x1c, 0x63, 0x1a, 0x10, 0x1a, 0x6e, 0x56, 0xbd, 0xfe, 0xdf, 0x55, 0x9f, 0xe8, 0x55, 0x0f,
0x74, 0xec, 0x6a, 0xc9, 0x23, 0xb9, 0x64, 0xae, 0x0d, 0xd1, 0x5f, 0xb6, 0xd6, 0xeb, 0xd9, 0xa5,
0x6f, 0x2d, 0x2e, 0x7d, 0x6b, 0xb6, 0xf4, 0xed, 0xc5, 0xd2, 0xb7, 0xbf, 0xae, 0x7c, 0xeb, 0xfb,
0xca, 0xb7, 0x17, 0x2b, 0xdf, 0xfa, 0xb5, 0xf2, 0xad, 0x4f, 0x0f, 0x43, 0x92, 0x0c, 0x26, 0xbd,
0x66, 0x9f, 0x8d, 0x8e, 0xe3, 0x2f, 0xb4, 0x9f, 0x0c, 0x08, 0x0d, 0x33, 0x4f, 0x57, 0x5f, 0x68,
0xaf, 0x2c, 0x3f, 0xc7, 0xa7, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xcf, 0x98, 0x86, 0x91,
0x04, 0x00, 0x00,
// 654 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0xc7, 0xed, 0xa6, 0x4d, 0xda, 0xed, 0x17, 0x32, 0x08, 0x5c, 0x3e, 0xbc, 0x61, 0x15, 0x50,
0x41, 0xa5, 0x95, 0xca, 0x05, 0x71, 0x23, 0x44, 0x94, 0x0a, 0x24, 0x2a, 0xa3, 0x22, 0xe0, 0x82,
0x92, 0x78, 0xeb, 0xae, 0x94, 0xd8, 0x96, 0xbd, 0xae, 0xda, 0x47, 0xe0, 0x86, 0x78, 0x02, 0x4e,
0x48, 0xdc, 0x79, 0x88, 0xdc, 0x92, 0x23, 0xa7, 0x95, 0x9a, 0xdc, 0x7c, 0xf4, 0x91, 0x13, 0xda,
0x0f, 0xbb, 0xb6, 0x6a, 0xe0, 0x64, 0xcf, 0xfc, 0xff, 0xf3, 0x9b, 0xd5, 0x78, 0xc7, 0xe0, 0xc6,
0x80, 0xf4, 0x76, 0xfa, 0xbe, 0x77, 0x44, 0x5c, 0xf5, 0xd8, 0x0e, 0x42, 0x9f, 0xfa, 0x46, 0x5d,
0x46, 0x37, 0x5b, 0x05, 0xc3, 0x91, 0x3f, 0x70, 0x70, 0x28, 0x83, 0x38, 0xec, 0x52, 0xe2, 0x7b,
0xd2, 0x5d, 0x72, 0x39, 0xf8, 0x84, 0xf4, 0x71, 0x95, 0xeb, 0x6e, 0xc1, 0xe5, 0xc6, 0xa4, 0xca,
0x82, 0x0a, 0x96, 0x81, 0xd3, 0x0d, 0xaa, 0x3c, 0xf7, 0x0a, 0x1e, 0x3f, 0xe0, 0x42, 0x54, 0x65,
0xdb, 0x28, 0xda, 0x7a, 0x11, 0x0e, 0x4f, 0xb0, 0xa3, 0xa4, 0x25, 0x7c, 0x4a, 0xe5, 0x2b, 0xfa,
0xde, 0x00, 0xab, 0xcf, 0x8b, 0xd5, 0x86, 0x0d, 0x1a, 0x27, 0x38, 0x8c, 0x88, 0xef, 0x99, 0x7a,
0x53, 0xdf, 0x5c, 0x68, 0x3f, 0x49, 0x18, 0xcc, 0x52, 0x29, 0x83, 0xc6, 0xe9, 0x70, 0xf0, 0x14,
0xa9, 0x78, 0xab, 0x4b, 0x69, 0x88, 0x7e, 0x33, 0x58, 0x23, 0x1e, 0x4d, 0xc6, 0xad, 0x95, 0x62,
0xde, 0xce, 0xaa, 0x8c, 0x77, 0xa0, 0x21, 0x87, 0x17, 0x99, 0x73, 0xcd, 0xda, 0xe6, 0xf2, 0xee,
0xad, 0x6d, 0x35, 0xed, 0x17, 0x22, 0x5d, 0x3a, 0x41, 0x1b, 0x8e, 0x18, 0xd4, 0x78, 0x53, 0x55,
0x93, 0x32, 0xb8, 0x22, 0x9a, 0xca, 0x18, 0xd9, 0x99, 0xc0, 0xb9, 0x72, 0xdc, 0x91, 0x59, 0x2b,
0x73, 0x3b, 0x22, 0xfd, 0x17, 0xae, 0xaa, 0xc9, 0xb9, 0x32, 0x46, 0x76, 0x26, 0x18, 0x36, 0xa8,
0xb9, 0x31, 0x31, 0xe7, 0x9b, 0xfa, 0xe6, 0xf2, 0xae, 0x99, 0x31, 0xf7, 0x0e, 0xf7, 0xcb, 0xc0,
0xfb, 0x1c, 0x38, 0x65, 0xb0, 0xb6, 0x77, 0xb8, 0x9f, 0x30, 0xc8, 0x6b, 0x52, 0x06, 0x97, 0x04,
0xd3, 0x8d, 0x09, 0xfa, 0x3a, 0x69, 0x71, 0xc9, 0xe6, 0x82, 0xf1, 0x01, 0xcc, 0xf3, 0x2f, 0x6a,
0x2e, 0x08, 0xe8, 0x46, 0x06, 0x7d, 0xdd, 0x79, 0x76, 0x50, 0xa6, 0x3e, 0x54, 0xd4, 0x79, 0x2e,
0x25, 0x0c, 0x8a, 0xb2, 0x94, 0x41, 0x20, 0xb8, 0x3c, 0xe0, 0x60, 0xa1, 0xda, 0x42, 0x33, 0xde,
0x83, 0x86, 0xba, 0x08, 0x66, 0x5d, 0xd0, 0x6f, 0x67, 0xf4, 0x37, 0x32, 0x5d, 0x6e, 0xd0, 0xcc,
0xe6, 0xa0, 0x8a, 0x52, 0x06, 0x57, 0x05, 0x5b, 0xc5, 0xc8, 0xce, 0x14, 0xe3, 0x87, 0x0e, 0xd6,
0x89, 0xeb, 0xf9, 0x21, 0x76, 0x3e, 0x65, 0x93, 0x6e, 0x88, 0x49, 0x5f, 0xcf, 0x5b, 0xa8, 0xbb,
0x25, 0x27, 0xde, 0x3e, 0x56, 0xf0, 0x6b, 0x21, 0x1e, 0xfa, 0x14, 0xef, 0xcb, 0xe2, 0x4e, 0x3e,
0xf1, 0x0d, 0xd1, 0xa9, 0x42, 0x44, 0xc9, 0xb8, 0x75, 0xb5, 0x22, 0x9f, 0x8e, 0x5b, 0x95, 0x2c,
0x7b, 0x8d, 0x94, 0x62, 0xe3, 0xb3, 0x0e, 0xd6, 0x03, 0xec, 0x39, 0xc4, 0x73, 0xf3, 0xb3, 0x2e,
0xfe, 0xf3, 0xac, 0x2f, 0xd5, 0xa4, 0xcd, 0x0e, 0x0e, 0x42, 0xdc, 0xef, 0x52, 0xec, 0x1c, 0x48,
0x80, 0x62, 0x26, 0x0c, 0xea, 0x8f, 0x52, 0x06, 0xef, 0x88, 0x43, 0x07, 0x45, 0x6d, 0xcb, 0x1f,
0x12, 0x8a, 0x87, 0x01, 0x3d, 0x43, 0xa6, 0x6e, 0xaf, 0x95, 0xb4, 0xc8, 0x38, 0x00, 0x8b, 0x0e,
0x3e, 0xea, 0xc6, 0x03, 0x1a, 0x99, 0x4b, 0xe2, 0x93, 0x5c, 0xb9, 0xb8, 0x99, 0x32, 0xdf, 0x46,
0x6a, 0x52, 0xb9, 0x33, 0x65, 0x70, 0x4d, 0xdd, 0x47, 0x99, 0x40, 0x76, 0xae, 0xa1, 0x9f, 0x3a,
0x58, 0xcc, 0x4a, 0x8d, 0xb7, 0xa0, 0x2e, 0x57, 0x40, 0xac, 0xe8, 0x7f, 0xd6, 0xc9, 0x52, 0x7d,
0x54, 0xc9, 0xa5, 0x6d, 0x52, 0x79, 0x0e, 0x95, 0x63, 0x33, 0xe7, 0xca, 0xd0, 0xaa, 0x5d, 0xca,
0xa1, 0xb2, 0xe4, 0xd2, 0x2a, 0xa9, 0x7c, 0xfb, 0xd5, 0xe8, 0xdc, 0xd2, 0x26, 0xe7, 0x96, 0x36,
0x9a, 0x5a, 0xfa, 0x64, 0x6a, 0xe9, 0x5f, 0x66, 0x96, 0xf6, 0x6d, 0x66, 0xe9, 0x93, 0x99, 0xa5,
0xfd, 0x9a, 0x59, 0xda, 0xc7, 0x07, 0x2e, 0xa1, 0xc7, 0x71, 0x6f, 0xbb, 0xef, 0x0f, 0x77, 0xa2,
0x33, 0xaf, 0x4f, 0x8f, 0x89, 0xe7, 0x16, 0xde, 0x2e, 0x7e, 0x63, 0xbd, 0xba, 0xf8, 0x67, 0x3d,
0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x50, 0xe9, 0xd5, 0x50, 0xb6, 0x05, 0x00, 0x00,
}
func (m *Configuration) Marshal() (dAtA []byte, err error) {
@@ -132,10 +178,20 @@ func (m *Configuration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.PendingDevices) > 0 {
for iNdEx := len(m.PendingDevices) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Defaults.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x4a
if len(m.DeprecatedPendingDevices) > 0 {
for iNdEx := len(m.DeprecatedPendingDevices) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.PendingDevices[iNdEx].MarshalToSizedBuffer(dAtA[:i])
size, err := m.DeprecatedPendingDevices[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -226,6 +282,49 @@ func (m *Configuration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *Defaults) Marshal() (dAtA []byte, err error) {
size := m.ProtoSize()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Defaults) MarshalTo(dAtA []byte) (int, error) {
size := m.ProtoSize()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Defaults) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size, err := m.Device.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
{
size, err := m.Folder.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func encodeVarintConfig(dAtA []byte, offset int, v uint64) int {
offset -= sovConfig(v)
base := offset
@@ -270,12 +369,27 @@ func (m *Configuration) ProtoSize() (n int) {
n += 1 + l + sovConfig(uint64(l))
}
}
if len(m.PendingDevices) > 0 {
for _, e := range m.PendingDevices {
if len(m.DeprecatedPendingDevices) > 0 {
for _, e := range m.DeprecatedPendingDevices {
l = e.ProtoSize()
n += 1 + l + sovConfig(uint64(l))
}
}
l = m.Defaults.ProtoSize()
n += 1 + l + sovConfig(uint64(l))
return n
}
func (m *Defaults) ProtoSize() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.Folder.ProtoSize()
n += 1 + l + sovConfig(uint64(l))
l = m.Device.ProtoSize()
n += 1 + l + sovConfig(uint64(l))
return n
}
@@ -536,7 +650,7 @@ func (m *Configuration) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PendingDevices", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedPendingDevices", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -563,8 +677,160 @@ func (m *Configuration) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PendingDevices = append(m.PendingDevices, ObservedDevice{})
if err := m.PendingDevices[len(m.PendingDevices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
m.DeprecatedPendingDevices = append(m.DeprecatedPendingDevices, ObservedDevice{})
if err := m.DeprecatedPendingDevices[len(m.DeprecatedPendingDevices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Defaults", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Defaults.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipConfig(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthConfig
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthConfig
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Defaults) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Defaults: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Defaults: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Folder", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Folder.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Device.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex

View File

@@ -8,9 +8,11 @@ package config
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@@ -21,6 +23,7 @@ import (
"testing"
"github.com/d4l3k/messagediff"
"github.com/thejerf/suture/v4"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
@@ -37,51 +40,93 @@ func init() {
}
func TestDefaultValues(t *testing.T) {
expected := OptionsConfiguration{
RawListenAddresses: []string{"default"},
RawGlobalAnnServers: []string{"default"},
GlobalAnnEnabled: true,
LocalAnnEnabled: true,
LocalAnnPort: 21027,
LocalAnnMCAddr: "[ff12::8384]:21027",
MaxSendKbps: 0,
MaxRecvKbps: 0,
ReconnectIntervalS: 60,
RelaysEnabled: true,
RelayReconnectIntervalM: 10,
StartBrowser: true,
NATEnabled: true,
NATLeaseM: 60,
NATRenewalM: 30,
NATTimeoutS: 10,
RestartOnWakeup: true,
AutoUpgradeIntervalH: 12,
KeepTemporariesH: 24,
CacheIgnoredFiles: false,
ProgressUpdateIntervalS: 5,
LimitBandwidthInLan: false,
MinHomeDiskFree: Size{1, "%"},
URURL: "https://data.syncthing.net/newdata",
URInitialDelayS: 1800,
URPostInsecurely: false,
ReleasesURL: "https://upgrades.syncthing.net/meta.json",
AlwaysLocalNets: []string{},
OverwriteRemoteDevNames: false,
TempIndexMinBlocks: 10,
UnackedNotificationIDs: []string{"authenticationUserAndPassword"},
DefaultFolderPath: "~",
SetLowPriority: true,
CRURL: "https://crash.syncthing.net/newcrash",
CREnabled: true,
StunKeepaliveStartS: 180,
StunKeepaliveMinS: 20,
RawStunServers: []string{"default"},
AnnounceLANAddresses: true,
size, err := ParseSize("1%")
if err != nil {
t.Fatal(err)
}
expected := Configuration{
Version: CurrentVersion,
Folders: []FolderConfiguration{},
Options: OptionsConfiguration{
RawListenAddresses: []string{"default"},
RawGlobalAnnServers: []string{"default"},
GlobalAnnEnabled: true,
LocalAnnEnabled: true,
LocalAnnPort: 21027,
LocalAnnMCAddr: "[ff12::8384]:21027",
MaxSendKbps: 0,
MaxRecvKbps: 0,
ReconnectIntervalS: 60,
RelaysEnabled: true,
RelayReconnectIntervalM: 10,
StartBrowser: true,
NATEnabled: true,
NATLeaseM: 60,
NATRenewalM: 30,
NATTimeoutS: 10,
RestartOnWakeup: true,
AutoUpgradeIntervalH: 12,
KeepTemporariesH: 24,
CacheIgnoredFiles: false,
ProgressUpdateIntervalS: 5,
LimitBandwidthInLan: false,
MinHomeDiskFree: Size{1, "%"},
URURL: "https://data.syncthing.net/newdata",
URInitialDelayS: 1800,
URPostInsecurely: false,
ReleasesURL: "https://upgrades.syncthing.net/meta.json",
AlwaysLocalNets: []string{},
OverwriteRemoteDevNames: false,
TempIndexMinBlocks: 10,
UnackedNotificationIDs: []string{"authenticationUserAndPassword"},
SetLowPriority: true,
CRURL: "https://crash.syncthing.net/newcrash",
CREnabled: true,
StunKeepaliveStartS: 180,
StunKeepaliveMinS: 20,
RawStunServers: []string{"default"},
AnnounceLANAddresses: true,
FeatureFlags: []string{},
},
Defaults: Defaults{
Folder: FolderConfiguration{
FilesystemType: fs.FilesystemTypeBasic,
Path: "~",
Type: FolderTypeSendReceive,
Devices: []FolderDeviceConfiguration{{DeviceID: device1}},
RescanIntervalS: 3600,
FSWatcherEnabled: true,
FSWatcherDelayS: 10,
IgnorePerms: false,
AutoNormalize: true,
MinDiskFree: size,
Versioning: VersioningConfiguration{
CleanupIntervalS: 3600,
Params: map[string]string{},
},
MaxConflicts: 10,
WeakHashThresholdPct: 25,
MarkerName: ".stfolder",
MaxConcurrentWrites: 2,
},
Device: DeviceConfiguration{
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
Compression: protocol.CompressionMetadata,
IgnoredFolders: []ObservedFolder{},
},
},
IgnoredDevices: []ObservedDevice{},
}
expected.Devices = []DeviceConfiguration{expected.Defaults.Device.Copy()}
expected.Devices[0].DeviceID = device1
expected.Devices[0].Name, _ = os.Hostname()
cfg := New(device1)
cfg.GUI = GUIConfiguration{}
cfg.LDAP = LDAPConfiguration{}
if diff, equal := messagediff.PrettyDiff(expected, cfg.Options); !equal {
if diff, equal := messagediff.PrettyDiff(expected, cfg); !equal {
t.Errorf("Default config differs. Diff:\n%s", diff)
}
}
@@ -94,7 +139,8 @@ func TestDeviceConfig(t *testing.T) {
}
os.RemoveAll(filepath.Join("testdata", DefaultMarkerName))
wr, err := load(cfgFile, device1)
wr, wrCancel, err := copyAndLoad(cfgFile, device1)
defer wrCancel()
if err != nil {
t.Fatal(err)
}
@@ -106,7 +152,7 @@ func TestDeviceConfig(t *testing.T) {
t.Fatal("Unexpected file")
}
cfg := wr.(*wrapper).cfg
cfg := wr.Wrapper.(*wrapper).cfg
expectedFolders := []FolderConfiguration{
{
@@ -129,6 +175,7 @@ func TestDeviceConfig(t *testing.T) {
WeakHashThresholdPct: 25,
MarkerName: DefaultMarkerName,
JunctionsAsDirs: true,
MaxConcurrentWrites: maxConcurrentWritesDefault,
},
}
@@ -140,7 +187,6 @@ func TestDeviceConfig(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
{
DeviceID: device4,
@@ -149,7 +195,6 @@ func TestDeviceConfig(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
}
expectedDeviceIDs := []protocol.DeviceID{device1, device4}
@@ -170,7 +215,8 @@ func TestDeviceConfig(t *testing.T) {
}
func TestNoListenAddresses(t *testing.T) {
cfg, err := load("testdata/nolistenaddress.xml", device1)
cfg, cfgCancel, err := copyAndLoad("testdata/nolistenaddress.xml", device1)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -217,17 +263,19 @@ func TestOverriddenValues(t *testing.T) {
OverwriteRemoteDevNames: true,
TempIndexMinBlocks: 100,
UnackedNotificationIDs: []string{"asdfasdf"},
DefaultFolderPath: "/media/syncthing",
SetLowPriority: false,
CRURL: "https://localhost/newcrash",
CREnabled: false,
StunKeepaliveStartS: 9000,
StunKeepaliveMinS: 900,
RawStunServers: []string{"foo"},
FeatureFlags: []string{"feature"},
}
expectedPath := "/media/syncthing"
os.Unsetenv("STNOUPGRADE")
cfg, err := load("testdata/overridenvalues.xml", device1)
cfg, cfgCancel, err := copyAndLoad("testdata/overridenvalues.xml", device1)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -235,6 +283,10 @@ func TestOverriddenValues(t *testing.T) {
if diff, equal := messagediff.PrettyDiff(expected, cfg.Options()); !equal {
t.Errorf("Overridden config differs. Diff:\n%s", diff)
}
if path := cfg.DefaultFolder().Path; path != expectedPath {
t.Errorf("Default folder path is %v, expected %v", path, expectedPath)
}
}
func TestDeviceAddressesDynamic(t *testing.T) {
@@ -245,21 +297,18 @@ func TestDeviceAddressesDynamic(t *testing.T) {
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device2: {
DeviceID: device2,
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device3: {
DeviceID: device3,
Addresses: []string{"dynamic"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device4: {
DeviceID: device4,
@@ -268,11 +317,11 @@ func TestDeviceAddressesDynamic(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
}
cfg, err := load("testdata/deviceaddressesdynamic.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/deviceaddressesdynamic.xml", device4)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -292,7 +341,6 @@ func TestDeviceCompression(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device2: {
DeviceID: device2,
@@ -300,7 +348,6 @@ func TestDeviceCompression(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device3: {
DeviceID: device3,
@@ -308,7 +355,6 @@ func TestDeviceCompression(t *testing.T) {
Compression: protocol.CompressionNever,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device4: {
DeviceID: device4,
@@ -317,11 +363,11 @@ func TestDeviceCompression(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
}
cfg, err := load("testdata/devicecompression.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/devicecompression.xml", device4)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -340,21 +386,18 @@ func TestDeviceAddressesStatic(t *testing.T) {
Addresses: []string{"tcp://192.0.2.1", "tcp://192.0.2.2"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device2: {
DeviceID: device2,
Addresses: []string{"tcp://192.0.2.3:6070", "tcp://[2001:db8::42]:4242"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device3: {
DeviceID: device3,
Addresses: []string{"tcp://[2001:db8::44]:4444", "tcp://192.0.2.4:6090"},
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
device4: {
DeviceID: device4,
@@ -363,11 +406,11 @@ func TestDeviceAddressesStatic(t *testing.T) {
Compression: protocol.CompressionMetadata,
AllowedNetworks: []string{},
IgnoredFolders: []ObservedFolder{},
PendingFolders: []ObservedFolder{},
},
}
cfg, err := load("testdata/deviceaddressesstatic.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/deviceaddressesstatic.xml", device4)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -379,7 +422,8 @@ func TestDeviceAddressesStatic(t *testing.T) {
}
func TestVersioningConfig(t *testing.T) {
cfg, err := load("testdata/versioningconfig.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/versioningconfig.xml", device4)
defer cfgCancel()
if err != nil {
t.Error(err)
}
@@ -406,7 +450,8 @@ func TestIssue1262(t *testing.T) {
t.Skipf("path gets converted to absolute as part of the filesystem initialization on linux")
}
cfg, err := load("testdata/issue-1262.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/issue-1262.xml", device4)
defer cfgCancel()
if err != nil {
t.Fatal(err)
}
@@ -420,7 +465,8 @@ func TestIssue1262(t *testing.T) {
}
func TestIssue1750(t *testing.T) {
cfg, err := load("testdata/issue-1750.xml", device4)
cfg, cfgCancel, err := copyAndLoad("testdata/issue-1750.xml", device4)
defer cfgCancel()
if err != nil {
t.Fatal(err)
}
@@ -508,7 +554,7 @@ func TestFolderCheckPath(t *testing.T) {
}
if err := cfg.CheckPath(); testcase.err != err {
t.Errorf("unexpected error in case %s: %s != %s", testcase.path, err, testcase.err)
t.Errorf("unexpected error in case %s: %s != %v", testcase.path, err, testcase.err)
}
}
}
@@ -516,6 +562,7 @@ func TestFolderCheckPath(t *testing.T) {
func TestNewSaveLoad(t *testing.T) {
path := "testdata/temp.xml"
os.Remove(path)
defer os.Remove(path)
exists := func(path string) bool {
_, err := os.Stat(path)
@@ -523,7 +570,8 @@ func TestNewSaveLoad(t *testing.T) {
}
intCfg := New(device1)
cfg := wrap(path, intCfg)
cfg := wrap(path, intCfg, device1)
defer cfg.stop()
if exists(path) {
t.Error(path, "exists")
@@ -538,6 +586,7 @@ func TestNewSaveLoad(t *testing.T) {
}
cfg2, err := load(path, device1)
defer cfg2.stop()
if err != nil {
t.Error(err)
}
@@ -545,8 +594,6 @@ func TestNewSaveLoad(t *testing.T) {
if diff, equal := messagediff.PrettyDiff(cfg.RawCopy(), cfg2.RawCopy()); !equal {
t.Errorf("Configs are not equal. Diff:\n%s", diff)
}
os.Remove(path)
}
func TestPrepare(t *testing.T) {
@@ -564,7 +611,8 @@ func TestPrepare(t *testing.T) {
}
func TestCopy(t *testing.T) {
wrapper, err := load("testdata/example.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/example.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -603,7 +651,8 @@ func TestCopy(t *testing.T) {
}
func TestPullOrder(t *testing.T) {
wrapper, err := load("testdata/pullorder.xml", device1)
wrapper, wrapperCleanup, err := copyAndLoad("testdata/pullorder.xml", device1)
defer wrapperCleanup()
if err != nil {
t.Fatal(err)
}
@@ -643,8 +692,9 @@ func TestPullOrder(t *testing.T) {
if err != nil {
t.Fatal(err)
}
wrapper = wrap("testdata/pullorder.xml", cfg)
folders = wrapper.Folders()
wrapper2 := wrap(wrapper.ConfigPath(), cfg, device1)
defer wrapper2.stop()
folders = wrapper2.Folders()
for _, tc := range expected {
if actual := folders[tc.name].Order; actual != tc.order {
@@ -654,7 +704,8 @@ func TestPullOrder(t *testing.T) {
}
func TestLargeRescanInterval(t *testing.T) {
wrapper, err := load("testdata/largeinterval.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/largeinterval.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -692,7 +743,8 @@ func TestGUIConfigURL(t *testing.T) {
func TestDuplicateDevices(t *testing.T) {
// Duplicate devices should be removed
wrapper, err := load("testdata/dupdevices.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/dupdevices.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -710,7 +762,8 @@ func TestDuplicateDevices(t *testing.T) {
func TestDuplicateFolders(t *testing.T) {
// Duplicate folders are a loading error
_, err := load("testdata/dupfolders.xml", device1)
_, _Cancel, err := copyAndLoad("testdata/dupfolders.xml", device1)
defer _Cancel()
if err == nil || !strings.Contains(err.Error(), errFolderIDDuplicate.Error()) {
t.Fatal(`Expected error to mention "duplicate folder ID":`, err)
}
@@ -721,7 +774,8 @@ func TestEmptyFolderPaths(t *testing.T) {
// get messed up by the prepare steps (e.g., become the current dir or
// get a slash added so that it becomes the root directory or similar).
_, err := load("testdata/nopath.xml", device1)
_, _Cancel, err := copyAndLoad("testdata/nopath.xml", device1)
defer _Cancel()
if err == nil || !strings.Contains(err.Error(), errFolderPathEmpty.Error()) {
t.Fatal("Expected error due to empty folder path, got", err)
}
@@ -790,7 +844,8 @@ func TestIgnoredDevices(t *testing.T) {
// Verify that ignored devices that are also present in the
// configuration are not in fact ignored.
wrapper, err := load("testdata/ignoreddevices.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/ignoreddevices.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -808,7 +863,8 @@ func TestIgnoredFolders(t *testing.T) {
// configuration are not in fact ignored.
// Also, verify that folders that are shared with a device are not ignored.
wrapper, err := load("testdata/ignoredfolders.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/ignoredfolders.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -844,7 +900,8 @@ func TestIgnoredFolders(t *testing.T) {
func TestGetDevice(t *testing.T) {
// Verify that the Device() call does the right thing
wrapper, err := load("testdata/ignoreddevices.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/ignoreddevices.xml", device1)
defer wrapperCancel()
if err != nil {
t.Fatal(err)
}
@@ -871,7 +928,8 @@ func TestGetDevice(t *testing.T) {
}
func TestSharesRemovedOnDeviceRemoval(t *testing.T) {
wrapper, err := load("testdata/example.xml", device1)
wrapper, wrapperCancel, err := copyAndLoad("testdata/example.xml", device1)
defer wrapperCancel()
if err != nil {
t.Errorf("Failed: %s", err)
}
@@ -883,10 +941,7 @@ func TestSharesRemovedOnDeviceRemoval(t *testing.T) {
t.Error("Should have less devices")
}
_, err = wrapper.Replace(raw)
if err != nil {
t.Errorf("Failed: %s", err)
}
replace(t, wrapper, raw)
raw = wrapper.RawCopy()
if len(raw.Folders[0].Devices) > len(raw.Devices) {
@@ -938,7 +993,8 @@ func TestIssue4219(t *testing.T) {
]
}`))
cfg, err := ReadJSON(r, protocol.LocalDeviceID)
myID := protocol.LocalDeviceID
cfg, err := ReadJSON(r, myID)
if err != nil {
t.Fatal(err)
}
@@ -956,7 +1012,8 @@ func TestIssue4219(t *testing.T) {
t.Errorf("There should be three ignored folders, not %d", ignoredFolders)
}
w := wrap("/tmp/cfg", cfg)
w := wrap("/tmp/cfg", cfg, myID)
defer w.stop()
if !w.IgnoredFolder(device2, "t1") {
t.Error("Folder device2 t1 should be ignored")
}
@@ -1093,10 +1150,6 @@ func TestDeviceConfigObservedNotNil(t *testing.T) {
if dev.IgnoredFolders == nil {
t.Errorf("Ignored folders nil")
}
if dev.PendingFolders == nil {
t.Errorf("Pending folders nil")
}
}
}
@@ -1116,12 +1169,16 @@ func TestRemoveDeviceWithEmptyID(t *testing.T) {
},
}
cfg.clean()
cfg.prepare(device1)
if len(cfg.Devices) != 0 {
if len(cfg.Devices) != 1 {
t.Error("Expected one device")
} else if cfg.Devices[0].DeviceID != device1 {
t.Error("Expected device with empty ID to be removed from config:", cfg.Devices)
}
if len(cfg.Folders[0].Devices) != 0 {
if len(cfg.Folders[0].Devices) != 1 {
t.Error("Expected one device in folder")
} else if cfg.Folders[0].Devices[0].DeviceID != device1 {
t.Error("Expected device with empty ID to be removed from folder")
}
}
@@ -1147,13 +1204,29 @@ func TestMaxConcurrentFolders(t *testing.T) {
}
}
func adjustDeviceConfiguration(cfg *DeviceConfiguration, id protocol.DeviceID, name string) {
cfg.DeviceID = id
cfg.Name = name
}
func adjustFolderConfiguration(cfg *FolderConfiguration, id, label string, fsType fs.FilesystemType, path string) {
cfg.ID = id
cfg.Label = label
cfg.FilesystemType = fsType
cfg.Path = path
}
// defaultConfigAsMap returns a valid default config as a JSON-decoded
// map[string]interface{}. This is useful to override random elements and
// re-encode into JSON.
func defaultConfigAsMap() map[string]interface{} {
cfg := New(device1)
cfg.Devices = append(cfg.Devices, NewDeviceConfiguration(device2, "name"))
cfg.Folders = append(cfg.Folders, NewFolderConfiguration(device1, "default", "default", fs.FilesystemTypeBasic, "/tmp"))
dev := cfg.Defaults.Device.Copy()
adjustDeviceConfiguration(&dev, device2, "name")
cfg.Devices = append(cfg.Devices, dev)
folder := cfg.Defaults.Folder.Copy()
adjustFolderConfiguration(&folder, "default", "default", fs.FilesystemTypeBasic, "/tmp")
cfg.Folders = append(cfg.Folders, folder)
bs, err := json.Marshal(cfg)
if err != nil {
// can't happen
@@ -1167,13 +1240,80 @@ func defaultConfigAsMap() map[string]interface{} {
return tmp
}
func load(path string, myID protocol.DeviceID) (Wrapper, error) {
cfg, _, err := Load(path, myID, events.NoopLogger)
return cfg, err
func copyToTmp(path string) (string, error) {
orig, err := os.Open(path)
if err != nil {
return "", err
}
defer orig.Close()
temp, err := ioutil.TempFile("", "syncthing-configTest-")
if err != nil {
return "", err
}
defer temp.Close()
if _, err := io.Copy(temp, orig); err != nil {
return "", err
}
return temp.Name(), nil
}
func wrap(path string, cfg Configuration) Wrapper {
return Wrap(path, cfg, events.NoopLogger)
func copyAndLoad(path string, myID protocol.DeviceID) (*testWrapper, func(), error) {
temp, err := copyToTmp(path)
if err != nil {
return nil, func() {}, err
}
wrapper, err := load(temp, myID)
if err != nil {
return nil, func() {}, err
}
return wrapper, func() {
wrapper.stop()
os.Remove(temp)
}, nil
}
func load(path string, myID protocol.DeviceID) (*testWrapper, error) {
cfg, _, err := Load(path, myID, events.NoopLogger)
if err != nil {
return nil, err
}
return startWrapper(cfg), nil
}
func wrap(path string, cfg Configuration, myID protocol.DeviceID) *testWrapper {
wrapper := Wrap(path, cfg, myID, events.NoopLogger)
return startWrapper(wrapper)
}
type testWrapper struct {
Wrapper
cancel context.CancelFunc
done chan struct{}
}
func (w *testWrapper) stop() {
w.cancel()
<-w.done
}
func startWrapper(wrapper Wrapper) *testWrapper {
tw := &testWrapper{
Wrapper: wrapper,
done: make(chan struct{}),
}
s, ok := wrapper.(suture.Service)
if !ok {
tw.cancel = func() {}
close(tw.done)
return tw
}
ctx, cancel := context.WithCancel(context.Background())
tw.cancel = cancel
go func() {
s.Serve(ctx)
close(tw.done)
}()
return tw
}
func TestInternalVersioningConfiguration(t *testing.T) {
@@ -1181,7 +1321,9 @@ func TestInternalVersioningConfiguration(t *testing.T) {
// reasonable.
cfg := New(device1)
cfg.Folders = append(cfg.Folders, NewFolderConfiguration(device1, "default", "default", fs.FilesystemTypeBasic, "/tmp"))
folder := cfg.Defaults.Folder.Copy()
adjustFolderConfiguration(&folder, "default", "default", fs.FilesystemTypeBasic, "/tmp")
cfg.Folders = append(cfg.Folders, folder)
cfg.Folders[0].Versioning = VersioningConfiguration{
Type: "foo",
Params: map[string]string{"bar": "baz"},

View File

@@ -8,23 +8,8 @@ package config
import (
"sort"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/util"
)
func NewDeviceConfiguration(id protocol.DeviceID, name string) DeviceConfiguration {
d := DeviceConfiguration{
DeviceID: id,
Name: name,
}
util.SetDefaults(&d)
d.prepare(nil)
return d
}
func (cfg DeviceConfiguration) Copy() DeviceConfiguration {
c := cfg
c.Addresses = make([]string, len(cfg.Addresses))
@@ -33,8 +18,6 @@ func (cfg DeviceConfiguration) Copy() DeviceConfiguration {
copy(c.AllowedNetworks, cfg.AllowedNetworks)
c.IgnoredFolders = make([]ObservedFolder, len(cfg.IgnoredFolders))
copy(c.IgnoredFolders, cfg.IgnoredFolders)
c.PendingFolders = make([]ObservedFolder, len(cfg.PendingFolders))
copy(c.PendingFolders, cfg.PendingFolders)
return c
}
@@ -42,24 +25,14 @@ func (cfg *DeviceConfiguration) prepare(sharedFolders []string) {
if len(cfg.Addresses) == 0 || len(cfg.Addresses) == 1 && cfg.Addresses[0] == "" {
cfg.Addresses = []string{"dynamic"}
}
if len(cfg.AllowedNetworks) == 0 {
cfg.AllowedNetworks = []string{}
}
ignoredFolders := deduplicateObservedFoldersToMap(cfg.IgnoredFolders)
pendingFolders := deduplicateObservedFoldersToMap(cfg.PendingFolders)
for id := range ignoredFolders {
delete(pendingFolders, id)
}
for _, sharedFolder := range sharedFolders {
delete(ignoredFolders, sharedFolder)
delete(pendingFolders, sharedFolder)
}
cfg.IgnoredFolders = sortedObservedFolderSlice(ignoredFolders)
cfg.PendingFolders = sortedObservedFolderSlice(pendingFolders)
}
func (cfg *DeviceConfiguration) IgnoredFolder(folder string) bool {

View File

@@ -26,22 +26,24 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type DeviceConfiguration struct {
DeviceID github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"deviceID" xml:"id,attr"`
DeviceID github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"deviceID" xml:"id,attr" nodefault:"true"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name" xml:"name,attr,omitempty"`
Addresses []string `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses" xml:"address,omitempty" default:"dynamic"`
Compression protocol.Compression `protobuf:"varint,4,opt,name=compression,proto3,enum=protocol.Compression" json:"compression" xml:"compression,attr"`
CertName string `protobuf:"bytes,5,opt,name=cert_name,json=certName,proto3" json:"certName" xml:"certName,attr,omitempty"`
Introducer bool `protobuf:"varint,6,opt,name=introducer,proto3" json:"introducer" xml:"introducer,attr"`
SkipIntroductionRemovals bool `protobuf:"varint,7,opt,name=skip_introduction_removals,json=skipIntroductionRemovals,proto3" json:"skipIntroductionRemovals" xml:"skipIntroductionRemovals,attr"`
IntroducedBy github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,8,opt,name=introduced_by,json=introducedBy,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"introducedBy" xml:"introducedBy,attr"`
IntroducedBy github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,8,opt,name=introduced_by,json=introducedBy,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"introducedBy" xml:"introducedBy,attr" nodefault:"true"`
Paused bool `protobuf:"varint,9,opt,name=paused,proto3" json:"paused" xml:"paused"`
AllowedNetworks []string `protobuf:"bytes,10,rep,name=allowed_networks,json=allowedNetworks,proto3" json:"allowedNetworks" xml:"allowedNetwork,omitempty"`
AutoAcceptFolders bool `protobuf:"varint,11,opt,name=auto_accept_folders,json=autoAcceptFolders,proto3" json:"autoAcceptFolders" xml:"autoAcceptFolders"`
MaxSendKbps int `protobuf:"varint,12,opt,name=max_send_kbps,json=maxSendKbps,proto3,casttype=int" json:"maxSendKbps" xml:"maxSendKbps"`
MaxRecvKbps int `protobuf:"varint,13,opt,name=max_recv_kbps,json=maxRecvKbps,proto3,casttype=int" json:"maxRecvKbps" xml:"maxRecvKbps"`
IgnoredFolders []ObservedFolder `protobuf:"bytes,14,rep,name=ignored_folders,json=ignoredFolders,proto3" json:"ignoredFolders" xml:"ignoredFolder"`
PendingFolders []ObservedFolder `protobuf:"bytes,15,rep,name=pending_folders,json=pendingFolders,proto3" json:"pendingFolders" xml:"pendingFolder"`
DeprecatedPendingFolders []ObservedFolder `protobuf:"bytes,15,rep,name=pending_folders,json=pendingFolders,proto3" json:"-" xml:"pendingFolder,omitempty"` // Deprecated: Do not use.
MaxRequestKiB int `protobuf:"varint,16,opt,name=max_request_kib,json=maxRequestKib,proto3,casttype=int" json:"maxRequestKiB" xml:"maxRequestKiB"`
Untrusted bool `protobuf:"varint,17,opt,name=untrusted,proto3" json:"untrusted" xml:"untrusted"`
RemoteGUIPort int `protobuf:"varint,18,opt,name=remote_gui_port,json=remoteGuiPort,proto3,casttype=int" json:"remoteGUIPort" xml:"remoteGUIPort"`
}
func (m *DeviceConfiguration) Reset() { *m = DeviceConfiguration{} }
@@ -86,64 +88,72 @@ func init() {
}
var fileDescriptor_744b782bd13071dd = []byte{
// 902 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x31, 0x6f, 0xdb, 0x46,
0x18, 0x15, 0xeb, 0xc4, 0xb6, 0xce, 0x96, 0x65, 0xd3, 0x88, 0xc3, 0x18, 0x88, 0x4e, 0x60, 0x35,
0x28, 0x68, 0x2a, 0x17, 0x6e, 0x27, 0xa3, 0x1d, 0xca, 0x04, 0x45, 0x03, 0xa3, 0x49, 0x7b, 0xdd,
0xbc, 0xb0, 0x24, 0xef, 0xac, 0x1c, 0x2c, 0xf2, 0x58, 0xf2, 0xa4, 0x48, 0x40, 0x87, 0x8e, 0x1d,
0x3a, 0x14, 0x59, 0xbb, 0x14, 0x1d, 0x3a, 0xf4, 0x97, 0x18, 0xe8, 0x60, 0x8d, 0x45, 0x87, 0x03,
0x62, 0x6f, 0x1c, 0x39, 0x66, 0x2a, 0x78, 0x47, 0x51, 0x24, 0x1d, 0x17, 0x06, 0xba, 0xdd, 0xbd,
0xf7, 0xee, 0xbd, 0xe3, 0xd3, 0x7d, 0x10, 0xe8, 0x8d, 0xa8, 0x7b, 0xe0, 0xb1, 0xe0, 0x94, 0x0e,
0x0f, 0x30, 0x99, 0x50, 0x8f, 0xa8, 0xcd, 0x38, 0x72, 0x38, 0x65, 0xc1, 0x20, 0x8c, 0x18, 0x67,
0xfa, 0xaa, 0x02, 0xf7, 0xf7, 0x32, 0xb5, 0x84, 0x3c, 0x36, 0x3a, 0x70, 0x49, 0xa8, 0xf8, 0xfd,
0x07, 0x25, 0x17, 0xe6, 0xc6, 0x24, 0x9a, 0x10, 0x9c, 0x53, 0x4d, 0x32, 0xe5, 0x6a, 0x69, 0xfe,
0xb5, 0x05, 0x76, 0x9f, 0xca, 0x8c, 0x27, 0xe5, 0x0c, 0xfd, 0x4f, 0x0d, 0x34, 0x55, 0xb6, 0x4d,
0xb1, 0xa1, 0x75, 0xb5, 0xfe, 0xa6, 0xf5, 0xb3, 0x76, 0x2e, 0x60, 0xe3, 0x1f, 0x01, 0x3f, 0x19,
0x52, 0xfe, 0x72, 0xec, 0x0e, 0x3c, 0xe6, 0x1f, 0xc4, 0xb3, 0xc0, 0xe3, 0x2f, 0x69, 0x30, 0x2c,
0xad, 0xca, 0x37, 0x1a, 0x28, 0xf7, 0x67, 0x4f, 0x2f, 0x05, 0x5c, 0x5f, 0xac, 0x13, 0x01, 0xd7,
0x71, 0xbe, 0x4e, 0x05, 0x6c, 0x4d, 0xfd, 0xd1, 0x91, 0x49, 0xf1, 0x63, 0x87, 0xf3, 0xc8, 0x4c,
0x2e, 0x7a, 0x6b, 0xf9, 0x3a, 0xbd, 0xe8, 0x15, 0xba, 0x9f, 0xe6, 0x3d, 0xed, 0xf5, 0xbc, 0x57,
0x78, 0xa0, 0x05, 0x83, 0xf5, 0xaf, 0xc1, 0x9d, 0xc0, 0xf1, 0x89, 0xf1, 0x5e, 0x57, 0xeb, 0x37,
0xad, 0x4f, 0x13, 0x01, 0xe5, 0x3e, 0x15, 0xf0, 0x81, 0x74, 0xce, 0x36, 0xd2, 0xef, 0x31, 0xf3,
0x29, 0x27, 0x7e, 0xc8, 0x67, 0x59, 0xca, 0xee, 0x3b, 0x70, 0x24, 0x4f, 0xea, 0x53, 0xd0, 0x74,
0x30, 0x8e, 0x48, 0x1c, 0x93, 0xd8, 0x58, 0xe9, 0xae, 0xf4, 0x9b, 0xd6, 0x49, 0x22, 0xe0, 0x12,
0x4c, 0x05, 0x7c, 0x24, 0xbd, 0x73, 0xa4, 0xe4, 0xdc, 0xc5, 0xe4, 0xd4, 0x19, 0x8f, 0xf8, 0x91,
0x89, 0x67, 0x81, 0xe3, 0x53, 0x2f, 0xcb, 0xda, 0xb9, 0xa6, 0x7b, 0x7b, 0xd1, 0x5b, 0xcb, 0x05,
0x68, 0xe9, 0xab, 0x4f, 0xc0, 0x86, 0xc7, 0xfc, 0x30, 0xdb, 0x51, 0x16, 0x18, 0x77, 0xba, 0x5a,
0x7f, 0xeb, 0xf0, 0xde, 0xa0, 0xa8, 0xf3, 0xc9, 0x92, 0xb4, 0x3e, 0x4b, 0x04, 0x2c, 0xab, 0x53,
0x01, 0xf7, 0xe4, 0xa5, 0x4a, 0x58, 0xd1, 0xe9, 0x76, 0x1d, 0x44, 0xe5, 0xa3, 0x3a, 0x01, 0x4d,
0x8f, 0x44, 0xdc, 0x96, 0x45, 0xde, 0x95, 0x45, 0x7e, 0x99, 0xfd, 0x4c, 0x19, 0xf8, 0x5c, 0x95,
0xf9, 0x50, 0x79, 0xe7, 0xc0, 0x3b, 0x0a, 0xbd, 0x7f, 0x03, 0x87, 0x0a, 0x17, 0xfd, 0x04, 0x00,
0x1a, 0xf0, 0x88, 0xe1, 0xb1, 0x47, 0x22, 0x63, 0xb5, 0xab, 0xf5, 0xd7, 0xad, 0xa3, 0x44, 0xc0,
0x12, 0x9a, 0x0a, 0x78, 0x4f, 0x3d, 0x88, 0x02, 0x2a, 0x3e, 0xa2, 0x5d, 0xc3, 0x50, 0xe9, 0x9c,
0xfe, 0xbb, 0x06, 0xf6, 0xe3, 0x33, 0x1a, 0xda, 0x0b, 0x2c, 0x7b, 0xc9, 0x76, 0x44, 0x7c, 0x36,
0x71, 0x46, 0xb1, 0xb1, 0x26, 0xc3, 0x70, 0x22, 0xa0, 0x91, 0xa9, 0x9e, 0x95, 0x44, 0x28, 0xd7,
0xa4, 0x02, 0xbe, 0x2f, 0xa3, 0x6f, 0x12, 0x14, 0x17, 0x79, 0xf8, 0x9f, 0x0a, 0x74, 0x63, 0x82,
0xfe, 0x87, 0x06, 0x5a, 0xc5, 0x9d, 0xb1, 0xed, 0xce, 0x8c, 0x75, 0x39, 0x5c, 0x3f, 0xfe, 0xaf,
0xe1, 0x4a, 0x04, 0xdc, 0x5c, 0xba, 0x5a, 0xb3, 0x54, 0xc0, 0xfb, 0xd5, 0x0e, 0xb1, 0x35, 0x2b,
0x2e, 0xbf, 0x73, 0x0d, 0xcd, 0x86, 0x0b, 0x55, 0x1c, 0xf4, 0x43, 0xb0, 0x1a, 0x3a, 0xe3, 0x98,
0x60, 0xa3, 0x29, 0x8b, 0xdb, 0x4f, 0x04, 0xcc, 0x91, 0x54, 0xc0, 0x4d, 0xe9, 0xae, 0xb6, 0x26,
0xca, 0x71, 0xfd, 0x07, 0xb0, 0xed, 0x8c, 0x46, 0xec, 0x15, 0xc1, 0x76, 0x40, 0xf8, 0x2b, 0x16,
0x9d, 0xc5, 0x06, 0x90, 0xd3, 0xf3, 0x4d, 0x22, 0x60, 0x3b, 0xe7, 0x9e, 0xe7, 0x54, 0x2a, 0x60,
0x47, 0xcd, 0x50, 0x05, 0xaf, 0xbe, 0x29, 0xe3, 0x26, 0x12, 0xd5, 0xed, 0xf4, 0xef, 0xc0, 0xae,
0x33, 0xe6, 0xcc, 0x76, 0x3c, 0x8f, 0x84, 0xdc, 0x3e, 0x65, 0x23, 0x4c, 0xa2, 0xd8, 0xd8, 0x90,
0xd7, 0xff, 0x28, 0x11, 0x70, 0x27, 0xa3, 0x3f, 0x97, 0xec, 0x17, 0x8a, 0x2c, 0x7a, 0xba, 0xc6,
0x98, 0xe8, 0xba, 0x5a, 0x7f, 0x01, 0x5a, 0xbe, 0x33, 0xb5, 0x63, 0x12, 0x60, 0xfb, 0xcc, 0x0d,
0x63, 0x63, 0xb3, 0xab, 0xf5, 0xef, 0x5a, 0x1f, 0x64, 0x73, 0xe8, 0x3b, 0xd3, 0x6f, 0x49, 0x80,
0x8f, 0xdd, 0x30, 0x73, 0xdd, 0x91, 0xae, 0x25, 0xcc, 0x7c, 0x2b, 0xe0, 0x0a, 0x0d, 0x38, 0x2a,
0x0b, 0x17, 0x86, 0x11, 0xf1, 0x26, 0xca, 0xb0, 0x55, 0x31, 0x44, 0xc4, 0x9b, 0xd4, 0x0d, 0x17,
0x58, 0xc5, 0x70, 0x01, 0xea, 0x01, 0x68, 0xd3, 0x61, 0xc0, 0x22, 0x82, 0x8b, 0xef, 0xdf, 0xea,
0xae, 0xf4, 0x37, 0x0e, 0xf7, 0x06, 0xea, 0xbf, 0x60, 0xf0, 0x22, 0xff, 0x2f, 0x50, 0xdf, 0x64,
0x7d, 0x98, 0x3d, 0xbb, 0x44, 0xc0, 0xad, 0xfc, 0xd8, 0xb2, 0x98, 0x5d, 0xf5, 0x80, 0xca, 0xb0,
0x89, 0x6a, 0xb2, 0x2c, 0x2f, 0x24, 0x01, 0xa6, 0xc1, 0xb0, 0xc8, 0x6b, 0xdf, 0x2e, 0x2f, 0x3f,
0x56, 0xcf, 0xab, 0xc0, 0x26, 0xaa, 0xc9, 0xf4, 0x5f, 0x35, 0xd0, 0x56, 0x8d, 0x7d, 0x3f, 0x26,
0x31, 0xb7, 0xcf, 0xa8, 0x6b, 0x6c, 0xcb, 0xce, 0xe2, 0x4b, 0x01, 0x5b, 0x5f, 0x65, 0x55, 0x48,
0xe6, 0x98, 0x5a, 0x89, 0x80, 0x2d, 0xbf, 0x0c, 0x14, 0x21, 0x15, 0x74, 0x51, 0x64, 0x72, 0xd1,
0xab, 0xc9, 0xeb, 0xc0, 0xeb, 0x79, 0xaf, 0x9a, 0x80, 0x2a, 0xbc, 0x6b, 0x1d, 0x9f, 0xbf, 0xe9,
0x34, 0xe6, 0x6f, 0x3a, 0x8d, 0xf3, 0xcb, 0x8e, 0x36, 0xbf, 0xec, 0x68, 0xbf, 0x5c, 0x75, 0x1a,
0xbf, 0x5d, 0x75, 0xb4, 0xf9, 0x55, 0xa7, 0xf1, 0xf7, 0x55, 0xa7, 0x71, 0xf2, 0xe8, 0x16, 0xd3,
0xad, 0x8a, 0x73, 0x57, 0xe5, 0x94, 0x7f, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xda, 0x35,
0x78, 0xb9, 0x0f, 0x08, 0x00, 0x00,
// 1026 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xbf, 0x6f, 0xdb, 0x46,
0x18, 0x15, 0xeb, 0xc4, 0xb6, 0xce, 0x3f, 0x64, 0xd3, 0x88, 0xc3, 0x18, 0x88, 0x4e, 0x50, 0x35,
0x28, 0x68, 0x22, 0x17, 0x6e, 0x27, 0xa3, 0x2d, 0x50, 0xc6, 0x68, 0x63, 0x18, 0x4d, 0x5c, 0x16,
0x5d, 0xbc, 0xb0, 0x24, 0xef, 0xac, 0x1c, 0x2c, 0xf2, 0x58, 0xf2, 0xa8, 0x58, 0x40, 0xff, 0x80,
0x76, 0x2b, 0x02, 0x74, 0xea, 0x92, 0xf6, 0xdf, 0xe8, 0xd0, 0xd5, 0x9b, 0x35, 0x16, 0x1d, 0x0e,
0x88, 0xbd, 0x71, 0x29, 0xc0, 0x31, 0x53, 0x71, 0x77, 0x14, 0x45, 0xca, 0x51, 0x50, 0xa0, 0x1b,
0xef, 0xbd, 0x77, 0xef, 0xdd, 0xf7, 0xe9, 0xbb, 0x13, 0xe8, 0x0c, 0x88, 0xbb, 0xeb, 0xd1, 0xe0,
0x94, 0xf4, 0x77, 0x11, 0x1e, 0x12, 0x0f, 0xab, 0x45, 0x12, 0x39, 0x8c, 0xd0, 0xa0, 0x17, 0x46,
0x94, 0x51, 0x7d, 0x51, 0x81, 0x3b, 0xdb, 0x42, 0x2d, 0x21, 0x8f, 0x0e, 0x76, 0x5d, 0x1c, 0x2a,
0x7e, 0xe7, 0x5e, 0xc9, 0x85, 0xba, 0x31, 0x8e, 0x86, 0x18, 0xe5, 0x54, 0x1d, 0x9f, 0x33, 0xf5,
0xd9, 0xfe, 0x67, 0x03, 0x6c, 0x1d, 0xc8, 0x8c, 0xc7, 0xe5, 0x0c, 0xfd, 0x4f, 0x0d, 0xd4, 0x55,
0xb6, 0x4d, 0x90, 0xa1, 0xb5, 0xb4, 0xee, 0xaa, 0xf9, 0x9b, 0x76, 0xc1, 0x61, 0xed, 0x6f, 0x0e,
0x3f, 0xee, 0x13, 0xf6, 0x3c, 0x71, 0x7b, 0x1e, 0xf5, 0x77, 0xe3, 0x51, 0xe0, 0xb1, 0xe7, 0x24,
0xe8, 0x97, 0xbe, 0xca, 0x27, 0xea, 0x29, 0xf7, 0xc3, 0x83, 0x2b, 0x0e, 0x97, 0x27, 0xdf, 0x29,
0x87, 0xcb, 0x28, 0xff, 0xce, 0x38, 0x6c, 0x9e, 0xfb, 0x83, 0xfd, 0x36, 0x41, 0x0f, 0x1d, 0xc6,
0xa2, 0x76, 0x2b, 0xa0, 0x08, 0x9f, 0x3a, 0xc9, 0x80, 0xed, 0xb7, 0x59, 0x94, 0xe0, 0x76, 0x7a,
0xd9, 0x59, 0xca, 0xc9, 0xec, 0xb2, 0x53, 0x6c, 0xfc, 0x71, 0xdc, 0xd1, 0x5e, 0x8e, 0x3b, 0x85,
0xe9, 0xab, 0x71, 0x47, 0xb3, 0x26, 0x2c, 0xd2, 0x8f, 0xc1, 0xad, 0xc0, 0xf1, 0xb1, 0xf1, 0x5e,
0x4b, 0xeb, 0xd6, 0xcd, 0x4f, 0x52, 0x0e, 0xe5, 0x3a, 0xe3, 0xf0, 0x9e, 0x8c, 0x13, 0x0b, 0xe9,
0xf9, 0x90, 0xfa, 0x84, 0x61, 0x3f, 0x64, 0x23, 0x91, 0xb4, 0xf5, 0x16, 0xdc, 0x92, 0x3b, 0xf5,
0x73, 0x50, 0x77, 0x10, 0x8a, 0x70, 0x1c, 0xe3, 0xd8, 0x58, 0x68, 0x2d, 0x74, 0xeb, 0xe6, 0x49,
0xca, 0xe1, 0x14, 0xcc, 0x38, 0x7c, 0x20, 0xbd, 0x73, 0xa4, 0xe4, 0xdc, 0x2a, 0x4a, 0x42, 0xa3,
0xc0, 0xf1, 0x89, 0x27, 0xb2, 0x36, 0x6f, 0xe8, 0xde, 0x5c, 0x76, 0x96, 0x72, 0x81, 0x35, 0xf5,
0xd5, 0x87, 0x60, 0xc5, 0xa3, 0x7e, 0x28, 0x56, 0x84, 0x06, 0xc6, 0xad, 0x96, 0xd6, 0x5d, 0xdf,
0xbb, 0xd3, 0x2b, 0x7a, 0xfc, 0x78, 0x4a, 0x9a, 0x9f, 0xa6, 0x1c, 0x96, 0xd5, 0x19, 0x87, 0xdb,
0xf2, 0x50, 0x25, 0x4c, 0x35, 0x3a, 0xbd, 0xec, 0x6c, 0xcc, 0x82, 0x56, 0x79, 0xab, 0x8e, 0x41,
0xdd, 0xc3, 0x11, 0xb3, 0x65, 0x23, 0x6f, 0xcb, 0x46, 0x3e, 0x11, 0xbf, 0x9d, 0x00, 0x9f, 0xaa,
0x66, 0xde, 0x57, 0xde, 0x39, 0xf0, 0x96, 0x86, 0xde, 0x9d, 0xc3, 0x59, 0x85, 0x8b, 0x7e, 0x02,
0x00, 0x09, 0x58, 0x44, 0x51, 0xe2, 0xe1, 0xc8, 0x58, 0x6c, 0x69, 0xdd, 0x65, 0x73, 0x3f, 0xe5,
0xb0, 0x84, 0x66, 0x1c, 0xde, 0x51, 0x53, 0x52, 0x40, 0x45, 0x11, 0x8d, 0x19, 0xcc, 0x2a, 0xed,
0xd3, 0x7f, 0xd7, 0xc0, 0x4e, 0x7c, 0x46, 0x42, 0x7b, 0x82, 0x89, 0xf1, 0xb6, 0x23, 0xec, 0xd3,
0xa1, 0x33, 0x88, 0x8d, 0x25, 0x19, 0x86, 0x52, 0x0e, 0x0d, 0xa1, 0x3a, 0x2c, 0x89, 0xac, 0x5c,
0x93, 0x71, 0xf8, 0xbe, 0x8c, 0x9e, 0x27, 0x28, 0x0e, 0x72, 0xff, 0x9d, 0x0a, 0x6b, 0x6e, 0x82,
0xfe, 0x87, 0x06, 0xd6, 0x8a, 0x33, 0x23, 0xdb, 0x1d, 0x19, 0xcb, 0xf2, 0xc6, 0xfd, 0xf2, 0xbf,
0x6e, 0x5c, 0xca, 0xe1, 0xea, 0xd4, 0xd5, 0x1c, 0x65, 0x1c, 0x76, 0xab, 0x3d, 0x44, 0xe6, 0x68,
0xfe, 0x9d, 0xdb, 0xbc, 0x21, 0x13, 0x37, 0x4e, 0xde, 0xb2, 0x8a, 0xad, 0xbe, 0x07, 0x16, 0x43,
0x27, 0x89, 0x31, 0x32, 0xea, 0xb2, 0x9b, 0x3b, 0x29, 0x87, 0x39, 0x92, 0x71, 0xb8, 0x2a, 0x23,
0xd5, 0xb2, 0x6d, 0xe5, 0xb8, 0xfe, 0x03, 0xd8, 0x70, 0x06, 0x03, 0xfa, 0x02, 0x23, 0x3b, 0xc0,
0xec, 0x05, 0x8d, 0xce, 0x62, 0x03, 0xc8, 0x2b, 0xf5, 0x75, 0xca, 0x61, 0x23, 0xe7, 0x9e, 0xe6,
0x54, 0xf1, 0x46, 0x54, 0xf1, 0xea, 0xa0, 0x19, 0xf3, 0x48, 0x6b, 0xd6, 0x4e, 0xff, 0x0e, 0x6c,
0x39, 0x09, 0xa3, 0xb6, 0xe3, 0x79, 0x38, 0x64, 0xf6, 0x29, 0x1d, 0x20, 0x1c, 0xc5, 0xc6, 0x8a,
0x3c, 0xfe, 0x87, 0x29, 0x87, 0x9b, 0x82, 0xfe, 0x5c, 0xb2, 0x5f, 0x28, 0x32, 0xe3, 0xf0, 0xae,
0x3a, 0xc2, 0x2c, 0xd3, 0xb6, 0x6e, 0xaa, 0xf5, 0x67, 0x60, 0xcd, 0x77, 0xce, 0xed, 0x18, 0x07,
0xc8, 0x3e, 0x73, 0xc3, 0xd8, 0x58, 0x6d, 0x69, 0xdd, 0xdb, 0xe6, 0x07, 0xe2, 0x72, 0xfa, 0xce,
0xf9, 0x37, 0x38, 0x40, 0x47, 0x6e, 0x28, 0x5c, 0x37, 0xa5, 0x6b, 0x09, 0x6b, 0xbf, 0xe1, 0x70,
0x81, 0x04, 0xcc, 0x2a, 0x0b, 0x27, 0x86, 0x11, 0xf6, 0x86, 0xca, 0x70, 0xad, 0x62, 0x68, 0x61,
0x6f, 0x38, 0x6b, 0x38, 0xc1, 0x2a, 0x86, 0x13, 0x50, 0x0f, 0x40, 0x83, 0xf4, 0x03, 0x1a, 0x61,
0x54, 0xd4, 0xbf, 0xde, 0x5a, 0xe8, 0xae, 0xec, 0x6d, 0xf7, 0xd4, 0xbf, 0x46, 0xef, 0x59, 0xfe,
0xaf, 0xa1, 0x6a, 0x32, 0x1f, 0x89, 0x59, 0x4c, 0x39, 0x5c, 0xcf, 0xb7, 0x4d, 0x1b, 0xb3, 0xa5,
0xa6, 0xaa, 0x0c, 0xb7, 0xad, 0x19, 0x99, 0xfe, 0x93, 0x06, 0x1a, 0x21, 0x0e, 0x10, 0x09, 0xfa,
0x45, 0x60, 0xe3, 0x9d, 0x81, 0x4f, 0x44, 0xe0, 0x15, 0x87, 0xc6, 0x01, 0x0e, 0x23, 0xec, 0x39,
0x0c, 0xa3, 0x63, 0x65, 0x90, 0x7b, 0xa6, 0x1c, 0x6a, 0x8f, 0x8a, 0x37, 0x28, 0x2c, 0x73, 0xa5,
0xd1, 0x30, 0x34, 0x6b, 0xbd, 0xc2, 0xc5, 0xfa, 0xaf, 0x1a, 0x68, 0xa8, 0x6e, 0x7e, 0x9f, 0xe0,
0x98, 0xd9, 0x67, 0xc4, 0x35, 0x36, 0x64, 0x3f, 0xe3, 0x2b, 0x0e, 0xd7, 0xbe, 0x12, 0x6d, 0x92,
0xcc, 0x11, 0x31, 0x53, 0x0e, 0xd7, 0xfc, 0x32, 0x50, 0x14, 0x5c, 0x41, 0x27, 0x4d, 0x4e, 0x2f,
0x3b, 0x33, 0xf2, 0x59, 0xe0, 0xe5, 0xb8, 0x53, 0x4d, 0xb0, 0x2a, 0xbc, 0xab, 0x7f, 0x06, 0xea,
0x49, 0xc0, 0xa2, 0x24, 0x66, 0x18, 0x19, 0x9b, 0x72, 0x26, 0x5b, 0xe2, 0x7f, 0xa6, 0x00, 0x33,
0x0e, 0x1b, 0xf2, 0x04, 0x05, 0xd2, 0xb6, 0xa6, 0xac, 0xac, 0x4e, 0x3c, 0x70, 0x0c, 0xdb, 0xfd,
0x84, 0xd8, 0x21, 0x8d, 0x98, 0xa1, 0x4f, 0xab, 0xb3, 0x24, 0xf5, 0xe5, 0xb7, 0x87, 0xc7, 0x34,
0x62, 0xa2, 0xba, 0xa8, 0x0c, 0x14, 0xd5, 0x55, 0xd0, 0x72, 0x75, 0x55, 0xf9, 0x2c, 0x20, 0xaa,
0xab, 0x24, 0x58, 0x13, 0x3e, 0x21, 0x62, 0x69, 0x1e, 0x5d, 0xbc, 0x6e, 0xd6, 0xc6, 0xaf, 0x9b,
0xb5, 0x8b, 0xab, 0xa6, 0x36, 0xbe, 0x6a, 0x6a, 0x3f, 0x5f, 0x37, 0x6b, 0xaf, 0xae, 0x9b, 0xda,
0xf8, 0xba, 0x59, 0xfb, 0xeb, 0xba, 0x59, 0x3b, 0x79, 0xf0, 0x1f, 0x1e, 0x3b, 0x35, 0x31, 0xee,
0xa2, 0x7c, 0xf4, 0x3e, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x4a, 0x4f, 0x60, 0x33, 0x09,
0x00, 0x00,
}
func (m *DeviceConfiguration) Marshal() (dAtA []byte, err error) {
@@ -166,6 +176,25 @@ func (m *DeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.RemoteGUIPort != 0 {
i = encodeVarintDeviceconfiguration(dAtA, i, uint64(m.RemoteGUIPort))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x90
}
if m.Untrusted {
i--
if m.Untrusted {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x88
}
if m.MaxRequestKiB != 0 {
i = encodeVarintDeviceconfiguration(dAtA, i, uint64(m.MaxRequestKiB))
i--
@@ -173,10 +202,10 @@ func (m *DeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x80
}
if len(m.PendingFolders) > 0 {
for iNdEx := len(m.PendingFolders) - 1; iNdEx >= 0; iNdEx-- {
if len(m.DeprecatedPendingFolders) > 0 {
for iNdEx := len(m.DeprecatedPendingFolders) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.PendingFolders[iNdEx].MarshalToSizedBuffer(dAtA[:i])
size, err := m.DeprecatedPendingFolders[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -379,8 +408,8 @@ func (m *DeviceConfiguration) ProtoSize() (n int) {
n += 1 + l + sovDeviceconfiguration(uint64(l))
}
}
if len(m.PendingFolders) > 0 {
for _, e := range m.PendingFolders {
if len(m.DeprecatedPendingFolders) > 0 {
for _, e := range m.DeprecatedPendingFolders {
l = e.ProtoSize()
n += 1 + l + sovDeviceconfiguration(uint64(l))
}
@@ -388,6 +417,12 @@ func (m *DeviceConfiguration) ProtoSize() (n int) {
if m.MaxRequestKiB != 0 {
n += 2 + sovDeviceconfiguration(uint64(m.MaxRequestKiB))
}
if m.Untrusted {
n += 3
}
if m.RemoteGUIPort != 0 {
n += 2 + sovDeviceconfiguration(uint64(m.RemoteGUIPort))
}
return n
}
@@ -793,7 +828,7 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 15:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PendingFolders", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedPendingFolders", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -820,8 +855,8 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PendingFolders = append(m.PendingFolders, ObservedFolder{})
if err := m.PendingFolders[len(m.PendingFolders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
m.DeprecatedPendingFolders = append(m.DeprecatedPendingFolders, ObservedFolder{})
if err := m.DeprecatedPendingFolders[len(m.DeprecatedPendingFolders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
@@ -844,6 +879,45 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error {
break
}
}
case 17:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Untrusted", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDeviceconfiguration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Untrusted = bool(v != 0)
case 18:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RemoteGUIPort", wireType)
}
m.RemoteGUIPort = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDeviceconfiguration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RemoteGUIPort |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipDeviceconfiguration(dAtA[iNdEx:])

View File

@@ -10,10 +10,11 @@ import (
"errors"
"fmt"
"runtime"
"sort"
"strings"
"time"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/v3/disk"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
@@ -26,22 +27,11 @@ var (
ErrMarkerMissing = errors.New("folder marker missing (this indicates potential data loss, search docs/forum to get information about how to proceed)")
)
const DefaultMarkerName = ".stfolder"
func NewFolderConfiguration(myID protocol.DeviceID, id, label string, fsType fs.FilesystemType, path string) FolderConfiguration {
f := FolderConfiguration{
ID: id,
Label: label,
Devices: []FolderDeviceConfiguration{{DeviceID: myID}},
FilesystemType: fsType,
Path: path,
}
util.SetDefaults(&f)
f.prepare()
return f
}
const (
DefaultMarkerName = ".stfolder"
maxConcurrentWritesDefault = 2
maxConcurrentWritesLimit = 64
)
func (f FolderConfiguration) Copy() FolderConfiguration {
c := f
@@ -60,7 +50,7 @@ func (f FolderConfiguration) Filesystem() fs.Filesystem {
}
filesystem := fs.NewFilesystem(f.FilesystemType, f.Path, opts...)
if !f.CaseSensitiveFS {
filesystem = fs.NewCaseFilesystem(filesystem)
filesystem = fs.NewCaseFilesystem(filesystem, opts...)
}
return filesystem
}
@@ -71,7 +61,7 @@ func (f FolderConfiguration) ModTimeWindow() time.Duration {
if usage, err := disk.Usage(f.Filesystem().URI()); err != nil {
dur = 2 * time.Second
l.Debugf(`Detecting FS at "%v" on android: Setting mtime window to 2s: err == "%v"`, f.Path, err)
} else if usage.Fstype == "" || strings.Contains(strings.ToLower(usage.Fstype), "fat") {
} else if usage.Fstype == "" || strings.Contains(strings.ToLower(usage.Fstype), "fat") || strings.Contains(strings.ToLower(usage.Fstype), "msdos") {
dur = 2 * time.Second
l.Debugf(`Detecting FS at "%v" on android: Setting mtime window to 2s: usage.Fstype == "%v"`, f.Path, usage.Fstype)
} else {
@@ -178,7 +168,19 @@ func (f *FolderConfiguration) DeviceIDs() []protocol.DeviceID {
return deviceIDs
}
func (f *FolderConfiguration) prepare() {
func (f *FolderConfiguration) prepare(myID protocol.DeviceID, existingDevices map[protocol.DeviceID]bool) {
// Ensure that
// - any loose devices are not present in the wrong places
// - there are no duplicate devices
// - we are part of the devices
f.Devices = ensureExistingDevices(f.Devices, existingDevices)
f.Devices = ensureNoDuplicateFolderDevices(f.Devices)
f.Devices = ensureDevicePresent(f.Devices, myID)
sort.Slice(f.Devices, func(a, b int) bool {
return f.Devices[a].DeviceID.Compare(f.Devices[b].DeviceID) == -1
})
if f.RescanIntervalS > MaxRescanIntervalS {
f.RescanIntervalS = MaxRescanIntervalS
} else if f.RescanIntervalS < 0 {
@@ -190,9 +192,6 @@ func (f *FolderConfiguration) prepare() {
f.FSWatcherDelayS = 10
}
if f.Versioning.Params == nil {
f.Versioning.Params = make(map[string]string)
}
if f.Versioning.CleanupIntervalS > MaxRescanIntervalS {
f.Versioning.CleanupIntervalS = MaxRescanIntervalS
} else if f.Versioning.CleanupIntervalS < 0 {
@@ -206,6 +205,12 @@ func (f *FolderConfiguration) prepare() {
if f.MarkerName == "" {
f.MarkerName = DefaultMarkerName
}
if f.MaxConcurrentWrites <= 0 {
f.MaxConcurrentWrites = maxConcurrentWritesDefault
} else if f.MaxConcurrentWrites > maxConcurrentWritesLimit {
f.MaxConcurrentWrites = maxConcurrentWritesLimit
}
}
// RequiresRestartOnly returns a copy with only the attributes that require
@@ -226,13 +231,18 @@ func (f FolderConfiguration) RequiresRestartOnly() FolderConfiguration {
return copy
}
func (f *FolderConfiguration) SharedWith(device protocol.DeviceID) bool {
func (f *FolderConfiguration) Device(device protocol.DeviceID) (FolderDeviceConfiguration, bool) {
for _, dev := range f.Devices {
if dev.DeviceID == device {
return true
return dev, true
}
}
return false
return FolderDeviceConfiguration{}, false
}
func (f *FolderConfiguration) SharedWith(device protocol.DeviceID) bool {
_, ok := f.Device(device)
return ok
}
func (f *FolderConfiguration) CheckAvailableSpace(req uint64) error {

View File

@@ -27,8 +27,9 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type FolderDeviceConfiguration struct {
DeviceID github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"deviceID" xml:"id,attr"`
IntroducedBy github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,2,opt,name=introduced_by,json=introducedBy,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"introducedBy" xml:"introducedBy,attr"`
DeviceID github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"deviceID" xml:"id,attr"`
IntroducedBy github_com_syncthing_syncthing_lib_protocol.DeviceID `protobuf:"bytes,2,opt,name=introduced_by,json=introducedBy,proto3,customtype=github.com/syncthing/syncthing/lib/protocol.DeviceID" json:"introducedBy" xml:"introducedBy,attr"`
EncryptionPassword string `protobuf:"bytes,3,opt,name=encryption_password,json=encryptionPassword,proto3" json:"encryptionPassword" xml:"encryptionPassword"`
}
func (m *FolderDeviceConfiguration) Reset() { *m = FolderDeviceConfiguration{} }
@@ -65,10 +66,10 @@ func (m *FolderDeviceConfiguration) XXX_DiscardUnknown() {
var xxx_messageInfo_FolderDeviceConfiguration proto.InternalMessageInfo
type FolderConfiguration struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id" xml:"id,attr"`
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id" xml:"id,attr" nodefault:"true"`
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label" xml:"label,attr" restart:"false"`
FilesystemType fs.FilesystemType `protobuf:"varint,3,opt,name=filesystem_type,json=filesystemType,proto3,enum=fs.FilesystemType" json:"filesystemType" xml:"filesystemType"`
Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path" xml:"path,attr"`
Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path" xml:"path,attr" default:"~"`
Type FolderType `protobuf:"varint,5,opt,name=type,proto3,enum=config.FolderType" json:"type" xml:"type,attr"`
Devices []FolderDeviceConfiguration `protobuf:"bytes,6,rep,name=devices,proto3" json:"devices" xml:"device"`
RescanIntervalS int `protobuf:"varint,7,opt,name=rescan_interval_s,json=rescanIntervalS,proto3,casttype=int" json:"rescanIntervalS" xml:"rescanIntervalS,attr" default:"3600"`
@@ -76,7 +77,7 @@ type FolderConfiguration struct {
FSWatcherDelayS int `protobuf:"varint,9,opt,name=fs_watcher_delay_s,json=fsWatcherDelayS,proto3,casttype=int" json:"fsWatcherDelayS" xml:"fsWatcherDelayS,attr" default:"10"`
IgnorePerms bool `protobuf:"varint,10,opt,name=ignore_perms,json=ignorePerms,proto3" json:"ignorePerms" xml:"ignorePerms,attr"`
AutoNormalize bool `protobuf:"varint,11,opt,name=auto_normalize,json=autoNormalize,proto3" json:"autoNormalize" xml:"autoNormalize,attr" default:"true"`
MinDiskFree Size `protobuf:"bytes,12,opt,name=min_disk_free,json=minDiskFree,proto3" json:"minDiskFree" xml:"minDiskFree"`
MinDiskFree Size `protobuf:"bytes,12,opt,name=min_disk_free,json=minDiskFree,proto3" json:"minDiskFree" xml:"minDiskFree" default:"1 %"`
Versioning VersioningConfiguration `protobuf:"bytes,13,opt,name=versioning,proto3" json:"versioning" xml:"versioning"`
Copiers int `protobuf:"varint,14,opt,name=copiers,proto3,casttype=int" json:"copiers" xml:"copiers"`
PullerMaxPendingKiB int `protobuf:"varint,15,opt,name=puller_max_pending_kib,json=pullerMaxPendingKib,proto3,casttype=int" json:"pullerMaxPendingKiB" xml:"pullerMaxPendingKiB"`
@@ -85,7 +86,7 @@ type FolderConfiguration struct {
IgnoreDelete bool `protobuf:"varint,18,opt,name=ignore_delete,json=ignoreDelete,proto3" json:"ignoreDelete" xml:"ignoreDelete"`
ScanProgressIntervalS int `protobuf:"varint,19,opt,name=scan_progress_interval_s,json=scanProgressIntervalS,proto3,casttype=int" json:"scanProgressIntervalS" xml:"scanProgressIntervalS"`
PullerPauseS int `protobuf:"varint,20,opt,name=puller_pause_s,json=pullerPauseS,proto3,casttype=int" json:"pullerPauseS" xml:"pullerPauseS"`
MaxConflicts int `protobuf:"varint,21,opt,name=max_conflicts,json=maxConflicts,proto3,casttype=int" json:"maxConflicts" xml:"maxConflicts" default:"-1"`
MaxConflicts int `protobuf:"varint,21,opt,name=max_conflicts,json=maxConflicts,proto3,casttype=int" json:"maxConflicts" xml:"maxConflicts" default:"10"`
DisableSparseFiles bool `protobuf:"varint,22,opt,name=disable_sparse_files,json=disableSparseFiles,proto3" json:"disableSparseFiles" xml:"disableSparseFiles"`
DisableTempIndexes bool `protobuf:"varint,23,opt,name=disable_temp_indexes,json=disableTempIndexes,proto3" json:"disableTempIndexes" xml:"disableTempIndexes"`
Paused bool `protobuf:"varint,24,opt,name=paused,proto3" json:"paused" xml:"paused"`
@@ -148,131 +149,135 @@ func init() {
}
var fileDescriptor_44a9785876ed3afa = []byte{
// 1983 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6f, 0x1c, 0x49,
0x15, 0x77, 0x3b, 0x5f, 0x76, 0xf9, 0xbb, 0x12, 0x27, 0x15, 0x67, 0xd7, 0xe5, 0x6d, 0x86, 0xc5,
0xbb, 0xda, 0x38, 0x89, 0x17, 0x71, 0x88, 0x76, 0x17, 0x76, 0xe2, 0xb5, 0x08, 0x21, 0x9b, 0x51,
0x3b, 0x10, 0x11, 0x90, 0x9a, 0x9e, 0xee, 0x9a, 0x99, 0x5a, 0xf7, 0x17, 0x55, 0x3d, 0xb1, 0x27,
0xa7, 0x70, 0x41, 0x20, 0xf6, 0x80, 0xcc, 0x81, 0x2b, 0x12, 0x08, 0xc1, 0xfe, 0x03, 0x48, 0xfc,
0x05, 0xb9, 0x20, 0xcf, 0x11, 0x71, 0x28, 0x69, 0x9d, 0xdb, 0xdc, 0xe8, 0x63, 0x4e, 0xa8, 0xaa,
0xba, 0x7b, 0xba, 0x7b, 0x66, 0x11, 0xd2, 0xde, 0xa6, 0x7e, 0xbf, 0x5f, 0xbd, 0xf7, 0xfa, 0xf5,
0x7b, 0xaf, 0xaa, 0x07, 0x34, 0x7c, 0xda, 0xbe, 0xe5, 0x46, 0x61, 0x87, 0x76, 0x6f, 0x75, 0x22,
0xdf, 0x23, 0x4c, 0x2f, 0xfa, 0xcc, 0x49, 0x68, 0x14, 0xee, 0xc4, 0x2c, 0x4a, 0x22, 0x78, 0x51,
0x83, 0x1b, 0x37, 0x26, 0xd4, 0xc9, 0x20, 0x26, 0x5a, 0xb4, 0xb1, 0x5e, 0x22, 0x39, 0x7d, 0x9e,
0xc3, 0x1b, 0x25, 0x38, 0xee, 0xfb, 0x7e, 0xc4, 0x3c, 0xc2, 0x32, 0x6e, 0xbb, 0xc4, 0x3d, 0x23,
0x8c, 0xd3, 0x28, 0xa4, 0x61, 0x77, 0x4a, 0x04, 0x1b, 0xb8, 0xa4, 0x6c, 0xfb, 0x91, 0x7b, 0x58,
0x37, 0x05, 0xa5, 0xa0, 0xc3, 0x6f, 0xc9, 0x80, 0x78, 0x86, 0xbd, 0x91, 0x61, 0x6e, 0x14, 0x0f,
0x98, 0x13, 0x76, 0x49, 0x40, 0x92, 0x5e, 0xe4, 0x65, 0xec, 0x3c, 0x39, 0x4e, 0xf4, 0x4f, 0xf3,
0x3f, 0xb3, 0xe0, 0xfa, 0xbe, 0x7a, 0x9e, 0x3d, 0xf2, 0x8c, 0xba, 0xe4, 0x5e, 0x39, 0x02, 0xf8,
0x85, 0x01, 0xe6, 0x3d, 0x85, 0xdb, 0xd4, 0x43, 0xc6, 0x96, 0xb1, 0xbd, 0xd8, 0xfc, 0xdc, 0x78,
0x29, 0xf0, 0xcc, 0xbf, 0x05, 0xfe, 0x76, 0x97, 0x26, 0xbd, 0x7e, 0x7b, 0xc7, 0x8d, 0x82, 0x5b,
0x7c, 0x10, 0xba, 0x49, 0x8f, 0x86, 0xdd, 0xd2, 0x2f, 0x19, 0x82, 0x72, 0xe2, 0x46, 0xfe, 0x8e,
0xb6, 0x7e, 0x7f, 0xef, 0x4c, 0xe0, 0xb9, 0xfc, 0xf7, 0x48, 0xe0, 0x39, 0x2f, 0xfb, 0x9d, 0x0a,
0xbc, 0x74, 0x1c, 0xf8, 0x77, 0x4d, 0xea, 0xbd, 0xe7, 0x24, 0x09, 0x33, 0x47, 0xa7, 0x8d, 0x4b,
0xd9, 0xef, 0xf4, 0xb4, 0x51, 0xe8, 0x7e, 0x3d, 0x6c, 0x18, 0x27, 0xc3, 0x46, 0x61, 0xc3, 0xca,
0x19, 0x0f, 0xfe, 0xc5, 0x00, 0x4b, 0x34, 0x4c, 0x58, 0xe4, 0xf5, 0x5d, 0xe2, 0xd9, 0xed, 0x01,
0x9a, 0x55, 0x01, 0xbf, 0xf8, 0x5a, 0x01, 0x8f, 0x04, 0x5e, 0x1c, 0x5b, 0x6d, 0x0e, 0x52, 0x81,
0xaf, 0xe9, 0x40, 0x4b, 0x60, 0x11, 0xf2, 0xda, 0x04, 0x2a, 0x03, 0xb6, 0x2a, 0x16, 0xcc, 0x57,
0x18, 0x5c, 0xd6, 0x39, 0xaf, 0x66, 0xfb, 0x23, 0x30, 0x9b, 0x65, 0x79, 0xbe, 0xb9, 0x73, 0x26,
0xf0, 0xac, 0xf2, 0x3e, 0x4b, 0xbd, 0xff, 0x95, 0x9c, 0x93, 0x61, 0x63, 0xf6, 0xfe, 0x9e, 0x35,
0x4b, 0x3d, 0xf8, 0x23, 0x70, 0xc1, 0x77, 0xda, 0xc4, 0x57, 0xcf, 0x3d, 0xdf, 0xfc, 0xee, 0x48,
0x60, 0x0d, 0xa4, 0x02, 0x6f, 0xa9, 0xfd, 0x6a, 0xa5, 0x4d, 0x6c, 0x31, 0xc2, 0x13, 0x87, 0x25,
0x77, 0xcd, 0x8e, 0xe3, 0x73, 0x22, 0x4d, 0x82, 0x31, 0xfd, 0x62, 0xd8, 0x98, 0xb1, 0xf4, 0x66,
0xd8, 0x05, 0x2b, 0x1d, 0xea, 0x13, 0x3e, 0xe0, 0x09, 0x09, 0x6c, 0x59, 0x65, 0xe8, 0xdc, 0x96,
0xb1, 0xbd, 0xbc, 0x0b, 0x77, 0x3a, 0x7c, 0x67, 0xbf, 0xa0, 0x1e, 0x0f, 0x62, 0xd2, 0x7c, 0x77,
0x24, 0xf0, 0x72, 0xa7, 0x82, 0xa5, 0x02, 0x5f, 0x51, 0xde, 0xab, 0xb0, 0x69, 0xd5, 0x74, 0xf0,
0x03, 0x70, 0x3e, 0x76, 0x92, 0x1e, 0x3a, 0xaf, 0xc2, 0xdf, 0x1e, 0x09, 0xac, 0xd6, 0xa9, 0xc0,
0x2b, 0x6a, 0xbf, 0x5c, 0x14, 0xcf, 0x3f, 0x5f, 0xac, 0x2c, 0xa5, 0x82, 0x2d, 0x70, 0x5e, 0xc5,
0x76, 0x21, 0x8b, 0x4d, 0xb7, 0xcc, 0x8e, 0x4e, 0xb4, 0x8a, 0x4d, 0x59, 0x4c, 0x74, 0x44, 0xda,
0xa2, 0x5c, 0x8c, 0x2d, 0x16, 0x2b, 0x4b, 0xa9, 0xe0, 0xcf, 0xc0, 0x25, 0x5d, 0x5c, 0x1c, 0x5d,
0xdc, 0x3a, 0xb7, 0xbd, 0xb0, 0xfb, 0x56, 0xd5, 0xe8, 0x94, 0x8e, 0x69, 0x62, 0x59, 0x6b, 0x23,
0x81, 0xf3, 0x9d, 0xa9, 0xc0, 0x8b, 0xca, 0x95, 0x5e, 0x9b, 0x56, 0x4e, 0xc0, 0xdf, 0x1b, 0x60,
0x8d, 0x11, 0xee, 0x3a, 0xa1, 0x4d, 0xc3, 0x84, 0xb0, 0x67, 0x8e, 0x6f, 0x73, 0x74, 0x69, 0xcb,
0xd8, 0xbe, 0xd0, 0xec, 0x8e, 0x04, 0x5e, 0xd1, 0xe4, 0xfd, 0x8c, 0x3b, 0x48, 0x05, 0x7e, 0x47,
0x59, 0xaa, 0xe1, 0xd9, 0xeb, 0xf4, 0x48, 0xc7, 0xe9, 0xfb, 0xc9, 0x5d, 0xf3, 0xfd, 0xef, 0xdc,
0xbe, 0x6d, 0xbe, 0x16, 0xf8, 0x1c, 0x0d, 0x93, 0xd1, 0x69, 0xe3, 0xca, 0x34, 0xf9, 0xeb, 0xd3,
0xc6, 0x79, 0xa9, 0xb3, 0xea, 0x4e, 0xe0, 0x3f, 0x0c, 0x00, 0x3b, 0xdc, 0x3e, 0x72, 0x12, 0xb7,
0x47, 0x98, 0x4d, 0x42, 0xa7, 0xed, 0x13, 0x0f, 0xcd, 0x6d, 0x19, 0xdb, 0x73, 0xcd, 0xdf, 0x1a,
0x67, 0x02, 0xaf, 0xee, 0x1f, 0x3c, 0xd1, 0xec, 0x27, 0x9a, 0x1c, 0x09, 0xbc, 0xda, 0xe1, 0x55,
0x2c, 0x15, 0xf8, 0x5d, 0xfd, 0xce, 0x6b, 0x44, 0x3d, 0xda, 0x84, 0xf5, 0x55, 0xed, 0xad, 0x4f,
0x15, 0xca, 0x38, 0xa5, 0xe2, 0x64, 0xd8, 0x98, 0x70, 0x6b, 0x4d, 0x38, 0x85, 0x7f, 0xaf, 0x06,
0xef, 0x11, 0xdf, 0x19, 0xd8, 0x1c, 0xcd, 0xab, 0x9c, 0xfe, 0x46, 0x06, 0xbf, 0x52, 0x58, 0xd9,
0x93, 0xe4, 0x81, 0xcc, 0x73, 0x61, 0x46, 0x43, 0xa9, 0xc0, 0xdf, 0xaa, 0x86, 0xae, 0xf1, 0x7a,
0xe4, 0x77, 0x2a, 0x59, 0x9e, 0x26, 0x7e, 0x7d, 0xda, 0x98, 0xbd, 0x73, 0xfb, 0x64, 0xd8, 0xa8,
0x7b, 0xb5, 0xea, 0x3e, 0xe1, 0xcf, 0xc1, 0x22, 0xed, 0x86, 0x11, 0x23, 0x76, 0x4c, 0x58, 0xc0,
0x11, 0x50, 0xf9, 0xfe, 0x70, 0x24, 0xf0, 0x82, 0xc6, 0x5b, 0x12, 0x4e, 0x05, 0xbe, 0xaa, 0xe7,
0xc0, 0x18, 0x2b, 0xca, 0x77, 0xb5, 0x0e, 0x5a, 0xe5, 0xad, 0xf0, 0x97, 0x06, 0x58, 0x76, 0xfa,
0x49, 0x64, 0x87, 0x11, 0x0b, 0x1c, 0x9f, 0x3e, 0x27, 0x68, 0x41, 0x39, 0x79, 0x3a, 0x12, 0x78,
0x49, 0x32, 0x9f, 0xe6, 0x44, 0x91, 0x81, 0x0a, 0xfa, 0x55, 0x6f, 0x0e, 0x4e, 0xaa, 0xf2, 0xd7,
0x66, 0x55, 0xed, 0xc2, 0xa7, 0x60, 0x29, 0xa0, 0xa1, 0xed, 0x51, 0x7e, 0x68, 0x77, 0x18, 0x21,
0x68, 0x71, 0xcb, 0xd8, 0x5e, 0xd8, 0x5d, 0xcc, 0xdb, 0xea, 0x80, 0x3e, 0x27, 0xcd, 0xed, 0xac,
0x83, 0x16, 0x02, 0x1a, 0xee, 0x51, 0x7e, 0xb8, 0xcf, 0x88, 0x8c, 0x68, 0x4d, 0x45, 0x54, 0xc2,
0x4c, 0xab, 0xac, 0x80, 0x5d, 0x00, 0xc6, 0xe7, 0x28, 0x5a, 0x52, 0x86, 0x71, 0x6e, 0xf8, 0xc7,
0x05, 0x53, 0xed, 0xd6, 0xb7, 0x33, 0x5f, 0xa5, 0xad, 0xa9, 0xc0, 0xab, 0xca, 0xd5, 0x18, 0x32,
0xad, 0x12, 0x0f, 0x3f, 0x04, 0x97, 0xdc, 0x28, 0xa6, 0x84, 0x71, 0xb4, 0xac, 0x0a, 0xeb, 0x1b,
0xb2, 0xdd, 0x33, 0xa8, 0x98, 0xd4, 0xd9, 0x3a, 0x2f, 0x11, 0x2b, 0x17, 0xc0, 0x7f, 0x1a, 0xe0,
0xaa, 0x3c, 0xc1, 0x09, 0xb3, 0x03, 0xe7, 0xd8, 0x8e, 0x49, 0xe8, 0xd1, 0xb0, 0x6b, 0x1f, 0xd2,
0x36, 0x5a, 0x51, 0xe6, 0xfe, 0x20, 0xeb, 0xf4, 0x72, 0x4b, 0x49, 0x1e, 0x3a, 0xc7, 0x2d, 0x2d,
0x78, 0x40, 0x9b, 0x23, 0x81, 0x2f, 0xc7, 0x93, 0x70, 0x2a, 0xf0, 0x75, 0x3d, 0x1e, 0x27, 0xb9,
0x52, 0x85, 0x4e, 0xdd, 0x3a, 0x1d, 0x3e, 0x19, 0x36, 0xa6, 0xf9, 0xb7, 0xa6, 0x68, 0xdb, 0x32,
0x1d, 0x3d, 0x87, 0xf7, 0x64, 0x3a, 0x56, 0xc7, 0xe9, 0xc8, 0xa0, 0x22, 0x1d, 0xd9, 0x7a, 0x9c,
0x8e, 0x0c, 0x80, 0x1f, 0x83, 0x0b, 0xea, 0x2e, 0x83, 0xd6, 0xd4, 0xd8, 0x5e, 0xcb, 0xdf, 0x98,
0xf4, 0xff, 0x48, 0x12, 0x4d, 0x24, 0x8f, 0x31, 0xa5, 0x49, 0x05, 0x5e, 0x50, 0xd6, 0xd4, 0xca,
0xb4, 0x34, 0x0a, 0x1f, 0x80, 0xa5, 0xac, 0x77, 0x3c, 0xe2, 0x93, 0x84, 0x20, 0xa8, 0xea, 0xfa,
0x6d, 0x75, 0x72, 0x2b, 0x62, 0x4f, 0xe1, 0xa9, 0xc0, 0xb0, 0xd4, 0x3d, 0x1a, 0x34, 0xad, 0x8a,
0x06, 0x1e, 0x03, 0xa4, 0x46, 0x72, 0xcc, 0xa2, 0x2e, 0x23, 0x9c, 0x97, 0x67, 0xf3, 0x65, 0xf5,
0x7c, 0xf2, 0x58, 0x5d, 0x97, 0x9a, 0x56, 0x26, 0x29, 0x4f, 0xe8, 0x1b, 0xca, 0xc1, 0x54, 0xb6,
0x78, 0xf6, 0xe9, 0x9b, 0xe1, 0x01, 0x58, 0xce, 0xea, 0x22, 0x76, 0xfa, 0x9c, 0xd8, 0x1c, 0x5d,
0x51, 0xfe, 0x6e, 0xca, 0xe7, 0xd0, 0x4c, 0x4b, 0x12, 0x07, 0xc5, 0x73, 0x94, 0xc1, 0xc2, 0x7a,
0x45, 0x0a, 0x09, 0x58, 0x92, 0x55, 0x26, 0x93, 0xea, 0x53, 0x37, 0xe1, 0x68, 0x5d, 0xd9, 0xfc,
0x9e, 0xb4, 0x19, 0x38, 0xc7, 0xf7, 0x72, 0x3c, 0x15, 0x18, 0xeb, 0x06, 0x2b, 0x81, 0xa5, 0x66,
0xbf, 0x79, 0x27, 0x77, 0x20, 0x87, 0xda, 0xcd, 0x3b, 0x56, 0x65, 0x37, 0xf4, 0xc0, 0x15, 0x8f,
0x72, 0x39, 0x84, 0x6d, 0x1e, 0x3b, 0x8c, 0x13, 0x5b, 0x1d, 0xed, 0xe8, 0xaa, 0x7a, 0x13, 0xbb,
0x23, 0x81, 0x61, 0xc6, 0x1f, 0x28, 0x5a, 0x5d, 0x1a, 0x52, 0x81, 0x91, 0x3e, 0x1a, 0x27, 0x28,
0xd3, 0x9a, 0xa2, 0x2f, 0x7b, 0x49, 0x48, 0x10, 0xdb, 0x34, 0xf4, 0xc8, 0x31, 0xe1, 0xe8, 0xda,
0x84, 0x97, 0xc7, 0x24, 0x88, 0xef, 0x6b, 0xb6, 0xee, 0xa5, 0x44, 0x8d, 0xbd, 0x94, 0x40, 0xb8,
0x0b, 0x2e, 0xaa, 0x17, 0xe0, 0x21, 0xa4, 0xec, 0x6e, 0x8c, 0x04, 0xce, 0x90, 0xe2, 0x30, 0xd7,
0x4b, 0xd3, 0xca, 0x70, 0x98, 0x80, 0x6b, 0x47, 0xc4, 0x39, 0xb4, 0x65, 0x55, 0xdb, 0x49, 0x8f,
0x11, 0xde, 0x8b, 0x7c, 0xcf, 0x8e, 0xdd, 0x04, 0x5d, 0x57, 0x09, 0x97, 0x93, 0xfc, 0x8a, 0x94,
0x7c, 0xdf, 0xe1, 0xbd, 0xc7, 0xb9, 0xa0, 0xe5, 0x26, 0xa9, 0xc0, 0x1b, 0xca, 0xe4, 0x34, 0xb2,
0x78, 0xa9, 0x53, 0xb7, 0xc2, 0x7b, 0x60, 0x21, 0x70, 0xd8, 0x21, 0x61, 0x76, 0xe8, 0x04, 0x04,
0x6d, 0xa8, 0x6b, 0x93, 0x29, 0xc7, 0x99, 0x86, 0x3f, 0x75, 0x02, 0x52, 0x8c, 0xb3, 0x31, 0x64,
0x5a, 0x25, 0x1e, 0x0e, 0xc0, 0x86, 0xfc, 0x48, 0xb0, 0xa3, 0xa3, 0x90, 0x30, 0xde, 0xa3, 0xb1,
0xdd, 0x61, 0x51, 0x60, 0xc7, 0x0e, 0x23, 0x61, 0x82, 0x6e, 0xa8, 0x14, 0x7c, 0x30, 0x12, 0xf8,
0x9a, 0x54, 0x3d, 0xca, 0x45, 0xfb, 0x2c, 0x0a, 0x5a, 0x4a, 0x92, 0x0a, 0xfc, 0x66, 0x3e, 0xf1,
0xa6, 0xf1, 0xa6, 0xf5, 0x55, 0x3b, 0xe1, 0xaf, 0x0c, 0xb0, 0x16, 0x44, 0x9e, 0x9d, 0xd0, 0x80,
0xd8, 0x47, 0x34, 0xf4, 0xa2, 0x23, 0x9b, 0xa3, 0x37, 0x54, 0xc2, 0x7e, 0x7a, 0x26, 0xf0, 0x9a,
0xe5, 0x1c, 0x3d, 0x8c, 0xbc, 0xc7, 0x34, 0x20, 0x4f, 0x14, 0x2b, 0x8f, 0xeb, 0xe5, 0xa0, 0x82,
0x14, 0x97, 0xcb, 0x2a, 0x9c, 0x67, 0xee, 0x64, 0xd8, 0x98, 0xb4, 0x62, 0xd5, 0x6c, 0xc0, 0x17,
0x06, 0x58, 0xcf, 0xda, 0xc4, 0xed, 0x33, 0x19, 0x9b, 0x7d, 0xc4, 0x68, 0x42, 0x38, 0x7a, 0x53,
0x05, 0xf3, 0x43, 0x39, 0x7a, 0x75, 0xc1, 0x67, 0xfc, 0x13, 0x45, 0xa7, 0x02, 0x7f, 0xb3, 0xd4,
0x35, 0x15, 0xae, 0xd4, 0x3c, 0xbb, 0xa5, 0xde, 0x31, 0x76, 0xad, 0x69, 0x96, 0xe4, 0x10, 0xcb,
0x6b, 0xbb, 0x23, 0xbf, 0x48, 0xd0, 0xe6, 0x78, 0x88, 0x65, 0xc4, 0xbe, 0xc4, 0x8b, 0xe6, 0x2f,
0x83, 0xa6, 0x55, 0xd1, 0x40, 0x1f, 0xac, 0xaa, 0x2f, 0x45, 0x5b, 0xce, 0x02, 0x5b, 0xcf, 0x57,
0xac, 0xe6, 0xeb, 0xd5, 0x7c, 0xbe, 0x36, 0x25, 0x3f, 0x1e, 0xb2, 0xea, 0xda, 0xde, 0xae, 0x60,
0x45, 0x66, 0xab, 0xb0, 0x69, 0xd5, 0x74, 0xf0, 0x73, 0x03, 0xac, 0xa9, 0x12, 0x52, 0x1f, 0x9a,
0xb6, 0xfe, 0xd2, 0x44, 0x5b, 0xca, 0xdf, 0x65, 0xf9, 0x89, 0x70, 0x2f, 0x8a, 0x07, 0x96, 0xe4,
0x1e, 0x2a, 0xaa, 0xf9, 0x40, 0xde, 0xba, 0xdc, 0x2a, 0x98, 0x0a, 0xbc, 0x5d, 0x94, 0x51, 0x09,
0x2f, 0xa5, 0x91, 0x27, 0x4e, 0xe8, 0x39, 0xcc, 0x33, 0x5f, 0x9f, 0x36, 0xe6, 0xf2, 0x85, 0x55,
0x37, 0x04, 0xff, 0x2c, 0xc3, 0x71, 0xe4, 0x00, 0x25, 0x21, 0xa7, 0x09, 0x7d, 0x26, 0x33, 0x8a,
0xde, 0x52, 0xe9, 0x3c, 0x96, 0x57, 0xc0, 0x7b, 0x0e, 0x27, 0x07, 0x39, 0xb7, 0xaf, 0xae, 0x80,
0x6e, 0x15, 0x4a, 0x05, 0x5e, 0xd7, 0xc1, 0x54, 0x71, 0x79, 0xdd, 0x99, 0xd0, 0x4e, 0x42, 0xf2,
0xc6, 0x57, 0x73, 0x62, 0xd5, 0x34, 0x1c, 0xfe, 0xc9, 0x00, 0xab, 0x9d, 0xc8, 0xf7, 0xa3, 0x23,
0xfb, 0xb3, 0x7e, 0xe8, 0xca, 0xeb, 0x08, 0x47, 0xe6, 0x38, 0xca, 0x1f, 0xe4, 0xe0, 0xc7, 0x7c,
0x8f, 0x32, 0x2e, 0xa3, 0xfc, 0xac, 0x0a, 0x15, 0x51, 0xd6, 0x70, 0x15, 0x65, 0x5d, 0x3b, 0x09,
0xc9, 0x28, 0x6b, 0x4e, 0xac, 0x15, 0x1d, 0x51, 0x01, 0xc3, 0x43, 0x30, 0xcf, 0x88, 0xe3, 0xd9,
0x51, 0xe8, 0x0f, 0xd0, 0x5f, 0xf7, 0x55, 0x78, 0x0f, 0xcf, 0x04, 0x86, 0x7b, 0x24, 0x66, 0xc4,
0x75, 0x12, 0xe2, 0x59, 0xc4, 0xf1, 0x1e, 0x85, 0xfe, 0x60, 0x24, 0xb0, 0x71, 0xb3, 0xf8, 0x3a,
0x66, 0x91, 0xba, 0x09, 0xbe, 0x17, 0x05, 0x54, 0xce, 0xea, 0x64, 0xa0, 0xbe, 0x8e, 0x27, 0x50,
0x64, 0x58, 0x73, 0x2c, 0x33, 0x00, 0x7f, 0x01, 0xd6, 0x2a, 0xd7, 0x43, 0x35, 0x3f, 0xff, 0x26,
0x9d, 0x1a, 0xcd, 0x4f, 0xce, 0x04, 0x46, 0x63, 0xa7, 0x0f, 0xc7, 0x37, 0xbf, 0x96, 0x9b, 0xe4,
0xae, 0x37, 0xeb, 0x77, 0xc4, 0x96, 0x9b, 0x94, 0x22, 0x40, 0x86, 0xb5, 0x5c, 0x25, 0xe1, 0x4f,
0xc0, 0x25, 0x7d, 0x5e, 0x72, 0xf4, 0xc5, 0xbe, 0xea, 0xf5, 0x8f, 0xe4, 0xe0, 0x19, 0x3b, 0xd2,
0xf7, 0x20, 0x5e, 0x7d, 0xb8, 0x6c, 0x4b, 0xc9, 0x74, 0xd6, 0xe0, 0xc8, 0xb0, 0x72, 0x7b, 0xcd,
0x07, 0x2f, 0xbf, 0xdc, 0x9c, 0x19, 0x7e, 0xb9, 0x39, 0xf3, 0xf2, 0x6c, 0xd3, 0x18, 0x9e, 0x6d,
0x1a, 0xbf, 0x7b, 0xb5, 0x39, 0xf3, 0xc7, 0x57, 0x9b, 0xc6, 0xf0, 0xd5, 0xe6, 0xcc, 0xbf, 0x5e,
0x6d, 0xce, 0x3c, 0x7d, 0xe7, 0xff, 0xf8, 0x3f, 0x42, 0xb7, 0x6b, 0xfb, 0xa2, 0xfa, 0x5f, 0xe2,
0xfd, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xde, 0x81, 0xf6, 0x5e, 0xb5, 0x12, 0x00, 0x00,
// 2043 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6f, 0x24, 0x47,
0x15, 0x77, 0x7b, 0xbf, 0xec, 0xf2, 0x77, 0x79, 0xbd, 0xdb, 0xf1, 0x26, 0x53, 0x93, 0x66, 0x36,
0x38, 0x51, 0xe2, 0xdd, 0x75, 0x10, 0x12, 0x2b, 0x16, 0xc8, 0xd8, 0xb1, 0x58, 0x16, 0x67, 0x47,
0xed, 0x85, 0x15, 0x01, 0xa9, 0xe9, 0xe9, 0xae, 0x99, 0xa9, 0xb8, 0xbf, 0xa8, 0xea, 0x59, 0x7b,
0xf6, 0x10, 0x2d, 0x17, 0x04, 0x22, 0x07, 0x64, 0x0e, 0xdc, 0x50, 0x24, 0x10, 0x82, 0xfc, 0x03,
0x48, 0xfc, 0x05, 0x7b, 0x41, 0x9e, 0x13, 0x42, 0x1c, 0x4a, 0x8a, 0xf7, 0x36, 0xc7, 0x3e, 0xfa,
0x84, 0xaa, 0xaa, 0xbb, 0xa7, 0xbb, 0x67, 0x22, 0x21, 0x71, 0x9b, 0xfa, 0xfd, 0x5e, 0xbd, 0xf7,
0xeb, 0x57, 0xaf, 0x5e, 0xbf, 0x1e, 0xd0, 0xf0, 0x48, 0xfb, 0x8e, 0x13, 0x06, 0x1d, 0xd2, 0xbd,
0xd3, 0x09, 0x3d, 0x17, 0x53, 0xb5, 0xe8, 0x53, 0x3b, 0x26, 0x61, 0xb0, 0x1d, 0xd1, 0x30, 0x0e,
0xe1, 0x55, 0x05, 0x6e, 0xde, 0x9a, 0xb0, 0x8e, 0x07, 0x11, 0x56, 0x46, 0x9b, 0x1b, 0x05, 0x92,
0x91, 0xe7, 0x19, 0xbc, 0x59, 0x80, 0xa3, 0xbe, 0xe7, 0x85, 0xd4, 0xc5, 0x34, 0xe5, 0xb6, 0x0a,
0xdc, 0x33, 0x4c, 0x19, 0x09, 0x03, 0x12, 0x74, 0xa7, 0x28, 0xd8, 0x44, 0x05, 0xcb, 0xb6, 0x17,
0x3a, 0x47, 0x55, 0x57, 0x50, 0x18, 0x74, 0xd8, 0x1d, 0x21, 0x88, 0xa5, 0xd8, 0xeb, 0x29, 0xe6,
0x84, 0xd1, 0x80, 0xda, 0x41, 0x17, 0xfb, 0x38, 0xee, 0x85, 0x6e, 0xca, 0xce, 0xe3, 0x93, 0x58,
0xfd, 0x34, 0xfe, 0x75, 0x09, 0xbc, 0xb6, 0x2f, 0x9f, 0x67, 0x0f, 0x3f, 0x23, 0x0e, 0xde, 0x2d,
0x2a, 0x80, 0x5f, 0x68, 0x60, 0xde, 0x95, 0xb8, 0x45, 0x5c, 0x5d, 0xab, 0x6b, 0x5b, 0x8b, 0xcd,
0xcf, 0xb4, 0x97, 0x1c, 0xcd, 0xfc, 0x87, 0xa3, 0x6f, 0x74, 0x49, 0xdc, 0xeb, 0xb7, 0xb7, 0x9d,
0xd0, 0xbf, 0xc3, 0x06, 0x81, 0x13, 0xf7, 0x48, 0xd0, 0x2d, 0xfc, 0x12, 0x12, 0x64, 0x10, 0x27,
0xf4, 0xb6, 0x95, 0xf7, 0x87, 0x7b, 0xe7, 0x1c, 0xcd, 0x65, 0xbf, 0x47, 0x1c, 0xcd, 0xb9, 0xe9,
0xef, 0x84, 0xa3, 0xa5, 0x13, 0xdf, 0xbb, 0x6f, 0x10, 0xf7, 0x5d, 0x3b, 0x8e, 0xa9, 0x31, 0x3a,
0x6b, 0x5c, 0x4b, 0x7f, 0x27, 0x67, 0x8d, 0xdc, 0xee, 0xd7, 0xc3, 0x86, 0x76, 0x3a, 0x6c, 0xe4,
0x3e, 0xcc, 0x8c, 0x71, 0xe1, 0x5f, 0x34, 0xb0, 0x44, 0x82, 0x98, 0x86, 0x6e, 0xdf, 0xc1, 0xae,
0xd5, 0x1e, 0xe8, 0xb3, 0x52, 0xf0, 0x8b, 0xff, 0x4b, 0xf0, 0x88, 0xa3, 0xc5, 0xb1, 0xd7, 0xe6,
0x20, 0xe1, 0xe8, 0xa6, 0x12, 0x5a, 0x00, 0x73, 0xc9, 0x6b, 0x13, 0xa8, 0x10, 0x6c, 0x96, 0x3c,
0x40, 0x07, 0xac, 0xe3, 0xc0, 0xa1, 0x83, 0x48, 0xe4, 0xd8, 0x8a, 0x6c, 0xc6, 0x8e, 0x43, 0xea,
0xea, 0x97, 0xea, 0xda, 0xd6, 0x7c, 0x73, 0x67, 0xc4, 0x11, 0x1c, 0xd3, 0xad, 0x94, 0x4d, 0x38,
0xd2, 0x65, 0xd8, 0x49, 0xca, 0x30, 0xa7, 0xd8, 0x1b, 0x7f, 0xac, 0x83, 0x75, 0x75, 0xb0, 0xe5,
0x23, 0x3d, 0x04, 0xb3, 0xe9, 0x51, 0xce, 0x37, 0x77, 0xcf, 0x39, 0x9a, 0x95, 0x8f, 0x38, 0x4b,
0x44, 0x84, 0x5a, 0xe9, 0x04, 0xea, 0x41, 0xe8, 0xe2, 0x8e, 0xdd, 0xf7, 0xe2, 0xfb, 0x46, 0x4c,
0xfb, 0xb8, 0x78, 0x24, 0xa7, 0xc3, 0xc6, 0xec, 0xc3, 0xbd, 0xcf, 0xc5, 0xb3, 0xcd, 0x12, 0x17,
0xfe, 0x08, 0x5c, 0xf1, 0xec, 0x36, 0xf6, 0x64, 0xc6, 0xe7, 0x9b, 0xdf, 0x1d, 0x71, 0xa4, 0x80,
0x84, 0xa3, 0xba, 0x74, 0x2a, 0x57, 0xa9, 0x5f, 0x8a, 0x59, 0x6c, 0xd3, 0xf8, 0xbe, 0xd1, 0xb1,
0x3d, 0x26, 0xdd, 0x82, 0x31, 0xfd, 0x62, 0xd8, 0x98, 0x31, 0xd5, 0x66, 0xd8, 0x05, 0x2b, 0x1d,
0xe2, 0x61, 0x36, 0x60, 0x31, 0xf6, 0x2d, 0x51, 0xdf, 0x32, 0x49, 0xcb, 0x3b, 0x70, 0xbb, 0xc3,
0xb6, 0xf7, 0x73, 0xea, 0xc9, 0x20, 0xc2, 0xcd, 0x77, 0x46, 0x1c, 0x2d, 0x77, 0x4a, 0x58, 0xc2,
0xd1, 0x75, 0x19, 0xbd, 0x0c, 0x1b, 0x66, 0xc5, 0x0e, 0x1e, 0x80, 0xcb, 0x91, 0x1d, 0xf7, 0xf4,
0xcb, 0x52, 0xfe, 0xb7, 0x46, 0x1c, 0xc9, 0x75, 0xc2, 0xd1, 0x2d, 0xb9, 0x5f, 0x2c, 0x52, 0xf1,
0x79, 0x4a, 0x3e, 0x15, 0xc2, 0xe7, 0x73, 0xe6, 0xe2, 0xac, 0xa1, 0x7d, 0x6a, 0xca, 0x6d, 0xb0,
0x05, 0x2e, 0x4b, 0xb1, 0x57, 0x52, 0xb1, 0xea, 0xf6, 0x6e, 0xab, 0xe3, 0x90, 0x62, 0xb7, 0x44,
0x88, 0x58, 0x49, 0x5c, 0x91, 0x21, 0xc4, 0x22, 0x2f, 0xa3, 0xf9, 0x7c, 0x65, 0x4a, 0x2b, 0xf8,
0x33, 0x70, 0x4d, 0xd5, 0x39, 0xd3, 0xaf, 0xd6, 0x2f, 0x6d, 0x2d, 0xec, 0xbc, 0x59, 0x76, 0x3a,
0xe5, 0xf2, 0x36, 0x91, 0x28, 0xfb, 0x11, 0x47, 0xd9, 0xce, 0x84, 0xa3, 0x45, 0x19, 0x4a, 0xad,
0x0d, 0x33, 0x23, 0xe0, 0xef, 0x35, 0xb0, 0x46, 0x31, 0x73, 0xec, 0xc0, 0x22, 0x41, 0x8c, 0xe9,
0x33, 0xdb, 0xb3, 0x98, 0x7e, 0xad, 0xae, 0x6d, 0x5d, 0x69, 0x76, 0x47, 0x1c, 0xad, 0x28, 0xf2,
0x61, 0xca, 0x1d, 0x26, 0x1c, 0xbd, 0x2d, 0x3d, 0x55, 0xf0, 0x6a, 0x8a, 0xde, 0xff, 0xe6, 0xdd,
0xbb, 0xc6, 0x05, 0x47, 0x97, 0x48, 0x10, 0x8f, 0xce, 0x1a, 0xd7, 0xa7, 0x99, 0x5f, 0x9c, 0x35,
0x2e, 0x0b, 0x3b, 0xb3, 0x1a, 0x04, 0xfe, 0x43, 0x03, 0xb0, 0xc3, 0xac, 0x63, 0x3b, 0x76, 0x7a,
0x98, 0x5a, 0x38, 0xb0, 0xdb, 0x1e, 0x76, 0xf5, 0xb9, 0xba, 0xb6, 0x35, 0xd7, 0xfc, 0xad, 0x76,
0xce, 0xd1, 0xea, 0xfe, 0xe1, 0x53, 0xc5, 0x7e, 0xa8, 0xc8, 0x11, 0x47, 0xab, 0x1d, 0x56, 0xc6,
0x12, 0x8e, 0xde, 0x51, 0x45, 0x50, 0x21, 0xaa, 0x6a, 0xb3, 0x1a, 0xdf, 0x98, 0x6a, 0x28, 0x74,
0x0a, 0x8b, 0xd3, 0x61, 0x63, 0x22, 0xac, 0x39, 0x11, 0x14, 0xfe, 0xbd, 0x2c, 0xde, 0xc5, 0x9e,
0x3d, 0xb0, 0x98, 0x3e, 0x2f, 0x73, 0xfa, 0x1b, 0x21, 0x7e, 0x25, 0xf7, 0xb2, 0x27, 0xc8, 0x43,
0x91, 0xe7, 0xdc, 0x8d, 0x82, 0x12, 0x8e, 0xbe, 0x5e, 0x96, 0xae, 0xf0, 0xaa, 0xf2, 0x7b, 0xa5,
0x2c, 0x4f, 0x33, 0xbe, 0x38, 0x6b, 0xcc, 0xde, 0xbb, 0x7b, 0x3a, 0x6c, 0x54, 0xa3, 0x9a, 0xd5,
0x98, 0xf0, 0xe7, 0x60, 0x91, 0x74, 0x83, 0x90, 0x62, 0x2b, 0xc2, 0xd4, 0x67, 0x3a, 0x90, 0xf9,
0x7e, 0x30, 0xe2, 0x68, 0x41, 0xe1, 0x2d, 0x01, 0x27, 0x1c, 0xdd, 0x50, 0xdd, 0x62, 0x8c, 0xe5,
0xe5, 0xbb, 0x5a, 0x05, 0xcd, 0xe2, 0x56, 0xf8, 0x4b, 0x0d, 0x2c, 0xdb, 0xfd, 0x38, 0xb4, 0x82,
0x90, 0xfa, 0xb6, 0x47, 0x9e, 0x63, 0x7d, 0x41, 0x06, 0xf9, 0x78, 0xc4, 0xd1, 0x92, 0x60, 0x3e,
0xca, 0x88, 0x3c, 0x03, 0x25, 0xf4, 0xab, 0x4e, 0x0e, 0x4e, 0x5a, 0x65, 0xc7, 0x66, 0x96, 0xfd,
0xc2, 0x10, 0x2c, 0xf9, 0x24, 0xb0, 0x5c, 0xc2, 0x8e, 0xac, 0x0e, 0xc5, 0x58, 0x5f, 0xac, 0x6b,
0x5b, 0x0b, 0x3b, 0x8b, 0xd9, 0xb5, 0x3a, 0x24, 0xcf, 0x71, 0xf3, 0x41, 0x7a, 0x83, 0x16, 0x7c,
0x12, 0xec, 0x11, 0x76, 0xb4, 0x4f, 0xb1, 0x50, 0x84, 0xa4, 0xa2, 0x02, 0x56, 0x3c, 0x8a, 0xfa,
0x6d, 0xe3, 0xe2, 0xac, 0x71, 0xe9, 0x5e, 0xfd, 0xb6, 0x59, 0xdc, 0x06, 0xbb, 0x00, 0x8c, 0xdf,
0xf3, 0xfa, 0x92, 0x8c, 0x86, 0xb2, 0x68, 0x3f, 0xce, 0x99, 0xf2, 0x15, 0x7e, 0x2b, 0x15, 0x50,
0xd8, 0x9a, 0x70, 0xb4, 0x2a, 0xe3, 0x8f, 0x21, 0xc3, 0x2c, 0xf0, 0xf0, 0x01, 0xb8, 0xe6, 0x84,
0x11, 0xc1, 0x94, 0xe9, 0xcb, 0xb2, 0xda, 0xbe, 0x26, 0x7a, 0x40, 0x0a, 0xe5, 0xaf, 0xd9, 0x74,
0x9d, 0xd5, 0x8d, 0x99, 0x19, 0xc0, 0x7f, 0x6a, 0xe0, 0x86, 0x98, 0x30, 0x30, 0xb5, 0x7c, 0xfb,
0xc4, 0x8a, 0x70, 0xe0, 0x92, 0xa0, 0x6b, 0x1d, 0x91, 0xb6, 0xbe, 0x22, 0xdd, 0xfd, 0x41, 0x14,
0xef, 0x7a, 0x4b, 0x9a, 0x1c, 0xd8, 0x27, 0x2d, 0x65, 0xf0, 0x88, 0x34, 0x47, 0x1c, 0xad, 0x47,
0x93, 0x70, 0xc2, 0xd1, 0x6b, 0xaa, 0x89, 0x4e, 0x72, 0x85, 0xb2, 0x9d, 0xba, 0x75, 0x3a, 0x7c,
0x3a, 0x6c, 0x4c, 0x8b, 0x6f, 0x4e, 0xb1, 0x6d, 0x8b, 0x74, 0xf4, 0x6c, 0xd6, 0x13, 0xe9, 0x58,
0x1d, 0xa7, 0x23, 0x85, 0xf2, 0x74, 0xa4, 0xeb, 0x71, 0x3a, 0x52, 0x00, 0x7e, 0x00, 0xae, 0xc8,
0x59, 0x4b, 0x5f, 0x93, 0xbd, 0x7c, 0x2d, 0x3b, 0x31, 0x11, 0xff, 0xb1, 0x20, 0x9a, 0xba, 0x78,
0xd9, 0x49, 0x9b, 0x84, 0xa3, 0x05, 0xe9, 0x4d, 0xae, 0x0c, 0x53, 0xa1, 0xf0, 0x11, 0x58, 0x4a,
0x2f, 0x94, 0x8b, 0x3d, 0x1c, 0x63, 0x1d, 0xca, 0x62, 0x7f, 0x4b, 0x4e, 0x16, 0x92, 0xd8, 0x93,
0x78, 0xc2, 0x11, 0x2c, 0x5c, 0x29, 0x05, 0x1a, 0x66, 0xc9, 0x06, 0x9e, 0x00, 0x5d, 0xf6, 0xe9,
0x88, 0x86, 0x5d, 0x8a, 0x19, 0x2b, 0x36, 0xec, 0x75, 0xf9, 0x7c, 0xe2, 0xe5, 0xbb, 0x21, 0x6c,
0x5a, 0xa9, 0x49, 0xb1, 0x6d, 0xab, 0xd7, 0xd9, 0x54, 0x36, 0x7f, 0xf6, 0xe9, 0x9b, 0xe1, 0x21,
0x58, 0x4e, 0xeb, 0x22, 0xb2, 0xfb, 0x0c, 0x5b, 0x4c, 0xbf, 0x2e, 0xe3, 0xbd, 0x27, 0x9e, 0x43,
0x31, 0x2d, 0x41, 0x1c, 0xe6, 0xcf, 0x51, 0x04, 0x73, 0xef, 0x25, 0x53, 0x88, 0xc1, 0x92, 0xa8,
0x32, 0x91, 0x54, 0x8f, 0x38, 0x31, 0xd3, 0x37, 0xa4, 0xcf, 0xef, 0x09, 0x9f, 0xbe, 0x7d, 0xb2,
0x9b, 0xe1, 0xe3, 0x5b, 0x57, 0x00, 0xa7, 0x76, 0x40, 0xd5, 0xe9, 0xcc, 0xd2, 0x6e, 0xe8, 0x82,
0xeb, 0x2e, 0x61, 0xa2, 0x33, 0x5b, 0x2c, 0xb2, 0x29, 0xc3, 0x96, 0x1c, 0x00, 0xf4, 0x1b, 0xf2,
0x24, 0xe4, 0xc8, 0x95, 0xf2, 0x87, 0x92, 0x96, 0xa3, 0x45, 0x3e, 0x72, 0x4d, 0x52, 0x86, 0x39,
0xc5, 0xbe, 0x18, 0x25, 0xc6, 0x7e, 0x64, 0x91, 0xc0, 0xc5, 0x27, 0x98, 0xe9, 0x37, 0x27, 0xa2,
0x3c, 0xc1, 0x7e, 0xf4, 0x50, 0xb1, 0xd5, 0x28, 0x05, 0x6a, 0x1c, 0xa5, 0x00, 0xc2, 0x1d, 0x70,
0x55, 0x1e, 0x80, 0xab, 0xeb, 0xd2, 0xef, 0xe6, 0x88, 0xa3, 0x14, 0xc9, 0xdf, 0xf0, 0x6a, 0x69,
0x98, 0x29, 0x0e, 0x63, 0x70, 0xf3, 0x18, 0xdb, 0x47, 0x96, 0xa8, 0x6a, 0x2b, 0xee, 0x51, 0xcc,
0x7a, 0xa1, 0xe7, 0x5a, 0x91, 0x13, 0xeb, 0xaf, 0xc9, 0x84, 0x8b, 0xf6, 0x7e, 0x5d, 0x98, 0x7c,
0xdf, 0x66, 0xbd, 0x27, 0x99, 0x41, 0xcb, 0x89, 0x13, 0x8e, 0x36, 0xa5, 0xcb, 0x69, 0x64, 0x7e,
0xa8, 0x53, 0xb7, 0xc2, 0x5d, 0xb0, 0xe0, 0xdb, 0xf4, 0x08, 0x53, 0x2b, 0xb0, 0x7d, 0xac, 0x6f,
0xca, 0xe1, 0xca, 0x10, 0xed, 0x4c, 0xc1, 0x1f, 0xd9, 0x3e, 0xce, 0xdb, 0xd9, 0x18, 0x32, 0xcc,
0x02, 0x0f, 0x07, 0x60, 0x53, 0x7c, 0xc4, 0x58, 0xe1, 0x71, 0x80, 0x29, 0xeb, 0x91, 0xc8, 0xea,
0xd0, 0xd0, 0xb7, 0x22, 0x9b, 0xe2, 0x20, 0xd6, 0x6f, 0xc9, 0x14, 0x7c, 0x7b, 0xc4, 0xd1, 0x4d,
0x61, 0xf5, 0x38, 0x33, 0xda, 0xa7, 0xa1, 0xdf, 0x92, 0x26, 0x09, 0x47, 0x6f, 0x64, 0x1d, 0x6f,
0x1a, 0x6f, 0x98, 0x5f, 0xb5, 0x13, 0xfe, 0x4a, 0x03, 0x6b, 0x7e, 0xe8, 0x5a, 0x31, 0xf1, 0xb1,
0x75, 0x4c, 0x02, 0x37, 0x3c, 0xb6, 0x98, 0xfe, 0xba, 0x4c, 0xd8, 0x4f, 0xcf, 0x39, 0x5a, 0x33,
0xed, 0xe3, 0x83, 0xd0, 0x7d, 0x42, 0x7c, 0xfc, 0x54, 0xb2, 0xe2, 0x1d, 0xbe, 0xec, 0x97, 0x90,
0x7c, 0x04, 0x2d, 0xc3, 0x59, 0xe6, 0x4e, 0x87, 0x8d, 0x49, 0x2f, 0x66, 0xc5, 0x07, 0x7c, 0xa1,
0x81, 0x8d, 0xf4, 0x9a, 0x38, 0x7d, 0x2a, 0xb4, 0x59, 0xc7, 0x94, 0xc4, 0x98, 0xe9, 0x6f, 0x48,
0x31, 0x3f, 0x14, 0xad, 0x57, 0x15, 0x7c, 0xca, 0x3f, 0x95, 0x74, 0xc2, 0xd1, 0xed, 0xc2, 0xad,
0x29, 0x71, 0x85, 0xcb, 0xb3, 0x53, 0xb8, 0x3b, 0xda, 0x8e, 0x39, 0xcd, 0x93, 0x68, 0x62, 0x59,
0x6d, 0x77, 0xc4, 0x17, 0x93, 0x5e, 0x1b, 0x37, 0xb1, 0x94, 0xd8, 0x17, 0x78, 0x7e, 0xf9, 0x8b,
0xa0, 0x61, 0x96, 0x6c, 0xa0, 0x07, 0x56, 0xe5, 0x97, 0xac, 0x25, 0x7a, 0x81, 0xa5, 0xfa, 0x2b,
0x92, 0xfd, 0xf5, 0x46, 0xd6, 0x5f, 0x9b, 0x82, 0x1f, 0x37, 0x59, 0x39, 0xdc, 0xb7, 0x4b, 0x58,
0x9e, 0xd9, 0x32, 0x6c, 0x98, 0x15, 0x3b, 0xf8, 0x99, 0x06, 0xd6, 0x64, 0x09, 0xc9, 0x0f, 0x61,
0x4b, 0x7d, 0x09, 0xeb, 0x75, 0x19, 0x6f, 0x5d, 0x7c, 0x48, 0xec, 0x86, 0xd1, 0xc0, 0x14, 0xdc,
0x81, 0xa4, 0x9a, 0x8f, 0xc4, 0x28, 0xe6, 0x94, 0xc1, 0x84, 0xa3, 0xad, 0xbc, 0x8c, 0x0a, 0x78,
0x21, 0x8d, 0x2c, 0xb6, 0x03, 0xd7, 0xa6, 0xae, 0x78, 0xff, 0xcf, 0x65, 0x0b, 0xb3, 0xea, 0x08,
0xfe, 0x59, 0xc8, 0xb1, 0x45, 0x03, 0xc5, 0x01, 0x23, 0x31, 0x79, 0x26, 0x32, 0xaa, 0xbf, 0x29,
0xd3, 0x79, 0x22, 0xe6, 0xc2, 0x5d, 0x9b, 0xe1, 0xc3, 0x8c, 0xdb, 0x97, 0x73, 0xa1, 0x53, 0x86,
0x12, 0x8e, 0x36, 0x94, 0x98, 0x32, 0x2e, 0x66, 0xa0, 0x09, 0xdb, 0x49, 0x48, 0x8c, 0x81, 0x95,
0x20, 0x66, 0xc5, 0x86, 0xc1, 0x3f, 0x69, 0x60, 0xb5, 0x13, 0x7a, 0x5e, 0x78, 0x6c, 0x7d, 0xd2,
0x0f, 0x1c, 0x31, 0x8e, 0x30, 0xdd, 0x18, 0xab, 0xfc, 0x41, 0x06, 0x7e, 0xc0, 0xf6, 0x08, 0x65,
0x42, 0xe5, 0x27, 0x65, 0x28, 0x57, 0x59, 0xc1, 0xa5, 0xca, 0xaa, 0xed, 0x24, 0x24, 0x54, 0x56,
0x82, 0x98, 0x2b, 0x4a, 0x51, 0x0e, 0xc3, 0x23, 0x30, 0x4f, 0xb1, 0xed, 0x5a, 0x61, 0xe0, 0x0d,
0xf4, 0xbf, 0xee, 0x4b, 0x79, 0x07, 0xe7, 0x1c, 0xc1, 0x3d, 0x1c, 0x51, 0xec, 0xd8, 0x31, 0x76,
0x4d, 0x6c, 0xbb, 0x8f, 0x03, 0x6f, 0x30, 0xe2, 0x48, 0x7b, 0x2f, 0xff, 0x7a, 0xa7, 0xa1, 0x1c,
0x0f, 0xdf, 0x0d, 0x7d, 0x22, 0x7a, 0x75, 0x3c, 0x90, 0x5f, 0xef, 0x13, 0xa8, 0xae, 0x99, 0x73,
0x34, 0x75, 0x00, 0x7f, 0x01, 0xd6, 0x4a, 0x33, 0xa3, 0xec, 0x9f, 0x7f, 0x13, 0x41, 0xb5, 0xe6,
0x87, 0xe7, 0x1c, 0xe9, 0xe3, 0xa0, 0x07, 0xe3, 0xc9, 0xaf, 0xe5, 0xc4, 0x59, 0xe8, 0x5a, 0x75,
0x70, 0x6c, 0x39, 0x71, 0x41, 0x81, 0xae, 0x99, 0xcb, 0x65, 0x12, 0xfe, 0x04, 0x5c, 0x53, 0xef,
0x4b, 0xa6, 0x7f, 0xb1, 0x2f, 0xef, 0xfa, 0x77, 0x44, 0xe3, 0x19, 0x07, 0x52, 0x73, 0x10, 0x2b,
0x3f, 0x5c, 0xba, 0xa5, 0xe0, 0x3a, 0xbd, 0xe0, 0xba, 0x66, 0x66, 0xfe, 0x9a, 0x8f, 0x5e, 0x7e,
0x59, 0x9b, 0x19, 0x7e, 0x59, 0x9b, 0x79, 0x79, 0x5e, 0xd3, 0x86, 0xe7, 0x35, 0xed, 0x77, 0xaf,
0x6a, 0x33, 0x9f, 0xbf, 0xaa, 0x69, 0xc3, 0x57, 0xb5, 0x99, 0x7f, 0xbf, 0xaa, 0xcd, 0x7c, 0xfc,
0xf6, 0xff, 0xf0, 0x7f, 0x89, 0xba, 0xae, 0xed, 0xab, 0xf2, 0x7f, 0x93, 0xf7, 0xff, 0x1b, 0x00,
0x00, 0xff, 0xff, 0x3e, 0xb6, 0x85, 0xe6, 0x55, 0x13, 0x00, 0x00,
}
func (m *FolderDeviceConfiguration) Marshal() (dAtA []byte, err error) {
@@ -295,6 +300,13 @@ func (m *FolderDeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, erro
_ = i
var l int
_ = l
if len(m.EncryptionPassword) > 0 {
i -= len(m.EncryptionPassword)
copy(dAtA[i:], m.EncryptionPassword)
i = encodeVarintFolderconfiguration(dAtA, i, uint64(len(m.EncryptionPassword)))
i--
dAtA[i] = 0x1a
}
{
size := m.IntroducedBy.ProtoSize()
i -= size
@@ -685,6 +697,10 @@ func (m *FolderDeviceConfiguration) ProtoSize() (n int) {
n += 1 + l + sovFolderconfiguration(uint64(l))
l = m.IntroducedBy.ProtoSize()
n += 1 + l + sovFolderconfiguration(uint64(l))
l = len(m.EncryptionPassword)
if l > 0 {
n += 1 + l + sovFolderconfiguration(uint64(l))
}
return n
}
@@ -914,6 +930,38 @@ func (m *FolderDeviceConfiguration) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptionPassword", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFolderconfiguration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthFolderconfiguration
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthFolderconfiguration
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.EncryptionPassword = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipFolderconfiguration(dAtA[iNdEx:])

View File

@@ -14,6 +14,8 @@ func (t FolderType) String() string {
return "sendonly"
case FolderTypeReceiveOnly:
return "receiveonly"
case FolderTypeReceiveEncrypted:
return "receiveencrypted"
default:
return "unknown"
}
@@ -31,6 +33,8 @@ func (t *FolderType) UnmarshalText(bs []byte) error {
*t = FolderTypeSendOnly
case "receiveonly":
*t = FolderTypeReceiveOnly
case "receiveencrypted":
*t = FolderTypeReceiveEncrypted
default:
*t = FolderTypeSendReceive
}

View File

@@ -24,21 +24,24 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type FolderType int32
const (
FolderTypeSendReceive FolderType = 0
FolderTypeSendOnly FolderType = 1
FolderTypeReceiveOnly FolderType = 2
FolderTypeSendReceive FolderType = 0
FolderTypeSendOnly FolderType = 1
FolderTypeReceiveOnly FolderType = 2
FolderTypeReceiveEncrypted FolderType = 3
)
var FolderType_name = map[int32]string{
0: "FOLDER_TYPE_SEND_RECEIVE",
1: "FOLDER_TYPE_SEND_ONLY",
2: "FOLDER_TYPE_RECEIVE_ONLY",
3: "FOLDER_TYPE_RECEIVE_ENCRYPTED",
}
var FolderType_value = map[string]int32{
"FOLDER_TYPE_SEND_RECEIVE": 0,
"FOLDER_TYPE_SEND_ONLY": 1,
"FOLDER_TYPE_RECEIVE_ONLY": 2,
"FOLDER_TYPE_SEND_RECEIVE": 0,
"FOLDER_TYPE_SEND_ONLY": 1,
"FOLDER_TYPE_RECEIVE_ONLY": 2,
"FOLDER_TYPE_RECEIVE_ENCRYPTED": 3,
}
func (FolderType) EnumDescriptor() ([]byte, []int) {
@@ -52,21 +55,23 @@ func init() {
func init() { proto.RegisterFile("lib/config/foldertype.proto", fileDescriptor_ea6ddb20c0633575) }
var fileDescriptor_ea6ddb20c0633575 = []byte{
// 254 bytes of a gzipped FileDescriptorProto
// 287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xce, 0xc9, 0x4c, 0xd2,
0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x4f, 0xcb, 0xcf, 0x49, 0x49, 0x2d, 0x2a, 0xa9, 0x2c,
0x48, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0x48, 0x48, 0x29, 0x17, 0xa5, 0x16,
0xe4, 0x17, 0xeb, 0x83, 0x05, 0x93, 0x4a, 0xd3, 0xf4, 0xd3, 0xf3, 0xd3, 0xf3, 0xc1, 0x1c, 0x30,
0x0b, 0xa2, 0x58, 0x6b, 0x3b, 0x23, 0x17, 0x97, 0x1b, 0xd8, 0x84, 0x90, 0xca, 0x82, 0x54, 0x21,
0x0b, 0xa2, 0x58, 0xeb, 0x17, 0x23, 0x17, 0x97, 0x1b, 0xd8, 0x84, 0x90, 0xca, 0x82, 0x54, 0x21,
0x73, 0x2e, 0x09, 0x37, 0x7f, 0x1f, 0x17, 0xd7, 0xa0, 0xf8, 0x90, 0xc8, 0x00, 0xd7, 0xf8, 0x60,
0x57, 0x3f, 0x97, 0xf8, 0x20, 0x57, 0x67, 0x57, 0xcf, 0x30, 0x57, 0x01, 0x06, 0x29, 0xc9, 0xae,
0xb9, 0x0a, 0xa2, 0x08, 0xd5, 0xc1, 0xa9, 0x79, 0x29, 0x41, 0xa9, 0xc9, 0xa9, 0x99, 0x65, 0xa9,
0x42, 0x86, 0x5c, 0xa2, 0x18, 0x1a, 0xfd, 0xfd, 0x7c, 0x22, 0x05, 0x18, 0xa5, 0xc4, 0xba, 0xe6,
0x2a, 0x08, 0xa1, 0xea, 0xf2, 0xcf, 0xcb, 0xa9, 0x44, 0xb7, 0x0b, 0x6a, 0x0d, 0x44, 0x17, 0x13,
0xba, 0x5d, 0x50, 0x7b, 0x40, 0x1a, 0xa5, 0x58, 0x56, 0x2c, 0x91, 0x63, 0x70, 0xf2, 0x3e, 0xf1,
0x50, 0x8e, 0xe1, 0xc2, 0x43, 0x39, 0x86, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x9c,
0xf0, 0x58, 0x8e, 0x61, 0xc1, 0x63, 0x39, 0xc6, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63,
0x88, 0xd2, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x2f, 0xae, 0xcc,
0x4b, 0x2e, 0xc9, 0xc8, 0xcc, 0x4b, 0x47, 0x62, 0x21, 0x02, 0x31, 0x89, 0x0d, 0x1c, 0x1a, 0xc6,
0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x1f, 0xe5, 0x1d, 0x59, 0x01, 0x00, 0x00,
0xba, 0x5d, 0x50, 0x7b, 0xc0, 0x1a, 0x1d, 0xb9, 0x64, 0xb1, 0x69, 0x74, 0xf5, 0x73, 0x0e, 0x8a,
0x0c, 0x08, 0x71, 0x75, 0x11, 0x60, 0x96, 0x92, 0xeb, 0x9a, 0xab, 0x20, 0x85, 0xa1, 0xdb, 0x35,
0x2f, 0xb9, 0xa8, 0xb2, 0xa0, 0x24, 0x35, 0x45, 0x8a, 0x65, 0xc5, 0x12, 0x39, 0x06, 0x27, 0xef,
0x13, 0x0f, 0xe5, 0x18, 0x2e, 0x3c, 0x94, 0x63, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39,
0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x16, 0x3c, 0x96, 0x63, 0xbc, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63,
0x39, 0x86, 0x28, 0xcd, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xe2,
0xca, 0xbc, 0xe4, 0x92, 0x8c, 0xcc, 0xbc, 0x74, 0x24, 0x16, 0x22, 0x1e, 0x92, 0xd8, 0xc0, 0x01,
0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x87, 0xbe, 0x2d, 0x9c, 0x01, 0x00, 0x00,
}

View File

@@ -11,6 +11,8 @@ import (
"os"
"strconv"
"strings"
"github.com/syncthing/syncthing/lib/rand"
)
func (c GUIConfiguration) IsAuthEnabled() bool {
@@ -126,6 +128,12 @@ func (c GUIConfiguration) IsValidAPIKey(apiKey string) bool {
}
}
func (c *GUIConfiguration) prepare() {
if c.APIKey == "" {
c.APIKey = rand.String(32)
}
}
func (c GUIConfiguration) Copy() GUIConfiguration {
return c
}

View File

@@ -14,6 +14,7 @@ import (
"runtime"
"sort"
"strings"
"sync"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/upgrade"
@@ -24,30 +25,36 @@ import (
// config version. The conversion function can be nil in which case we just
// update the config version. The order of migrations doesn't matter here,
// put the newest on top for readability.
var migrations = migrationSet{
{32, migrateToConfigV32},
{31, migrateToConfigV31},
{30, migrateToConfigV30},
{29, migrateToConfigV29},
{28, migrateToConfigV28},
{27, migrateToConfigV27},
{26, nil}, // triggers database update
{25, migrateToConfigV25},
{24, migrateToConfigV24},
{23, migrateToConfigV23},
{22, migrateToConfigV22},
{21, migrateToConfigV21},
{20, migrateToConfigV20},
{19, nil}, // Triggers a database tweak
{18, migrateToConfigV18},
{17, nil}, // Fsync = true removed
{16, nil}, // Triggers a database tweak
{15, migrateToConfigV15},
{14, migrateToConfigV14},
{13, migrateToConfigV13},
{12, migrateToConfigV12},
{11, migrateToConfigV11},
}
var (
migrations = migrationSet{
{35, migrateToConfigV35},
{34, migrateToConfigV34},
{33, migrateToConfigV33},
{32, migrateToConfigV32},
{31, migrateToConfigV31},
{30, migrateToConfigV30},
{29, migrateToConfigV29},
{28, migrateToConfigV28},
{27, migrateToConfigV27},
{26, nil}, // triggers database update
{25, migrateToConfigV25},
{24, migrateToConfigV24},
{23, migrateToConfigV23},
{22, migrateToConfigV22},
{21, migrateToConfigV21},
{20, migrateToConfigV20},
{19, nil}, // Triggers a database tweak
{18, migrateToConfigV18},
{17, nil}, // Fsync = true removed
{16, nil}, // Triggers a database tweak
{15, migrateToConfigV15},
{14, migrateToConfigV14},
{13, migrateToConfigV13},
{12, migrateToConfigV12},
{11, migrateToConfigV11},
}
migrationsMut = sync.Mutex{}
)
type migrationSet []migration
@@ -87,9 +94,34 @@ func (m migration) apply(cfg *Configuration) {
cfg.Version = m.targetVersion
}
func migrateToConfigV31(cfg *Configuration) {
// Show a notification about setting User and Password
cfg.Options.UnackedNotificationIDs = append(cfg.Options.UnackedNotificationIDs, "authenticationUserAndPassword")
func migrateToConfigV35(cfg *Configuration) {
for i, fcfg := range cfg.Folders {
params := fcfg.Versioning.Params
if params["fsType"] != "" {
var fsType fs.FilesystemType
_ = fsType.UnmarshalText([]byte(params["fsType"]))
cfg.Folders[i].Versioning.FSType = fsType
}
if params["versionsPath"] != "" && params["fsPath"] == "" {
params["fsPath"] = params["versionsPath"]
}
cfg.Folders[i].Versioning.FSPath = params["fsPath"]
delete(cfg.Folders[i].Versioning.Params, "fsType")
delete(cfg.Folders[i].Versioning.Params, "fsPath")
delete(cfg.Folders[i].Versioning.Params, "versionsPath")
}
}
func migrateToConfigV34(cfg *Configuration) {
cfg.Defaults.Folder.Path = cfg.Options.DeprecatedDefaultFolderPath
cfg.Options.DeprecatedDefaultFolderPath = ""
}
func migrateToConfigV33(cfg *Configuration) {
for i := range cfg.Devices {
cfg.Devices[i].DeprecatedPendingFolders = nil
}
cfg.DeprecatedPendingDevices = nil
}
func migrateToConfigV32(cfg *Configuration) {
@@ -98,6 +130,11 @@ func migrateToConfigV32(cfg *Configuration) {
}
}
func migrateToConfigV31(cfg *Configuration) {
// Show a notification about setting User and Password
cfg.Options.UnackedNotificationIDs = append(cfg.Options.UnackedNotificationIDs, "authenticationUserAndPassword")
}
func migrateToConfigV30(cfg *Configuration) {
// The "max concurrent scans" option is now spelled "max folder concurrency"
// to be more general.

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