Compare commits

...

50 Commits

Author SHA1 Message Date
Syncthing Release Automation
97625ccc26 gui, man, authors: Update docs, translations, and contributors 2023-07-31 03:45:37 +00:00
Jakob Borg
4fe746d9aa build: Run govulncheck (fixes #8983) 2023-07-30 14:38:36 +02:00
Jakob Borg
4f8cdd41ee build: Run build & tests on main branch nightly 2023-07-30 14:24:17 +02:00
Jakob Borg
406e3646e5 build: Send test logs to Grafana Loki for statistics 2023-07-30 13:40:26 +02:00
Jakob Borg
9d21b91124 all: Refactor the protocol/model interface a bit (ref #8981) (#9007) 2023-07-29 10:24:44 +02:00
Chih-Hsuan Yen
b806026990 lib/connections: Fix building with -tags noquic (#9009) 2023-07-28 10:08:50 +00:00
tomasz1986
341b79814e gui: Fix tooltips on buttons inside button groups (ref #7984) (#9008)
As per Bootstrap recommendation, buttons with tooltips inside button
groups require to have container: 'body' set. This prevents tooltips
from causing the buttons to jump on hover and also allows the tooltips
to be wider instead of wrapping on every space.

Ref: https://getbootstrap.com/docs/3.3/components/#btn-groups

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2023-07-27 14:38:48 +02:00
Jakob Borg
319916124b cmd/strelaysrv: Handle accept error with debug set (fixes #9001) (#9004) 2023-07-26 23:55:48 +01:00
Emil Lundberg
b08b99e284 lib/api: Fix data race in TestCSRFRequired (#9006) 2023-07-26 21:33:45 +00:00
Jakob Borg
f565df628c gui: Show full error for failed items (#9005)
Also closes #8992.
2023-07-26 23:20:17 +02:00
Jakob Borg
855c6dc67b lib/api: Allow Bearer authentication style with API key (#9002)
Currently, historically, we look for the `X-API-Key` header to
authenticate with an API key. There's nothing wrong with this, but in
some scenarios it's easier to produce an `Authorization` header with a
`Bearer $token` content, which is nowadays more common. This change adds
support for both, so that we will accept an API key either in our custom
header or as a bearer token.
2023-07-26 13:13:06 +02:00
tomasz1986
dc5e10fa2c gui: Remove Twitter link from footer (#9000) 2023-07-25 00:53:57 +02:00
Syncthing Release Automation
b857e57a35 gui, man, authors: Update docs, translations, and contributors 2023-07-24 03:45:42 +00:00
tomasz1986
f42f041f53 lib/ur: Don't report uptime if start time is in the past (fixes #7698) (#8996)
Currently, because of devices with unset RTC clock, the 100% percentile
for Uptime on [1] is calculated since the Unix epoch which is useless as
far as usage statistics are concerned. Thus, if the Syncthing start time
is set to a past date, assume that the clock is wrong and do not even
try to report the uptime.

[1] https://data.syncthing.net

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2023-07-22 21:25:03 +00:00
Christian Kujau
6b6b2c6194 lib/model: use WARN for "Unexpected folder" messages (#8998) 2023-07-22 21:17:32 +00:00
tomasz1986
d70eb569f2 lib/osutil: Skip setLowPriority in Windows if already lower (fixes #6597) (#8993) 2023-07-21 04:38:15 +00:00
deepsource-autofix[bot]
21c074cc2c all: replace empty slice literal with var (#8990)
refactor: replace empty slice literal with `var`

An empty slice can be represented by `nil` or an empty slice literal. They are
functionally equivalent — their `len` and `cap` are both zero — but the `nil`
slice is the preferred style. For more information about empty slices,
see [Declaring Empty Slices](https://github.com/golang/go/wiki/CodeReviewComments#declaring-empty-slices).

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2023-07-18 14:44:37 +00:00
deepsource-autofix[bot]
f23c41221b all: fix unused method receiver (#8988)
refactor: fix unused method receiver

Methods with unused receivers can be a symptom of unfinished refactoring or a bug. To keep 
the same method signature, omit the receiver name or '_' as it is unused.

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2023-07-18 14:34:50 +00:00
deepsource-autofix[bot]
24e230d455 all: unused parameter should be replaced by underscore (#8989)
refactor: unused parameter should be replaced by underscore

Unused parameters in functions or methods should be replaced with `_`
(underscore) or removed.

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2023-07-18 14:33:13 +00:00
Syncthing Release Automation
31daa20367 gui, man, authors: Update docs, translations, and contributors 2023-07-17 03:46:46 +00:00
Jakob Borg
e4d0f9dd6c cmd/syncthing: Mention STVERSIONEXTRA in --help output (ref #8980) 2023-07-16 17:48:24 +02:00
Jakob Borg
df2ac7aaeb gui, lib/api: Add possibility to feed through extra version information (#8980)
This adds an environment variable STVERSIONEXTRA that, when set, gets
added to the version information in the API and GUI.

The purpose of all this is to be able to communicate something about the
bundling or packaging, through the log & GUI and the end user, to the
potential person supporting it -- i.e., us. :) A wrapper can set this
variable to indicate that Syncthing is being run via `SyncTrayzor`,
`Syncthing-macOS`, etc., and thus indicate to the end user that the GUI
they are looking at is perhaps not the only source of truth and
management for this instance.
2023-07-16 17:43:10 +02:00
Jakob Borg
b96b23957b cmd/ursrv: Update map tile URL 2023-07-16 17:36:05 +02:00
bt90
265ce139c5 cmd/strelaypoolsrv: Update map tile URL (#8985) 2023-07-16 17:20:40 +02:00
Jakob Borg
48c95eb41d cmd/stcrashreceiver: Correct parsing of current version string 2023-07-12 09:27:34 +02:00
Jakob Borg
937895be69 build: Update dependencies 2023-07-11 09:14:21 +02:00
Jakob Borg
a3886f778d cmd/ursrv: Remove old, unused user movement code 2023-07-10 09:21:40 +02:00
Jakob Borg
6aecc2622c cmd/ursrv: Merge ursrv and uraggregate as subcommands 2023-07-10 09:00:57 +02:00
Jakob Borg
c55b205a0b cmd/ursrv: Remove useless static TLS cert handling 2023-07-10 08:39:30 +02:00
Jakob Borg
2fcf7006e6 cmd/ursrv: Embed static assets 2023-07-10 08:33:09 +02:00
Jakob Borg
bf61e485a6 cmd/ursrv: Refactor to use CLI options, fewer global vars 2023-07-10 08:27:16 +02:00
Jakob Borg
b2886f11b1 gui: Show xattr filter editor when send xattrs checked (fixes #8958) (#8959) 2023-07-10 08:01:08 +02:00
Syncthing Release Automation
11ece5d89e gui, man, authors: Update docs, translations, and contributors 2023-07-10 03:46:49 +00:00
Jakob Borg
cf68dfac43 build: Build Docker image for plain 32 bit arm (fixes #8973) 2023-07-08 10:55:09 +02:00
Jakob Borg
c44de2cd58 lib/fs: Clarify errors for Windows filenames (fixes #8968) (#8969)
With this change, error messages include the offending characters or
name parts. Examples:

    nul.txt: name is invalid, contains Windows reserved name: "nul"
    foo>bar.txt: name is invalid, contains Windows reserved character: ">"
    foo \bar.txt: name is invalid, must not end in space or period on Windows
2023-07-07 11:00:40 +00:00
Jakob Borg
6ff5ed6d23 gui: Avoid spurious comma in shared-with device list (fixes #8967) (#8970) 2023-07-07 07:25:24 +02:00
Jakob Borg
25ec2b63ab cmd/ursrv: Summarize tiny fraction items into Other 2023-07-05 08:22:10 +02:00
Jakob Borg
c5ab71d7a5 cmd/ursrv: Update distributions list 2023-07-05 08:08:29 +02:00
Jakob Borg
1fc4c9d9c5 build: Only push releases to cloud storage, and also use latest 2023-07-04 10:27:26 +02:00
Jakob Borg
bebf2c259c readme: Remove outdated build badges/links 2023-07-03 13:03:09 +02:00
Jakob Borg
b7d526903e build: Push to correct Docker images 2023-07-03 12:08:53 +02:00
Jakob Borg
92917c9f62 Merge branch 'release'
* release:
  build: Build and publish Docker images for relay and discovery server (fixes #8691, fixes #8960)
2023-07-03 11:52:11 +02:00
Syncthing Release Automation
a7d7325e9b gui, man, authors: Update docs, translations, and contributors 2023-07-03 03:45:49 +00:00
Jakob Borg
465823237f build: Build and publish Docker images for relay and discovery server (fixes #8691, fixes #8960)
This adds builds for the discovery and relay servers in the same manner
as Syncthing, so that Docker images are kept up to date with releases.

Inspired by and closes #8834.

Co-authored-by: Migelo <miha@filetki.si>
2023-07-01 08:48:12 +02:00
Jakob Borg
5a1f996e56 build: Build infrastructure images 2023-07-01 08:23:55 +02:00
Jakob Borg
229b6a292c cmd/stcrashreceiver: Add /ping endpoint 2023-07-01 07:53:50 +02:00
Jakob Borg
c84e47a7b2 build: Update dependencies 2023-06-28 14:00:30 +02:00
otbutz
daf7baaeff etc: Update sysctl configs (#8955) 2023-06-28 07:05:12 +02:00
Jakob Borg
a4a1231e92 gui: Remove tilde auto-expansions (fixes #8890) (#8954)
This removes the tilde expansion we had in the GUI. I'm not sure why we
had it, but there are valid reasons to have a folder path with tilde in
it in the config, and it was previously impossible to enter one of
those.
2023-06-28 07:03:53 +02:00
Jakob Borg
b99dee3ac3 cmd/syncthing: Add environment variables for --home, --conf, and --data (fixes #8957) (#8952)
This allows environment overrides for our directories. This is
advantageous because, apart from the obvious, it means we can set it in
the Docker file and not add command line options there. Having the
command line option as we did meant that it was impossible to use the
Docker image for other commands than `serve` (because that is implied
when we see other options on the command line).
2023-06-28 07:03:36 +02:00
147 changed files with 2327 additions and 2032 deletions

View File

@@ -0,0 +1,54 @@
name: Build Infrastructure Images
on:
push:
branches:
- infrastructure
env:
GO_VERSION: "^1.20.5"
CGO_ENABLED: "0"
BUILD_USER: docker
BUILD_HOST: github.syncthing.net
jobs:
docker-syncthing:
name: Build and push Docker images
runs-on: ubuntu-latest
environment: docker
strategy:
matrix:
pkg:
- stcrashreceiver
- strelaypoolsrv
- stupgrades
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build binaries
run: |
for arch in arm64 amd64; do
go run build.go -goos linux -goarch "$arch" build ${{ matrix.pkg }}
mv ${{ matrix.pkg }} ${{ matrix.pkg }}-linux-"$arch"
done
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.${{ matrix.pkg }}
platforms: linux/amd64,linux/arm64
push: true
tags: syncthing/${{ matrix.pkg }}:latest,syncthing/${{ matrix.pkg }}:${{ github.sha }}

View File

@@ -3,6 +3,9 @@ name: Build Syncthing
on:
pull_request:
push:
schedule:
# Run nightly build at 05:00 UTC
- cron: '00 05 * * *'
env:
# The go version to use for builds. We set check-latest to true when
@@ -69,9 +72,19 @@ jobs:
run: |
go run build.go
- name: Install go-test-json-to-loki
run: |
go install calmh.dev/go-test-json-to-loki@latest
- name: Test
run: |
go run build.go test
go run build.go test | go-test-json-to-loki
env:
GOFLAGS: "-json"
LOKI_URL: ${{ secrets.LOKI_URL }}
LOKI_USER: ${{ secrets.LOKI_USER }}
LOKI_PASSWORD: ${{ secrets.LOKI_PASSWORD }}
LOKI_LABELS: "go=${{ matrix.go }},runner=${{ matrix.runner }},repo=${{ github.repository }},ref=${{ github.ref }}"
#
# Meta checks for formatting, copyright, etc
@@ -112,6 +125,7 @@ jobs:
- package-cross
- package-source
- package-debian
- govulncheck
steps:
- uses: actions/checkout@v3
@@ -602,7 +616,7 @@ jobs:
publish-release-files:
name: Publish release files
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release')
if: github.event_name == 'push' && github.ref == 'refs/heads/release'
environment: signing
needs:
- sign-for-upgrade
@@ -630,7 +644,7 @@ jobs:
version=$(go run build.go version)
echo "VERSION=$version" >> $GITHUB_ENV
- name: Push to Spaces
- name: Push to Spaces (${{ env.VERSION }})
uses: docker://docker.io/rclone/rclone:latest
env:
RCLONE_CONFIG_SPACES_TYPE: s3
@@ -642,6 +656,22 @@ jobs:
with:
args: sync packages spaces:syncthing/release/${{ env.VERSION }}
- name: Push to Spaces (latest)
uses: docker://docker.io/rclone/rclone:latest
env:
RCLONE_CONFIG_SPACES_TYPE: s3
RCLONE_CONFIG_SPACES_PROVIDER: DigitalOcean
RCLONE_CONFIG_SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_KEY }}
RCLONE_CONFIG_SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET }}
RCLONE_CONFIG_SPACES_ENDPOINT: ams3.digitaloceanspaces.com
RCLONE_CONFIG_SPACES_ACL: public-read
with:
args: sync spaces:syncthing/release/${{ env.VERSION }} spaces:syncthing/release/latest
#
# Build and push to Docker Hub
#
docker-syncthing:
name: Build and push Docker images
runs-on: ubuntu-latest
@@ -656,10 +686,13 @@ jobs:
include:
- pkg: syncthing
dockerfile: Dockerfile
image: syncthing/syncthing
- pkg: strelaysrv
dockerfile: Dockerfile.strelaysrv
image: syncthing/relaysrv
- pkg: stdiscosrv
dockerfile: Dockerfile.stdiscosrv
image: syncthing/discosrv
steps:
- uses: actions/checkout@v3
with:
@@ -680,7 +713,7 @@ jobs:
- name: Build binaries
run: |
for arch in arm64 amd64; do
for arch in amd64 arm64 arm; do
go run build.go -goos linux -goarch "$arch" -no-upgrade build ${{ matrix.pkg }}
mv ${{ matrix.pkg }} ${{ matrix.pkg }}-linux-"$arch"
done
@@ -688,8 +721,15 @@ jobs:
CGO_ENABLED: "0"
BUILD_USER: docker
- name: Check if we will be able to push images
run: |
if [[ "${{ secrets.DOCKERHUB_TOKEN }}" != "" ]]; then
echo "DOCKER_PUSH=true" >> $GITHUB_ENV;
fi
- name: Login to Docker Hub
uses: docker/login-action@v2
if: env.DOCKER_PUSH == 'true'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -705,13 +745,13 @@ jobs:
echo Release version, pushing to :latest and version tags
major=${version%.*.*}
minor=${version%.*}
tags=syncthing/${{ matrix.pkg }}:$version,syncthing/${{ matrix.pkg }}:$major,syncthing/${{ matrix.pkg }}:$minor,syncthing/${{ matrix.pkg }}:latest
tags=${{ matrix.image }}:$version,${{ matrix.image }}:$major,${{ matrix.image }}:$minor,${{ matrix.image }}:latest
elif [[ $version == *-rc.@([0-9]|[0-9][0-9]) ]] ; then
echo Release candidate, pushing to :rc
tags=syncthing/${{ matrix.pkg }}:rc
tags=${{ matrix.image }}:rc
else
echo Development version, pushing to :edge
tags=syncthing/${{ matrix.pkg }}:edge
tags=${{ matrix.image }}:edge
fi
echo "DOCKER_TAGS=$tags" >> $GITHUB_ENV
@@ -720,6 +760,28 @@ jobs:
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: linux/amd64,linux/arm64
push: true
platforms: linux/amd64,linux/arm64,linux/arm/7
push: ${{ env.DOCKER_PUSH == 'true' }}
tags: ${{ env.DOCKER_TAGS }}
#
# Check for known vulnerabilities in Go dependencies
#
govulncheck:
runs-on: ubuntu-latest
name: Run govulncheck
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
cache: false
check-latest: true
- name: run govulncheck
run: |
go run build.go assets
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

View File

@@ -71,11 +71,12 @@ 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>
Chih-Hsuan Yen <yan12125@gmail.com>
Chih-Hsuan Yen <yan12125@gmail.com> <1937689+yan12125@users.noreply.github.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 Kujau <ckujau@users.noreply.github.com>
Christian Prescott <me@christianprescott.com>
chucic <chucic@seznam.cz>
Colin Kennedy (moshen) <moshen.colin@gmail.com>
@@ -105,6 +106,7 @@ Dominik Heidler (asdil12) <dominik@heidler.eu>
Elias Jarlebring (jarlebring) <jarlebring@gmail.com>
Elliot Huffman <thelich2@gmail.com>
Emil Hessman (ceh) <emil@hessman.se>
Emil Lundberg <emil@emlun.se>
Eng Zer Jun <engzerjun@gmail.com>
entity0xfe <109791748+entity0xfe@users.noreply.github.com> <entity0xfe@my.domain>
Eric Lesiuta <elesiuta@gmail.com>
@@ -220,6 +222,7 @@ Michael Ploujnikov (plouj) <ploujj@gmail.com>
Michael Rienstra <mrienstra@gmail.com>
Michael Tilli (pyfisch) <pyfisch@gmail.com>
MichaIng <micha@dietpi.com>
Migelo <miha@filetki.si>
Mike Boone <mike@boonedocks.net>
MikeLund <MikeLund@users.noreply.github.com>
MikolajTwarog <43782609+MikolajTwarog@users.noreply.github.com>

View File

@@ -44,5 +44,6 @@ HEALTHCHECK --interval=1m --timeout=10s \
CMD curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1
ENV STGUIADDRESS=0.0.0.0:8384
ENV STHOMEDIR=/var/syncthing/config
RUN chmod 755 /bin/entrypoint.sh
ENTRYPOINT ["/bin/entrypoint.sh", "/bin/syncthing", "-home", "/var/syncthing/config"]
ENTRYPOINT ["/bin/entrypoint.sh", "/bin/syncthing"]

View File

@@ -1,18 +1,8 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f stcrashreceiver && go run build.go build stcrashreceiver
FROM alpine
ARG TARGETARCH
EXPOSE 8080
COPY --from=builder /src/stcrashreceiver /bin/stcrashreceiver
COPY stcrashreceiver-linux-${TARGETARCH} /bin/stcrashreceiver
ENTRYPOINT [ "/bin/stcrashreceiver" ]

View File

@@ -1,15 +1,5 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f strelaysrv && go run build.go -no-upgrade build strelaypoolsrv
FROM alpine
ARG TARGETARCH
EXPOSE 8080
@@ -19,8 +9,8 @@ ENV PUID=1000 PGID=1000 MAXMIND_KEY=
RUN mkdir /var/strelaypoolsrv && chown 1000 /var/strelaypoolsrv
USER 1000
COPY --from=builder /src/strelaypoolsrv /bin/strelaypoolsrv
COPY --from=builder /src/script/strelaypoolsrv-entrypoint.sh /bin/entrypoint.sh
COPY strelaypoolsrv-linux-${TARGETARCH} /bin/strelaypoolsrv
COPY script/strelaypoolsrv-entrypoint.sh /bin/entrypoint.sh
WORKDIR /var/strelaypoolsrv
ENTRYPOINT ["/bin/entrypoint.sh", "/bin/strelaypoolsrv", "-listen", ":8080"]

View File

@@ -1,18 +1,8 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f stupgrades && go run build.go build stupgrades
FROM alpine
ARG TARGETARCH
EXPOSE 8080
COPY --from=builder /src/stupgrades /bin/stupgrades
COPY stupgrades-linux-${TARGETARCH} /bin/stupgrades
ENTRYPOINT [ "/bin/stupgrades" ]

View File

@@ -2,9 +2,6 @@
---
[![Latest Linux & Cross Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildLinuxCross.svg?style=flat-square&label=linux+%26+cross+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildLinuxCross&guest=1)
[![Latest Windows Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildWindows.svg?style=flat-square&label=windows+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildWindows&guest=1)
[![Latest Mac Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildMac.svg?style=flat-square&label=mac+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildMac&guest=1)
[![MPLv2 License](https://img.shields.io/badge/license-MPLv2-blue.svg?style=flat-square)](https://www.mozilla.org/MPL/2.0/)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/88/badge)](https://bestpractices.coreinfrastructure.org/projects/88)
[![Go Report Card](https://goreportcard.com/badge/github.com/syncthing/syncthing)](https://goreportcard.com/report/github.com/syncthing/syncthing)

View File

@@ -214,11 +214,17 @@ var targets = map[string]target{
binaryName: "stupgrades",
},
"stcrashreceiver": {
name: "stupgrastcrashreceiverdes",
name: "stcrashreceiver",
description: "Syncthing Crash Server",
buildPkgs: []string{"github.com/syncthing/syncthing/cmd/stcrashreceiver"},
binaryName: "stcrashreceiver",
},
"ursrv": {
name: "ursrv",
description: "Syncthing Usage Reporting Server",
buildPkgs: []string{"github.com/syncthing/syncthing/cmd/ursrv"},
binaryName: "ursrv",
},
}
func initTargets() {

View File

@@ -69,6 +69,9 @@ func main() {
}
mux.Handle("/", cr)
mux.HandleFunc("/ping", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("OK"))
})
if params.DSN != "" {
mux.HandleFunc("/newcrash/failure", handleFailureFn(params.DSN, filepath.Join(params.Dir, "failure_reports")))

View File

@@ -215,7 +215,13 @@ func crashReportFingerprint(message string) []string {
}
// syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]
var longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
// or, somewhere along the way the "+" in the version tag disappeared:
// syncthing v1.23.7-dev.26.gdf7b56ae.dirty-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]
var (
longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
gitExtraRE = regexp.MustCompile(`\.\d+\.g[0-9a-f]+`) // ".1.g6aaae618"
gitExtraSepRE = regexp.MustCompile(`[.-]`) // dot or dash
)
type version struct {
version string // "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep"
@@ -257,10 +263,21 @@ func parseVersion(line string) (version, error) {
builder: m[6],
}
parts := strings.Split(v.version, "+")
// Split the version tag into tag and commit. This is old style
// v1.2.3-something.4+11-g12345678 or newer with just dots
// v1.2.3-something.4.11.g12345678 or v1.2.3-dev.11.g12345678.
parts := []string{v.version}
if strings.Contains(v.version, "+") {
parts = strings.Split(v.version, "+")
} else {
idxs := gitExtraRE.FindStringIndex(v.version)
if len(idxs) > 0 {
parts = []string{v.version[:idxs[0]], v.version[idxs[0]+1:]}
}
}
v.tag = parts[0]
if len(parts) > 1 {
fields := strings.Split(parts[1], "-")
fields := gitExtraSepRE.Split(parts[1], -1)
if len(fields) >= 2 && strings.HasPrefix(fields[1], "g") {
v.commit = fields[1][1:]
}

View File

@@ -44,6 +44,20 @@ func TestParseVersion(t *testing.T) {
extra: []string{"foo", "bar"},
},
},
{
longVersion: `syncthing v1.23.7-dev.26.gdf7b56ae-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]`,
parsed: version{
version: "v1.23.7-dev.26.gdf7b56ae-stversionextra",
tag: "v1.23.7-dev",
commit: "df7b56ae",
codename: "Fermium Flea",
runtime: "go1.20.5",
goos: "darwin",
goarch: "arm64",
builder: "jb@ok.kastelo.net",
extra: []string{"Some Wrapper", "purego", "stnoupgrade"},
},
},
}
for _, tc := range cases {

View File

@@ -237,7 +237,7 @@
uptimeSeconds: 0,
};
$scope.map = L.map('map').setView([40.90296, 1.90925], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution: 'Leaflet',
maxZoom: 17

View File

@@ -36,8 +36,14 @@ func listener(_, addr string, config *tls.Config, token string) {
for {
conn, isTLS, err := listener.AcceptNoWrapTLS()
if err != nil {
// Conn may be nil if accept failed, or non-nil if the initial
// read to figure out if it's TLS or not failed. In the latter
// case, close the connection before moving on.
if conn != nil {
conn.Close()
}
if debug {
log.Println("Listener failed to accept connection from", conn.RemoteAddr(), ". Possibly a TCP Ping.")
log.Println("Listener failed to accept:", err)
}
continue
}

View File

@@ -57,7 +57,7 @@ type githubReleases struct {
url string
}
func (p *githubReleases) ServeHTTP(w http.ResponseWriter, req *http.Request) {
func (p *githubReleases) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
log.Println("Fetching", p.url)
rels := upgrade.FetchLatestReleases(p.url, "")
if rels == nil {

View File

@@ -9,8 +9,8 @@ package cmdutil
// CommonOptions are reused among several subcommands
type CommonOptions struct {
buildCommonOptions
ConfDir string `name:"config" placeholder:"PATH" help:"Set configuration directory (config and keys)"`
HomeDir string `name:"home" placeholder:"PATH" help:"Set configuration and data directory"`
ConfDir string `name:"config" placeholder:"PATH" env:"STCONFDIR" help:"Set configuration directory (config and keys)"`
HomeDir string `name:"home" placeholder:"PATH" env:"STHOMEDIR" help:"Set configuration and data directory"`
NoDefaultFolder bool `env:"STNODEFAULTFOLDER" help:"Don't create the \"default\" folder on first startup"`
SkipPortProbing bool `help:"Don't try to find free ports for GUI and listen addresses on first startup"`
}

View File

@@ -99,6 +99,11 @@ above.
"minio" for the github.com/minio/sha256-simd implementation,
and blank (the default) for auto detection.
STVERSIONEXTRA Add extra information to the version string in logs and the
version line in the GUI. Can be set to the name of a wrapper
or tool controlling syncthing to communicate this to the end
user.
GOMAXPROCS Set the maximum number of CPU cores to use. Defaults to all
available CPU cores.
@@ -144,9 +149,9 @@ type serveOptions struct {
Audit bool `help:"Write events to audit file"`
AuditFile string `name:"auditfile" placeholder:"PATH" help:"Specify audit file (use \"-\" for stdout, \"--\" for stderr)"`
BrowserOnly bool `help:"Open GUI in browser"`
DataDir string `name:"data" placeholder:"PATH" help:"Set data directory (database and logs)"`
DataDir string `name:"data" placeholder:"PATH" env:"STDATADIR" help:"Set data directory (database and logs)"`
DeviceID bool `help:"Show the device ID"`
GenerateDir string `name:"generate" placeholder:"PATH" help:"Generate key and config in specified dir, then exit"` //DEPRECATED: replaced by subcommand!
GenerateDir string `name:"generate" placeholder:"PATH" help:"Generate key and config in specified dir, then exit"` // DEPRECATED: replaced by subcommand!
GUIAddress string `name:"gui-address" placeholder:"URL" help:"Override GUI address (e.g. \"http://192.0.2.42:8443\")"`
GUIAPIKey string `name:"gui-apikey" placeholder:"API-KEY" help:"Override GUI API key"`
LogFile string `name:"logfile" default:"${logFile}" placeholder:"PATH" help:"Log file name (see below)"`
@@ -354,7 +359,7 @@ func (options serveOptions) Run() error {
}
// Ensure that our home directory exists.
if err := syncthing.EnsureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0700); err != nil {
if err := syncthing.EnsureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0o700); err != nil {
l.Warnln("Failure on home directory:", err)
os.Exit(svcutil.ExitError.AsInt())
}
@@ -722,7 +727,6 @@ func setupSignalHandling(app *syncthing.App) {
func loadOrDefaultConfig() (config.Wrapper, error) {
cfgFile := locations.Get(locations.ConfigFile)
cfg, _, err := config.Load(cfgFile, protocol.EmptyDeviceID, events.NoopLogger)
if err != nil {
newCfg := config.New(protocol.EmptyDeviceID)
return config.Wrap(cfgFile, newCfg, protocol.EmptyDeviceID, events.NoopLogger), nil
@@ -750,7 +754,7 @@ func auditWriter(auditFile string) io.Writer {
} else {
auditFlags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
}
fd, err = os.OpenFile(auditFile, auditFlags, 0600)
fd, err = os.OpenFile(auditFile, auditFlags, 0o600)
if err != nil {
l.Warnln("Audit:", err)
os.Exit(svcutil.ExitError.AsInt())

View File

@@ -4,10 +4,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package aggregate
import (
"database/sql"
"fmt"
"log"
"os"
"time"
@@ -15,26 +16,21 @@ import (
_ "github.com/lib/pq"
)
var dbConn = getEnvDefault("UR_DB_URL", "postgres://user:password@localhost/ur?sslmode=disable")
func getEnvDefault(key, def string) string {
if val := os.Getenv(key); val != "" {
return val
}
return def
type CLI struct {
DBConn string `env:"UR_DB_URL" default:"postgres://user:password@localhost/ur?sslmode=disable"`
}
func main() {
func (cli *CLI) Run() error {
log.SetFlags(log.Ltime | log.Ldate)
log.SetOutput(os.Stdout)
db, err := sql.Open("postgres", dbConn)
db, err := sql.Open("postgres", cli.DBConn)
if err != nil {
log.Fatalln("database:", err)
return fmt.Errorf("database: %w", err)
}
err = setupDB(db)
if err != nil {
log.Fatalln("database:", err)
return fmt.Errorf("database: %w", err)
}
for {
@@ -87,16 +83,6 @@ func setupDB(db *sql.DB) error {
return err
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS UserMovement (
Day TIMESTAMP NOT NULL,
Added INTEGER NOT NULL,
Bounced INTEGER NOT NULL,
Removed INTEGER NOT NULL
)`)
if err != nil {
return err
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS Performance (
Day TIMESTAMP NOT NULL,
TotFiles INTEGER NOT NULL,
@@ -136,11 +122,6 @@ func setupDB(db *sql.DB) error {
_, _ = db.Exec(`CREATE INDEX VersionDayIndex ON VersionSummary (Day)`)
}
row = db.QueryRow(`SELECT 'MovementDayIndex'::regclass`)
if err := row.Scan(&t); err != nil {
_, _ = db.Exec(`CREATE INDEX MovementDayIndex ON UserMovement (Day)`)
}
row = db.QueryRow(`SELECT 'PerformanceDayIndex'::regclass`)
if err := row.Scan(&t); err != nil {
_, _ = db.Exec(`CREATE INDEX PerformanceDayIndex ON Performance (Day)`)
@@ -185,87 +166,6 @@ func aggregateVersionSummary(db *sql.DB, since time.Time) (int64, error) {
return res.RowsAffected()
}
func aggregateUserMovement(db *sql.DB) (int64, error) {
rows, err := db.Query(`SELECT
DATE_TRUNC('day', Received) AS Day,
Report->>'uniqueID'
FROM ReportsJson
WHERE
Report->>'uniqueID' IS NOT NULL
AND Received < DATE_TRUNC('day', NOW())
AND Report->>'version' like 'v_.%'
ORDER BY Day
`)
if err != nil {
return 0, err
}
defer rows.Close()
firstSeen := make(map[string]time.Time)
lastSeen := make(map[string]time.Time)
var minTs time.Time
minTs = minTs.In(time.UTC)
for rows.Next() {
var ts time.Time
var id string
if err := rows.Scan(&ts, &id); err != nil {
return 0, err
}
if minTs.IsZero() {
minTs = ts
}
if _, ok := firstSeen[id]; !ok {
firstSeen[id] = ts
}
lastSeen[id] = ts
}
type sumRow struct {
day time.Time
added int
removed int
bounced int
}
var sumRows []sumRow
for t := minTs; t.Before(time.Now().Truncate(24 * time.Hour)); t = t.AddDate(0, 0, 1) {
var added, removed, bounced int
old := t.Before(time.Now().AddDate(0, 0, -30))
for id, first := range firstSeen {
last := lastSeen[id]
if first.Equal(t) && last.Equal(t) && old {
bounced++
continue
}
if first.Equal(t) {
added++
}
if last == t && old {
removed++
}
}
sumRows = append(sumRows, sumRow{t, added, removed, bounced})
}
tx, err := db.Begin()
if err != nil {
return 0, err
}
if _, err := tx.Exec("DELETE FROM UserMovement"); err != nil {
tx.Rollback()
return 0, err
}
for _, r := range sumRows {
if _, err := tx.Exec("INSERT INTO UserMovement (Day, Added, Removed, Bounced) VALUES ($1, $2, $3, $4)", r.day, r.added, r.removed, r.bounced); err != nil {
tx.Rollback()
return 0, err
}
}
return int64(len(sumRows)), tx.Commit()
}
func aggregatePerformance(db *sql.DB, since time.Time) (int64, error) {
res, err := db.Exec(`INSERT INTO Performance (
SELECT

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import (
"regexp"
@@ -145,7 +145,7 @@ func statsForFloats(data []float64) [4]float64 {
return res
}
func group(by func(string) string, as []analytic, perGroup int) []analytic {
func group(by func(string) string, as []analytic, perGroup int, otherPct float64) []analytic {
var res []analytic
next:
@@ -170,6 +170,25 @@ next:
}
sort.Sort(analyticList(res))
if otherPct > 0 {
// Groups with less than otherPCt go into "Other"
other := analytic{
Key: "Other",
}
for i := 0; i < len(res); i++ {
if res[i].Percentage < otherPct || res[i].Key == "Other" {
other.Count += res[i].Count
other.Percentage += res[i].Percentage
res = append(res[:i], res[i+1:]...)
i--
}
}
if other.Count > 0 {
res = append(res, other)
}
}
return res
}

View File

@@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import "testing"

View File

@@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import (
"bytes"

1114
cmd/ursrv/serve/serve.go Normal file
View File

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -197,7 +197,7 @@ found in the LICENSE file.
};
var baseLayer = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '...',
maxZoom: 18
}
@@ -454,13 +454,13 @@ found in the LICENSE file.
<table class="table table-striped">
<thead>
<tr>
<th>Builder</th>
<th>Distribution Channel</th>
<th class="text-right">Devices</th>
<th class="text-right">Share</th>
</tr>
</thead>
<tbody>
{{range .builders}}
{{range .distributions}}
<tr>
<td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td>
@@ -475,13 +475,13 @@ found in the LICENSE file.
<table class="table table-striped">
<thead>
<tr>
<th>Distribution Channel</th>
<th>Builder</th>
<th class="text-right">Devices</th>
<th class="text-right">Share</th>
</tr>
</thead>
<tbody>
{{range .distributions}}
{{range .builders}}
<tr>
<td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td>

View File

@@ -1,3 +1,4 @@
# Increase maximum receive socket buffer size to 2MiB for QUIC connections
# see https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size
net.core.rmem_max = 2097152
# Increase maximum socket buffer sizes to 2.5MiB for QUIC connections
# see https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes
net.core.rmem_max = 2621440
net.core.wmem_max = 2621440

36
go.mod
View File

@@ -5,7 +5,7 @@ go 1.19
require (
github.com/AudriusButkevicius/pfilter v0.0.11
github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f
github.com/alecthomas/kong v0.7.1
github.com/alecthomas/kong v0.8.0
github.com/calmh/incontainer v0.0.0-20221224152218-b3e71b103d7a
github.com/calmh/xdr v1.1.0
github.com/ccding/go-stun v0.1.4
@@ -22,7 +22,7 @@ require (
github.com/gogo/protobuf v1.3.2
github.com/golang/snappy v0.0.4 // indirect
github.com/greatroar/blobloom v0.7.2
github.com/hashicorp/golang-lru/v2 v2.0.3
github.com/hashicorp/golang-lru/v2 v2.0.4
github.com/jackpal/gateway v1.0.10
github.com/jackpal/go-nat-pmp v1.0.2
github.com/julienschmidt/httprouter v1.3.0
@@ -33,29 +33,29 @@ require (
github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0
github.com/minio/sha256-simd v1.0.1
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75
github.com/oschwald/geoip2-golang v1.8.0
github.com/pierrec/lz4/v4 v4.1.17
github.com/oschwald/geoip2-golang v1.9.0
github.com/pierrec/lz4/v4 v4.1.18
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.15.1
github.com/prometheus/client_golang v1.16.0
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/prometheus/procfs v0.11.0 // indirect
github.com/quic-go/quic-go v0.34.0
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/sasha-s/go-deadlock v0.3.1
github.com/shirou/gopsutil/v3 v3.23.5
github.com/shirou/gopsutil/v3 v3.23.6
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
github.com/thejerf/suture/v4 v4.0.2
github.com/urfave/cli v1.22.14
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
golang.org/x/crypto v0.10.0
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.11.0
golang.org/x/sys v0.9.0
golang.org/x/text v0.10.0
golang.org/x/crypto v0.11.0
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.12.0
golang.org/x/sys v0.10.0
golang.org/x/text v0.11.0
golang.org/x/time v0.3.0
golang.org/x/tools v0.9.3
google.golang.org/protobuf v1.30.0
golang.org/x/tools v0.11.0
google.golang.org/protobuf v1.31.0
)
require (
@@ -65,10 +65,10 @@ require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/onsi/ginkgo/v2 v2.10.0 // indirect
github.com/oschwald/maxminddb-golang v1.10.0 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/oschwald/maxminddb-golang v1.11.0 // indirect
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/prometheus/client_model v0.4.0 // indirect
@@ -76,7 +76,7 @@ require (
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 // indirect
)
// https://github.com/gobwas/glob/pull/55

77
go.sum
View File

@@ -6,8 +6,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4=
github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
github.com/alecthomas/kong v0.8.0 h1:ryDCzutfIqJPnNn0omnrgHLbAggDQM2VWHikE1xqK7s=
github.com/alecthomas/kong v0.8.0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
@@ -81,12 +81,12 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/greatroar/blobloom v0.7.2 h1:F30MGLHOcb4zr0pwCPTcKdlTM70rEgkf+LzdUPc5ss8=
github.com/greatroar/blobloom v0.7.2/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE=
github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/golang-lru/v2 v2.0.4 h1:7GHuZcgid37q8o5i3QI9KMT4nCWQQ3Kx3Ov6bb9MfK0=
github.com/hashicorp/golang-lru/v2 v2.0.4/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -127,22 +127,22 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.10.0 h1:sfUl4qgLdvkChZrWCYndY2EAu9BRIw1YphNAzy1VNWs=
github.com/onsi/ginkgo/v2 v2.10.0/go.mod h1:UDQOh5wbQUlMnkLfVaIUMtQ1Vus92oM+P2JX1aulgcE=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/oschwald/geoip2-golang v1.8.0 h1:KfjYB8ojCEn/QLqsDU0AzrJ3R5Qa9vFlx3z6SLNcKTs=
github.com/oschwald/geoip2-golang v1.8.0/go.mod h1:R7bRvYjOeaoenAp9sKRS8GX5bJWcZ0laWO5+DauEktw=
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0=
github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 h1:W04oB3d0J01W5jgYRGKsV8LCM6g9EkCvPkZcmFuy0OE=
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
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=
@@ -151,14 +151,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U=
github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
@@ -172,8 +172,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y=
github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY=
github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHEHT08=
github.com/shirou/gopsutil/v3 v3.23.6/go.mod h1:j7QX50DrXYggrpN30W0Mo+I4/8U2UUIQrnrhqUeWrAU=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -184,7 +184,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY=
@@ -211,17 +210,17 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 h1:FqrVOBQxQ8r/UwwXibI0KMolVhvFiGobSfdE33deHJM=
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -236,8 +235,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -246,7 +245,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -275,9 +274,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -288,8 +287,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -300,8 +299,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
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=
@@ -315,8 +314,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

View File

@@ -574,13 +574,6 @@ html[lang|="ko"] i {
font-style: normal;
}
/* Prevent buttons from jumping up and down
when a tooltip is shown for one of them. */
.btn-group-vertical > .tooltip + .btn,
.btn-group-vertical > .tooltip + .btn-group {
margin-top: -1px;
}
.select-on-click {
-webkit-user-select: all;
user-select: all;

View File

@@ -52,6 +52,7 @@
"Cancel": "إلغاء",
"Changelog": "سجل التغيير",
"Clean out after": "نظف بعد",
"Cleaning Versions": "إصدارات نظيفة",
"Cleanup Interval": "الفاصل الزمني للتنظيف",
"Click to see full identification string and QR code.": "انقر لرؤية سلسلة التعريف الكاملة ورمز الاستجابة السريعة QR.",
"Close": "أغلق",
@@ -65,6 +66,7 @@
"Connection Error": "خطأ في الإتصال",
"Connection Type": "نوع الاتصال",
"Connections": "اتصالات",
"Connections via relays might be rate limited by the relay": "قد يكون معدل التوصيلات عبر المرحلات محدودًا بواسطة المرحل",
"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": "منسوخ من الأصل",
@@ -83,12 +85,18 @@
"Default Ignore Patterns": "أنماط التجاهل الافتراضية",
"Defaults": "الافتراضات",
"Delete": "حذف",
"Delete Unexpected Items": "حذف العناصر غير المتوقعة",
"Deleted {%file%}": "حُذِفت {{file}}",
"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?": "الجهاز \"{{الاسم}}\" ({{الجهاز}} في {{العنوان}}) يرغب في الاتصال، إضافة جهاز جديد؟",
"Device Certificate": "شهادة الجهاز",
"Device ID": "هوية الجهاز",
"Device Identification": "هوية الجهاز",
"Device Name": "أسم الجهاز",
"Device is untrusted, enter encryption password": "الجهاز غير موثوق به، أدخل كلمة مرور التشفير",
"Device rate limits": "حدود معدل نقل البيانات",
"Device that last modified the item": "اخر جهاز جهاز عدل على العنصر",
"Devices": "الأجهزة",
@@ -97,11 +105,17 @@
"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).": "تعطيل مقارنة أذونات الملفات ومزامنتها. مفيد على الأنظمة ذات الأذونات غير الموجودة أو المخصصة (مثل FAT و exFAT و Synology و Android).",
"Discard": "تجاهل",
"Disconnected": "غير متصل",
"Disconnected (Inactive)": "غير متصل (غير نشط)",
"Disconnected (Unused)": "غير متصل (غير مستخدم)",
"Discovered": "مكتشفة",
"Discovery": "اكتشاف",
"Discovery Failures": "فشل الاكتشاف",
"Discovery Status": "حالة الاكتشاف",
"Dismiss": "رفض",
"Do not add it to the ignore list, so this notification may recur.": "لا تقم بإضافته إلى قائمة التجاهل، لذلك قد يتكرر هذا الإشعار.",
"Do not restore": "الغاء الاستعادة",
"Do not restore all": "الغاء استعادة الكل",
"Do you want to enable watching for changes for all your folders?": "هل تريد تفعيل مراقبة التغيرات على كل المجلدات؟",
@@ -111,6 +125,7 @@
"Downloading": "جاري التحميل",
"Edit": "تعديل",
"Edit Device": "تعديل الجهاز",
"Edit Device Defaults": "تحرير الإعدادات الافتراضية للجهاز",
"Edit Folder": "تعديل المجلد",
"Editing {%path%}.": "تعديل {{path}}.",
"Enable Crash Reporting": "تفعيل التبليغ عن الاخطاء",
@@ -301,7 +316,6 @@
"This is a major version upgrade.": "ترقية أساسية ",
"Time": "الوقت",
"Time the item was last modified": "توقيت اخر تعديل للعنصر",
"Twitter": "Twitter",
"Type": "نوع",
"Unavailable": "غير متوفر",
"Unavailable/Disabled by administrator or maintainer": "غير متوفر/معطل من قبل المسؤول أو الصيانة",

View File

@@ -105,7 +105,6 @@
"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 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.",
"Twitter": "Twitter",
"Unknown": "Невядома",
"Up to Date": "Найноўшае",
"Upgrade To {%version%}": "Upgrade To {{version}}",

View File

@@ -2,7 +2,7 @@
"A device with that ID is already added.": "Устройство с този идентификатор вече е добавено.",
"A negative number of days doesn't make sense.": "Отрицателният брой дни е безсмислен.",
"A new major version may not be compatible with previous versions.": "Ново значимо издание, което може да е несъвместимо с предните издания.",
"API Key": "Ключ за ППИ",
"API Key": "API Ключ",
"About": "Относно",
"Action": "Действие",
"Actions": "Действия",
@@ -94,7 +94,7 @@
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Устройство \"{{name}}\" ({{device}}) с адрес {{address}} желае да се свърже. Да бъде ли добавено?",
"Device Certificate": "Сертификат на устройството",
"Device ID": "Идентификатор на устройство",
"Device Identification": "Идентификатор на устройство",
"Device Identification": "Идентификация на устройство",
"Device Name": "Име на устройството",
"Device is untrusted, enter encryption password": "Устройството е недоверено, въведете парола за шифроване",
"Device rate limits": "Ограничаване на скоростта",
@@ -448,7 +448,6 @@
"Today": "Днес",
"Trash Can": "Кошче за отпадъци",
"Trash Can File Versioning": "Версии от вида „кошче за отпадъци“",
"Twitter": "Twitter",
"Type": "Вид",
"UNIX Permissions": "Права на UNIX",
"Unavailable": "Няма налични",

View File

@@ -448,7 +448,6 @@
"Today": "Avui",
"Trash Can": "Paperera",
"Trash Can File Versioning": "Paperera de versionat de fitxers",
"Twitter": "Twitter",
"Type": "Tipus",
"UNIX Permissions": "Permisos UNIX",
"Unavailable": "No disponible",

View File

@@ -448,7 +448,6 @@
"Today": "Avui",
"Trash Can": "Paperera",
"Trash Can File Versioning": "Versionat d'arxius de la paperera",
"Twitter": "Twitter",
"Type": "Tipus",
"UNIX Permissions": "Permisos UNIX",
"Unavailable": "No disponible",

View File

@@ -415,7 +415,6 @@
"Today": "Dnes",
"Trash Can": "Koš",
"Trash Can File Versioning": "Ponechávat jednu předchozí verzi (jako Koš) ",
"Twitter": "Twitter",
"Type": "Typ",
"UNIX Permissions": "UNIX oprávnění",
"Unavailable": "Nedostupné",

View File

@@ -448,7 +448,6 @@
"Today": "I dag",
"Trash Can": "Affaldskurv",
"Trash Can File Versioning": "Versionering med papirkurv",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX rettigheder",
"Unavailable": "Ikke tilgængelig",

View File

@@ -448,7 +448,6 @@
"Today": "Heute",
"Trash Can": "Papierkorb",
"Trash Can File Versioning": "Papierkorb Dateiversionierung",
"Twitter": "Twitter",
"Type": "Typ",
"UNIX Permissions": "UNIX-Berechtigungen",
"Unavailable": "Nicht verfügbar",

View File

@@ -314,7 +314,6 @@
"Time": "Χρόνος",
"Time the item was last modified": "Ώρα τελευταίας τροποποίησης του στοιχείου",
"Trash Can File Versioning": "Τήρηση εκδόσεων κάδου ανακύκλωσης",
"Twitter": "Twitter",
"Type": "Τύπος",
"UNIX Permissions": "Άδειες αρχείων UNIX",
"Unavailable": "Μη διαθέσιμο",

View File

@@ -448,7 +448,6 @@
"Today": "Today",
"Trash Can": "Trash Can",
"Trash Can File Versioning": "Bin File Versioning",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX Permissions",
"Unavailable": "Unavailable",

View File

@@ -448,7 +448,6 @@
"Today": "Today",
"Trash Can": "Rubbish Bin",
"Trash Can File Versioning": "Rubbish Bin File Versioning",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX Permissions",
"Unavailable": "Unavailable",

View File

@@ -448,7 +448,6 @@
"Today": "Today",
"Trash Can": "Trash Can",
"Trash Can File Versioning": "Trash Can File Versioning",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX Permissions",
"Unavailable": "Unavailable",

View File

@@ -317,7 +317,6 @@
"Time": "Tempo",
"Time the item was last modified": "Tempo de lasta modifo de la ero",
"Trash Can File Versioning": "Rubuja Dosiera Versionado",
"Twitter": "Twitter",
"Type": "Tipo",
"UNIX Permissions": "Permesoj UNIX",
"Unavailable": "Ne disponebla",

View File

@@ -448,7 +448,6 @@
"Today": "Hoy",
"Trash Can": "Papelera",
"Trash Can File Versioning": "Versionado de archivos de la papelera",
"Twitter": "Twitter",
"Type": "Tipo",
"UNIX Permissions": "Permisos de UNIX",
"Unavailable": "No disponible",

View File

@@ -113,7 +113,6 @@
"The folder path cannot be blank.": "Kausta asukoht ei tohi olla tühi!",
"The following items could not be synchronized.": "Järgnevaid üksusi ei õnnestunud sünkroniseerida.",
"The maximum age must be a number and cannot be blank.": "Maksimaalne vanus peab olema arv ning ei tohi olla tühi.",
"Twitter": "Twitter",
"Unknown": "Teadmata",
"Upload Rate": "Üleslaadimise Kiirus",
"Use HTTPS for GUI": "Kasuta HTTPS'i GUI jaoks",

View File

@@ -384,7 +384,6 @@
"Time": "Ordua",
"Time the item was last modified": "Itema azkenekoz aldatu zen ordua",
"Trash Can File Versioning": "Zakarrontzia",
"Twitter": "Twitter",
"Type": "Mota",
"UNIX Permissions": "UNIX baimenak",
"Unavailable": "Ez dago erabilgarri",

View File

@@ -310,7 +310,6 @@
"Time": "Aika",
"Time the item was last modified": "Aika jolloin kohdetta viimeksi muokattiin",
"Trash Can File Versioning": "Roskakorin tiedostoversiointi",
"Twitter": "Twitter",
"Type": "Tyyppi",
"Unavailable": "Ei saatavilla",
"Unavailable/Disabled by administrator or maintainer": "Ei saatavilla / ylläpitäjän estämä.",

View File

@@ -210,7 +210,6 @@
"This setting controls the free space required on the home (i.e., index database) disk.": "Ce réglage contrôle l'espace disque requis dans le disque qui abrite votre répertoire utilisateur (pour la base de données d'indexation).",
"Time": "Heure",
"Trash Can File Versioning": "Style poubelle",
"Twitter": "Twitter",
"Unknown": "Inconnu",
"Unshared": "Non partagé",
"Up to Date": "À jour",

View File

@@ -6,7 +6,7 @@
"About": "À propos",
"Action": "Action",
"Actions": "Actions",
"Active filter rules": "Règles de filtrage actives",
"Active filter rules": "Filtres enregistrés",
"Add": "Ajouter",
"Add Device": "Ajouter l'appareil",
"Add Folder": "Ajouter un partage",
@@ -135,8 +135,8 @@
"Enabled": "Activée",
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "Active la synchronisation des attributs étendus. Cette option peut nécessiter d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "Active l'envoi des attributs étendus mais ignore leur réception. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser les attributs étendus\".",
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Active la synchronisation de l'attribut \"Propriétaire\". Cette option nécessite habituellement d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Active l'envoi de l'attribut \"Propriétaire\" mais ignore sa réception. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser le propriétaire\".",
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Active la synchronisation bidirectionnelle de l'attribut \"Propriétaire\". Cette option nécessite habituellement d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Active l'envoi de l'attribut local \"Propriétaire\" mais ignore sa réception de la part des autres appareils. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser l'appartenance\".",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Nombre positif (p.ex, \"2.35\") et unité. Pourcentage de l'espace disque total.",
"Enter a non-privileged port number (1024 - 65535).": "Entrez un numéro de port non-privilégié (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Entrer les adresses (\"tcp://ip:port\" ou \"tcp://hôte:port\") séparées par une virgule, ou \"dynamic\" afin d'activer la recherche automatique de l'adresse.",
@@ -144,7 +144,7 @@
"Enter up to three octal digits.": "Entrez jusqu'à 3 chiffres octaux.",
"Error": "Erreur",
"Extended Attributes": "Attributs étendus",
"Extended Attributes Filter": "Filtre d'attributs étendus",
"Extended Attributes Filter": "Filtres d'attributs étendus",
"External": "Gestion externe",
"External File Versioning": "Gestion externe des versions de fichiers",
"Failed Items": "Éléments en échec",
@@ -186,7 +186,7 @@
"Global Discovery Servers": "Serveurs de découverte globale",
"Global State": "État global",
"Help": "Aide (en anglais)",
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Remarque : quand la règle par défaut est le rejet, seules les règles de rejet sont prises en compte. Envisagez d'ajouter * (Accepter tout) comme dernière règle.",
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Remarque : vous n'avez indiqué que des filtres de refus alors que le comportement par défaut est déjà le refus. Envisagez d'ajouter * (Partager tout les autres attributs non spécifiés) comme dernier filtre (coché) pour inverser le comportement par défaut.",
"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.",
"Identification": "Identifiant abrégé",
@@ -253,7 +253,7 @@
"No": "Non",
"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 rules set": "Aucune règle définie (accepter tout)",
"No rules set": "Aucun filtre défini (partager tous les attributs)",
"No upgrades": "Pas de mises à jour",
"Not shared": "Non partagé",
"Notice": "Notification",
@@ -336,7 +336,7 @@
"Send & Receive": "Envoi & réception",
"Send Extended Attributes": "Envoyer les attributs étendus",
"Send Only": "Envoi (lecture seule)",
"Send Ownership": "Envoyer le propriétaire",
"Send Ownership": "Envoyer l'appartenance",
"Set Ignores on Added Folder": "Définir des exclusions pour le nouveau partage",
"Settings": "Configuration",
"Share": "Partager",
@@ -378,7 +378,7 @@
"Support": "Forum",
"Support Bundle": "Kit d'assistance",
"Sync Extended Attributes": "Synchroniser les attributs étendus",
"Sync Ownership": "Synchroniser le propriétaire",
"Sync Ownership": "Synchroniser l'appartenance",
"Sync Protocol Listen Addresses": "Adresses d'écoute du protocole de synchronisation",
"Sync Status": "État de la synchronisation",
"Syncing": "Synchronisation en cours",
@@ -444,11 +444,10 @@
"Time": "Heure",
"Time the item was last modified": "Dernière modification de l'élément",
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "Pour connecter votre appareil avec celui nommé \"{{devicename}}\", ajoutez ce nouvel appareil distant portant cet identifiant de votre côté :",
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Activez les règles souhaitées en cochant la case. Laissez décoché pour ignorer la règle.",
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Partagez l'attribut spécifié en cochant la case. Laissez décoché pour refuser (comportement par défaut dès la première règle pour les attributs non spécifiés).",
"Today": "Aujourd'hui",
"Trash Can": "Corbeille",
"Trash Can File Versioning": "Style poubelle",
"Twitter": "Piaf",
"Type": "Type",
"UNIX Permissions": "Permissions UNIX",
"Unavailable": "Indisponible",
@@ -519,7 +518,7 @@
"full documentation": "Documentation complète ici (en anglais)",
"items": "élément(s)",
"modified": "modifié",
"permit": "accepter",
"permit": "partager tous les attributs",
"seconds": "secondes",
"theme-name-black": "Noir",
"theme-name-dark": "Sombre",

View File

@@ -368,7 +368,6 @@
"Time": "Tiid",
"Time the item was last modified": "Tiidstip dat it ûnderdiel foar it lest oanpast waard.",
"Trash Can File Versioning": "Jiskefet-triemferzjebehear",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX-Rjochten",
"Unavailable": "Net beskikber",

View File

@@ -22,6 +22,5 @@
"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.": "Un comando externo xestiona as versións. Ten que eliminar o ficheiro do cartafol compartido. Si a ruta ao aplicativo contén espazos, deberían ir acotados.",
"Anonymous Usage Reporting": "Informe anónimo de uso",
"LDAP": "LDAP",
"Twitter": "Twitter"
"LDAP": "LDAP"
}

View File

@@ -98,7 +98,6 @@
"Source Code": "קוד מקור",
"Support": "תמיכה",
"Syncing": "כעת בסנכרון",
"Twitter": "Twitter",
"Upgrade": "שדרוג",
"Upgrade To {%version%}": "שדרוג לגרסה {{version}}",
"Upgrading": "כעת בשדרוג",

View File

@@ -18,6 +18,5 @@
"Allowed Networks": "Dozvoljene mreže",
"Alphabetic": "Abecednim redom",
"Apply": "Primijeni",
"LDAP": "LDAP",
"Twitter": "Twitter"
"LDAP": "LDAP"
}

View File

@@ -439,7 +439,6 @@
"Today": "Ma",
"Trash Can": "Szemetes",
"Trash Can File Versioning": "Szemetes fájlverzió-követés",
"Twitter": "Twitter",
"Type": "Típus",
"UNIX Permissions": "UNIX jogosultságok",
"Unavailable": "Nem elérhető",

View File

@@ -395,7 +395,6 @@
"Time the item was last modified": "Waktu file terakhir dimodifikasi",
"Today": "Hari Ini",
"Trash Can File Versioning": "Pemversian Berkas Tempat Sampah",
"Twitter": "Twitter",
"Type": "Tipe",
"UNIX Permissions": "Izin UNIX",
"Unavailable": "Tidak Tersedia",

View File

@@ -448,7 +448,6 @@
"Today": "Oggi",
"Trash Can": "Cestino",
"Trash Can File Versioning": "Controllo Versione con Cestino",
"Twitter": "Twitter",
"Type": "Tipo",
"UNIX Permissions": "Permessi UNIX",
"Unavailable": "Non disponibile",

View File

@@ -379,7 +379,6 @@
"Time the item was last modified": "項目を最後に変更した日時",
"Today": "今日",
"Trash Can File Versioning": "ゴミ箱によるバージョン管理",
"Twitter": "Twitter",
"Type": "タイプ",
"UNIX Permissions": "UNIX パーミッション",
"Unavailable": "利用不可",

View File

@@ -448,7 +448,6 @@
"Today": "오늘",
"Trash Can": "휴지통",
"Trash Can File Versioning": "휴지통을 통한 파일 버전 관리",
"Twitter": "트위터",
"Type": "유형",
"UNIX Permissions": "UNIX 권한",
"Unavailable": "변경 불가",

View File

@@ -376,7 +376,6 @@
"Today": "Šiandien",
"Trash Can": "Šiukšlinė",
"Trash Can File Versioning": "Šiukšliadėžės versijų valdymas",
"Twitter": "„Twitter“",
"Type": "Tipas",
"UNIX Permissions": "UNIX leidimai",
"Unavailable": "Neprieinama",

View File

@@ -294,7 +294,6 @@
"Time": "Klokkeslett",
"Time the item was last modified": "Tidspunktet elementet sist ble endret",
"Trash Can File Versioning": "Papirkurv versjonskontroll",
"Twitter": "Twitter",
"Unavailable": "Utilgjengelig",
"Unavailable/Disabled by administrator or maintainer": "Utilgjengelig/avskrudd av administrator eller vedlikeholder",
"Undecided (will prompt)": "Ikke bestemt (vil spørre)",

View File

@@ -24,6 +24,5 @@
"Copied from elsewhere": "अन्यत्रबाट प्रतिलिपित्",
"Copied from original": "मूलबाट प्रतिलिपित्",
"Danger!": "खतरा!",
"LDAP": "LDAP",
"Twitter": "Twitter"
"LDAP": "LDAP"
}

View File

@@ -448,7 +448,6 @@
"Today": "Vandaag",
"Trash Can": "Prullenbak",
"Trash Can File Versioning": "Prullenbak-versiebeheer",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX-machtigingen",
"Unavailable": "Niet beschikbaar",

View File

@@ -231,7 +231,6 @@
"This can easily give hackers access to read and change any files on your computer.": "Dette kan lett gje datasnokar tilgang til å lesa og endra vilkårlege filer på denne maskina.",
"This is a major version upgrade.": "Dette er ei hovudoppgradering",
"Trash Can File Versioning": "Papirkorg-filutgåvehandtering",
"Twitter": "Twitter",
"Unknown": "Ukjent",
"Unshared": "Ikkje delt",
"Up to Date": "Oppdatert",

View File

@@ -448,7 +448,6 @@
"Today": "Dzisiaj",
"Trash Can": "Kosz",
"Trash Can File Versioning": "Wersjonowanie plików w koszu",
"Twitter": "Twitter",
"Type": "Rodzaj",
"UNIX Permissions": "UNIX-owe uprawnienia",
"Unavailable": "Niedostępne",

View File

@@ -448,7 +448,6 @@
"Today": "Hoje",
"Trash Can": "Cesto de Lixo",
"Trash Can File Versioning": "Lixeira",
"Twitter": "Twitter",
"Type": "Tipo",
"UNIX Permissions": "Permissões UNIX",
"Unavailable": "Não disponível",

View File

@@ -4,13 +4,15 @@
"A new major version may not be compatible with previous versions.": "Uma nova versão principal pode não ser compatível com versões anteriores.",
"API Key": "Chave da API",
"About": "Acerca da aplicação",
"Action": "Acção",
"Actions": "Acções",
"Action": "Operação",
"Actions": "Operações",
"Active filter rules": "Regras de filtros em uso",
"Add": "Adicionar",
"Add Device": "Adicionar dispositivo",
"Add Folder": "Adicionar pasta",
"Add Remote Device": "Adicionar dispositivo remoto",
"Add devices from the introducer to our device list, for mutually shared folders.": "Adicione dispositivos do apresentador à nossa lista de dispositivos para ter pastas mutuamente partilhadas.",
"Add filter entry": "Adicionar filtro",
"Add ignore patterns": "Adicionar padrões de exclusão",
"Add new folder?": "Adicionar nova pasta?",
"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.": "Para além disso o intervalo entre verificações completas irá ser aumentado (vezes 60, ou seja, um novo valor predefinido de 1h). Também o pode configurar manualmente para cada pasta, posteriormente, depois de seleccionar Não.",
@@ -53,7 +55,7 @@
"Cleaning Versions": "Limpando versões",
"Cleanup Interval": "Intervalo entre limpezas",
"Click to see full identification string and QR code.": "Clique para ver a identificação completa e o código QR.",
"Close": "Fechar",
"Close": "Dispensar",
"Command": "Comando",
"Comment, when used at the start of a line": "Comentário, quando usado no início de uma linha",
"Compression": "Compressão",
@@ -76,6 +78,7 @@
"Danger!": "Perigo!",
"Database Location": "Localização da base de dados",
"Debugging Facilities": "Recursos de depuração",
"Default": "Predefinido",
"Default Configuration": "Configuração predefinida",
"Default Device": "Dispositivo predefinido",
"Default Folder": "Pasta predefinida",
@@ -111,7 +114,7 @@
"Discovery": "Descoberta",
"Discovery Failures": "Falhas da descoberta",
"Discovery Status": "Estado da descoberta",
"Dismiss": "Fechar",
"Dismiss": "Dispensar",
"Do not add it to the ignore list, so this notification may recur.": "Não adicionar à lista dos ignorados, para que esta notificação volte a aparecer.",
"Do not restore": "Não restaurar",
"Do not restore all": "Não restaurar nenhum",
@@ -141,6 +144,7 @@
"Enter up to three octal digits.": "Insira de um a três dígitos em octal.",
"Error": "Erro",
"Extended Attributes": "Atributos estendidos",
"Extended Attributes Filter": "Filtro de atributos extendidos",
"External": "Externa",
"External File Versioning": "Externa",
"Failed Items": "Itens que falharam",
@@ -182,6 +186,7 @@
"Global Discovery Servers": "Servidores de descoberta global",
"Global State": "Estado global",
"Help": "Ajuda",
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Dica: quando a predefinição é \"negar\", apenas as regras de negação são encontradas. Considere adicionar \"permitir tudo\" como última regra.",
"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.",
"Identification": "Identificação",
@@ -228,8 +233,10 @@
"Log tailing paused. Scroll to the bottom to continue.": "O acompanhamento do final do registo está em pausa. Desloque para o final para continuar.",
"Logs": "Registos",
"Major Upgrade": "Actualização importante",
"Mass actions": "Acções em massa",
"Mass actions": "Operações em massa",
"Maximum Age": "Idade máxima",
"Maximum single entry size": "Tamanho máximo das entradas únicas",
"Maximum total size": "Tamanho máximo total",
"Metadata Only": "Metadados apenas",
"Minimum Free Disk Space": "Espaço livre mínimo no disco",
"Mod. Device": "Dispositivo mod.",
@@ -246,6 +253,7 @@
"No": "Não",
"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 rules set": "Não foram definidas regras",
"No upgrades": "Sem actualizações",
"Not shared": "Não partilhada",
"Notice": "Avisos",
@@ -396,7 +404,7 @@
"The cleanup interval cannot be blank.": "O intervalo entre limpezas não pode estar vazio.",
"The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.": "A configuração foi gravada mas não activada. O Syncthing tem que reiniciar para activar a nova configuração.",
"The device ID cannot be blank.": "O ID do dispositivo não pode estar vazio.",
"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).": "O ID do dispositivo a colocar aqui pode ser obtido no menu \"Acções > Mostrar ID\" do outro dispositivo. Espaços e hífenes são opcionais (ignorados).",
"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).": "O ID do dispositivo a colocar aqui pode ser obtido no menu \"Operações > Mostrar ID\" do outro dispositivo. Espaços e hífenes são opcionais (ignorados).",
"The encrypted usage report is sent daily. It is used to track common platforms, folder sizes and app versions. If the reported data set is changed you will be prompted with this dialog again.": "O relatório de utilização cifrado é enviado diariamente. É utilizado para rastrear plataformas comuns, tamanhos de pastas e versões da aplicação. Se o tipo de dados do relatório for alterado, será notificado novamente através desta janela.",
"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.": "O ID do dispositivo fornecido não parece ser válido. Deveria ter 52 ou 56 caracteres constituídos por letras e números, com espaços e hífenes opcionais.",
"The folder ID cannot be blank.": "O ID da pasta não pode estar vazio.",
@@ -436,10 +444,10 @@
"Time": "Quando",
"Time the item was last modified": "Quando o item foi modificado pela última vez",
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "Para se ligar ao dispositivo Syncthing com o nome \"{{devicename}}\", adicione um novo dispositivo remoto do seu lado com este ID:",
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Para permitir uma regra, marque a caixa. Para negar uma regra, deixe-a desmarcada.",
"Today": "Hoje",
"Trash Can": "Lixo",
"Trash Can File Versioning": "Reciclagem",
"Twitter": "Twitter",
"Type": "Tipo",
"UNIX Permissions": "Permissões UNIX",
"Unavailable": "Indisponível",
@@ -465,6 +473,8 @@
"Use notifications from the filesystem to detect changed items.": "Usar notificações do sistema de ficheiros para detectar itens alterados.",
"User Home": "Pasta do utilizador",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "O nome de utilizador e a respectiva senha para a autenticação na interface gráfica não foram definidos. Considere efectuar essa configuração.",
"Using a QUIC connection over LAN": "Usando uma ligação QUIC sobre LAN",
"Using a QUIC connection over WAN": "Usando uma ligação QUIC sobre WAN",
"Using a direct TCP connection over LAN": "Usando uma ligação TCP directa sobre LAN",
"Using a direct TCP connection over WAN": "Usando uma ligação TCP directa sobre WAN",
"Version": "Versão",
@@ -499,10 +509,16 @@
"Your SMS app should open to let you choose the recipient and send it from your own number.": "A sua aplicação de SMS deverá abrir para deixar escolher o destinatário e enviar a partir do seu próprio número.",
"Your email app should open to let you choose the recipient and send it from your own address.": "A sua aplicação de email deverá abrir para deixar escolher o destinatário e enviar a partir do seu próprio endereço.",
"days": "dias",
"deleted": "eliminada",
"deny": "negar",
"directories": "pastas",
"file": "ficheiro",
"files": "ficheiros",
"folder": "pasta",
"full documentation": "documentação completa",
"items": "itens",
"modified": "modificada",
"permit": "permitir",
"seconds": "segundos",
"theme-name-black": "Preto",
"theme-name-dark": "Escuro",

View File

@@ -360,7 +360,6 @@
"Time": "Time",
"Time the item was last modified": "Time the item was last modified",
"Trash Can File Versioning": "Trash Can File Versioning",
"Twitter": "Twitter",
"Type": "Type",
"UNIX Permissions": "UNIX Permissions",
"Unavailable": "Unavailable",

View File

@@ -432,7 +432,6 @@
"Today": "Сегодня",
"Trash Can": "Корзина",
"Trash Can File Versioning": "Использовать версионность для файлов в Корзине",
"Twitter": "Twitter",
"Type": "Тип",
"UNIX Permissions": "Разрешения UNIX",
"Unavailable": "Недоступно",

View File

@@ -12,6 +12,7 @@
"Add Folder": "බහාලුමක් යොදන්න",
"Add Remote Device": "දුරස්ථ උපාංගයක් යොදන්න",
"Add devices from the introducer to our device list, for mutually shared folders.": "අන්‍යෝන්‍ය වශයෙන් බෙදා ගත් ෆෝල්ඩර සඳහා, අපගේ උපාංග ලැයිස්තුවට හඳුන්වා දෙන්නා වෙතින් උපාංග එක් කරන්න.",
"Add filter entry": "පෙරීමේ නිවේශිතයක් යොදන්න",
"Add ignore patterns": "නොසලකා හැරීමේ රටා එක් කරන්න",
"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, එනම් 1h හි නව පෙරනිමිය). අංක තේරීමෙන් පසුව ඔබට සෑම ෆෝල්ඩරයක් සඳහාම එය අතින් වින්‍යාසගත කළ හැක.",
@@ -37,14 +38,16 @@
"Are you sure you want to restore {%count%} files?": "ඔබට ගොනු {{count}} ක් ප්‍රත්‍යර්පණය කිරීමට වුවමනාද?",
"Are you sure you want to revert all local changes?": "ඔබට සියලු දේශීය වෙනස්කම් ප්‍රතිවර්තනය කිරීමට අවශ්‍ය බව විශ්වාසද?",
"Are you sure you want to upgrade?": "ඔබට උත්ශ්‍රේණි කිරීමට වුවමනාද?",
"Authors": "කතුවරුන්",
"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.": "අපේක්ෂක නිකුතු සඳහා ස්වයංක්‍රීය උත්ශ්‍රේණි කිරීම් සැමවිටම සක්‍රීය වේ.",
"Automatically create or share folders that this device advertises at the default path.": "මෙම උපාංගය පෙරනිමි මාර්ගයේ ප්‍රචාරණය කරන ෆෝල්ඩර ස්වයංක්‍රීයව සාදන්න හෝ බෙදාගන්න.",
"Available debug logging facilities:": "පවතින දෝශ නිරාකරණය කිරීමේ පහසුකම්:",
"Be careful!": "පරෙස්සම් වෙන්න!",
"Body:": "අන්තර්ගතය:",
"Bugs": "දෝෂ",
"Cancel": "අවලංගු",
"Changelog": "වෙනස්කම්",
@@ -56,6 +59,8 @@
"Command": "විධානය",
"Comment, when used at the start of a line": "පේළියක ආරම්භයේ භාවිතා කරන විට අදහස් දක්වන්න",
"Compression": "සම්පීඩනය",
"Configuration Directory": "වින්‍යාස නාමාවලිය",
"Configuration File": "වින්‍යාස ගොනුව",
"Configured": "වින්‍යාසගතයි",
"Connected (Unused)": "සම්බන්ධයි (භාවිතයේ නැත)",
"Connection Error": "සම්බන්ධතාවයේ දෝෂයකි",
@@ -64,10 +69,15 @@
"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.": "වෙනස්කම් සඳහා අඛණ්ඩව නැරඹීම දැන් සමමුහුර්තකරණය තුළ පවතී. මෙය තැටියේ වෙනස්කම් හඳුනාගෙන වෙනස් කරන ලද මාර්ගවල පමණක් ස්කෑන් කිරීමක් නිකුත් කරයි. ප්‍රතිලාභ නම් වෙනස්කම් ඉක්මනින් ප්‍රචාරණය වීම සහ අඩු සම්පූර්ණ ස්කෑන් අවශ්‍ය වීමයි.",
"Copied from elsewhere": "වෙනත් තැනකින් පිටපත් කර ඇත",
"Copied from original": "මුල් පිටපතෙන් පිටපත් කර ඇත",
"Copied!": "පිටපත් විය!",
"Copy": "පිටපතක්",
"Copy failed! Try to select and copy manually.": "පිටපත් වීමට අසමත් විය! අතින් තෝරා පිටපත් කිරීමට බලන්න.",
"Currently Shared With Devices": "දැනට උපාංග සමඟ බෙදාගෙන ඇත",
"Custom Range": "අභිරුචි පරාසය",
"Danger!": "අනතුර!",
"Database Location": "දත්ත සමුදායේ ස්ථානය",
"Debugging Facilities": "නිදොස්කරණ පහසුකම්",
"Default": "පෙරනිමි",
"Default Configuration": "පෙරනිමි වින්‍යාසය",
"Default Device": "පෙරනිමි උපාංගය",
"Default Folder": "පෙරනිමි බහාලුම",
@@ -81,6 +91,7 @@
"Deselect folders to stop sharing with this device.": "මෙම උපාංගය සමඟ බෙදා ගැනීම නැවැත්වීමට ෆෝල්ඩර තේරීම ඉවත් කරන්න.",
"Device": "උපාංගය",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "උපාංගය \"{{name}}\" ({{device}} ට {{address}}) සම්බන්ධ වීමට අවශ්‍යයි. නව උපාංගයක් එක් කරන්නද?",
"Device Certificate": "උපාංගයේ සහතිකය",
"Device ID": "උපාංගයේ හැඳු.",
"Device Identification": "උපාංගයේ හැඳුනුම",
"Device Name": "උපාංගයේ නම",
@@ -96,26 +107,27 @@
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "ගොනු අවසර සංසන්දනය කිරීම සහ සමමුහුර්ත කිරීම අබල කරයි. නොපවතින හෝ අභිරුචි අවසර සහිත පද්ධති මත ප්‍රයෝජනවත් වේ (උදා: FAT, exFAT, Synology, Android).",
"Discard": "ඉවතලන්න",
"Disconnected": "විසන්ධියි",
"Disconnected (Inactive)": "විසන්ධියි (අක්‍රිය)",
"Disconnected (Unused)": "විසන්ධියි (භාවිතයේ නැත)",
"Discovered": "සොයා ගන්නා ලදී",
"Discovery": "සොයාගැනීම",
"Discovery Failures": "සොයාගැනීමේ අසාර්ථකත්වය",
"Discovery Status": "සොයාගැනීමේ තත්ත්වය",
"Discovery Status": "සොයාගැනීමේ තත්වය",
"Dismiss": "අහකට",
"Do not add it to the ignore list, so this notification may recur.": "එය නොසලකා හැරීමේ ලැයිස්තුවට එක් නොකරන්න, එබැවින් මෙම දැනුම්දීම නැවත සිදු විය හැක.",
"Do not restore": "ප්‍රත්‍යර්පණය නොකරන්න",
"Do not restore all": "සියල්ල ප්‍රත්‍යර්පණය නොකරන්න",
"Do you want to enable watching for changes for all your folders?": "ඔබට ඔබගේ සියලුම ෆෝල්ඩර සඳහා වෙනස්කම් නැරඹීම සබල කිරීමට අවශ්‍යද?",
"Documentation": "ප්‍රලේඛනය",
"Download Rate": "බාගත කිරීමේ අනුපාතය",
"Download Rate": "බාගැනීමේ අනුපාතය",
"Downloaded": "බාගත වී ඇත",
"Downloading": "බාගැනෙමින්",
"Edit": "සංස්කරණය",
"Edit Device": "උපාංගය සංස්කරණය",
"Edit Device Defaults": "උපාංග පෙරනිමි සංස්කරණය කරන්න",
"Edit Device Defaults": "පෙරනිමි සංස්කරණය කරන්න",
"Edit Folder": "බහාලුම සංස්කරණය",
"Edit Folder Defaults": "ෆෝල්ඩර පෙරනිමි සංස්කරණය කරන්න",
"Editing {%path%}.": "සංස්කරණය {{path}}.",
"Editing {%path%}.": "{{path}} සංශෝධනය.",
"Enable Crash Reporting": "බිඳවැටීම් වාර්තා කිරීම සබල කරන්න",
"Enable NAT traversal": "NAT සංක්‍රමණය සබල කරන්න",
"Enable Relaying": "Relaying සබල කරන්න",
@@ -127,11 +139,11 @@
"Enter up to three octal digits.": "අෂ්ටක ඉලක්කම් තුනක් දක්වා ඇතුළු කරන්න.",
"Error": "දෝෂයකි",
"External": "බාහිර",
"External File Versioning": "බාහිර ගොනු අනුවාදය",
"External File Versioning": "බාහිර ගොනු අනුවාදය",
"Failed Items": "අසාර්ථක අයිතම",
"Failed to load file versions.": "ගොනු අනුවාද පූරණය කිරීමට අසමත් විය.",
"Failed to load ignore patterns.": "නොසලකා හැරීමේ රටා පූරණය කිරීමට අසමත් විය.",
"Failed to setup, retrying": "පිහිටුවීමට අසමත් විය, නැවත උත්සාහ කරමින්",
"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": "ගොනු අනුවාදය",
@@ -151,12 +163,15 @@
"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.": "පහත ෆෝල්ඩර සඳහා වෙනස්කම් නැරඹීමට පටන් ගැනීමේදී දෝෂයක් ඇති විය. එය සෑම මිනිත්තුවකම නැවත උත්සාහ කරනු ඇත, එබැවින් දෝෂ ඉක්මනින් පහව යනු ඇත. ඒවා දිගටම පවතින්නේ නම්, යටින් පවතින ගැටලුව විසඳීමට උත්සාහ කර ඔබට නොහැකි නම් උදව් ඉල්ලන්න.",
"Full Rescan Interval (s)": "සම්පූර්ණ නැවත ස්කෑන් පරතරය (ය)",
"Forever": "සදහටම",
"Full Rescan Interval (s)": "පූර්ණ සුපිරික්සීමේ පරතරය (ත.)",
"GUI": "GUI",
"GUI / API HTTPS Certificate": "GUI / යෙ.ක්‍ර.මු. HTTPS සහතිකය",
"GUI Authentication Password": "GUI සත්‍යාපන මුරපදය",
"GUI Authentication User": "GUI සත්‍යාපන පරිශ්‍රීලක",
"GUI Authentication: Set User and Password": "GUI සත්‍යාපනය: පරිශ්‍රීලක හා මුරපදය සකසන්න",
"GUI Listen Address": "GUI සවන්දීමේ ලිපිනය",
"GUI Override Directory": "GUI අභිබවන නාමාවලිය",
"GUI Theme": "GUI තේමාව",
"General": "සාමාන්‍ය",
"Generate": "උත්පාදනය",
@@ -174,7 +189,7 @@
"Ignore Permissions": "අවසර නොසලකන්න",
"Ignore patterns can only be added after the folder is created. If checked, an input field to enter ignore patterns will be presented after saving.": "නොසලකා හැරීමේ රටා එකතු කළ හැක්කේ ෆෝල්ඩරය නිර්මාණය කිරීමෙන් පසුව පමණි. පරීක්ෂා කළහොත්, නොසලකා හැරීමේ රටා ඇතුළු කිරීමට ආදාන ක්ෂේත්‍රයක් සුරැකීමෙන් පසුව ඉදිරිපත් කෙරේ.",
"Ignored Devices": "නොසැලකූ උපාංග",
"Ignored Folders": "නොසලක බහාලුම්",
"Ignored Folders": "නොසලක බහාලුම්",
"Ignored at": "දී නොසලකා හරින ලදී",
"Incoming Rate Limit (KiB/s)": "එන අනුපාත සීමාව (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "වැරදි වින්‍යාසය ඔබගේ ෆෝල්ඩර අන්තර්ගතයට හානි කළ හැකි අතර සමමුහුර්ත කිරීම අක්‍රිය කරයි.",
@@ -191,6 +206,7 @@
"Last seen": "අවසන දුටුවේ",
"Latest Change": "නවතම වෙනස",
"Learn more": "තව දැනගන්න",
"Learn more at {%url%}": "{{url}} හරහා තව දැනගන්න",
"Limit": "සීමාව",
"Listener Failures": "සවන්දෙන්නන්ගේ අසාර්ථකත්වය",
"Listener Status": "සවන්දෙන්නන්ගේ තත්ත්වය",
@@ -198,49 +214,58 @@
"Loading data...": "දත්ත පූරණය වෙමින්...",
"Loading...": "පූරණය වෙමින්...",
"Local Additions": "දේශීය එකතු කිරීම්",
"Local Discovery": "ස්ථානීය සොයාගැනීම",
"Local Discovery": "ස්ථානීය සොයාගැනීම",
"Local State": "ස්ථානීය තත්‍වය",
"Local State (Total)": "ස්ථානීය තත්‍වය (මුළු)",
"Locally Changed Items": "දේශීයව වෙනස් කරන ලද අයිතම",
"Log": "සටහන",
"Log File": "සටහන් ගොනුව",
"Log tailing paused. Scroll to the bottom to continue.": "ලොග් වලිගය විරාම කරන ලදී. ඉදිරියට යාමට පහළට අනුචලනය කරන්න.",
"Logs": "සටහන්",
"Major Upgrade": "ප්රධාන උත්ශ්රේණි කිරීම",
"Major Upgrade": "ප්රධාන උත්ශ්රේණි කිරීම",
"Mass actions": "මහා ක්‍රියා",
"Maximum Age": "උපරිම වයස",
"Maximum single entry size": "තනි නිවේශිතයක උපරිම ප්‍රමාණය",
"Maximum total size": "උපරිම මුළු ප්‍රමාණය",
"Metadata Only": "පාරදත්ත පමණි",
"Minimum Free Disk Space": "අවම තැටියේ ඉඩ",
"Mod. Device": "mod. උපාංගය",
"Mod. Time": "mod. කාලය",
"More than a month ago": "මාසයකට පෙර",
"More than a week ago": "සතියකට පෙර",
"More than a year ago": "වසරකට පෙර",
"Move to top of queue": "පෝලිමේ මුලට ගෙනයන්න",
"Multi level wildcard (matches multiple directory levels)": "බහු මට්ටමේ වයිල්ඩ්කාඩ් (බහු ඩිරෙක්ටරි මට්ටම් වලට ගැලපේ)",
"Never": "කවදාවත්",
"New Device": "නව උපාංගය",
"New Folder": "නව බහාලුම",
"Newest First": "අලුත්ම මුලින්ම",
"Newest First": "නව දෑ පළමුව",
"No": "නැහැ",
"No File Versioning": "ගොනු අනුවාදනයක් නැත",
"No files will be deleted as a result of this operation.": "මෙම මෙහෙයුමේ ප්‍රතිඵලයක් ලෙස කිසිදු ගොනුවක් මකා නොදමනු ඇත.",
"No rules set": "නීති සකසා නැත",
"No upgrades": "උත්ශ්‍රේණි නැත",
"Not shared": "බෙදාගෙන නැත",
"Notice": "දැන්වීම",
"OK": "හරි",
"Off": "අක්‍රියයි",
"Oldest First": "පරණිතම පළමු",
"Oldest First": "පරණ දෑ පළමු",
"Optional descriptive label for the folder. Can be different on each device.": "ෆෝල්ඩරය සඳහා විකල්ප විස්තර ලේබලය. එක් එක් උපාංගය මත වෙනස් විය හැක.",
"Options": "විකල්ප",
"Out of Sync": "සමමුහර්ත නොවේ",
"Out of Sync Items": "අයිතම සමමුහර්ත නොව",
"Out of Sync": "සමමුහර්ත නොවේ",
"Out of Sync Items": "සමමුහර්ත නොවන අථක",
"Outgoing Rate Limit (KiB/s)": "පිටතට යන ගාස්තු සීමාව (KiB/s)",
"Override": "අභිබවන්න",
"Override Changes": "වෙනස්කම් අභිබවන්න",
"Ownership": "අයිතිය",
"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": "දේශීය පරිගණකයේ ෆෝල්ඩරය වෙත මාර්ගය. එය නොමැති නම් නිර්මාණය වනු ඇත. 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)": "විරාමයි (භාවිතා නොකළ)",
"Paths": "මාර්ග",
"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": "ලබා දී ඇති කාල සීමාව තුළ වරින් වර ස්කෑන් කිරීම සහ වෙනස්කම් සඳහා නැරඹීම සබල කර ඇත",
@@ -251,9 +276,12 @@
"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": "සමමුහූර්තයට සූදානම් වෙමින්",
"Preview": "පෙරදසුන",
"Preview Usage Report": "භාවිත වාර්තාවේ පෙරදසුන",
"QR code": "QR කේතය",
"QUIC LAN": "QUIC LAN",
"QUIC WAN": "QUIC WAN",
"Quick guide to supported patterns": "සහාය දක්වන රටා සඳහා ඉක්මන් මාර්ගෝපදේශය",
"Random": "අහඹු",
"Receive Encrypted": "සංකේතිිතව ලබන්න",
@@ -269,15 +297,15 @@
"Remove Device": "උපාංගය ඉවත් කරන්න",
"Remove Folder": "බහාලුම ඉවත් කරන්න",
"Required identifier for the folder. Must be the same on all cluster devices.": "ෆෝල්ඩරය සඳහා අවශ්‍ය හඳුනාගැනීම. සියලුම පොකුරු උපාංග මත සමාන විය යුතුය.",
"Rescan": "නැවත ස්කෑන් කරන්න",
"Rescan All": "සියල්ල නැවත ස්කෑන් කරන්න",
"Rescan": "යළි සුපිරික්සන්න",
"Rescan All": "සියල්ල යළි සුපිරික්සන්න",
"Rescans": "නැවත ස්කෑන් කරයි",
"Restart": "යළි අරඹන්න",
"Restart Needed": "නැවත ආරම්භ කිරීම අවශ්‍යයි",
"Restarting": "යළි ඇරඹෙමින්",
"Restore": "ප්‍රත්‍යර්පණය",
"Restore Versions": "අනුවාද ප්‍රත්‍යර්පණය",
"Resume": "අරඹන්න",
"Resume": "නැවතත්",
"Resume All": "සියල්ල නැවතත්",
"Reused": "යළි භාවිත",
"Revert": "ආපසු හරවන්න",
@@ -294,10 +322,13 @@
"Select oldest version": "පරණම අනුවාදය තෝරන්න",
"Send & Receive": "යැවීම සහ ලැබීම",
"Send Only": "යැවීම පමණි",
"Send Ownership": "අයිතිය යවන්න",
"Set Ignores on Added Folder": "එකතු කළ ෆෝල්ඩරයේ නොසලකා හැරීම් සකසන්න",
"Settings": "සැකසුම්",
"Share": "බෙදාගන්න",
"Share Folder": "බහාලුම බෙදාගන්න",
"Share by Email": "වි-තැපෑලෙන් බෙදාගන්න",
"Share by SMS": "කෙටි පණිවුඩ මගින් බෙදාගන්න",
"Share this folder?": "මෙම බහාලුම බෙදා ගන්නද?",
"Shared Folders": "බෙදාගත් බහාලුම්",
"Shared With": "සමඟ බෙදාගෙන ඇත",
@@ -329,10 +360,14 @@
"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.": "සංකේතනය කළ දත්ත පමණක් ගබඩා කර සමමුහුර්ත කරයි. සියලුම සම්බන්ධිත උපාංගවල ඇති ෆෝල්ඩර එකම මුරපදයකින් හෝ \"{{receiveEncrypted}}\" වර්ගයට අයත් විය යුතුය.",
"Subject:": "මාතෘකාව:",
"Support": "සහාය",
"Support Bundle": "ආධාරක බණ්ඩලය",
"Sync Ownership": "සමමුහූර්ත අයිතිය",
"Sync Protocol Listen Addresses": "ප්‍රොටෝකෝලය සවන්දීමේ ලිපින සමමුහුර්ත කරන්න",
"Sync Status": "සමමුහූර්ත තත්‍වය",
"Syncing": "සමමුහූර්තය",
"Syncthing device ID for \"{%devicename%}\"": "\"{{devicename}}\" සඳහා සයින්තින් උපාංගයේ හැඳු.",
"Syncthing has been shut down.": "සමමුහුර්ත කිරීම වසා ඇත.",
"Syncthing includes the following software or portions thereof:": "සමමුහුර්තකරණයට පහත මෘදුකාංග හෝ එහි කොටස් ඇතුළත් වේ:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "සමමුහුර්ත කිරීම MPL v2.0 ලෙස බලපත්‍ර ලබා ඇති නිදහස් සහ විවෘත මූලාශ්‍ර මෘදුකාංගයකි.",
@@ -343,6 +378,8 @@
"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 experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "සමමුහුර්ත කිරීම ඔබගේ ඉල්ලීම සැකසීමේ ගැටලුවක් අත්විඳින බව පෙනේ. ගැටලුව දිගටම පවතින්නේ නම් කරුණාකර පිටුව නැවුම් කරන්න හෝ සමමුහුර්ත කිරීම නැවත ආරම්භ කරන්න.",
"TCP LAN": "TCP LAN",
"TCP WAN": "TCP WAN",
"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": "සයින්තින් කතුවරුන්",
@@ -363,6 +400,7 @@
"The following items could not be synchronized.": "පහත අථක සමමුහූර්ත කිරීමට නොහැකිය.",
"The following items were changed locally.": "පහත අථක ස්ථානීයව වෙනස් කර ඇත.",
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "ජාලයේ වෙනත් උපාංග සොයා ගැනීමට සහ මෙම උපාංගය අන් අය විසින් සොයා ගන්නා ලෙස නිවේදනය කිරීමට පහත ක්‍රම භාවිතා කරයි:",
"The following text will automatically be inserted into a new message.": "පහත පෙළ නව පණිවිඩයකට ස්වයංක්‍රීයව ඇතුළු කෙරේ.",
"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.": "අනුවාද නාමාවලිය තුළ පිරිසිදු කිරීම ධාවනය කිරීම සඳහා තත්පර කිහිපයකින් පරතරය. ආවර්තිතා පිරිසිදු කිරීම අක්රිය කිරීමට ශුන්ය.",
@@ -389,10 +427,10 @@
"This setting controls the free space required on the home (i.e., index database) disk.": "මෙම සිටුවම නිවසේ (එනම්, දර්ශක දත්ත ගබඩාව) තැටියේ අවශ්‍ය නිදහස් ඉඩ පාලනය කරයි.",
"Time": "කාලය",
"Time the item was last modified": "අයිතමය අවසන් වරට වෙනස් කළ වේලාව",
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "\"{{devicename}}\" සයින්තින් උපාංගය සමඟ සම්බන්ධ වීමට, මෙම හැඳු. සහිත නව දුරස්ථ උපාංගයක් ඔබගේ පසට එක් කරන්න:",
"Today": "අද",
"Trash Can": "කසල බඳුන",
"Trash Can File Versioning": "කුණු කූඩය ගොනු අනුවාදය",
"Twitter": "ට්විටර්",
"Type": "වර්ගය",
"UNIX Permissions": "UNIX අවසර",
"Unavailable": "නොතිබේ",
@@ -417,6 +455,10 @@
"Use HTTPS for GUI": "GUI සඳහා HTTPS භාවිතා කරන්න",
"Use notifications from the filesystem to detect changed items.": "වෙනස් කළ අයිතම හඳුනා ගැනීමට ගොනු පද්ධතියෙන් දැනුම්දීම් භාවිතා කරන්න.",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "GUI සත්‍යාපනය සඳහා පරිශීලක නාමය/මුරපදය සකසා නොමැත. කරුණාකර එය පිහිටුවීම සලකා බලන්න.",
"Using a QUIC connection over LAN": "LAN හරහා QUIC සම්බන්ධතාවයක් භාවිතය",
"Using a QUIC connection over WAN": "WAN හරහා QUIC සම්බන්ධතාවයක් භාවිතය",
"Using a direct TCP connection over LAN": "LAN හරහා සෘජු TCP සම්බන්ධතාවයක් භාවිතය",
"Using a direct TCP connection over WAN": "WAN හරහා සෘජු TCP සම්බන්ධතාවයක් භාවිතය",
"Version": "අනුවාදය",
"Versions": "අනුවාද",
"Versions Path": "අනුවාද මාර්ගය",
@@ -437,19 +479,28 @@
"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": "ඔව්",
"Yesterday": "ඊයේ",
"You can also copy and paste the text into a new message manually.": "ඔබට අතින් නව පණිවිඩයකට පෙළ පිටපත් කර ඇලවීමට හැකිය.",
"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 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}}\" ෆෝල්ඩරයකට දේශීයව කිසිවක් එකතු කිරීම හෝ වෙනස් කිරීම නොකළ යුතුය.",
"Your SMS app should open to let you choose the recipient and send it from your own number.": "ලබන්නා තේරීමට සහ එය ඔබගේම අංකයෙන් යැවීමට කෙටි පණිවිඩ යෙදුම විවෘත විය යුතුය.",
"Your email app should open to let you choose the recipient and send it from your own address.": "ලබන්නා තේරීමට සහ එය ඔබගේම ලිපිනයෙන් යැවීමට වි-තැපැල් යෙදුම විවෘත විය යුතුය.",
"days": "දවස්",
"deleted": "මකා ඇත",
"deny": "ප්‍රතිෂේධනය",
"directories": "නාමාවලි",
"file": "ගොනුව",
"files": "ගොනු",
"folder": "බහාලුම",
"full documentation": "පූර්ණ ප්‍රලේඛනය",
"items": "අථක",
"modified": "සංශෝධිතයි",
"permit": "අවසරය",
"seconds": "තත්පර",
"theme-name-black": "කළු",
"theme-name-dark": "අඳුරු",

View File

@@ -448,7 +448,6 @@
"Today": "Dnes",
"Trash Can": "Kôš",
"Trash Can File Versioning": "Verzie súborov v koši",
"Twitter": "Twitter",
"Type": "Typ",
"UNIX Permissions": "UNIX povolenia",
"Unavailable": "Nedostupné",

View File

@@ -395,7 +395,6 @@
"Today": "Danes",
"Trash Can": "Koš",
"Trash Can File Versioning": "Beleženje različic datotek s Smetnjakom",
"Twitter": "Twitter",
"Type": "Vrsta",
"UNIX Permissions": "UNIX dovoljenja",
"Unavailable": "Ni na voljo",

View File

@@ -64,7 +64,6 @@
"Scanning": "Duke skanuar",
"Select a version": "Zgjidh një version",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing është program falas dhe Open Source liçensuar si MPL v2.0.",
"Twitter": "Twitter",
"Type": "Lloji",
"Yes": "Po",
"days": "ditë",

View File

@@ -448,7 +448,6 @@
"Today": "Idag",
"Trash Can": "Papperskorgen",
"Trash Can File Versioning": "Papperskorgs filversionshantering",
"Twitter": "Twitter",
"Type": "Typ",
"UNIX Permissions": "UNIX-behörigheter",
"Unavailable": "Otillgänglig",

View File

@@ -448,7 +448,6 @@
"Today": "Bugün",
"Trash Can": "Çöp Kutusu",
"Trash Can File Versioning": "Çöp Kutusu Dosyası Sürümlendirme",
"Twitter": "Twitter",
"Type": "Tür",
"UNIX Permissions": "Unix İzinleri",
"Unavailable": "Kullanılamaz",

View File

@@ -439,7 +439,6 @@
"Today": "Сьогодні",
"Trash Can": "Смітник",
"Trash Can File Versioning": "Версіювання файлів у кошику",
"Twitter": "Twitter",
"Type": "Тип",
"UNIX Permissions": "UNIX дозволи",
"Unavailable": "Недоступно",

View File

@@ -205,7 +205,6 @@
"This can easily give hackers access to read and change any files on your computer.": "Th.tác này có thể khiến tin tặc dễ dàng tr.cập để đọc và th.đổi bất kỳ t.tin nào trên máy của bạn.",
"This is a major version upgrade.": "Đây là bản nâng cấp quan trọng.",
"Trash Can File Versioning": "Kiểu thùng rác",
"Twitter": "Twitter",
"Unknown": "Không biết",
"Unshared": "Chưa chia sẻ",
"Up to Date": "Đã đồng bộ",

View File

@@ -448,7 +448,6 @@
"Today": "今天",
"Trash Can": "回收站",
"Trash Can File Versioning": "回收站式版本控制",
"Twitter": "推特",
"Type": "类型",
"UNIX Permissions": "UNIX权限",
"Unavailable": "无效",

View File

@@ -434,7 +434,6 @@
"Today": "今天",
"Trash Can": "回收站",
"Trash Can File Versioning": "回收站式版本控制",
"Twitter": "Twitter",
"Type": "類型",
"UNIX Permissions": "UNIX權限",
"Unavailable": "無效",

View File

@@ -11,6 +11,7 @@
"Add Folder": "添加資料夾",
"Add Remote Device": "新增遠端裝置",
"Add devices from the introducer to our device list, for mutually shared folders.": "對於共享的資料夾,匯入引入者的裝置清單。",
"Add ignore patterns": "新增忽略模式",
"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": "位址",
@@ -18,6 +19,7 @@
"Advanced": "進階",
"Advanced Configuration": "進階配置",
"All Data": "全部資料",
"All Time": "所有時間",
"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": "允許的網路",
@@ -391,7 +393,6 @@
"Time": "時間",
"Time the item was last modified": "前次修改時間",
"Trash Can File Versioning": "垃圾筒式檔案版本控制",
"Twitter": "Twitter",
"Type": "類型",
"UNIX Permissions": "UNIX 權限",
"Unavailable": "無法使用",

View File

@@ -555,8 +555,8 @@
<tr>
<th><span class="fas fa-fw fa-share-alt"></span>&nbsp;<span translate>Shared With</span></th>
<td class="text-right no-overflow-ellipse word-break-all">
<span ng-repeat="device in folder.devices">
<span ng-if="device.deviceID != myID" ng-switch="completion[device.deviceID][folder.id].remoteState">
<span ng-repeat="device in otherDevices(folder.devices)">
<span ng-switch="completion[device.deviceID][folder.id].remoteState">
<span ng-switch-when="notSharing" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>1</sup><span ng-if="!$last">,</span></span>
<span ng-switch-when="paused" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>2</sup><span ng-if="!$last">,</span></span>
<span ng-switch-default>{{deviceName(devices[device.deviceID])}}<span ng-if="!$last">,</span></span>
@@ -963,7 +963,6 @@
<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;<span translate>Twitter</span></a></li>
</ul>
</div>
</nav>
@@ -1022,7 +1021,6 @@
<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>

View File

@@ -26,7 +26,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, 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, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, Eric Lesiuta, Eric P, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, 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, Martchus, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, 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, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, 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, Vik, Vil Brekin, Vladimir Rusinov, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, bt90, chenrui, chucic, cui fliter, derekriemer, desbma, entity0xfe, georgespatton, ghjklw, guangwu, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, luzpaz, marco-m, mclang, mv1005, otbutz, overkill, perewa, red_led, rubenbe, sec65, villekalliomaki, wangguoliang, wouter bolsterlee, 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, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Kujau, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Emil Lundberg, Eng Zer Jun, Eric Lesiuta, Eric P, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, 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, Martchus, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, 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, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, 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, Vik, Vil Brekin, Vladimir Rusinov, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, bt90, chenrui, chucic, cui fliter, derekriemer, desbma, entity0xfe, georgespatton, ghjklw, guangwu, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, luzpaz, marco-m, mclang, mv1005, otbutz, overkill, perewa, red_led, rubenbe, sec65, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
</div>
</div>
</div>

View File

@@ -1,12 +0,0 @@
angular.module('syncthing.core')
.filter('lastErrorComponent', function () {
return function (input) {
if (input === undefined)
return "";
var parts = input.split(/:\s*/);
if (!parts || parts.length < 1) {
return input;
}
return parts[parts.length - 1];
};
});

View File

@@ -740,20 +740,12 @@ angular.module('syncthing.core')
}
function pathJoin(base, name) {
base = expandTilde(base);
if (base[base.length - 1] !== $scope.system.pathSeparator) {
return base + $scope.system.pathSeparator + name;
}
return base + name;
}
function expandTilde(path) {
if (path && path.trim().charAt(0) === '~') {
return $scope.system.tilde + path.trim().substring(1);
}
return path;
}
function shouldSetDefaultFolderPath() {
return $scope.config.defaults.folder.path && $scope.folderEditor.folderPath.$pristine && $scope.editingFolderNew();
}
@@ -1900,8 +1892,11 @@ angular.module('syncthing.core')
}
};
$scope.otherDevices = function () {
return $scope.deviceList().filter(function (n) {
$scope.otherDevices = function (devices) {
if (devices === undefined) {
devices = $scope.deviceList();
}
return devices.filter(function (n) {
return n.deviceID !== $scope.myID;
});
};
@@ -1988,7 +1983,7 @@ angular.module('syncthing.core')
if (!newvalue) {
return;
}
$scope.currentFolder.path = expandTilde(newvalue);
$scope.currentFolder.path = newvalue;
$http.get(urlbase + '/system/browse', {
params: { current: newvalue }
}).success(function (data) {
@@ -3056,7 +3051,11 @@ angular.module('syncthing.core')
arch += " Container";
}
return $scope.version.version + ', ' + os + ' (' + arch + ')';
var verStr = $scope.version.version;
if ($scope.version.extra) {
verStr += ' (' + $scope.version.extra + ')';
}
return verStr + ', ' + os + ' (' + arch + ')';
};
$scope.versionBase = function () {

View File

@@ -14,16 +14,16 @@
<input ng-if="editingDeviceNew()" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required="" valid-deviceid list="discovery-list" aria-required="true" />
<div ng-if="!editingDeviceNew()" class="well well-sm form-control text-monospace" style="height: auto;" select-on-click>{{currentDevice.deviceID}}</div>
<div id="shareDeviceIdButtons" class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="copyToClipboard($event, currentDevice.deviceID)" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Copy' | translate }}">
<button data-container="body" type="button" class="btn btn-default" ng-click="copyToClipboard($event, currentDevice.deviceID)" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Copy' | translate }}">
<span class="fa fa-lg fa-clone"></span>
</button>
<button type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('email')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by Email' | translate }}">
<button data-container="body" type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('email')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by Email' | translate }}">
<span class="fa fa-lg fa-envelope-o"></span>
</button>
<button type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('sms')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by SMS' | translate }}">
<button data-container="body" type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('sms')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by SMS' | translate }}">
<span class="fa fa-lg fa-comments-o"></span>
</button>
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#idqr" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Show QR' | translate }}">
<button data-container="body" type="button" class="btn btn-default" data-toggle="modal" data-target="#idqr" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Show QR' | translate }}">
<span class="fa fa-lg fa-qrcode"></span>
</button>
</div>

View File

@@ -324,7 +324,7 @@
</div>
</div>
<div class="row" ng-if="currentFolder.syncXattrs">
<div class="row" ng-if="currentFolder.syncXattrs || currentFolder.sendXattrs">
<div class="col-md-12">
<p>
<label translate>Extended Attributes Filter</label>

View File

@@ -7,7 +7,7 @@
<table class="table table-striped table-dynamic">
<tr dir-paginate="e in failed.errors | itemsPerPage: failed.perpage" current-page="failed.page" total-items="model[failed.folder].pullErrors" pagination-id="failed">
<td>{{e.path}}</td>
<td><abbr tooltip data-original-title="{{e.error}}">{{e.error | lastErrorComponent}}</abbr></td>
<td>{{e.error}}</td>
</tr>
</table>
<dir-pagination-controls on-page-change="refreshFailed(newPageNumber, failed.perpage)" pagination-id="failed"></dir-pagination-controls>

View File

@@ -713,6 +713,7 @@ func (*service) getSystemVersion(w http.ResponseWriter, _ *http.Request) {
"version": build.Version,
"codename": build.Codename,
"longVersion": build.LongVersion,
"extra": build.Extra,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"isBeta": build.IsBeta,

View File

@@ -39,7 +39,7 @@ func emitLoginAttempt(success bool, username, address string, evLogger events.Lo
func basicAuthAndSessionMiddleware(cookieName string, guiCfg config.GUIConfiguration, ldapCfg config.LDAPConfiguration, next http.Handler, evLogger events.Logger) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if guiCfg.IsValidAPIKey(r.Header.Get("X-API-Key")) {
if hasValidAPIKeyHeader(r, guiCfg) {
next.ServeHTTP(w, r)
return
}

View File

@@ -59,7 +59,7 @@ func newCsrfManager(unique string, prefix string, apiKeyValidator apiKeyValidato
func (m *csrfManager) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Allow requests carrying a valid API key
if m.apiKeyValidator.IsValidAPIKey(r.Header.Get("X-API-Key")) {
if hasValidAPIKeyHeader(r, m.apiKeyValidator) {
// Set the access-control-allow-origin header for CORS requests
// since a valid API key has been provided
w.Header().Add("Access-Control-Allow-Origin", "*")
@@ -178,3 +178,14 @@ func (m *csrfManager) load() {
m.tokens = append(m.tokens, s.Text())
}
}
func hasValidAPIKeyHeader(r *http.Request, validator apiKeyValidator) bool {
if key := r.Header.Get("X-API-Key"); validator.IsValidAPIKey(key) {
return true
}
if auth := r.Header.Get("Authorization"); strings.HasPrefix(strings.ToLower(auth), "bearer ") {
bearerToken := auth[len("bearer "):]
return validator.IsValidAPIKey(bearerToken)
}
return false
}

View File

@@ -58,7 +58,7 @@ var (
func init() {
dev1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
apiCfg.GUIReturns(config.GUIConfiguration{APIKey: testAPIKey})
apiCfg.GUIReturns(config.GUIConfiguration{APIKey: testAPIKey, RawAddress: "127.0.0.1:0"})
}
func TestMain(m *testing.M) {
@@ -496,7 +496,9 @@ func TestAPIServiceRequests(t *testing.T) {
}
for _, tc := range cases {
tc := tc
t.Run(cases[0].URL, func(t *testing.T) {
t.Parallel()
testHTTPRequest(t, baseURL, tc, testAPIKey)
})
}
@@ -557,69 +559,132 @@ func TestHTTPLogin(t *testing.T) {
cfg := newMockedConfig()
cfg.GUIReturns(config.GUIConfiguration{
User: "üser",
Password: "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq", // bcrypt of "räksmörgås" in UTF-8
User: "üser",
Password: "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq", // bcrypt of "räksmörgås" in UTF-8
RawAddress: "127.0.0.1:0",
APIKey: testAPIKey,
})
baseURL, cancel, err := startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer cancel()
t.Cleanup(cancel)
// Verify rejection when not using authorization
t.Run("no auth is rejected", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for unauthed request", resp.StatusCode)
}
})
req, _ := http.NewRequest("GET", baseURL, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for unauthed request", resp.StatusCode)
}
t.Run("incorrect password is rejected", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.SetBasicAuth("üser", "rksmrgs")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for incorrect password", resp.StatusCode)
}
})
// Verify that incorrect password is rejected
t.Run("incorrect username is rejected", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.SetBasicAuth("user", "räksmörgås") // string literals in Go source code are in UTF-8
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for incorrect username", resp.StatusCode)
}
})
req.SetBasicAuth("üser", "rksmrgs")
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for incorrect password", resp.StatusCode)
}
t.Run("UTF-8 auth works", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.SetBasicAuth("üser", "räksmörgås") // string literals in Go source code are in UTF-8
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for authed request (UTF-8)", resp.StatusCode)
}
})
// Verify that incorrect username is rejected
t.Run("ISO-8859-1 auth work", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.SetBasicAuth("\xfcser", "r\xe4ksm\xf6rg\xe5s") // escaped ISO-8859-1
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for authed request (ISO-8859-1)", resp.StatusCode)
}
})
req.SetBasicAuth("user", "räksmörgås") // string literals in Go source code are in UTF-8
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for incorrect username", resp.StatusCode)
}
t.Run("bad X-API-Key is rejected", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.Header.Set("X-API-Key", testAPIKey+"X")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for bad API key", resp.StatusCode)
}
})
// Verify that UTF-8 auth works
t.Run("good X-API-Key is accepted", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.Header.Set("X-API-Key", testAPIKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for API key", resp.StatusCode)
}
})
req.SetBasicAuth("üser", "räksmörgås") // string literals in Go source code are in UTF-8
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for authed request (UTF-8)", resp.StatusCode)
}
t.Run("bad Bearer is rejected", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.Header.Set("Authorization", "Bearer "+testAPIKey+"X")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusUnauthorized {
t.Errorf("Unexpected non-401 return code %d for bad API key", resp.StatusCode)
}
})
// Verify that ISO-8859-1 auth
req.SetBasicAuth("\xfcser", "r\xe4ksm\xf6rg\xe5s") // escaped ISO-8859-1
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for authed request (ISO-8859-1)", resp.StatusCode)
}
t.Run("good Bearer is accepted", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL, nil)
req.Header.Set("Authorization", "Bearer "+testAPIKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected non-200 return code %d for API key", resp.StatusCode)
}
})
}
func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) {
@@ -681,7 +746,7 @@ func TestCSRFRequired(t *testing.T) {
if err != nil {
t.Fatal("Unexpected error from getting base URL:", err)
}
defer cancel()
t.Cleanup(cancel)
cli := &http.Client{
Timeout: time.Minute,
@@ -709,42 +774,87 @@ func TestCSRFRequired(t *testing.T) {
}
}
// Calling on /rest without a token should fail
t.Run("/rest without a token should fail", func(t *testing.T) {
t.Parallel()
resp, err := cli.Get(baseURL + "/rest/system/config")
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusForbidden {
t.Fatal("Getting /rest/system/config without CSRF token should fail, not", resp.Status)
}
})
resp, err = cli.Get(baseURL + "/rest/system/config")
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusForbidden {
t.Fatal("Getting /rest/system/config without CSRF token should fail, not", resp.Status)
}
t.Run("/rest with a token should succeed", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("X-"+csrfTokenName, csrfTokenValue)
resp, err := cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatal("Getting /rest/system/config with CSRF token should succeed, not", resp.Status)
}
})
// Calling on /rest with a token should succeed
t.Run("/rest with an incorrect API key should fail, X-API-Key version", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("X-API-Key", testAPIKey+"X")
resp, err := cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusForbidden {
t.Fatal("Getting /rest/system/config with incorrect API token should fail, not", resp.Status)
}
})
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("X-"+csrfTokenName, csrfTokenValue)
resp, err = cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatal("Getting /rest/system/config with CSRF token should succeed, not", resp.Status)
}
t.Run("/rest with an incorrect API key should fail, Bearer auth version", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("Authorization", "Bearer "+testAPIKey+"X")
resp, err := cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusForbidden {
t.Fatal("Getting /rest/system/config with incorrect API token should fail, not", resp.Status)
}
})
// Calling on /rest with the API key should succeed
t.Run("/rest with the API key should succeed", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("X-API-Key", testAPIKey)
resp, err := cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatal("Getting /rest/system/config with API key should succeed, not", resp.Status)
}
})
req, _ = http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("X-API-Key", testAPIKey)
resp, err = cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatal("Getting /rest/system/config with API key should succeed, not", resp.Status)
}
t.Run("/rest with the API key as a bearer token should succeed", func(t *testing.T) {
t.Parallel()
req, _ := http.NewRequest("GET", baseURL+"/rest/system/config", nil)
req.Header.Set("Authorization", "Bearer "+testAPIKey)
resp, err := cli.Do(req)
if err != nil {
t.Fatal("Unexpected error from getting /rest/system/config:", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatal("Getting /rest/system/config with API key should succeed, not", resp.Status)
}
})
}
func TestRandomString(t *testing.T) {
@@ -943,30 +1053,31 @@ func TestHostCheck(t *testing.T) {
t.Error("Incorrect host header, check disabled: expected 200 OK, not", resp.Status)
}
// A server bound to a wildcard address also doesn't do the check
if !testing.Short() {
// A server bound to a wildcard address also doesn't do the check
cfg = newMockedConfig()
cfg.GUIReturns(config.GUIConfiguration{
RawAddress: "0.0.0.0:0",
InsecureSkipHostCheck: true,
})
baseURL, cancel, err = startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer cancel()
cfg = newMockedConfig()
cfg.GUIReturns(config.GUIConfiguration{
RawAddress: "0.0.0.0:0",
})
baseURL, cancel, err = startHTTP(cfg)
if err != nil {
t.Fatal(err)
}
defer cancel()
// A request with a suspicious Host header should be allowed
// A request with a suspicious Host header should be allowed
req, _ = http.NewRequest("GET", baseURL, nil)
req.Host = "example.com"
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Error("Incorrect host header, wildcard bound: expected 200 OK, not", resp.Status)
req, _ = http.NewRequest("GET", baseURL, nil)
req.Host = "example.com"
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Error("Incorrect host header, wildcard bound: expected 200 OK, not", resp.Status)
}
}
// This should all work over IPv6 as well

View File

@@ -35,6 +35,7 @@ var (
IsCandidate bool
IsBeta bool
LongVersion string
Extra string
allowedVersionExp = regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z0-9]+)*(\.\d+)*(\+\d+-g[0-9a-f]+)?(-[^\s]+)?$`)
@@ -46,6 +47,8 @@ var (
}
)
const versionExtraAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-. "
func init() {
if Version != "unknown-dev" {
// If not a generic dev build, version string should come from git describe
@@ -75,6 +78,7 @@ func setBuildData() {
IsRelease = exp.MatchString(Version)
IsCandidate = strings.Contains(Version, "-rc.")
IsBeta = strings.Contains(Version, "-")
Extra = filterString(os.Getenv("STVERSIONEXTRA"), versionExtraAllowedChars)
stamp, _ := strconv.Atoi(Stamp)
Date = time.Unix(int64(stamp), 0)
@@ -103,7 +107,22 @@ func TagsList() []string {
tags = append(tags, strings.ToLower(envVar))
}
}
if Extra != "" {
tags = append(tags, Extra)
}
sort.Strings(tags)
return tags
}
// filterString returns a copy of s with all characters not in allowedChars
// removed.
func filterString(s, allowedChars string) string {
var res strings.Builder
for _, c := range s {
if strings.ContainsRune(allowedChars, c) {
res.WriteRune(c)
}
}
return res.String()
}

View File

@@ -35,3 +35,23 @@ func TestAllowedVersions(t *testing.T) {
}
}
}
func TestFilterString(t *testing.T) {
cases := []struct {
input string
filter string
output string
}{
{"abcba", "abc", "abcba"},
{"abcba", "ab", "abba"},
{"abcba", "c", "c"},
{"abcba", "!", ""},
{"Foo (v1.5)", versionExtraAllowedChars, "Foo v1.5"},
}
for i, c := range cases {
if out := filterString(c.input, c.filter); out != c.output {
t.Errorf("%d: %q != %q", i, out, c.output)
}
}
}

View File

@@ -9,6 +9,10 @@
package connections
import (
"fmt"
)
var errNotInBuild = fmt.Errorf("%w: disabled at build time", errUnsupported)
func init() {

View File

@@ -65,7 +65,7 @@ func (d *relayDialer) Dial(ctx context.Context, id protocol.DeviceID, uri *url.U
return newInternalConn(tc, connTypeRelayClient, false, d.wanPriority), nil
}
func (d *relayDialer) Priority(host string) int {
func (d *relayDialer) Priority(_ string) int {
return d.wanPriority
}

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