mirror of
https://github.com/searxng/searxng.git
synced 2026-07-24 17:01:25 +00:00
Compare commits
52 Commits
539c90647b
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
031a160ce4 | ||
|
|
ef8f6470e0 | ||
|
|
6da6eee265 | ||
|
|
277d8469cd | ||
|
|
81c9c23862 | ||
|
|
6913fba208 | ||
|
|
2daa4d4815 | ||
|
|
de8f73f434 | ||
|
|
9f9c00819e | ||
|
|
b72a87676f | ||
|
|
f2432e33d6 | ||
|
|
7b2199ecdf | ||
|
|
4a9c19d7bf | ||
|
|
5cb4cb2bc5 | ||
|
|
5a448596ab | ||
|
|
9c49b7e0d7 | ||
|
|
58e02a01ae | ||
|
|
7fa9f16225 | ||
|
|
9e25585aec | ||
|
|
c19d86faa3 | ||
|
|
21fa7b0be1 | ||
|
|
74b4e7c8d1 | ||
|
|
39f4dd24a5 | ||
|
|
62a1ab7edd | ||
|
|
4abac08de5 | ||
|
|
6a4d5148d6 | ||
|
|
799086874d | ||
|
|
83139c26b3 | ||
|
|
8456831a04 | ||
|
|
b512eaa272 | ||
|
|
1412926f5c | ||
|
|
3b573e0f89 | ||
|
|
da6a230413 | ||
|
|
f69b22c45c | ||
|
|
f930443726 | ||
|
|
d58ced8f71 | ||
|
|
556d08c395 | ||
|
|
1017631800 | ||
|
|
b64e6ee44a | ||
|
|
a6438586a5 | ||
|
|
fd5eb84a37 | ||
|
|
888364c1ce | ||
|
|
1cdf01a719 | ||
|
|
747cec4c23 | ||
|
|
4ef70e9451 | ||
|
|
80c9806de1 | ||
|
|
9d7ca4febc | ||
|
|
c5cd510d82 | ||
|
|
73a0219ab8 | ||
|
|
7ed7adfb05 | ||
|
|
d7367e0897 | ||
|
|
21773bbb2d |
136
.github/workflows/container.yml
vendored
136
.github/workflows/container.yml
vendored
@@ -25,25 +25,21 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository_owner == 'searxng' || github.event_name == 'workflow_dispatch'
|
if: |
|
||||||
|
github.event_name == 'workflow_dispatch'
|
||||||
|
|| (github.repository_owner == 'searxng' && github.event.workflow_run.conclusion == 'success')
|
||||||
name: Build (${{ matrix.arch }})
|
name: Build (${{ matrix.arch }})
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.runner }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: amd64
|
- runner: ubuntu-26.04
|
||||||
march: amd64
|
arch: amd64
|
||||||
os: ubuntu-24.04
|
- runner: ubuntu-26.04-arm
|
||||||
emulation: false
|
arch: arm64
|
||||||
- arch: arm64
|
- runner: ubuntu-26.04-arm
|
||||||
march: arm64
|
arch: armv7
|
||||||
os: ubuntu-24.04-arm
|
|
||||||
emulation: false
|
|
||||||
- arch: armv7
|
|
||||||
march: arm64
|
|
||||||
os: ubuntu-24.04-arm
|
|
||||||
emulation: true
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
@@ -53,109 +49,82 @@ jobs:
|
|||||||
git_url: ${{ steps.build.outputs.git_url }}
|
git_url: ${{ steps.build.outputs.git_url }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# yamllint disable rule:line-length
|
- name: Login to GHCR
|
||||||
- name: Setup podman
|
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
|
||||||
env:
|
with:
|
||||||
PODMAN_VERSION: "v5.7.1"
|
registry: "ghcr.io"
|
||||||
run: |
|
username: "${{ github.repository_owner }}"
|
||||||
sudo apt-get purge -y podman runc crun conmon
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
curl -fsSLO "https://github.com/mgoltzsche/podman-static/releases/download/${{ env.PODMAN_VERSION }}/podman-linux-${{ matrix.march }}.tar.gz"
|
|
||||||
curl -fsSLO "https://github.com/mgoltzsche/podman-static/releases/download/${{ env.PODMAN_VERSION }}/podman-linux-${{ matrix.march }}.tar.gz.asc"
|
|
||||||
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 0CCF102C4F95D89E583FF1D4F8B5AF50344BB503
|
|
||||||
gpg --batch --verify "podman-linux-${{ matrix.march }}.tar.gz.asc" "podman-linux-${{ matrix.march }}.tar.gz"
|
|
||||||
|
|
||||||
tar -xzf "podman-linux-${{ matrix.march }}.tar.gz"
|
|
||||||
sudo cp -rfv ./podman-linux-${{ matrix.march }}/etc/. /etc/
|
|
||||||
sudo cp -rfv ./podman-linux-${{ matrix.march }}/usr/. /usr/
|
|
||||||
|
|
||||||
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
|
||||||
# yamllint enable rule:line-length
|
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
|
- name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
|
ref: "${{ github.event.workflow_run.head_sha || github.sha }}"
|
||||||
persist-credentials: "false"
|
persist-credentials: "false"
|
||||||
fetch-depth: "0"
|
fetch-depth: "0"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-
|
python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-
|
||||||
path: "./local/"
|
path: "./local/"
|
||||||
|
|
||||||
- name: Get date
|
|
||||||
id: date
|
|
||||||
run: echo "date=$(date +'%Y%m%d')" >>$GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Setup cache container
|
- name: Setup cache container
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "container-${{ matrix.arch }}-${{ steps.date.outputs.date }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "container-${{ matrix.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
container-${{ matrix.arch }}-${{ steps.date.outputs.date }}-
|
|
||||||
container-${{ matrix.arch }}-
|
container-${{ matrix.arch }}-
|
||||||
path: "/var/tmp/buildah-cache-*/*"
|
path: "/var/tmp/buildah-cache-*/*"
|
||||||
|
|
||||||
- if: ${{ matrix.emulation }}
|
|
||||||
name: Setup QEMU
|
|
||||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
|
|
||||||
|
|
||||||
- name: Login to GHCR
|
|
||||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
|
||||||
with:
|
|
||||||
registry: "ghcr.io"
|
|
||||||
username: "${{ github.repository_owner }}"
|
|
||||||
password: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
id: build
|
id: build
|
||||||
env:
|
env:
|
||||||
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
||||||
run: make podman.build
|
run: make container.build
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test (${{ matrix.arch }})
|
name: Test (${{ matrix.arch }})
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.runner }}
|
||||||
needs: build
|
needs: build
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: amd64
|
- runner: ubuntu-26.04
|
||||||
os: ubuntu-24.04
|
arch: amd64
|
||||||
emulation: false
|
- runner: ubuntu-26.04-arm
|
||||||
- arch: arm64
|
arch: arm64
|
||||||
os: ubuntu-24.04-arm
|
- runner: ubuntu-26.04-arm
|
||||||
emulation: false
|
arch: armv7
|
||||||
- arch: armv7
|
|
||||||
os: ubuntu-24.04-arm
|
|
||||||
emulation: true
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
||||||
with:
|
|
||||||
persist-credentials: "false"
|
|
||||||
|
|
||||||
- if: ${{ matrix.emulation }}
|
|
||||||
name: Setup QEMU
|
|
||||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
|
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
|
||||||
with:
|
with:
|
||||||
registry: "ghcr.io"
|
registry: "ghcr.io"
|
||||||
username: "${{ github.repository_owner }}"
|
username: "${{ github.repository_owner }}"
|
||||||
password: "${{ secrets.GITHUB_TOKEN }}"
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
with:
|
||||||
|
ref: "${{ github.event.workflow_run.head_sha || github.sha }}"
|
||||||
|
persist-credentials: "false"
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
env:
|
env:
|
||||||
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
||||||
@@ -165,7 +134,7 @@ jobs:
|
|||||||
release:
|
release:
|
||||||
if: github.repository_owner == 'searxng' && github.ref_name == 'master'
|
if: github.repository_owner == 'searxng' && github.ref_name == 'master'
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
needs:
|
needs:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
@@ -174,24 +143,25 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Login to Docker Hub
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: "false"
|
registry: "docker.io"
|
||||||
|
username: "${{ secrets.DOCKER_USER }}"
|
||||||
|
password: "${{ secrets.DOCKER_TOKEN }}"
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
|
||||||
with:
|
with:
|
||||||
registry: "ghcr.io"
|
registry: "ghcr.io"
|
||||||
username: "${{ github.repository_owner }}"
|
username: "${{ github.repository_owner }}"
|
||||||
password: "${{ secrets.GITHUB_TOKEN }}"
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Checkout
|
||||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
registry: "docker.io"
|
ref: "${{ github.event.workflow_run.head_sha || github.sha }}"
|
||||||
username: "${{ secrets.DOCKER_USER }}"
|
persist-credentials: "false"
|
||||||
password: "${{ secrets.DOCKER_TOKEN }}"
|
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
env:
|
env:
|
||||||
|
|||||||
21
.github/workflows/data-update.yml
vendored
21
.github/workflows/data-update.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
data:
|
data:
|
||||||
if: github.repository_owner == 'searxng'
|
if: github.repository_owner == 'searxng'
|
||||||
name: ${{ matrix.fetch }}
|
name: ${{ matrix.fetch }}
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -33,7 +33,6 @@ jobs:
|
|||||||
- update_engine_traits.py
|
- update_engine_traits.py
|
||||||
- update_wikidata_units.py
|
- update_wikidata_units.py
|
||||||
- update_engine_descriptions.py
|
- update_engine_descriptions.py
|
||||||
- update_gsa_useragents.py
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -41,7 +40,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ jobs:
|
|||||||
persist-credentials: "false"
|
persist-credentials: "false"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
@@ -65,23 +64,17 @@ jobs:
|
|||||||
run: V=1 ./manage pyenv.cmd python "./searxng_extra/update/${{ matrix.fetch }}"
|
run: V=1 ./manage pyenv.cmd python "./searxng_extra/update/${{ matrix.fetch }}"
|
||||||
|
|
||||||
- name: Create PR
|
- name: Create PR
|
||||||
id: cpr
|
|
||||||
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
||||||
with:
|
with:
|
||||||
author: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
author: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
||||||
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
||||||
title: "[data] update searx.data - ${{ matrix.fetch }}"
|
title: "[mod] data: update searx.data - ${{ matrix.fetch }}"
|
||||||
commit-message: "[data] update searx.data - ${{ matrix.fetch }}"
|
commit-message: "[mod] data: update searx.data - ${{ matrix.fetch }}"
|
||||||
branch: "update_data_${{ matrix.fetch }}"
|
branch: "ci-data-${{ matrix.fetch }}"
|
||||||
delete-branch: "true"
|
delete-branch: "true"
|
||||||
draft: "false"
|
draft: "false"
|
||||||
signoff: "false"
|
signoff: "false"
|
||||||
body: |
|
body: |
|
||||||
[data] update searx.data - ${{ matrix.fetch }}
|
Update searx.data - ${{ matrix.fetch }}
|
||||||
labels: |
|
labels: |
|
||||||
data
|
data
|
||||||
|
|
||||||
- name: Display information
|
|
||||||
run: |
|
|
||||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
|
||||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
|
||||||
|
|||||||
8
.github/workflows/documentation.yml
vendored
8
.github/workflows/documentation.yml
vendored
@@ -25,14 +25,14 @@ jobs:
|
|||||||
release:
|
release:
|
||||||
if: github.repository_owner == 'searxng' || github.event_name == 'workflow_dispatch'
|
if: github.repository_owner == 'searxng' || github.event_name == 'workflow_dispatch'
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
permissions:
|
permissions:
|
||||||
# for JamesIves/github-pages-deploy-action to push
|
# for JamesIves/github-pages-deploy-action to push
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
fetch-depth: "0"
|
fetch-depth: "0"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
@@ -65,7 +65,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
folder: "dist/docs"
|
folder: "dist/docs"
|
||||||
branch: "gh-pages"
|
branch: "gh-pages"
|
||||||
commit-message: "[doc] build from commit ${{ github.sha }}"
|
commit-message: "[mod] docs: build from commit ${{ github.sha }}"
|
||||||
# Automatically remove deleted files from the deploy branch
|
# Automatically remove deleted files from the deploy branch
|
||||||
clean: "true"
|
clean: "true"
|
||||||
single-commit: "true"
|
single-commit: "true"
|
||||||
|
|||||||
37
.github/workflows/integration.yml
vendored
37
.github/workflows/integration.yml
vendored
@@ -23,7 +23,7 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: Python ${{ matrix.python-version }}
|
name: Python ${{ matrix.python-version }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-26.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ matrix.python-version }}"
|
python-version: "${{ matrix.python-version }}"
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
persist-credentials: "false"
|
persist-credentials: "false"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ matrix.python-version }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ matrix.python-version }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
@@ -59,37 +59,40 @@ jobs:
|
|||||||
|
|
||||||
theme:
|
theme:
|
||||||
name: Theme
|
name: Theme
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||||
|
with:
|
||||||
|
node-version: "26"
|
||||||
|
check-latest: "true"
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: "false"
|
persist-credentials: "false"
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
||||||
with:
|
|
||||||
node-version-file: "./.nvmrc"
|
|
||||||
|
|
||||||
- name: Setup cache Node.js
|
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
||||||
with:
|
|
||||||
key: "nodejs-${{ runner.arch }}-${{ hashFiles('./.nvmrc', './package.json') }}"
|
|
||||||
path: "./client/simple/node_modules/"
|
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-
|
python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-
|
||||||
path: "./local/"
|
path: "./local/"
|
||||||
|
|
||||||
|
- name: Setup cache Node.js
|
||||||
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
|
with:
|
||||||
|
key: "nodejs-${{ runner.arch }}-${{ hashFiles('**/package-lock.json') }}"
|
||||||
|
restore-keys: |
|
||||||
|
nodejs-${{ runner.arch }}-
|
||||||
|
path: "./client/simple/node_modules/"
|
||||||
|
|
||||||
- name: Setup venv
|
- name: Setup venv
|
||||||
run: make V=1 install
|
run: make V=1 install
|
||||||
|
|
||||||
|
|||||||
30
.github/workflows/l10n.yml
vendored
30
.github/workflows/l10n.yml
vendored
@@ -26,16 +26,16 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
if: github.repository_owner == 'searxng' && github.event.workflow_run.conclusion == 'success'
|
if: github.event.workflow_run.conclusion == 'success' && github.repository_owner == 'searxng'
|
||||||
name: Update
|
name: Update
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
permissions:
|
permissions:
|
||||||
# For "make V=1 weblate.push.translations"
|
# For "make V=1 weblate.push.translations"
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
fetch-depth: "0"
|
fetch-depth: "0"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
- name: Setup Weblate
|
- name: Setup Weblate
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.config
|
mkdir -p ~/.config
|
||||||
echo "${{ secrets.WEBLATE_CONFIG }}" > ~/.config/weblate
|
echo "${{ secrets.WEBLATE_CONFIG }}" >~/.config/weblate
|
||||||
|
|
||||||
- name: Setup Git
|
- name: Setup Git
|
||||||
run: |
|
run: |
|
||||||
@@ -74,7 +74,7 @@ jobs:
|
|||||||
github.repository_owner == 'searxng'
|
github.repository_owner == 'searxng'
|
||||||
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
|
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
|
||||||
name: Pull Request
|
name: Pull Request
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-26.04-arm
|
||||||
permissions:
|
permissions:
|
||||||
# For "make V=1 weblate.translations.commit"
|
# For "make V=1 weblate.translations.commit"
|
||||||
contents: write
|
contents: write
|
||||||
@@ -83,7 +83,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "${{ env.PYTHON_VERSION }}"
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ jobs:
|
|||||||
fetch-depth: "0"
|
fetch-depth: "0"
|
||||||
|
|
||||||
- name: Setup cache Python
|
- name: Setup cache Python
|
||||||
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
with:
|
with:
|
||||||
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
@@ -107,7 +107,7 @@ jobs:
|
|||||||
- name: Setup Weblate
|
- name: Setup Weblate
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.config
|
mkdir -p ~/.config
|
||||||
echo "${{ secrets.WEBLATE_CONFIG }}" > ~/.config/weblate
|
echo "${{ secrets.WEBLATE_CONFIG }}" >~/.config/weblate
|
||||||
|
|
||||||
- name: Setup Git
|
- name: Setup Git
|
||||||
run: |
|
run: |
|
||||||
@@ -118,23 +118,17 @@ jobs:
|
|||||||
run: make V=1 weblate.translations.commit
|
run: make V=1 weblate.translations.commit
|
||||||
|
|
||||||
- name: Create PR
|
- name: Create PR
|
||||||
id: cpr
|
|
||||||
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
||||||
with:
|
with:
|
||||||
author: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
author: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
||||||
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
||||||
title: "[l10n] update translations from Weblate"
|
title: "[mod] i18n: update translations from Weblate"
|
||||||
commit-message: "[l10n] update translations from Weblate"
|
commit-message: "[mod] i18n: update translations from Weblate"
|
||||||
branch: "translations_update"
|
branch: "translations_update"
|
||||||
delete-branch: "true"
|
delete-branch: "true"
|
||||||
draft: "false"
|
draft: "false"
|
||||||
signoff: "false"
|
signoff: "false"
|
||||||
body: |
|
body: |
|
||||||
[l10n] update translations from Weblate
|
Update translations from Weblate
|
||||||
labels: |
|
labels: |
|
||||||
area:i18n
|
area:i18n
|
||||||
|
|
||||||
- name: Display information
|
|
||||||
run: |
|
|
||||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
|
||||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
|
||||||
|
|||||||
46
.github/workflows/security.yml
vendored
46
.github/workflows/security.yml
vendored
@@ -1,46 +0,0 @@
|
|||||||
---
|
|
||||||
name: Security
|
|
||||||
|
|
||||||
# yamllint disable-line rule:truthy
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "42 05 * * *"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
container:
|
|
||||||
if: github.repository_owner == 'searxng'
|
|
||||||
name: Container
|
|
||||||
runs-on: ubuntu-24.04-arm
|
|
||||||
permissions:
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
||||||
with:
|
|
||||||
persist-credentials: "false"
|
|
||||||
|
|
||||||
- name: Sync GHCS from Docker Scout
|
|
||||||
uses: docker/scout-action@7520205ff60037fdc436b40b6a1d1e55a839ec2d # v1.22.0
|
|
||||||
with:
|
|
||||||
organization: "searxng"
|
|
||||||
dockerhub-user: "${{ secrets.DOCKER_USER }}"
|
|
||||||
dockerhub-password: "${{ secrets.DOCKER_TOKEN }}"
|
|
||||||
image: "registry://ghcr.io/searxng/searxng:latest"
|
|
||||||
command: "cves"
|
|
||||||
sarif-file: "./scout.sarif"
|
|
||||||
exit-code: "false"
|
|
||||||
write-comment: "false"
|
|
||||||
|
|
||||||
- name: Upload SARIFs
|
|
||||||
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
|
||||||
with:
|
|
||||||
sarif_file: "./scout.sarif"
|
|
||||||
2
Makefile
2
Makefile
@@ -63,7 +63,7 @@ format: format.python format.shell
|
|||||||
# wrap ./manage script
|
# wrap ./manage script
|
||||||
|
|
||||||
MANAGE += weblate.translations.commit weblate.push.translations
|
MANAGE += weblate.translations.commit weblate.push.translations
|
||||||
MANAGE += data.all data.traits data.useragents data.gsa_useragents data.locales data.currencies
|
MANAGE += data.all data.traits data.useragents data.locales data.currencies
|
||||||
MANAGE += docs.html docs.live docs.gh-pages docs.prebuild docs.clean
|
MANAGE += docs.html docs.live docs.gh-pages docs.prebuild docs.clean
|
||||||
MANAGE += podman.build
|
MANAGE += podman.build
|
||||||
MANAGE += docker.build docker.buildx
|
MANAGE += docker.build docker.buildx
|
||||||
|
|||||||
521
client/simple/package-lock.json
generated
521
client/simple/package-lock.json
generated
@@ -15,9 +15,9 @@
|
|||||||
"swiped-events": "1.2.0"
|
"swiped-events": "1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.5.2",
|
"@biomejs/biome": "2.5.3",
|
||||||
"@types/node": "^26.1.0",
|
"@types/node": "^26.1.1",
|
||||||
"browserslist": "^4.28.4",
|
"browserslist": "^4.28.6",
|
||||||
"browserslist-to-esbuild": "^2.1.1",
|
"browserslist-to-esbuild": "^2.1.1",
|
||||||
"edge.js": "^6.5.1",
|
"edge.js": "^6.5.1",
|
||||||
"less": "^4.6.7",
|
"less": "^4.6.7",
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
"stylelint": "^17.14.0",
|
"stylelint": "^17.14.0",
|
||||||
"stylelint-config-standard-less": "^4.1.0",
|
"stylelint-config-standard-less": "^4.1.0",
|
||||||
"stylelint-prettier": "^5.0.3",
|
"stylelint-prettier": "^5.0.3",
|
||||||
"svgo": "^4.0.1",
|
"svgo": "^4.0.2",
|
||||||
"typescript": "~6.0.3",
|
"typescript": "~7.0.2",
|
||||||
"vite": "^8.1.3",
|
"vite": "^8.1.4",
|
||||||
"vite-bundle-analyzer": "^1.3.8"
|
"vite-bundle-analyzer": "^1.3.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -69,9 +69,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/biome": {
|
"node_modules/@biomejs/biome": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.3.tgz",
|
||||||
"integrity": "sha512-VQ3RCqr7JmDIX+w6stWYl+g/3bYofN3q2wDBHUKKc/c7i5QWrFKFBZYCYPWTE6agsUPMIZZe6/CMmVUfUAhkKA==",
|
"integrity": "sha512-MrJswFdei9EfDwwUy2tQrPDpK0AO+RmMFvBoaaJ6ayBc3sUbHdCE+XG5N8vp+5So41ZupZJQm0roHFFhMGVD7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT OR Apache-2.0",
|
"license": "MIT OR Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -85,20 +85,20 @@
|
|||||||
"url": "https://opencollective.com/biome"
|
"url": "https://opencollective.com/biome"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@biomejs/cli-darwin-arm64": "2.5.2",
|
"@biomejs/cli-darwin-arm64": "2.5.3",
|
||||||
"@biomejs/cli-darwin-x64": "2.5.2",
|
"@biomejs/cli-darwin-x64": "2.5.3",
|
||||||
"@biomejs/cli-linux-arm64": "2.5.2",
|
"@biomejs/cli-linux-arm64": "2.5.3",
|
||||||
"@biomejs/cli-linux-arm64-musl": "2.5.2",
|
"@biomejs/cli-linux-arm64-musl": "2.5.3",
|
||||||
"@biomejs/cli-linux-x64": "2.5.2",
|
"@biomejs/cli-linux-x64": "2.5.3",
|
||||||
"@biomejs/cli-linux-x64-musl": "2.5.2",
|
"@biomejs/cli-linux-x64-musl": "2.5.3",
|
||||||
"@biomejs/cli-win32-arm64": "2.5.2",
|
"@biomejs/cli-win32-arm64": "2.5.3",
|
||||||
"@biomejs/cli-win32-x64": "2.5.2"
|
"@biomejs/cli-win32-x64": "2.5.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-darwin-arm64": {
|
"node_modules/@biomejs/cli-darwin-arm64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.3.tgz",
|
||||||
"integrity": "sha512-e7P3P7EkwFc/KiX2AHw4YDLIBOMfG9CPCAwy52k5Bp0dfhkozx9hf6wCmIr2QeXy2XeccJ3V/Sg+hDmzYEqxSg==",
|
"integrity": "sha512-QhYP9muVQ0nUO5zztFuPbEwi4+94sJWVjaZds9aMi1l/KNZBiUjdiSUrGHsTaMGDXrYl+r4AS2sUKfgH3w+V3g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -113,9 +113,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-darwin-x64": {
|
"node_modules/@biomejs/cli-darwin-x64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.3.tgz",
|
||||||
"integrity": "sha512-ymzMvjC1Jg0b9K0D26ZdARqFQXs7MocfLC5FOCGfkC0Ss+ACUJkX5364ZM5nT4NLZanHRZNVrZEy+Ibwcvux/g==",
|
"integrity": "sha512-NC1Ss13UaW7QZX+y8j44bF7AP0jSJdBl6iRhe0MAkvaSqZy+mWg3GaXsrb+eSoHoGDBtaXWEbMVV0iVN2cZ7cQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -130,9 +130,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-arm64": {
|
"node_modules/@biomejs/cli-linux-arm64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.3.tgz",
|
||||||
"integrity": "sha512-t7sseOmqND57uUWTwlawU6BYj+J06T/9EkydzBhkrgw/FK3QVhjU2wsJR0frljrKZ0/I8A/rYw7284QgqjQfIQ==",
|
"integrity": "sha512-ksx1KWeyYW18ILL04msF/J4ZBtBDN33znYK8Z/aNv/vlBVxL9/g3mGP+omgHJKy4+KWbK87vcmmpmurfNjSgiA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -150,9 +150,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-arm64-musl": {
|
"node_modules/@biomejs/cli-linux-arm64-musl": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.3.tgz",
|
||||||
"integrity": "sha512-w+ANG0ZvTu9IeEg9QnstoOnk6L0fpwJifW6aHR18+cb5Z39bkANItYjAfMrnvce5tmMK+IQ6nPX7/kQFdam5iw==",
|
"integrity": "sha512-fccix0w6xp6csCXgxeC0dU/3ecgRQal0y+cv2SP9ajNlhe7Yrk2Ug7UDe2j9AT9ZDYitkXpvUKgZjjuoYeP4Vg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -170,9 +170,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-x64": {
|
"node_modules/@biomejs/cli-linux-x64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.3.tgz",
|
||||||
"integrity": "sha512-M/lOZrewzTCRDINbjhQ1gYYru37KlD3kJBQwwKCG0ckz5E9IZwIoJ3X0wBwRXA+yBDIwWUuPBHS67HzJY4dTfA==",
|
"integrity": "sha512-yMkJtilsgvILDcVkh187aVLTb64xYsrxYajx5kym+r1ULkO5HUOfu9AYKLGQbOVLwJtT2utNw7hhFNg+17mUYA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -190,9 +190,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-x64-musl": {
|
"node_modules/@biomejs/cli-linux-x64-musl": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.3.tgz",
|
||||||
"integrity": "sha512-VArNLAzND063tF+XY0yPyM+DyahpzOMzOAvb7qs259nhjJWRjvjZdssuA+Rfl+l07+NOesKZ0Xu2yFrXyBMtzw==",
|
"integrity": "sha512-O/yU9YKRUiHhmcjF2f38PSjseVk3G4VLWYc0G2HWpzdBVREV6G8IGWIVEFf7MFPfWIzNUIvPsEjeAZQIOgnLcQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -210,9 +210,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-win32-arm64": {
|
"node_modules/@biomejs/cli-win32-arm64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.3.tgz",
|
||||||
"integrity": "sha512-kbjFFKyZlzYnAuw7sRy5qDoFG6zrP40UK08oPQsWK0ct3NMnGSt+Bs1iviEEyEIP57N5MrykGXdO/wRiaR4lww==",
|
"integrity": "sha512-cX5z+GYwRcqEok0AH3KSfQGgqYd0Nomfp6Fbe1uiTtELE38hdH2k842wQ9wLNaF/JJ7r4rjJQ4VR+ce+fRmQbw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -227,9 +227,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-win32-x64": {
|
"node_modules/@biomejs/cli-win32-x64": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.3.tgz",
|
||||||
"integrity": "sha512-4InchVpdVmdkkkgjQqKpgvyu+VPnoF/7RPSw5YATgEVpt2j72wcCAeV5TwaE9ZGJUZWZn7v2CwSAj6CrMJEx8A==",
|
"integrity": "sha512-ExSaJWi4/u6+GXCszlSKpWSjKNbDseAYqqkCznsCsZ/4uidZ/BEqsCc5/3ctlq6dfIubdIIRSVLC/PG9xPl70Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1648,9 +1648,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "26.1.0",
|
"version": "26.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz",
|
||||||
"integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==",
|
"integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1670,6 +1670,346 @@
|
|||||||
"integrity": "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==",
|
"integrity": "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@typescript/typescript-aix-ppc64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-darwin-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-darwin-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-freebsd-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-freebsd-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-arm": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-loong64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-mips64el": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-ppc64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-riscv64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-s390x": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-linux-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-netbsd-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-netbsd-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-openbsd-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-openbsd-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-sunos-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-win32-arm64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript/typescript-win32-x64": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@zarrita/storage": {
|
"node_modules/@zarrita/storage": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.2.0.tgz",
|
||||||
@@ -1767,9 +2107,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.10.41",
|
"version": "2.10.43",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.41.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz",
|
||||||
"integrity": "sha512-WwS7MHhqGHHlaVsqRZnhvCEMS0owDX+SxRlve7JkuH7My1Ara3ZriTmCQupPfYjxMZ8I/tgxtJYr2t7taHaH4A==",
|
"integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1800,9 +2140,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.28.4",
|
"version": "4.28.6",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz",
|
||||||
"integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
|
"integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1820,10 +2160,10 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.10.38",
|
"baseline-browser-mapping": "^2.10.42",
|
||||||
"caniuse-lite": "^1.0.30001799",
|
"caniuse-lite": "^1.0.30001803",
|
||||||
"electron-to-chromium": "^1.5.376",
|
"electron-to-chromium": "^1.5.389",
|
||||||
"node-releases": "^2.0.48",
|
"node-releases": "^2.0.51",
|
||||||
"update-browserslist-db": "^1.2.3"
|
"update-browserslist-db": "^1.2.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1877,9 +2217,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001800",
|
"version": "1.0.30001805",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001800.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz",
|
||||||
"integrity": "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==",
|
"integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2295,9 +2635,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.385",
|
"version": "1.5.389",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.385.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz",
|
||||||
"integrity": "sha512-78sa/M08MNAYHQfjoWMvOlKQqZ0ElhSm/L5HNUc96VZ3b+KvDVnngFm8sYQy0XrhTRgAhggHr5abA7yTvRdo4Q==",
|
"integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -3430,9 +3770,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.50",
|
"version": "2.0.51",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
|
||||||
"integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==",
|
"integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4388,9 +4728,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/svgo": {
|
"node_modules/svgo": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.2.tgz",
|
||||||
"integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==",
|
"integrity": "sha512-ekx94z1rRc5LDi6oSUaeRnYhd0UOJxdtQCL2rF8xpWxD3TPAsISWOrxezqGovqS38GRZOdpDfvQe3ts6F7nsng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4561,17 +4901,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "6.0.3",
|
"version": "7.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz",
|
||||||
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
"integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc"
|
||||||
"tsserver": "bin/tsserver"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.17"
|
"node": ">=16.20.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@typescript/typescript-aix-ppc64": "7.0.2",
|
||||||
|
"@typescript/typescript-darwin-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-darwin-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-freebsd-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-freebsd-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-arm": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-loong64": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-mips64el": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-ppc64": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-riscv64": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-s390x": "7.0.2",
|
||||||
|
"@typescript/typescript-linux-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-netbsd-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-netbsd-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-openbsd-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-openbsd-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-sunos-x64": "7.0.2",
|
||||||
|
"@typescript/typescript-win32-arm64": "7.0.2",
|
||||||
|
"@typescript/typescript-win32-x64": "7.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
@@ -4642,16 +5003,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "8.1.3",
|
"version": "8.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz",
|
||||||
"integrity": "sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==",
|
"integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.32.0",
|
"lightningcss": "^1.32.0",
|
||||||
"picomatch": "^4.0.4",
|
"picomatch": "^4.0.5",
|
||||||
"postcss": "^8.5.16",
|
"postcss": "^8.5.16",
|
||||||
"rolldown": "~1.1.3",
|
"rolldown": "~1.1.4",
|
||||||
"tinyglobby": "^0.2.17"
|
"tinyglobby": "^0.2.17"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4730,9 +5091,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite/node_modules/picomatch": {
|
"node_modules/vite/node_modules/picomatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
|
||||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
"integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -29,9 +29,9 @@
|
|||||||
"swiped-events": "1.2.0"
|
"swiped-events": "1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.5.2",
|
"@biomejs/biome": "2.5.3",
|
||||||
"@types/node": "^26.1.0",
|
"@types/node": "^26.1.1",
|
||||||
"browserslist": "^4.28.4",
|
"browserslist": "^4.28.6",
|
||||||
"browserslist-to-esbuild": "^2.1.1",
|
"browserslist-to-esbuild": "^2.1.1",
|
||||||
"edge.js": "^6.5.1",
|
"edge.js": "^6.5.1",
|
||||||
"less": "^4.6.7",
|
"less": "^4.6.7",
|
||||||
@@ -41,9 +41,9 @@
|
|||||||
"stylelint": "^17.14.0",
|
"stylelint": "^17.14.0",
|
||||||
"stylelint-config-standard-less": "^4.1.0",
|
"stylelint-config-standard-less": "^4.1.0",
|
||||||
"stylelint-prettier": "^5.0.3",
|
"stylelint-prettier": "^5.0.3",
|
||||||
"svgo": "^4.0.1",
|
"svgo": "^4.0.2",
|
||||||
"typescript": "~6.0.3",
|
"typescript": "~7.0.2",
|
||||||
"vite": "^8.1.3",
|
"vite": "^8.1.4",
|
||||||
"vite-bundle-analyzer": "^1.3.8"
|
"vite-bundle-analyzer": "^1.3.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ const imageLoader = (resultElement: HTMLElement): void => {
|
|||||||
}, 1000) as unknown as number;
|
}, 1000) as unknown as number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const imageThumbnails: NodeListOf<HTMLImageElement> =
|
const imageThumbnails: NodeListOf<HTMLImageElement> = document.querySelectorAll<HTMLImageElement>(
|
||||||
document.querySelectorAll<HTMLImageElement>("#urls img.image_thumbnail");
|
"#urls img.image_thumbnail, img.thumbnail"
|
||||||
|
);
|
||||||
for (const thumbnail of imageThumbnails) {
|
for (const thumbnail of imageThumbnails) {
|
||||||
if (thumbnail.complete && thumbnail.naturalWidth === 0) {
|
if (thumbnail.complete && thumbnail.naturalWidth === 0) {
|
||||||
thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;
|
thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM ghcr.io/searxng/base:searxng-builder AS builder
|
FROM docker.io/searxng/base:searxng-builder AS builder
|
||||||
|
|
||||||
COPY ./requirements.txt ./requirements-server.txt ./
|
COPY ./requirements.txt ./requirements-server.txt ./
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ ARG CONTAINER_IMAGE_ORGANIZATION="searxng"
|
|||||||
ARG CONTAINER_IMAGE_NAME="searxng"
|
ARG CONTAINER_IMAGE_NAME="searxng"
|
||||||
|
|
||||||
FROM localhost/$CONTAINER_IMAGE_ORGANIZATION/$CONTAINER_IMAGE_NAME:builder AS builder
|
FROM localhost/$CONTAINER_IMAGE_ORGANIZATION/$CONTAINER_IMAGE_NAME:builder AS builder
|
||||||
FROM ghcr.io/searxng/base:searxng AS dist
|
FROM docker.io/searxng/base:searxng AS dist
|
||||||
|
|
||||||
COPY --chown=977:977 --from=builder /usr/local/searxng/.venv/ ./.venv/
|
COPY --chown=977:977 --from=builder /usr/local/searxng/.venv/ ./.venv/
|
||||||
COPY --chown=977:977 --from=builder /usr/local/searxng/searx/ ./searx/
|
COPY --chown=977:977 --from=builder /usr/local/searxng/searx/ ./searx/
|
||||||
|
|||||||
@@ -112,6 +112,15 @@ if [ "$(id -u)" -eq 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ENVs aliases
|
# ENVs aliases
|
||||||
export GRANIAN_PORT="${SEARXNG_PORT:-$GRANIAN_PORT}"
|
# https://github.com/searxng/searxng/issues/5934
|
||||||
|
case "${SEARXNG_PORT:-}" in
|
||||||
|
'') ;;
|
||||||
|
*[!0-9]*)
|
||||||
|
unset SEARXNG_PORT
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export GRANIAN_PORT="$SEARXNG_PORT"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
exec /usr/local/searxng/.venv/bin/granian searx.webapp:app
|
exec /usr/local/searxng/.venv/bin/granian searx.webapp:app
|
||||||
|
|||||||
@@ -283,12 +283,12 @@ container images are not officially supported):
|
|||||||
$ make container
|
$ make container
|
||||||
|
|
||||||
$ docker images
|
$ docker images
|
||||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
REPOSITORY TAG IMAGE ID SIZE
|
||||||
localhost/searxng/searxng 2025.8.1-3d96414 ... About a minute ago 183 MB
|
localhost/searxng/searxng 2026.6.19-93f66bfb4 ... 265 MB
|
||||||
localhost/searxng/searxng latest ... About a minute ago 183 MB
|
localhost/searxng/searxng latest ... 265 MB
|
||||||
localhost/searxng/searxng builder ... About a minute ago 524 MB
|
localhost/searxng/searxng builder ... 687 MB
|
||||||
ghcr.io/searxng/base searxng-builder ... 2 days ago 378 MB
|
docker.io/searxng/base searxng-builder ... 565 MB
|
||||||
ghcr.io/searxng/base searxng ... 2 days ago 42.2 MB
|
docker.io/searxng/base searxng ... 143 MB
|
||||||
|
|
||||||
Migrate from ``searxng-docker``
|
Migrate from ``searxng-docker``
|
||||||
===============================
|
===============================
|
||||||
|
|||||||
2
manage
2
manage
@@ -48,7 +48,7 @@ PATH="${PY_ENV}/bin:${REPO_ROOT}/node_modules/.bin:${GOROOT}/bin:${GOPATH}/bin:$
|
|||||||
|
|
||||||
PYOBJECTS="searx"
|
PYOBJECTS="searx"
|
||||||
PY_SETUP_EXTRAS='[test]'
|
PY_SETUP_EXTRAS='[test]'
|
||||||
GECKODRIVER_VERSION="v0.36.0"
|
GECKODRIVER_VERSION="v0.37.0"
|
||||||
# SPHINXOPTS=
|
# SPHINXOPTS=
|
||||||
BLACK_OPTIONS=("--target-version" "py311" "--line-length" "120" "--skip-string-normalization")
|
BLACK_OPTIONS=("--target-version" "py311" "--line-length" "120" "--skip-string-normalization")
|
||||||
BLACK_TARGETS=("--exclude" "(searx/static|searx/languages.py)" "--include" 'searxng.msg|\.pyi?$' "searx" "searxng_extra" "tests")
|
BLACK_TARGETS=("--exclude" "(searx/static|searx/languages.py)" "--include" 'searxng.msg|\.pyi?$' "searx" "searxng_extra" "tests")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ cov-core==1.15.0
|
|||||||
black==25.9.0
|
black==25.9.0
|
||||||
pylint==4.0.6
|
pylint==4.0.6
|
||||||
splinter==0.21.0
|
splinter==0.21.0
|
||||||
selenium==4.45.0
|
selenium==4.46.0
|
||||||
Sphinx==8.2.3;python_version <= "3.11"
|
Sphinx==8.2.3;python_version <= "3.11"
|
||||||
Sphinx==9.1.0; python_version > "3.11"
|
Sphinx==9.1.0; python_version > "3.11"
|
||||||
sphinx-issues==6.0.0
|
sphinx-issues==6.0.0
|
||||||
@@ -18,11 +18,11 @@ myst-parser==5.0.0
|
|||||||
linuxdoc==20260504
|
linuxdoc==20260504
|
||||||
aiounittest==1.5.0
|
aiounittest==1.5.0
|
||||||
yamllint==1.38.0
|
yamllint==1.38.0
|
||||||
wlc==2.0.0
|
wlc==2.1.0
|
||||||
coloredlogs==15.0.1
|
coloredlogs==15.0.1
|
||||||
docutils>=0.21.2;python_version <= "3.11"
|
docutils>=0.21.2;python_version <= "3.11"
|
||||||
docutils>=0.22.4; python_version > "3.11"
|
docutils>=0.22.4; python_version > "3.11"
|
||||||
parameterized==0.9.0
|
parameterized==0.9.0
|
||||||
granian[reload]==2.7.7
|
granian[reload]==2.7.9
|
||||||
basedpyright==1.39.8
|
basedpyright==1.39.9
|
||||||
types-lxml==2026.2.16
|
types-lxml==2026.2.16
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
granian==2.7.7
|
granian==2.7.9
|
||||||
granian[pname]==2.7.7
|
granian[pname]==2.7.9
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ sniffio==1.3.1
|
|||||||
valkey==6.1.1
|
valkey==6.1.1
|
||||||
markdown-it-py==4.2.0
|
markdown-it-py==4.2.0
|
||||||
msgspec==0.21.1
|
msgspec==0.21.1
|
||||||
typer==0.26.7
|
typer==0.27.0
|
||||||
isodate==0.7.2
|
isodate==0.7.2
|
||||||
whitenoise==6.12.0
|
whitenoise==6.12.0
|
||||||
typing-extensions==4.15.0
|
typing-extensions==4.16.0
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ from searx.engines import (
|
|||||||
from searx.network import get as http_get, post as http_post
|
from searx.network import get as http_get, post as http_post
|
||||||
from searx.exceptions import SearxEngineResponseException
|
from searx.exceptions import SearxEngineResponseException
|
||||||
from searx.utils import extr, gen_useragent
|
from searx.utils import extr, gen_useragent
|
||||||
|
from searx.data import ENGINE_TRAITS
|
||||||
|
from searx.enginelib.traits import EngineTraits
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
from searx.extended_types import SXNG_Response
|
from searx.extended_types import SXNG_Response
|
||||||
@@ -133,7 +135,9 @@ def google_complete(query: str, sxng_locale: str) -> list[str]:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
google_info: dict[str, t.Any] = google.get_google_info({'searxng_locale': sxng_locale}, engines['google'].traits)
|
data = ENGINE_TRAITS.get("google") or {}
|
||||||
|
traits = EngineTraits(**data)
|
||||||
|
google_info: dict[str, t.Any] = google.get_google_info({'searxng_locale': sxng_locale}, traits)
|
||||||
url = 'https://{subdomain}/complete/search?{args}'
|
url = 'https://{subdomain}/complete/search?{args}'
|
||||||
args = urlencode(
|
args = urlencode(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class ExpireCacheCfg(msgspec.Struct): # pylint: disable=too-few-public-methods
|
|||||||
MAXHOLD_TIME: int = 60 * 60 * 24 * 7 # 7 days
|
MAXHOLD_TIME: int = 60 * 60 * 24 * 7 # 7 days
|
||||||
"""Hold time (default in sec.), after which a value is removed from the cache."""
|
"""Hold time (default in sec.), after which a value is removed from the cache."""
|
||||||
|
|
||||||
MAINTENANCE_PERIOD: int = 60 * 60 # 2h
|
MAINTENANCE_PERIOD: int = 60 * 60 # 1h
|
||||||
"""Maintenance period in seconds / when :py:obj:`MAINTENANCE_MODE` is set to
|
"""Maintenance period in seconds / when :py:obj:`MAINTENANCE_MODE` is set to
|
||||||
``auto``."""
|
``auto``."""
|
||||||
|
|
||||||
@@ -458,12 +458,22 @@ class ExpireCacheSQLite(sqlitedb.SQLiteAppl, ExpireCache):
|
|||||||
# Before values are taken from the table, a maintenance interval may
|
# Before values are taken from the table, a maintenance interval may
|
||||||
# need to be carried out.
|
# need to be carried out.
|
||||||
self.maintenance()
|
self.maintenance()
|
||||||
sql = f"SELECT value FROM {table} WHERE key = ?"
|
sql = f"SELECT value, expire FROM {table} WHERE key = ?"
|
||||||
row = self.DB.execute(sql, (key,)).fetchone()
|
row = self.DB.execute(sql, (key,)).fetchone()
|
||||||
if row is None:
|
if row is None:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
return self.deserialize(row[0])
|
# Check if value is expired. It's possible that it's expired but has not
|
||||||
|
# yet been automatically deleted by the periodic maintenance
|
||||||
|
(value, expire) = row
|
||||||
|
now = time.time()
|
||||||
|
if expire < now:
|
||||||
|
# The record is deleted during the maintenance interval. Deleting
|
||||||
|
# the record at this point offers no advantage, as a SELECT
|
||||||
|
# statement must be executed for every cache.get request anyways.
|
||||||
|
return default
|
||||||
|
|
||||||
|
return self.deserialize(value)
|
||||||
|
|
||||||
def pairs(self, ctx: str) -> Iterator[tuple[str, typing.Any]]:
|
def pairs(self, ctx: str) -> Iterator[tuple[str, typing.Any]]:
|
||||||
"""Iterate over key/value pairs from table given by argument ``ctx``.
|
"""Iterate over key/value pairs from table given by argument ``ctx``.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ make data.all
|
|||||||
"""
|
"""
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
__all__ = ["ahmia_blacklist_loader", "gsa_useragents_loader", "data_dir", "get_cache"]
|
__all__ = ["ahmia_blacklist_loader", "data_dir", "get_cache"]
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import typing as t
|
import typing as t
|
||||||
@@ -63,7 +63,6 @@ lazy_globals = {
|
|||||||
"ENGINE_TRAITS": None,
|
"ENGINE_TRAITS": None,
|
||||||
"LOCALES": None,
|
"LOCALES": None,
|
||||||
"TRACKER_PATTERNS": TrackerPatternsDB(),
|
"TRACKER_PATTERNS": TrackerPatternsDB(),
|
||||||
"GSA_USER_AGENTS": None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data_json_files = {
|
data_json_files = {
|
||||||
@@ -106,24 +105,3 @@ def ahmia_blacklist_loader() -> list[str]:
|
|||||||
"""
|
"""
|
||||||
with open(data_dir / 'ahmia_blacklist.txt', encoding='utf-8') as f:
|
with open(data_dir / 'ahmia_blacklist.txt', encoding='utf-8') as f:
|
||||||
return f.read().split()
|
return f.read().split()
|
||||||
|
|
||||||
|
|
||||||
def gsa_useragents_loader() -> list[str]:
|
|
||||||
"""Load data from `gsa_useragents.txt` and return a list of user agents
|
|
||||||
suitable for Google. The user agents are fetched by::
|
|
||||||
|
|
||||||
searxng_extra/update/update_gsa_useragents.py
|
|
||||||
|
|
||||||
This function is used by :py:mod:`searx.engines.google`.
|
|
||||||
|
|
||||||
"""
|
|
||||||
data = lazy_globals["GSA_USER_AGENTS"]
|
|
||||||
if data is not None:
|
|
||||||
return data
|
|
||||||
|
|
||||||
log.debug("init searx.data.%s", "GSA_USER_AGENTS")
|
|
||||||
|
|
||||||
with open(data_dir / 'gsa_useragents.txt', encoding='utf-8') as f:
|
|
||||||
lazy_globals["GSA_USER_AGENTS"] = f.read().splitlines()
|
|
||||||
|
|
||||||
return lazy_globals["GSA_USER_AGENTS"]
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@ ENGINES_CACHE: ExpireCacheSQLite = ExpireCacheSQLite.build_cache(
|
|||||||
ExpireCacheCfg(
|
ExpireCacheCfg(
|
||||||
name="ENGINES_CACHE",
|
name="ENGINES_CACHE",
|
||||||
MAXHOLD_TIME=60 * 60 * 24 * 7, # 7 days
|
MAXHOLD_TIME=60 * 60 * 24 * 7, # 7 days
|
||||||
MAINTENANCE_PERIOD=60 * 60, # 2h
|
MAINTENANCE_PERIOD=60 * 60, # 1h
|
||||||
MAX_VALUE_LEN=1024 * 1024 * 1024, # 1MB
|
MAX_VALUE_LEN=1024 * 1024 * 1024, # 1MB
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def extract_video_data(video_block):
|
|||||||
published_date = None
|
published_date = None
|
||||||
if create_time:
|
if create_time:
|
||||||
try:
|
try:
|
||||||
published_date = datetime.strptime(create_time.strip(), "%Y-%m-%d")
|
published_date = datetime.fromisoformat(create_time.strip())
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
comments_elements = eval_xpath_getindex(entry, xpath_comment, 0, default=None)
|
comments_elements = eval_xpath_getindex(entry, xpath_comment, 0, default=None)
|
||||||
comments: str = "" if comments_elements is None else comments_elements.text
|
comments: str = "" if comments_elements is None else comments_elements.text
|
||||||
|
|
||||||
publishedDate = datetime.strptime(eval_xpath_getindex(entry, xpath_published, 0).text, "%Y-%m-%dT%H:%M:%SZ")
|
publishedDate = datetime.fromisoformat(eval_xpath_getindex(entry, xpath_published, 0).text.rstrip("Z"))
|
||||||
|
|
||||||
res.add(
|
res.add(
|
||||||
res.types.Paper(
|
res.types.Paper(
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ def parse_images(data):
|
|||||||
img_date = item.get("bdImgnewsDate")
|
img_date = item.get("bdImgnewsDate")
|
||||||
publishedDate = None
|
publishedDate = None
|
||||||
if img_date:
|
if img_date:
|
||||||
publishedDate = datetime.strptime(img_date, "%Y-%m-%d %H:%M")
|
publishedDate = datetime.fromisoformat(img_date)
|
||||||
results.append(
|
results.append(
|
||||||
{
|
{
|
||||||
"template": "images.html",
|
"template": "images.html",
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def response(resp):
|
|||||||
"url": 'https://www.bitchute.com/video/' + item['video_id'],
|
"url": 'https://www.bitchute.com/video/' + item['video_id'],
|
||||||
"content": html_to_text(item['description']),
|
"content": html_to_text(item['description']),
|
||||||
"author": item['channel']['channel_name'],
|
"author": item['channel']['channel_name'],
|
||||||
"publishedDate": datetime.strptime(item["date_published"], "%Y-%m-%dT%H:%M:%S.%fZ"),
|
"publishedDate": datetime.fromisoformat(item["date_published"].rstrip("Z")),
|
||||||
"length": item['duration'],
|
"length": item['duration'],
|
||||||
"views": item['view_count'],
|
"views": item['view_count'],
|
||||||
"thumbnail": item['thumbnail_url'],
|
"thumbnail": item['thumbnail_url'],
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
title=_remove_keyword_marker(result["Subject"]),
|
title=_remove_keyword_marker(result["Subject"]),
|
||||||
content=_remove_keyword_marker(result["Text"]),
|
content=_remove_keyword_marker(result["Text"]),
|
||||||
url=result["Url"],
|
url=result["Url"],
|
||||||
publishedDate=datetime.strptime(result["Published"], "%Y-%m-%d %H:%M:%S"),
|
publishedDate=datetime.fromisoformat(result["Published"]),
|
||||||
metadata=gettext.gettext("Posted by {author}").format(author=result["Author"]),
|
metadata=gettext.gettext("Posted by {author}").format(author=result["Author"]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from dateutil import parser
|
|||||||
|
|
||||||
from searx.exceptions import SearxEngineAPIException
|
from searx.exceptions import SearxEngineAPIException
|
||||||
from searx.result_types import EngineResults
|
from searx.result_types import EngineResults
|
||||||
|
from searx.utils import html_to_text
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
from searx.extended_types import SXNG_Response
|
from searx.extended_types import SXNG_Response
|
||||||
@@ -75,6 +76,7 @@ def request(query: str, params: "OnlineParams") -> None:
|
|||||||
"q": query,
|
"q": query,
|
||||||
"count": results_per_page,
|
"count": results_per_page,
|
||||||
"offset": (params["pageno"] - 1) * results_per_page,
|
"offset": (params["pageno"] - 1) * results_per_page,
|
||||||
|
"text_decorations": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Apply time filter if specified
|
# Apply time filter if specified
|
||||||
@@ -112,14 +114,19 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
res = EngineResults()
|
res = EngineResults()
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
|
|
||||||
for result in data.get("web", {}).get("results", []):
|
for result in (data.get("web") or {}).get("results", []):
|
||||||
|
thumbnail_obj = result.get("thumbnail")
|
||||||
|
thumbnail = ""
|
||||||
|
if thumbnail_obj and not thumbnail_obj.get("logo", False):
|
||||||
|
thumbnail = thumbnail_obj.get("src") or ""
|
||||||
|
|
||||||
res.add(
|
res.add(
|
||||||
res.types.MainResult(
|
res.types.MainResult(
|
||||||
url=result["url"],
|
url=result["url"],
|
||||||
title=result["title"],
|
title=html_to_text(result["title"]),
|
||||||
content=result.get("description", ""),
|
content=html_to_text(result.get("description", "")),
|
||||||
publishedDate=_extract_published_date(result.get("age")),
|
publishedDate=_extract_published_date(result.get("age")),
|
||||||
thumbnail=result.get("thumbnail", {}).get("src"),
|
thumbnail=thumbnail,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ def response(resp):
|
|||||||
|
|
||||||
publishedDate = None
|
publishedDate = None
|
||||||
if recipe['submissionDate']:
|
if recipe['submissionDate']:
|
||||||
publishedDate = datetime.strptime(result['recipe']['submissionDate'][:19], "%Y-%m-%dT%H:%M:%S")
|
publishedDate = datetime.fromisoformat(result['recipe']['submissionDate'][:19])
|
||||||
|
|
||||||
content = [
|
content = [
|
||||||
f"Schwierigkeitsstufe (1-3): {recipe['difficulty']}",
|
f"Schwierigkeitsstufe (1-3): {recipe['difficulty']}",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def response(resp):
|
|||||||
for item in search_res:
|
for item in search_res:
|
||||||
img = 'https://s3.thehackerblog.com/findthatmeme/' + item['image_path']
|
img = 'https://s3.thehackerblog.com/findthatmeme/' + item['image_path']
|
||||||
thumb = 'https://s3.thehackerblog.com/findthatmeme/thumb/' + item.get('thumbnail', '')
|
thumb = 'https://s3.thehackerblog.com/findthatmeme/thumb/' + item.get('thumbnail', '')
|
||||||
date = datetime.strptime(item["updated_at"].split("T")[0], "%Y-%m-%d")
|
date = datetime.fromisoformat(item["updated_at"].split("T")[0])
|
||||||
formatted_date = datetime.fromtimestamp(date.timestamp())
|
formatted_date = datetime.fromtimestamp(date.timestamp())
|
||||||
|
|
||||||
results.append(
|
results.append(
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ def response(resp: "SXNG_Response"):
|
|||||||
title=result["title"],
|
title=result["title"],
|
||||||
content=result["description"],
|
content=result["description"],
|
||||||
thumbnail=result["smallImageURL"],
|
thumbnail=result["smallImageURL"],
|
||||||
publishedDate=datetime.strptime(result["status_since"], "%Y-%m-%d %H:%M:%S"),
|
publishedDate=datetime.fromisoformat(result["status_since"]),
|
||||||
metadata=f"Rank: {result['rank']} || {result['episode_count']} episodes",
|
metadata=f"Rank: {result['rank']} || {result['episode_count']} episodes",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from searx.utils import (
|
|||||||
eval_xpath_getindex,
|
eval_xpath_getindex,
|
||||||
eval_xpath_list,
|
eval_xpath_list,
|
||||||
extract_text,
|
extract_text,
|
||||||
gen_gsa_useragent,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
@@ -197,7 +196,7 @@ def get_google_info(params: "OnlineParams", eng_traits: EngineTraits) -> dict[st
|
|||||||
# https://developers.google.com/custom-search/docs/xml_results_appendices#interfaceLanguages
|
# https://developers.google.com/custom-search/docs/xml_results_appendices#interfaceLanguages
|
||||||
|
|
||||||
# https://github.com/searxng/searxng/issues/2515#issuecomment-1607150817
|
# https://github.com/searxng/searxng/issues/2515#issuecomment-1607150817
|
||||||
ret_val["params"]["hl"] = f"{lang_code}-{country}"
|
ret_val["params"]["hl"] = f"{lang_code}"
|
||||||
|
|
||||||
# lr parameter:
|
# lr parameter:
|
||||||
# The lr (language restrict) parameter restricts search results to
|
# The lr (language restrict) parameter restricts search results to
|
||||||
@@ -268,7 +267,6 @@ def get_google_info(params: "OnlineParams", eng_traits: EngineTraits) -> dict[st
|
|||||||
# HTTP headers
|
# HTTP headers
|
||||||
|
|
||||||
ret_val["headers"]["Accept"] = "*/*"
|
ret_val["headers"]["Accept"] = "*/*"
|
||||||
ret_val["headers"]["User-Agent"] = gen_gsa_useragent()
|
|
||||||
|
|
||||||
# Cookies
|
# Cookies
|
||||||
|
|
||||||
|
|||||||
190
searx/engines/google_cse.py
Normal file
190
searx/engines/google_cse.py
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
"""Google Custom Search Engine"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import typing as t
|
||||||
|
from json import loads
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
from searx.enginelib import EngineCache
|
||||||
|
from searx.exceptions import SearxEngineAPIException, SearxEngineTooManyRequestsException
|
||||||
|
from searx.network import get
|
||||||
|
from searx.result_types import EngineResults, Result, MainResult, Image
|
||||||
|
|
||||||
|
from searx.engines.google import fetch_traits # pylint: disable=unused-import
|
||||||
|
from searx.engines.google import filter_mapping, get_google_info
|
||||||
|
|
||||||
|
if t.TYPE_CHECKING:
|
||||||
|
from searx.extended_types import SXNG_Response
|
||||||
|
from searx.search.processors import OnlineParams
|
||||||
|
|
||||||
|
about = {
|
||||||
|
"website": "https://www.google.com",
|
||||||
|
"wikidata_id": "Q2233943",
|
||||||
|
"official_api_documentation": "https://developers.google.com/custom-search/docs/element",
|
||||||
|
"use_official_api": False,
|
||||||
|
"require_api_key": False,
|
||||||
|
"results": "JSONP",
|
||||||
|
"description": "Platform for creating custom search engines based on Google Search.",
|
||||||
|
}
|
||||||
|
|
||||||
|
categories = ["general", "web"]
|
||||||
|
paging = True
|
||||||
|
max_page = 5
|
||||||
|
page_size = 20
|
||||||
|
time_range_support = True
|
||||||
|
language_support = True
|
||||||
|
safesearch = True
|
||||||
|
|
||||||
|
GoogleCategType = t.Literal["", "image"]
|
||||||
|
google_categ: GoogleCategType = ""
|
||||||
|
"""Google CSE category. Set to ``""`` for web search."""
|
||||||
|
|
||||||
|
CX = "partner-pub-8993703457585266:4862972284" # blackle.com
|
||||||
|
|
||||||
|
CACHE: EngineCache
|
||||||
|
|
||||||
|
|
||||||
|
def setup(engine_settings: dict[str, t.Any]) -> bool:
|
||||||
|
global CACHE # pylint: disable=global-statement
|
||||||
|
|
||||||
|
if google_categ not in t.get_args(GoogleCategType):
|
||||||
|
raise ValueError("invalid google cse category: %s" % google_categ)
|
||||||
|
|
||||||
|
CACHE = EngineCache(engine_settings["name"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _cse_token() -> dict[str, str]:
|
||||||
|
token: dict[str, str] = CACHE.get(CX)
|
||||||
|
if token:
|
||||||
|
return token
|
||||||
|
|
||||||
|
resp = get(f"https://www.google.com/cse/cse.js?cx={CX}", timeout=10)
|
||||||
|
if not resp.ok:
|
||||||
|
raise SearxEngineAPIException("failed to obtain cse token")
|
||||||
|
|
||||||
|
end = resp.text.rfind("});")
|
||||||
|
start = resp.text.rfind("({")
|
||||||
|
opts: dict[str, str] = loads(resp.text[start + 1 : end + 1])
|
||||||
|
|
||||||
|
cse_tok = opts.get("cse_token")
|
||||||
|
if not cse_tok:
|
||||||
|
raise SearxEngineAPIException("failed to obtain cse token")
|
||||||
|
|
||||||
|
exp = opts.get("exp")
|
||||||
|
token = {
|
||||||
|
"cse_tok": cse_tok,
|
||||||
|
"cselibv": opts.get("cselibVersion", ""),
|
||||||
|
"exp": ",".join(exp) if exp else "",
|
||||||
|
}
|
||||||
|
CACHE.set(CX, token, expire=3600)
|
||||||
|
return token
|
||||||
|
|
||||||
|
|
||||||
|
def _get_start_and_end_date_str(time_range: str) -> tuple[str, str]:
|
||||||
|
time_range_map = {"day": 1, "week": 7, "month": 30, "year": 365}
|
||||||
|
|
||||||
|
end_date = datetime.datetime.now()
|
||||||
|
start_date = end_date - datetime.timedelta(days=time_range_map[time_range])
|
||||||
|
|
||||||
|
return start_date.strftime("%Y%m%d"), end_date.strftime("%Y%m%d")
|
||||||
|
|
||||||
|
|
||||||
|
def request(query: str, params: "OnlineParams") -> None:
|
||||||
|
token = _cse_token()
|
||||||
|
|
||||||
|
google_info = get_google_info(params, traits)
|
||||||
|
info: dict[str, str] = google_info["params"]
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"rsz": "filtered_cse",
|
||||||
|
"num": str(page_size),
|
||||||
|
"hl": info["hl"],
|
||||||
|
"cselibv": token["cselibv"],
|
||||||
|
"cx": CX,
|
||||||
|
"q": query,
|
||||||
|
"safe": filter_mapping[params["safesearch"]],
|
||||||
|
"cse_tok": token["cse_tok"],
|
||||||
|
"callback": "_",
|
||||||
|
"rurl": "",
|
||||||
|
"searchtype": google_categ,
|
||||||
|
}
|
||||||
|
if params["time_range"]:
|
||||||
|
start_date, end_date = _get_start_and_end_date_str(params["time_range"])
|
||||||
|
args["sort"] = f"date:r:{start_date}:{end_date}"
|
||||||
|
|
||||||
|
if info.get("lr"):
|
||||||
|
args["lr"] = info["lr"]
|
||||||
|
if info.get("cr"):
|
||||||
|
args["cr"] = info["cr"]
|
||||||
|
if google_info["country"] not in (None, "ZZ"):
|
||||||
|
args["gl"] = google_info["country"]
|
||||||
|
if token["exp"]:
|
||||||
|
args["exp"] = token["exp"]
|
||||||
|
|
||||||
|
start = (params["pageno"] - 1) * page_size
|
||||||
|
if start:
|
||||||
|
args["start"] = str(start)
|
||||||
|
|
||||||
|
params["url"] = "https://cse.google.com/cse/element/v1?" + urlencode(args)
|
||||||
|
params["cookies"] = google_info["cookies"]
|
||||||
|
params["headers"].update(google_info["headers"])
|
||||||
|
params["headers"]["Referer"] = "https://cse.google.com/"
|
||||||
|
|
||||||
|
|
||||||
|
def response(resp: "SXNG_Response") -> EngineResults:
|
||||||
|
json_resp = resp.text[resp.text.find("{") : resp.text.rfind("}") + 1]
|
||||||
|
data = loads(json_resp)
|
||||||
|
|
||||||
|
# not the real types, but a sufficient approximation
|
||||||
|
item: dict[str, str]
|
||||||
|
error: dict[str, str | int]
|
||||||
|
|
||||||
|
if error := data.get("error"):
|
||||||
|
message = error.get("message", "unknown error")
|
||||||
|
if error.get("code") == 429:
|
||||||
|
raise SearxEngineTooManyRequestsException(message=f"google cse: {message}")
|
||||||
|
raise SearxEngineAPIException(f"google cse: {message}")
|
||||||
|
|
||||||
|
results = EngineResults()
|
||||||
|
|
||||||
|
for item in data.get("results", []):
|
||||||
|
|
||||||
|
res: Result | None
|
||||||
|
if google_categ == "":
|
||||||
|
res = web_item(item)
|
||||||
|
elif google_categ == "image":
|
||||||
|
res = img_item(item)
|
||||||
|
|
||||||
|
if res is not None:
|
||||||
|
results.add(res)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def web_item(item: dict[str, str]) -> MainResult | None:
|
||||||
|
url = item.get("unescapedUrl")
|
||||||
|
if not url:
|
||||||
|
return None
|
||||||
|
return MainResult(
|
||||||
|
url=url,
|
||||||
|
title=item.get("titleNoFormatting", ""),
|
||||||
|
content=item.get("contentNoFormatting", ""),
|
||||||
|
thumbnail=item.get("richSnippet", {}).get("cseThumbnail", {}).get("src", ""), # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def img_item(item: dict[str, str]) -> Image | None:
|
||||||
|
resolution = ""
|
||||||
|
if item.get("height") and item.get("width"):
|
||||||
|
resolution = f"{item['width']}x{item['height']}"
|
||||||
|
return Image(
|
||||||
|
url=item["originalContextUrl"],
|
||||||
|
title=item.get("titleNoFormatting", ""),
|
||||||
|
content=item.get("contentNoFormatting", ""),
|
||||||
|
img_src=item["unescapedUrl"],
|
||||||
|
thumbnail_src=item["tbUrl"],
|
||||||
|
resolution=resolution,
|
||||||
|
img_format=item["fileFormat"].split("/")[-1],
|
||||||
|
)
|
||||||
@@ -13,13 +13,12 @@ It seems to use Bing internally, as the image thumbnails are loaded from Bing.
|
|||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
from lxml import html
|
|
||||||
|
|
||||||
from searx.enginelib import EngineCache
|
from searx.enginelib import EngineCache
|
||||||
from searx.network import get
|
from searx.network import get
|
||||||
from searx.exceptions import SearxEngineAPIException, SearxEngineAccessDeniedException
|
from searx.exceptions import SearxEngineAPIException, SearxEngineAccessDeniedException
|
||||||
from searx.result_types import EngineResults
|
from searx.result_types import EngineResults
|
||||||
from searx.utils import eval_xpath, extract_text, gen_useragent
|
from searx.utils import gen_useragent
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
from searx.extended_types import SXNG_Response
|
from searx.extended_types import SXNG_Response
|
||||||
@@ -69,16 +68,17 @@ def _get_api_token(query: str) -> str:
|
|||||||
if cached_token:
|
if cached_token:
|
||||||
return cached_token
|
return cached_token
|
||||||
|
|
||||||
resp = get(f"{base_url}/search?q={query}", headers={"User-Agent": gen_useragent()})
|
resp = get(
|
||||||
|
f"{base_url}/search?q={query}", headers={"User-Agent": gen_useragent(), "Accept-Language": "en-US,en:q=0.9"}
|
||||||
|
)
|
||||||
if not resp.ok:
|
if not resp.ok:
|
||||||
raise SearxEngineAPIException("failed to obtain request token: invalid response code")
|
raise SearxEngineAPIException("failed to obtain request token: invalid response code")
|
||||||
|
|
||||||
doc = html.fromstring(resp.text)
|
token = resp.cookies["cacheft"]
|
||||||
token = extract_text(eval_xpath(doc, "//html/@data-cacheft"))
|
|
||||||
if not token:
|
if not token:
|
||||||
raise SearxEngineAPIException("failed to obtain request token: no token found")
|
raise SearxEngineAPIException("failed to obtain request token: no token found")
|
||||||
|
|
||||||
CACHE.set("token", token)
|
CACHE.set("token", token, expire=3 * 60)
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
|
||||||
@@ -92,8 +92,9 @@ def request(query: str, params: "OnlineParams") -> None:
|
|||||||
args["lang"] = params["searxng_locale"].split("-")[0]
|
args["lang"] = params["searxng_locale"].split("-")[0]
|
||||||
|
|
||||||
params["url"] = f"{api_url}/search/{heexy_categ}?{urlencode(args)}"
|
params["url"] = f"{api_url}/search/{heexy_categ}?{urlencode(args)}"
|
||||||
params["headers"]["X-Data-Cacheft"] = _get_api_token(query)
|
|
||||||
params["headers"]["Origin"] = api_url
|
params["headers"]["Origin"] = api_url
|
||||||
|
params["cookies"]["cacheft"] = _get_api_token(query)
|
||||||
|
|
||||||
|
|
||||||
def response(resp: "SXNG_Response"):
|
def response(resp: "SXNG_Response"):
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ def response(resp) -> EngineResults:
|
|||||||
|
|
||||||
published_date = None
|
published_date = None
|
||||||
try:
|
try:
|
||||||
published_date = datetime.strptime(entry["createdAt"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
published_date = datetime.fromisoformat(entry["createdAt"].rstrip("Z"))
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ def _result(video: dict[str, typing.Any], album_info: dict[str, typing.Any]):
|
|||||||
release_time = album_info.get("releaseTime", {}).get("value")
|
release_time = album_info.get("releaseTime", {}).get("value")
|
||||||
if release_time:
|
if release_time:
|
||||||
try:
|
try:
|
||||||
published_date = datetime.strptime(release_time, "%Y-%m-%d")
|
published_date = datetime.fromisoformat(release_time)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -42,15 +42,14 @@ To enable Kagi, add the following to the ``engines`` seciton of
|
|||||||
.. _Api Portal: https://help.kagi.com/kagi/api/overview.html
|
.. _Api Portal: https://help.kagi.com/kagi/api/overview.html
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
import html
|
|
||||||
|
|
||||||
from searx.extended_types import SXNG_Response
|
from searx.extended_types import SXNG_Response
|
||||||
from searx.result_types import EngineResults
|
from searx.result_types import EngineResults
|
||||||
from searx.utils import parse_duration_string
|
from searx.utils import html_to_text, parse_duration_string
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
from searx.search.processors import OnlineParams
|
from searx.search.processors import OnlineParams
|
||||||
@@ -77,7 +76,12 @@ kagi_categ: t.Literal["search", "images", "news", "videos"] = "search"
|
|||||||
base_url = "https://kagi.com"
|
base_url = "https://kagi.com"
|
||||||
|
|
||||||
safe_search_map = {0: False, 1: True, 2: True}
|
safe_search_map = {0: False, 1: True, 2: True}
|
||||||
time_range_to_days_map: dict[TimeRangeType, int] = {"day": 1, "week": 7, "month": 30, "year": 365}
|
time_range_to_days_map: dict[TimeRangeType, int] = {
|
||||||
|
"day": 1,
|
||||||
|
"week": 7,
|
||||||
|
"month": 30,
|
||||||
|
"year": 365,
|
||||||
|
}
|
||||||
|
|
||||||
api_key = ""
|
api_key = ""
|
||||||
"""Kagi API key. Required for using this engine."""
|
"""Kagi API key. Required for using this engine."""
|
||||||
@@ -135,9 +139,13 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
|
|
||||||
if kagi_categ in ("images", "videos"):
|
if kagi_categ in ("images", "videos"):
|
||||||
# the JSON key is "image" for "images" and "video" for "videos"
|
# the JSON key is "image" for "images" and "video" for "videos"
|
||||||
json_results = json_data["data"][kagi_categ[:-1]]
|
json_results = json_data["data"].get(kagi_categ[:-1])
|
||||||
else:
|
else:
|
||||||
json_results = json_data["data"][kagi_categ]
|
json_results = json_data["data"].get(kagi_categ)
|
||||||
|
|
||||||
|
# if no results were found, the response doesn't contain the results field
|
||||||
|
if not json_results:
|
||||||
|
return res
|
||||||
|
|
||||||
for result in json_results:
|
for result in json_results:
|
||||||
published_date: datetime | None = None
|
published_date: datetime | None = None
|
||||||
@@ -148,8 +156,8 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
res.add(
|
res.add(
|
||||||
res.types.MainResult(
|
res.types.MainResult(
|
||||||
url=result["url"],
|
url=result["url"],
|
||||||
title=html.unescape(result["title"]),
|
title=html_to_text(result.get("title", "no title available")),
|
||||||
content=html.unescape(result["snippet"]),
|
content=html_to_text(result.get("snippet", "")),
|
||||||
thumbnail=result.get("image", {}).get("url") or "",
|
thumbnail=result.get("image", {}).get("url") or "",
|
||||||
publishedDate=published_date,
|
publishedDate=published_date,
|
||||||
)
|
)
|
||||||
@@ -158,15 +166,15 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
res.add(
|
res.add(
|
||||||
res.types.Image(
|
res.types.Image(
|
||||||
url=result["url"],
|
url=result["url"],
|
||||||
title=html.unescape(result.get("title")),
|
title=html_to_text(result.get("title", "no title available")),
|
||||||
img_src=result.get("image", {}).get("url"),
|
img_src=result.get("image", {}).get("url"),
|
||||||
resolution=f"{result['image']['width']}x{result['image']['height']}",
|
resolution=f"{result.get('image', {}).get('width')}x{result.get('image', {}).get('height')}",
|
||||||
thumbnail_src=result.get("props", {}).get("thumbnail", {}).get("url"),
|
thumbnail_src=result.get("props", {}).get("thumbnail", {}).get("url"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif kagi_categ == "videos":
|
elif kagi_categ == "videos":
|
||||||
length: timedelta | None = None
|
length: timedelta | None = None
|
||||||
if result["props"].get("duration"):
|
if result.get("props", {}).get("duration"):
|
||||||
length = parse_duration_string(result["props"]["duration"])
|
length = parse_duration_string(result["props"]["duration"])
|
||||||
|
|
||||||
res.add(
|
res.add(
|
||||||
@@ -174,11 +182,11 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
{
|
{
|
||||||
"template": "videos.html",
|
"template": "videos.html",
|
||||||
"url": result["url"],
|
"url": result["url"],
|
||||||
"title": html.unescape(result["title"]),
|
"title": html_to_text(result.get("title", "no title available")),
|
||||||
"content": html.unescape(result["snippet"]),
|
"content": html_to_text(result.get("snippet", "")),
|
||||||
"thumbnail": result.get("image", {}).get("url"),
|
"thumbnail": result.get("image", {}).get("url"),
|
||||||
"publishedDate": published_date,
|
"publishedDate": published_date,
|
||||||
"author": result["props"].get("creator_name"),
|
"author": result.get("props", {}).get("creator_name"),
|
||||||
"length": length,
|
"length": length,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ def _get_communities(json):
|
|||||||
'title': result['community']['title'],
|
'title': result['community']['title'],
|
||||||
'content': markdown_to_text(result['community'].get('description', '')),
|
'content': markdown_to_text(result['community'].get('description', '')),
|
||||||
'thumbnail': result['community'].get('icon', result['community'].get('banner')),
|
'thumbnail': result['community'].get('icon', result['community'].get('banner')),
|
||||||
'publishedDate': datetime.strptime(counts['published'][:19], '%Y-%m-%dT%H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(counts['published'][:19]),
|
||||||
'metadata': metadata,
|
'metadata': metadata,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -141,7 +141,7 @@ def _get_posts(json):
|
|||||||
'title': result['post']['name'],
|
'title': result['post']['name'],
|
||||||
'content': content,
|
'content': content,
|
||||||
'thumbnail': thumbnail,
|
'thumbnail': thumbnail,
|
||||||
'publishedDate': datetime.strptime(result['post']['published'][:19], '%Y-%m-%dT%H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(result['post']['published'][:19]),
|
||||||
'metadata': metadata,
|
'metadata': metadata,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -170,7 +170,7 @@ def _get_comments(json):
|
|||||||
'url': result['comment']['ap_id'],
|
'url': result['comment']['ap_id'],
|
||||||
'title': result['post']['name'],
|
'title': result['post']['name'],
|
||||||
'content': markdown_to_text(result['comment']['content']),
|
'content': markdown_to_text(result['comment']['content']),
|
||||||
'publishedDate': datetime.strptime(result['comment']['published'][:19], '%Y-%m-%dT%H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(result['comment']['published'][:19]),
|
||||||
'metadata': metadata,
|
'metadata': metadata,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ def response(resp):
|
|||||||
'title': result['username'] + f" ({result['followers_count']} followers)",
|
'title': result['username'] + f" ({result['followers_count']} followers)",
|
||||||
'content': result['note'],
|
'content': result['note'],
|
||||||
'thumbnail': result.get('avatar'),
|
'thumbnail': result.get('avatar'),
|
||||||
'publishedDate': datetime.strptime(result['created_at'][:10], "%Y-%m-%d"),
|
'publishedDate': datetime.fromisoformat(result['created_at'][:10]),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
elif mastodon_type == "hashtags":
|
elif mastodon_type == "hashtags":
|
||||||
|
|||||||
66
searx/engines/neocities.py
Normal file
66
searx/engines/neocities.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
"""Neocities_ is open source software for creating blogs.
|
||||||
|
|
||||||
|
.. _Neocities : https://github.com/neocities/neocities
|
||||||
|
"""
|
||||||
|
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
import typing as t
|
||||||
|
|
||||||
|
from lxml import html
|
||||||
|
|
||||||
|
from searx.utils import eval_xpath, eval_xpath_list, extract_text
|
||||||
|
from searx.result_types import EngineResults
|
||||||
|
|
||||||
|
if t.TYPE_CHECKING:
|
||||||
|
from extended_types import SXNG_Response
|
||||||
|
from search.processors import OnlineParams
|
||||||
|
|
||||||
|
|
||||||
|
# Engine metadata
|
||||||
|
about = {
|
||||||
|
"website": "https://neocities.org/",
|
||||||
|
"wikidata_id": "Q17071099",
|
||||||
|
"official_api_documentation": None,
|
||||||
|
"use_official_api": False,
|
||||||
|
"require_api_key": False,
|
||||||
|
"results": "HTML",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Engine configuration
|
||||||
|
categories = ["general", "blogs"]
|
||||||
|
paging = True
|
||||||
|
|
||||||
|
# Search URL
|
||||||
|
base_url = "https://neocities.org"
|
||||||
|
|
||||||
|
results_xpath = "//div[@class='result-item']"
|
||||||
|
url_xpath = './/div[@class="result-url"]/a/@href'
|
||||||
|
title_xpath = './/h3[@class="result-title"]/a/text()'
|
||||||
|
content_xpath = './/p[@class="result-snippet"]//text()'
|
||||||
|
screenshot_xpath = './/a[@class="result-screenshot"]/img/@src'
|
||||||
|
|
||||||
|
|
||||||
|
def request(query: str, params: "OnlineParams") -> None:
|
||||||
|
query_params: dict[str, t.Any] = {"q": query}
|
||||||
|
if params['pageno'] > 1:
|
||||||
|
offset = (params["pageno"] - 1) * 100
|
||||||
|
query_params["start"] = offset
|
||||||
|
params["url"] = f"{base_url}/search?{urlencode(query_params)}"
|
||||||
|
|
||||||
|
|
||||||
|
def response(resp: "SXNG_Response") -> EngineResults:
|
||||||
|
results = EngineResults()
|
||||||
|
dom = html.fromstring(resp.text)
|
||||||
|
|
||||||
|
for result in eval_xpath_list(dom, results_xpath):
|
||||||
|
results.add(
|
||||||
|
results.types.MainResult(
|
||||||
|
url=extract_text(eval_xpath(result, url_xpath)),
|
||||||
|
title=extract_text(eval_xpath(result, title_xpath)) or "",
|
||||||
|
content=extract_text(eval_xpath(result, content_xpath)) or "",
|
||||||
|
thumbnail=base_url + (extract_text(eval_xpath(result, screenshot_xpath)) or ""),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
@@ -44,7 +44,7 @@ def response(resp) -> EngineResults:
|
|||||||
|
|
||||||
cve_id = item["cve"]["id"]
|
cve_id = item["cve"]["id"]
|
||||||
description = item["cve"]["descriptions"][0]["value"]
|
description = item["cve"]["descriptions"][0]["value"]
|
||||||
date = datetime.strptime(item["cve"]["published"], "%Y-%m-%dT%H:%M:%S.%f")
|
date = datetime.fromisoformat(item["cve"]["published"])
|
||||||
|
|
||||||
# Extract severity (Low, Medium, High, or Critical) and CVSS score, if available
|
# Extract severity (Low, Medium, High, or Critical) and CVSS score, if available
|
||||||
info = item["cve"].get("metrics", {}).get("cvssMetricV31", [{}])[0].get("cvssData", {})
|
info = item["cve"].get("metrics", {}).get("cvssMetricV31", [{}])[0].get("cvssData", {})
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ def response(resp):
|
|||||||
release_time = item["release_time"]
|
release_time = item["release_time"]
|
||||||
duration = item["duration"]
|
duration = item["duration"]
|
||||||
|
|
||||||
release_date = datetime.strptime(release_time.split("T")[0], "%Y-%m-%d")
|
release_date = datetime.fromisoformat(release_time.split("T")[0])
|
||||||
formatted_date = datetime.fromtimestamp(release_date.timestamp())
|
formatted_date = datetime.fromtimestamp(release_date.timestamp())
|
||||||
|
|
||||||
url = f"https://odysee.com/{name}:{claim_id}"
|
url = f"https://odysee.com/{name}:{claim_id}"
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ def response(resp: "SXNG_Response"):
|
|||||||
title=result["title"],
|
title=result["title"],
|
||||||
content=result["description"],
|
content=result["description"],
|
||||||
thumbnail=result["image_url"],
|
thumbnail=result["image_url"],
|
||||||
publishedDate=datetime.strptime(result["created_at"], "%Y-%m-%d %H:%M:%S"),
|
publishedDate=datetime.fromisoformat(result["created_at"]),
|
||||||
metadata=" | ".join(metadata),
|
metadata=" | ".join(metadata),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ def response(resp):
|
|||||||
results.append(
|
results.append(
|
||||||
{
|
{
|
||||||
'template': 'images.html',
|
'template': 'images.html',
|
||||||
'url': _clean_url(f"{about['website']}/images/{result['objectID']}"),
|
'url': _clean_url(f"{pdia_base_url}/images/{result['objectID']}"),
|
||||||
'img_src': _clean_url(base_image_url),
|
'img_src': _clean_url(base_image_url),
|
||||||
'thumbnail_src': _clean_url(base_image_url + THUMBNAIL_SUFFIX),
|
'thumbnail_src': _clean_url(base_image_url + THUMBNAIL_SUFFIX),
|
||||||
'title': f"{result['title'].strip()} by {result['artist']} {result.get('displayYear', '')}",
|
'title': f"{result['title'].strip()} by {result['artist']} {result.get('displayYear', '')}",
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ def parse_news_uchq(data):
|
|||||||
results = []
|
results = []
|
||||||
for item in data.get('feed', []):
|
for item in data.get('feed', []):
|
||||||
try:
|
try:
|
||||||
published_date = datetime.strptime(item.get('time'), "%Y-%m-%d")
|
published_date = datetime.fromisoformat(item.get('time'))
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
# Sometime Quark will return non-standard format like "1天前", set published_date as None
|
# Sometime Quark will return non-standard format like "1天前", set published_date as None
|
||||||
published_date = None
|
published_date = None
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ from urllib.parse import urlencode
|
|||||||
import babel
|
import babel
|
||||||
from flask_babel import gettext # pyright: ignore[reportUnknownVariableType]
|
from flask_babel import gettext # pyright: ignore[reportUnknownVariableType]
|
||||||
|
|
||||||
|
from searx.enginelib import EngineCache
|
||||||
from searx.enginelib.traits import EngineTraits
|
from searx.enginelib.traits import EngineTraits
|
||||||
from searx.exceptions import (
|
from searx.exceptions import (
|
||||||
SearxEngineAccessDeniedException,
|
SearxEngineAccessDeniedException,
|
||||||
@@ -105,9 +106,19 @@ qwant_news_locales = [
|
|||||||
]
|
]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
base_url = "https://www.qwant.com"
|
||||||
api_url = "https://api.qwant.com/v3/search/"
|
api_url = "https://api.qwant.com/v3/search/"
|
||||||
"""URL of Qwant's API (JSON)"""
|
"""URL of Qwant's API (JSON)"""
|
||||||
|
|
||||||
|
CACHE: EngineCache
|
||||||
|
"""Cache for storing the ``datadome`` cookie."""
|
||||||
|
|
||||||
|
|
||||||
|
def setup(engine_settings: dict[str, t.Any]) -> bool:
|
||||||
|
global CACHE # pylint: disable=global-statement
|
||||||
|
CACHE = EngineCache(engine_settings["name"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def request(query: str, params: "OnlineParams") -> None:
|
def request(query: str, params: "OnlineParams") -> None:
|
||||||
"""Qwant search request"""
|
"""Qwant search request"""
|
||||||
@@ -129,24 +140,29 @@ def request(query: str, params: "OnlineParams") -> None:
|
|||||||
"tgp": test_group_value,
|
"tgp": test_group_value,
|
||||||
"device": "desktop",
|
"device": "desktop",
|
||||||
"safesearch": params["safesearch"],
|
"safesearch": params["safesearch"],
|
||||||
"display": True,
|
# True would be encoded to "True", instead of "true", which makes the request
|
||||||
"llm": True,
|
# easier to detect and block
|
||||||
|
"displayed": "true",
|
||||||
|
"llm": "true",
|
||||||
}
|
}
|
||||||
|
|
||||||
# shuffle query parameters to be harder to fingerprint
|
|
||||||
args = list(args.items())
|
|
||||||
random.shuffle(args)
|
|
||||||
args = dict(args)
|
|
||||||
|
|
||||||
params["raise_for_httperror"] = False
|
params["raise_for_httperror"] = False
|
||||||
|
|
||||||
params["url"] = f"{api_url}{qwant_categ}?{urlencode(args)}"
|
params["url"] = f"{api_url}{qwant_categ}?{urlencode(args)}"
|
||||||
|
|
||||||
|
params["cookies"]["datadome"] = CACHE.get("datadome")
|
||||||
|
params["headers"].update({"Accept": "application/json", "Referer": f"{base_url}/", "Origin": base_url})
|
||||||
|
|
||||||
|
|
||||||
def response(resp: "SXNG_Response") -> EngineResults:
|
def response(resp: "SXNG_Response") -> EngineResults:
|
||||||
"""Parse results from Qwant's API"""
|
"""Parse results from Qwant's API"""
|
||||||
# pylint: disable=too-many-locals, too-many-branches, too-many-statements
|
# pylint: disable=too-many-locals, too-many-branches, too-many-statements
|
||||||
|
|
||||||
|
# cache datadome cookie - changes on each request
|
||||||
|
datadome = resp.cookies.get("datadome")
|
||||||
|
if datadome:
|
||||||
|
CACHE.set("datadome", datadome)
|
||||||
|
|
||||||
res = EngineResults()
|
res = EngineResults()
|
||||||
|
|
||||||
# Try to load JSON result
|
# Try to load JSON result
|
||||||
@@ -163,8 +179,8 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
error_code = data.get("error_code")
|
error_code = data.get("error_code")
|
||||||
if error_code == 24:
|
if error_code == 24:
|
||||||
raise SearxEngineTooManyRequestsException()
|
raise SearxEngineTooManyRequestsException()
|
||||||
if search_results.get("data", {}).get("error_data", {}).get("captchaUrl") is not None:
|
if search_results.get("url") is not None:
|
||||||
raise SearxEngineCaptchaException()
|
raise SearxEngineCaptchaException(suspended_time=0)
|
||||||
if resp.status_code == 403:
|
if resp.status_code == 403:
|
||||||
raise SearxEngineAccessDeniedException()
|
raise SearxEngineAccessDeniedException()
|
||||||
msg = ",".join(data.get("message", ["unknown"]))
|
msg = ",".join(data.get("message", ["unknown"]))
|
||||||
@@ -302,7 +318,7 @@ def fetch_traits(engine_traits: EngineTraits):
|
|||||||
from searx.utils import extr
|
from searx.utils import extr
|
||||||
|
|
||||||
resp = get(
|
resp = get(
|
||||||
about["website"], # pyright: ignore[reportArgumentType]
|
base_url, # pyright: ignore[reportArgumentType]
|
||||||
timeout=5,
|
timeout=5,
|
||||||
)
|
)
|
||||||
if not resp.ok:
|
if not resp.ok:
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ def response(resp):
|
|||||||
title = extract_text(result_dom.xpath(title_xpath))
|
title = extract_text(result_dom.xpath(title_xpath))
|
||||||
p_date = extract_text(result_dom.xpath(published_date))
|
p_date = extract_text(result_dom.xpath(published_date))
|
||||||
# fix offset date for line 644 webapp.py check
|
# fix offset date for line 644 webapp.py check
|
||||||
fixed_date = datetime.strptime(p_date, '%Y-%m-%dT%H:%M:%S%z')
|
fixed_date = datetime.fromisoformat(p_date)
|
||||||
earned = extract_text(result_dom.xpath(earned_xpath))
|
earned = extract_text(result_dom.xpath(earned_xpath))
|
||||||
views = extract_text(result_dom.xpath(views_xpath))
|
views = extract_text(result_dom.xpath(views_xpath))
|
||||||
rumbles = extract_text(result_dom.xpath(rumbles_xpath))
|
rumbles = extract_text(result_dom.xpath(rumbles_xpath))
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
|
|
||||||
publishedDate: datetime | None
|
publishedDate: datetime | None
|
||||||
if "pubDate" in result:
|
if "pubDate" in result:
|
||||||
publishedDate = datetime.strptime(result["pubDate"], "%Y-%m-%d")
|
publishedDate = datetime.fromisoformat(result["pubDate"])
|
||||||
else:
|
else:
|
||||||
publishedDate = None
|
publishedDate = None
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ def _parse_date(text):
|
|||||||
date_match = re.search(r"(\d{4}-\d{1,2}-\d{1,2})", text)
|
date_match = re.search(r"(\d{4}-\d{1,2}-\d{1,2})", text)
|
||||||
if date_match:
|
if date_match:
|
||||||
try:
|
try:
|
||||||
return datetime.strptime(date_match.group(1), "%Y-%m-%d")
|
y, m, d = date_match.group(1).split("-")
|
||||||
|
return datetime(year=int(y), month=int(m), day=int(d))
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ def response(resp):
|
|||||||
published_date = None
|
published_date = None
|
||||||
if entry.get("date") and entry.get("duration"):
|
if entry.get("date") and entry.get("duration"):
|
||||||
try:
|
try:
|
||||||
published_date = datetime.strptime(entry['date'], "%Y-%m-%d")
|
published_date = datetime.fromisoformat(entry['date'])
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
published_date = None
|
published_date = None
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ def response(resp: "SXNG_Response") -> EngineResults:
|
|||||||
return str(record.get(k, ""))
|
return str(record.get(k, ""))
|
||||||
|
|
||||||
for record in json_data["records"]:
|
for record in json_data["records"]:
|
||||||
published = datetime.strptime(record["publicationDate"], "%Y-%m-%d")
|
published = datetime.fromisoformat(record["publicationDate"])
|
||||||
authors: list[str] = [" ".join(author["creator"].split(", ")[::-1]) for author in record["creators"]]
|
authors: list[str] = [" ".join(author["creator"].split(", ")[::-1]) for author in record["creators"]]
|
||||||
|
|
||||||
pdf_url = ""
|
pdf_url = ""
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ def _story(item):
|
|||||||
return {
|
return {
|
||||||
'title': item['title'],
|
'title': item['title'],
|
||||||
'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
|
'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
|
||||||
'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(item['date'][:19]),
|
||||||
'content': item.get('firstSentence'),
|
'content': item.get('firstSentence'),
|
||||||
'url': item['shareURL'] if use_source_url else item['detailsweb'],
|
'url': item['shareURL'] if use_source_url else item['detailsweb'],
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ def _video(item):
|
|||||||
'template': 'videos.html',
|
'template': 'videos.html',
|
||||||
'title': title,
|
'title': title,
|
||||||
'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
|
'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
|
||||||
'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(item['date'][:19]),
|
||||||
'content': item.get('firstSentence', ''),
|
'content': item.get('firstSentence', ''),
|
||||||
'iframe_src': video_url,
|
'iframe_src': video_url,
|
||||||
'url': url,
|
'url': url,
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ def _obtain_session_code() -> str:
|
|||||||
if not code:
|
if not code:
|
||||||
raise SearxEngineAPIException("failed to obtain session code")
|
raise SearxEngineAPIException("failed to obtain session code")
|
||||||
|
|
||||||
CACHE.set("session", code, expire=60 * 24 * 60) # cookie is valid for two months
|
CACHE.set("session", code, expire=60 * 24 * 60 * 60) # cookie is valid for two months
|
||||||
return code
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ def parse_tineye_match(match_json):
|
|||||||
|
|
||||||
crawl_date = backlink_json.get("crawl_date")
|
crawl_date = backlink_json.get("crawl_date")
|
||||||
if crawl_date:
|
if crawl_date:
|
||||||
crawl_date = datetime.strptime(crawl_date, '%Y-%m-%d')
|
crawl_date = datetime.fromisoformat(crawl_date)
|
||||||
else:
|
else:
|
||||||
crawl_date = datetime.min
|
crawl_date = datetime.min
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ def response(resp):
|
|||||||
'title': title,
|
'title': title,
|
||||||
'content': html_to_text(result['content']),
|
'content': html_to_text(result['content']),
|
||||||
'thumbnail': thumbnail,
|
'thumbnail': thumbnail,
|
||||||
'publishedDate': datetime.strptime(result['created_at'], '%Y-%m-%d %H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(result['created_at']),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from dateutil import parser
|
|||||||
|
|
||||||
from searx.exceptions import SearxEngineAPIException
|
from searx.exceptions import SearxEngineAPIException
|
||||||
from searx.network import get
|
from searx.network import get
|
||||||
from searx.utils import html_to_text
|
from searx.utils import gen_useragent, html_to_text
|
||||||
from searx.result_types import EngineResults
|
from searx.result_types import EngineResults
|
||||||
|
|
||||||
if t.TYPE_CHECKING:
|
if t.TYPE_CHECKING:
|
||||||
@@ -52,7 +52,7 @@ def _obtain_x_sid() -> tuple[str, str]:
|
|||||||
The header key is usually called `x-sid-{UUIDv4}`, and the value is
|
The header key is usually called `x-sid-{UUIDv4}`, and the value is
|
||||||
usually a plain UUIDv4 (but a different one than in the header key).
|
usually a plain UUIDv4 (but a different one than in the header key).
|
||||||
"""
|
"""
|
||||||
resp = get(f"{api_url}/revcontent/embed.js")
|
resp = get(f"{api_url}/revcontent/embed.js", headers={"User-Agent": gen_useragent()})
|
||||||
if not resp.ok:
|
if not resp.ok:
|
||||||
raise SearxEngineAPIException("failed to obtain request x-sid token")
|
raise SearxEngineAPIException("failed to obtain request x-sid token")
|
||||||
|
|
||||||
@@ -89,12 +89,14 @@ def request(query: str, params: "OnlineParams") -> None:
|
|||||||
params["url"] = f"{api_url}/Search/Web?{urlencode(args)}"
|
params["url"] = f"{api_url}/Search/Web?{urlencode(args)}"
|
||||||
|
|
||||||
x_sid_header, x_sid_value = _obtain_x_sid()
|
x_sid_header, x_sid_value = _obtain_x_sid()
|
||||||
params["headers"] = {
|
params["headers"].update(
|
||||||
x_sid_header: x_sid_value,
|
{
|
||||||
# required - we send a random longitude and latitude instead of the actual user location
|
x_sid_header: x_sid_value,
|
||||||
'x-lon': str(random.random() * 90),
|
# required - we send a random longitude and latitude instead of the actual user location
|
||||||
'x-lat': str(random.random() * 90),
|
"x-lon": str(round(random.random() * 90, 4)),
|
||||||
}
|
"x-lat": str(round(random.random() * 90, 4)),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def response(resp: "SXNG_Response"):
|
def response(resp: "SXNG_Response"):
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ def response(resp):
|
|||||||
'img_src': result['path'],
|
'img_src': result['path'],
|
||||||
'thumbnail_src': result['thumbs']['small'],
|
'thumbnail_src': result['thumbs']['small'],
|
||||||
'resolution': result['resolution'].replace('x', ' x '),
|
'resolution': result['resolution'].replace('x', ' x '),
|
||||||
'publishedDate': datetime.strptime(result['created_at'], '%Y-%m-%d %H:%M:%S'),
|
'publishedDate': datetime.fromisoformat(result['created_at']),
|
||||||
'img_format': result['file_type'],
|
'img_format': result['file_type'],
|
||||||
'filesize': humanize_bytes(result['file_size']),
|
'filesize': humanize_bytes(result['file_size']),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,12 @@ def _normalize_url_fields(result: "Result | LegacyResult"):
|
|||||||
result.parsed_url = urllib.parse.urlparse(result.url)
|
result.parsed_url = urllib.parse.urlparse(result.url)
|
||||||
|
|
||||||
if result.parsed_url:
|
if result.parsed_url:
|
||||||
|
# properly format special characters (e.g. "ä", "ö") in IDN domains
|
||||||
|
# e.g. "xn--strung-xxa.de" becomes "störung.de"
|
||||||
|
if result.parsed_url.netloc.startswith("xn--"):
|
||||||
|
netloc = result.parsed_url.netloc.encode().decode("idna")
|
||||||
|
result.parsed_url = result.parsed_url._replace(netloc=netloc)
|
||||||
|
|
||||||
result.parsed_url = result.parsed_url._replace(
|
result.parsed_url = result.parsed_url._replace(
|
||||||
# if the result has no scheme, use http as default
|
# if the result has no scheme, use http as default
|
||||||
scheme=result.parsed_url.scheme or "http",
|
scheme=result.parsed_url.scheme or "http",
|
||||||
|
|||||||
@@ -477,6 +477,24 @@ engines:
|
|||||||
engine: arxiv
|
engine: arxiv
|
||||||
shortcut: arx
|
shortcut: arx
|
||||||
|
|
||||||
|
- name: avalw
|
||||||
|
engine: json_engine
|
||||||
|
shortcut: av
|
||||||
|
categories: general
|
||||||
|
paging: true
|
||||||
|
search_url: https://avalw.org/api/search?q={query}&page={pageno}&limit=10&tbm=all
|
||||||
|
results_query: results
|
||||||
|
url_query: url
|
||||||
|
title_query: title
|
||||||
|
content_query: snippet
|
||||||
|
thumbnail: image_url
|
||||||
|
disabled: true
|
||||||
|
inactive: true
|
||||||
|
about:
|
||||||
|
website: https://avalw.com
|
||||||
|
description: "Search engine from the Romanian news company AVALW S.R.L."
|
||||||
|
results: JSON
|
||||||
|
|
||||||
- name: ayo
|
- name: ayo
|
||||||
engine: xpath
|
engine: xpath
|
||||||
categories: general
|
categories: general
|
||||||
@@ -1199,10 +1217,12 @@ engines:
|
|||||||
- name: google
|
- name: google
|
||||||
engine: google
|
engine: google
|
||||||
shortcut: go
|
shortcut: go
|
||||||
|
inactive: true
|
||||||
|
|
||||||
- name: google images
|
- name: google images
|
||||||
engine: google_images
|
engine: google_images
|
||||||
shortcut: goi
|
shortcut: goi
|
||||||
|
inactive: true
|
||||||
|
|
||||||
- name: google news
|
- name: google news
|
||||||
engine: google_news
|
engine: google_news
|
||||||
@@ -1211,6 +1231,17 @@ engines:
|
|||||||
- name: google videos
|
- name: google videos
|
||||||
engine: google_videos
|
engine: google_videos
|
||||||
shortcut: gov
|
shortcut: gov
|
||||||
|
inactive: true
|
||||||
|
|
||||||
|
- name: google cse
|
||||||
|
engine: google_cse
|
||||||
|
shortcut: goc
|
||||||
|
|
||||||
|
- name: google cse images
|
||||||
|
engine: google_cse
|
||||||
|
categories: [images, web]
|
||||||
|
google_categ: image
|
||||||
|
shortcut: goci
|
||||||
|
|
||||||
- name: google scholar
|
- name: google scholar
|
||||||
engine: google_scholar
|
engine: google_scholar
|
||||||
@@ -1409,6 +1440,27 @@ engines:
|
|||||||
# api_key: "" # required
|
# api_key: "" # required
|
||||||
# kagi_categ: videos
|
# kagi_categ: videos
|
||||||
|
|
||||||
|
- name: kavunka demo
|
||||||
|
engine: xpath
|
||||||
|
categories: general
|
||||||
|
paging: true
|
||||||
|
shortcut: kav
|
||||||
|
search_url: https://kavunka.net/search/kavunka-srv.php
|
||||||
|
method: POST
|
||||||
|
request_body: request={query}&np={pageno}
|
||||||
|
headers:
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
disabled: true
|
||||||
|
inactive: true
|
||||||
|
results_xpath: //div[contains(@class, "issue")]
|
||||||
|
url_xpath: .//h2/a/@href
|
||||||
|
title_xpath: .//h2
|
||||||
|
content_xpath: .//div[contains(@class, "snip")]
|
||||||
|
about:
|
||||||
|
website: https://kavunka.net
|
||||||
|
description: "Demo index of Kavunka, a statistical search engine"
|
||||||
|
results: HTML
|
||||||
|
|
||||||
- name: kozmonavt
|
- name: kozmonavt
|
||||||
engine: xpath
|
engine: xpath
|
||||||
search_url: https://kozmonavt.su/s?q={query}
|
search_url: https://kozmonavt.su/s?q={query}
|
||||||
@@ -1691,6 +1743,12 @@ engines:
|
|||||||
shortcut: mwm
|
shortcut: mwm
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|
||||||
|
- name: neocities
|
||||||
|
engine: neocities
|
||||||
|
shortcut: nc
|
||||||
|
disabled: true
|
||||||
|
inactive: true
|
||||||
|
|
||||||
- name: niconico
|
- name: niconico
|
||||||
engine: niconico
|
engine: niconico
|
||||||
shortcut: nico
|
shortcut: nico
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"5Ako-qGW.min.js","names":[],"sources":["../../../../../client/simple/src/js/main/search.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { listen } from \"../toolkit.ts\";\nimport { getElement } from \"../util/getElement.ts\";\n\nconst searchForm: HTMLFormElement = getElement<HTMLFormElement>(\"search\");\nconst searchInput: HTMLInputElement = getElement<HTMLInputElement>(\"q\");\nconst searchReset: HTMLButtonElement = getElement<HTMLButtonElement>(\"clear_search\");\n\nconst isMobile: boolean = window.matchMedia(\"(max-width: 50em)\").matches;\nconst isResultsPage: boolean = document.querySelector(\"main\")?.id === \"main_results\";\n\nconst categoryButtons: HTMLButtonElement[] = Array.from(\n document.querySelectorAll<HTMLButtonElement>(\"#categories_container button.category\")\n);\n\nif (searchInput.value.length === 0) {\n searchReset.classList.add(\"empty\");\n}\n\n// focus search input on large screens\nif (!(isMobile || isResultsPage)) {\n searchInput.focus();\n}\n\n// On mobile, move cursor to the end of the input on focus\nif (isMobile) {\n listen(\"focus\", searchInput, () => {\n // Defer cursor move until the next frame to prevent a visual jump\n requestAnimationFrame(() => {\n const end = searchInput.value.length;\n searchInput.setSelectionRange(end, end);\n searchInput.scrollLeft = searchInput.scrollWidth;\n });\n });\n}\n\nlisten(\"input\", searchInput, () => {\n searchReset.classList.toggle(\"empty\", searchInput.value.length === 0);\n});\n\nlisten(\"click\", searchReset, (event: MouseEvent) => {\n event.preventDefault();\n searchInput.value = \"\";\n searchInput.focus();\n searchReset.classList.add(\"empty\");\n});\n\nfor (const button of categoryButtons) {\n listen(\"click\", button, (event: MouseEvent) => {\n if (event.shiftKey) {\n event.preventDefault();\n button.classList.toggle(\"selected\");\n return;\n }\n\n // deselect all other categories\n for (const categoryButton of categoryButtons) {\n categoryButton.classList.toggle(\"selected\", categoryButton === button);\n }\n });\n}\n\nif (document.querySelector(\"div.search_filters\")) {\n const safesearchElement = document.getElementById(\"safesearch\");\n if (safesearchElement) {\n listen(\"change\", safesearchElement, () => searchForm.submit());\n }\n\n const timeRangeElement = document.getElementById(\"time_range\");\n if (timeRangeElement) {\n listen(\"change\", timeRangeElement, () => searchForm.submit());\n }\n\n const languageElement = document.getElementById(\"language\");\n if (languageElement) {\n listen(\"change\", languageElement, () => searchForm.submit());\n }\n}\n\n// override searchForm submit event\nlisten(\"submit\", searchForm, (event: Event) => {\n event.preventDefault();\n\n if (categoryButtons.length > 0) {\n const searchCategories = getElement<HTMLInputElement>(\"selected-categories\");\n searchCategories.value = categoryButtons\n .filter((button) => button.classList.contains(\"selected\"))\n .map((button) => button.name.replace(\"category_\", \"\"))\n .join(\",\");\n }\n\n searchForm.submit();\n});\n"],"mappings":"yEAKA,IAAM,EAA8B,EAA4B,QAAQ,EAClE,EAAgC,EAA6B,GAAG,EAChE,EAAiC,EAA8B,cAAc,EAE7E,EAAoB,OAAO,WAAW,mBAAmB,EAAE,QAC3D,EAAyB,SAAS,cAAc,MAAM,GAAG,KAAO,eAEhE,EAAuC,MAAM,KACjD,SAAS,iBAAoC,uCAAuC,CACtF,EAEI,EAAY,MAAM,SAAW,GAC/B,EAAY,UAAU,IAAI,OAAO,EAI7B,GAAY,GAChB,EAAY,MAAM,EAIhB,GACF,EAAO,QAAS,MAAmB,CAEjC,0BAA4B,CAC1B,IAAM,EAAM,EAAY,MAAM,OAC9B,EAAY,kBAAkB,EAAK,CAAG,EACtC,EAAY,WAAa,EAAY,WACvC,CAAC,CACH,CAAC,EAGH,EAAO,QAAS,MAAmB,CACjC,EAAY,UAAU,OAAO,QAAS,EAAY,MAAM,SAAW,CAAC,CACtE,CAAC,EAED,EAAO,QAAS,EAAc,GAAsB,CAClD,EAAM,eAAe,EACrB,EAAY,MAAQ,GACpB,EAAY,MAAM,EAClB,EAAY,UAAU,IAAI,OAAO,CACnC,CAAC,EAED,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,EAAS,GAAsB,CAC7C,GAAI,EAAM,SAAU,CAClB,EAAM,eAAe,EACrB,EAAO,UAAU,OAAO,UAAU,EAClC,MACF,CAGA,IAAK,IAAM,KAAkB,EAC3B,EAAe,UAAU,OAAO,WAAY,IAAmB,CAAM,CAEzE,CAAC,EAGH,GAAI,SAAS,cAAc,oBAAoB,EAAG,CAChD,IAAM,EAAoB,SAAS,eAAe,YAAY,EAC1D,GACF,EAAO,SAAU,MAAyB,EAAW,OAAO,CAAC,EAG/D,IAAM,EAAmB,SAAS,eAAe,YAAY,EACzD,GACF,EAAO,SAAU,MAAwB,EAAW,OAAO,CAAC,EAG9D,IAAM,EAAkB,SAAS,eAAe,UAAU,EACtD,GACF,EAAO,SAAU,MAAuB,EAAW,OAAO,CAAC,CAE/D,CAGA,EAAO,SAAU,EAAa,GAAiB,CAG7C,GAFA,EAAM,eAAe,EAEjB,EAAgB,OAAS,EAAG,CAC9B,IAAM,EAAmB,EAA6B,qBAAqB,EAC3E,EAAiB,MAAQ,EACtB,OAAQ,GAAW,EAAO,UAAU,SAAS,UAAU,CAAC,EACxD,IAAK,GAAW,EAAO,KAAK,QAAQ,YAAa,EAAE,CAAC,EACpD,KAAK,GAAG,CACb,CAEA,EAAW,OAAO,CACpB,CAAC"}
|
{"version":3,"file":"5Ako-qGW.min.js","names":[],"sources":["../../../../../client/simple/src/js/main/search.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { listen } from \"../toolkit.ts\";\nimport { getElement } from \"../util/getElement.ts\";\n\nconst searchForm: HTMLFormElement = getElement<HTMLFormElement>(\"search\");\nconst searchInput: HTMLInputElement = getElement<HTMLInputElement>(\"q\");\nconst searchReset: HTMLButtonElement = getElement<HTMLButtonElement>(\"clear_search\");\n\nconst isMobile: boolean = window.matchMedia(\"(max-width: 50em)\").matches;\nconst isResultsPage: boolean = document.querySelector(\"main\")?.id === \"main_results\";\n\nconst categoryButtons: HTMLButtonElement[] = Array.from(\n document.querySelectorAll<HTMLButtonElement>(\"#categories_container button.category\")\n);\n\nif (searchInput.value.length === 0) {\n searchReset.classList.add(\"empty\");\n}\n\n// focus search input on large screens\nif (!(isMobile || isResultsPage)) {\n searchInput.focus();\n}\n\n// On mobile, move cursor to the end of the input on focus\nif (isMobile) {\n listen(\"focus\", searchInput, () => {\n // Defer cursor move until the next frame to prevent a visual jump\n requestAnimationFrame(() => {\n const end = searchInput.value.length;\n searchInput.setSelectionRange(end, end);\n searchInput.scrollLeft = searchInput.scrollWidth;\n });\n });\n}\n\nlisten(\"input\", searchInput, () => {\n searchReset.classList.toggle(\"empty\", searchInput.value.length === 0);\n});\n\nlisten(\"click\", searchReset, (event: MouseEvent) => {\n event.preventDefault();\n searchInput.value = \"\";\n searchInput.focus();\n searchReset.classList.add(\"empty\");\n});\n\nfor (const button of categoryButtons) {\n listen(\"click\", button, (event: MouseEvent) => {\n if (event.shiftKey) {\n event.preventDefault();\n button.classList.toggle(\"selected\");\n return;\n }\n\n // deselect all other categories\n for (const categoryButton of categoryButtons) {\n categoryButton.classList.toggle(\"selected\", categoryButton === button);\n }\n });\n}\n\nif (document.querySelector(\"div.search_filters\")) {\n const safesearchElement = document.getElementById(\"safesearch\");\n if (safesearchElement) {\n listen(\"change\", safesearchElement, () => searchForm.submit());\n }\n\n const timeRangeElement = document.getElementById(\"time_range\");\n if (timeRangeElement) {\n listen(\"change\", timeRangeElement, () => searchForm.submit());\n }\n\n const languageElement = document.getElementById(\"language\");\n if (languageElement) {\n listen(\"change\", languageElement, () => searchForm.submit());\n }\n}\n\n// override searchForm submit event\nlisten(\"submit\", searchForm, (event: Event) => {\n event.preventDefault();\n\n if (categoryButtons.length > 0) {\n const searchCategories = getElement<HTMLInputElement>(\"selected-categories\");\n searchCategories.value = categoryButtons\n .filter((button) => button.classList.contains(\"selected\"))\n .map((button) => button.name.replace(\"category_\", \"\"))\n .join(\",\");\n }\n\n searchForm.submit();\n});\n"],"mappings":"yEAKA,IAAM,EAA8B,EAA4B,QAAQ,EAClE,EAAgC,EAA6B,GAAG,EAChE,EAAiC,EAA8B,cAAc,EAE7E,EAAoB,OAAO,WAAW,mBAAmB,CAAC,CAAC,QAC3D,EAAyB,SAAS,cAAc,MAAM,CAAC,EAAE,KAAO,eAEhE,EAAuC,MAAM,KACjD,SAAS,iBAAoC,uCAAuC,CACtF,EAEI,EAAY,MAAM,SAAW,GAC/B,EAAY,UAAU,IAAI,OAAO,EAI7B,GAAY,GAChB,EAAY,MAAM,EAIhB,GACF,EAAO,QAAS,MAAmB,CAEjC,0BAA4B,CAC1B,IAAM,EAAM,EAAY,MAAM,OAC9B,EAAY,kBAAkB,EAAK,CAAG,EACtC,EAAY,WAAa,EAAY,WACvC,CAAC,CACH,CAAC,EAGH,EAAO,QAAS,MAAmB,CACjC,EAAY,UAAU,OAAO,QAAS,EAAY,MAAM,SAAW,CAAC,CACtE,CAAC,EAED,EAAO,QAAS,EAAc,GAAsB,CAClD,EAAM,eAAe,EACrB,EAAY,MAAQ,GACpB,EAAY,MAAM,EAClB,EAAY,UAAU,IAAI,OAAO,CACnC,CAAC,EAED,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,EAAS,GAAsB,CAC7C,GAAI,EAAM,SAAU,CAClB,EAAM,eAAe,EACrB,EAAO,UAAU,OAAO,UAAU,EAClC,MACF,CAGA,IAAK,IAAM,KAAkB,EAC3B,EAAe,UAAU,OAAO,WAAY,IAAmB,CAAM,CAEzE,CAAC,EAGH,GAAI,SAAS,cAAc,oBAAoB,EAAG,CAChD,IAAM,EAAoB,SAAS,eAAe,YAAY,EAC1D,GACF,EAAO,SAAU,MAAyB,EAAW,OAAO,CAAC,EAG/D,IAAM,EAAmB,SAAS,eAAe,YAAY,EACzD,GACF,EAAO,SAAU,MAAwB,EAAW,OAAO,CAAC,EAG9D,IAAM,EAAkB,SAAS,eAAe,UAAU,EACtD,GACF,EAAO,SAAU,MAAuB,EAAW,OAAO,CAAC,CAE/D,CAGA,EAAO,SAAU,EAAa,GAAiB,CAG7C,GAFA,EAAM,eAAe,EAEjB,EAAgB,OAAS,EAAG,CAC9B,IAAM,EAAmB,EAA6B,qBAAqB,EAC3E,EAAiB,MAAQ,EACtB,OAAQ,GAAW,EAAO,UAAU,SAAS,UAAU,CAAC,CAAC,CACzD,IAAK,GAAW,EAAO,KAAK,QAAQ,YAAa,EAAE,CAAC,CAAC,CACrD,KAAK,GAAG,CACb,CAEA,EAAW,OAAO,CACpB,CAAC"}
|
||||||
11
searx/static/themes/simple/chunk/B8prKeWj.min.js
vendored
11
searx/static/themes/simple/chunk/B8prKeWj.min.js
vendored
@@ -1,11 +0,0 @@
|
|||||||
import{i as e,n as t,r as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js";
|
|
||||||
/*!
|
|
||||||
* swiped-events.js - v@version@
|
|
||||||
* Pure JavaScript swipe events
|
|
||||||
* https://github.com/john-doherty/swiped-events
|
|
||||||
* @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element
|
|
||||||
* @author John Doherty <www.johndoherty.info>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
(function(e,t){typeof e.CustomEvent!=`function`&&(e.CustomEvent=function(e,n){n||={bubbles:!1,cancelable:!1,detail:void 0};var r=t.createEvent(`CustomEvent`);return r.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),r},e.CustomEvent.prototype=e.Event.prototype),t.addEventListener(`touchstart`,u,!1),t.addEventListener(`touchmove`,d,!1),t.addEventListener(`touchend`,l,!1);var n=null,r=null,i=null,a=null,o=null,s=null,c=0;function l(e){if(s===e.target){var l=parseInt(f(s,`data-swipe-threshold`,`20`),10),u=f(s,`data-swipe-unit`,`px`),d=parseInt(f(s,`data-swipe-timeout`,`500`),10),p=Date.now()-o,m=``,h=e.changedTouches||e.touches||[];if(u===`vh`&&(l=Math.round(l/100*t.documentElement.clientHeight)),u===`vw`&&(l=Math.round(l/100*t.documentElement.clientWidth)),Math.abs(i)>Math.abs(a)?Math.abs(i)>l&&p<d&&(m=i>0?`swiped-left`:`swiped-right`):Math.abs(a)>l&&p<d&&(m=a>0?`swiped-up`:`swiped-down`),m!==``){var g={dir:m.replace(/swiped-/,``),touchType:(h[0]||{}).touchType||`direct`,fingers:c,xStart:parseInt(n,10),xEnd:parseInt((h[0]||{}).clientX||-1,10),yStart:parseInt(r,10),yEnd:parseInt((h[0]||{}).clientY||-1,10)};s.dispatchEvent(new CustomEvent(`swiped`,{bubbles:!0,cancelable:!0,detail:g})),s.dispatchEvent(new CustomEvent(m,{bubbles:!0,cancelable:!0,detail:g}))}n=null,r=null,o=null}}function u(e){e.target.getAttribute(`data-swipe-ignore`)!==`true`&&(s=e.target,o=Date.now(),n=e.touches[0].clientX,r=e.touches[0].clientY,i=0,a=0,c=e.touches.length)}function d(e){if(!(!n||!r)){var t=e.touches[0].clientX,o=e.touches[0].clientY;i=n-t,a=r-o}}function f(e,n,r){for(;e&&e!==t.documentElement;){var i=e.getAttribute(n);if(i)return i;e=e.parentNode}return r}})(window,document);var i,a=t=>{i&&clearTimeout(i);let n=t.querySelector(`.result-images-source img`);if(!n)return;let r=t.querySelector(`.image_thumbnail`);if(r){if(r.src===`${e.theme_static_path}/img/img_load_error.svg`)return;n.onerror=()=>{n.src=r.src},n.src=r.src}let a=n.getAttribute(`data-src`);a&&(i=setTimeout(()=>{n.src=a,n.removeAttribute(`data-src`)},1e3))},o=document.querySelectorAll(`#urls img.image_thumbnail`);for(let t of o)t.complete&&t.naturalWidth===0&&(t.src=`${e.theme_static_path}/img/img_load_error.svg`),t.onerror=()=>{t.src=`${e.theme_static_path}/img/img_load_error.svg`};document.querySelector(`#search_url button#copy_url`)?.style.setProperty(`display`,`block`),n.selectImage=e=>{document.getElementById(`results`)?.classList.add(`image-detail-open`),window.location.hash=`#image-viewer`,n.scrollPageToSelected?.(),e&&a(e)},n.closeDetail=()=>{document.getElementById(`results`)?.classList.remove(`image-detail-open`),window.location.hash===`#image-viewer`&&window.history.back(),n.scrollPageToSelected?.()},t(`click`,`.btn-collapse`,function(){let e=this.getAttribute(`data-btn-text-collapsed`),t=this.getAttribute(`data-btn-text-not-collapsed`),n=this.getAttribute(`data-target`);if(!(n&&e&&t))return;let i=document.querySelector(n);r(i);let a=this.classList.contains(`collapsed`),o=a?t:e,s=a?e:t;this.innerHTML=this.innerHTML.replace(s,o),this.classList.toggle(`collapsed`),i.classList.toggle(`invisible`)}),t(`click`,`.media-loader`,function(){let e=this.getAttribute(`data-target`);if(!e)return;let t=document.querySelector(`${e} > iframe`);if(r(t),!t.getAttribute(`src`)){let e=t.getAttribute(`data-src`);e&&t.setAttribute(`src`,e)}}),t(`click`,`#copy_url`,async function(){let e=this.parentElement?.querySelector(`pre`);if(r(e),window.isSecureContext)await navigator.clipboard.writeText(e.innerText);else{let t=window.getSelection();if(t){let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),document.execCommand(`copy`)}}this.dataset.copiedText&&(this.innerText=this.dataset.copiedText)}),t(`click`,`.result-detail-close`,e=>{e.preventDefault(),n.closeDetail?.()}),t(`click`,`.result-detail-previous`,e=>{e.preventDefault(),n.selectPrevious?.(!1)}),t(`click`,`.result-detail-next`,e=>{e.preventDefault(),n.selectNext?.(!1)}),window.addEventListener(`hashchange`,()=>{window.location.hash!==`#image-viewer`&&n.closeDetail?.()});var s=document.querySelectorAll(`.swipe-horizontal`);for(let e of s)t(`swiped-left`,e,()=>{n.selectNext?.(!1)}),t(`swiped-right`,e,()=>{n.selectPrevious?.(!1)});window.addEventListener(`scroll`,()=>{let e=document.getElementById(`backToTop`),t=document.getElementById(`results`);if(e&&t){let e=(document.documentElement.scrollTop||document.body.scrollTop)>=100;t.classList.toggle(`scrolling`,e)}},!0);
|
|
||||||
//# sourceMappingURL=B8prKeWj.min.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
8
searx/static/themes/simple/chunk/BnnvKC7b.min.js
vendored
Normal file
8
searx/static/themes/simple/chunk/BnnvKC7b.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"e2-9fzwE.min.js","names":[],"sources":["../../../../../client/simple/src/js/main/preferences.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { http, listen, settings } from \"../toolkit.ts\";\nimport { assertElement } from \"../util/assertElement.ts\";\n\nlet engineDescriptions: Record<string, [string, string]> | undefined;\n\nconst loadEngineDescriptions = async (): Promise<void> => {\n if (engineDescriptions) return;\n try {\n const res = await http(\"GET\", \"engine_descriptions.json\");\n engineDescriptions = await res.json();\n } catch (error) {\n console.error(\"Error fetching engineDescriptions:\", error);\n }\n if (!engineDescriptions) return;\n\n for (const [engine_name, [description, source]] of Object.entries(engineDescriptions)) {\n const elements = document.querySelectorAll<HTMLElement>(`[data-engine-name=\"${engine_name}\"] .engine-description`);\n const sourceText = ` (<i>${settings.translations?.Source}: ${source}</i>)`;\n\n for (const element of elements) {\n element.innerHTML = description + sourceText;\n }\n }\n};\n\nconst toggleEngines = (enable: boolean, engineToggles: NodeListOf<HTMLInputElement>): void => {\n for (const engineToggle of engineToggles) {\n // check if element visible, so that only engines of the current category are modified\n if (engineToggle.offsetParent) {\n engineToggle.checked = !enable;\n }\n }\n};\n\nconst engineElements: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\"[data-engine-name]\");\nfor (const engineElement of engineElements) {\n listen(\"mouseenter\", engineElement, loadEngineDescriptions);\n}\n\nconst engineToggles: NodeListOf<HTMLInputElement> = document.querySelectorAll<HTMLInputElement>(\n \"tbody input[type=checkbox][class~=checkbox-onoff]\"\n);\n\nconst enableAllEngines: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\".enable-all-engines\");\nfor (const engine of enableAllEngines) {\n listen(\"click\", engine, () => toggleEngines(true, engineToggles));\n}\n\nconst disableAllEngines: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\".disable-all-engines\");\nfor (const engine of disableAllEngines) {\n listen(\"click\", engine, () => toggleEngines(false, engineToggles));\n}\n\nlisten(\"click\", \"#copy-hash\", async function (this: HTMLElement) {\n const target = this.parentElement?.querySelector<HTMLPreElement>(\"pre\");\n assertElement(target);\n\n if (window.isSecureContext) {\n await navigator.clipboard.writeText(target.innerText);\n } else {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(target);\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand(\"copy\");\n }\n }\n\n if (this.dataset.copiedText) {\n this.innerText = this.dataset.copiedText;\n }\n});\n"],"mappings":"4FAKA,IAAI,EAEE,EAAyB,SAA2B,CACpD,MACJ,IAAI,CAEF,EAAqB,MAAM,MADT,EAAK,MAAO,0BAA0B,GACzB,KAAK,CACtC,OAAS,EAAO,CACd,QAAQ,MAAM,qCAAsC,CAAK,CAC3D,CACK,KAEL,IAAK,GAAM,CAAC,EAAa,CAAC,EAAa,MAAY,OAAO,QAAQ,CAAkB,EAAG,CACrF,IAAM,EAAW,SAAS,iBAA8B,sBAAsB,EAAY,uBAAuB,EAC3G,EAAa,QAAQ,EAAS,cAAc,OAAO,SAAS,EAAO,OAEzE,IAAK,IAAM,KAAW,EACpB,EAAQ,UAAY,EAAc,CAEtC,CAVA,CAWF,EAEM,GAAiB,EAAiB,IAAsD,CAC5F,IAAK,IAAM,KAAgB,EAErB,EAAa,eACf,EAAa,QAAU,CAAC,EAG9B,EAEM,EAA0C,SAAS,iBAA8B,oBAAoB,EAC3G,IAAK,IAAM,KAAiB,EAC1B,EAAO,aAAc,EAAe,CAAsB,EAG5D,IAAM,EAA8C,SAAS,iBAC3D,mDACF,EAEM,EAA4C,SAAS,iBAA8B,qBAAqB,EAC9G,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,MAAc,EAAc,GAAM,CAAa,CAAC,EAGlE,IAAM,EAA6C,SAAS,iBAA8B,sBAAsB,EAChH,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,MAAc,EAAc,GAAO,CAAa,CAAC,EAGnE,EAAO,QAAS,aAAc,gBAAmC,CAC/D,IAAM,EAAS,KAAK,eAAe,cAA8B,KAAK,EAGtE,GAFA,EAAc,CAAM,EAEhB,OAAO,gBACT,MAAM,UAAU,UAAU,UAAU,EAAO,SAAS,MAC/C,CACL,IAAM,EAAY,OAAO,aAAa,EACtC,GAAI,EAAW,CACb,IAAM,EAAQ,SAAS,YAAY,EACnC,EAAM,mBAAmB,CAAM,EAC/B,EAAU,gBAAgB,EAC1B,EAAU,SAAS,CAAK,EACxB,SAAS,YAAY,MAAM,CAC7B,CACF,CAEI,KAAK,QAAQ,aACf,KAAK,UAAY,KAAK,QAAQ,WAElC,CAAC"}
|
{"version":3,"file":"e2-9fzwE.min.js","names":[],"sources":["../../../../../client/simple/src/js/main/preferences.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { http, listen, settings } from \"../toolkit.ts\";\nimport { assertElement } from \"../util/assertElement.ts\";\n\nlet engineDescriptions: Record<string, [string, string]> | undefined;\n\nconst loadEngineDescriptions = async (): Promise<void> => {\n if (engineDescriptions) return;\n try {\n const res = await http(\"GET\", \"engine_descriptions.json\");\n engineDescriptions = await res.json();\n } catch (error) {\n console.error(\"Error fetching engineDescriptions:\", error);\n }\n if (!engineDescriptions) return;\n\n for (const [engine_name, [description, source]] of Object.entries(engineDescriptions)) {\n const elements = document.querySelectorAll<HTMLElement>(`[data-engine-name=\"${engine_name}\"] .engine-description`);\n const sourceText = ` (<i>${settings.translations?.Source}: ${source}</i>)`;\n\n for (const element of elements) {\n element.innerHTML = description + sourceText;\n }\n }\n};\n\nconst toggleEngines = (enable: boolean, engineToggles: NodeListOf<HTMLInputElement>): void => {\n for (const engineToggle of engineToggles) {\n // check if element visible, so that only engines of the current category are modified\n if (engineToggle.offsetParent) {\n engineToggle.checked = !enable;\n }\n }\n};\n\nconst engineElements: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\"[data-engine-name]\");\nfor (const engineElement of engineElements) {\n listen(\"mouseenter\", engineElement, loadEngineDescriptions);\n}\n\nconst engineToggles: NodeListOf<HTMLInputElement> = document.querySelectorAll<HTMLInputElement>(\n \"tbody input[type=checkbox][class~=checkbox-onoff]\"\n);\n\nconst enableAllEngines: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\".enable-all-engines\");\nfor (const engine of enableAllEngines) {\n listen(\"click\", engine, () => toggleEngines(true, engineToggles));\n}\n\nconst disableAllEngines: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\".disable-all-engines\");\nfor (const engine of disableAllEngines) {\n listen(\"click\", engine, () => toggleEngines(false, engineToggles));\n}\n\nlisten(\"click\", \"#copy-hash\", async function (this: HTMLElement) {\n const target = this.parentElement?.querySelector<HTMLPreElement>(\"pre\");\n assertElement(target);\n\n if (window.isSecureContext) {\n await navigator.clipboard.writeText(target.innerText);\n } else {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(target);\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand(\"copy\");\n }\n }\n\n if (this.dataset.copiedText) {\n this.innerText = this.dataset.copiedText;\n }\n});\n"],"mappings":"4FAKA,IAAI,EAEE,EAAyB,SAA2B,CACpD,MACJ,IAAI,CAEF,EAAqB,MAAM,MADT,EAAK,MAAO,0BAA0B,EAAA,CACzB,KAAK,CACtC,OAAS,EAAO,CACd,QAAQ,MAAM,qCAAsC,CAAK,CAC3D,CACK,KAEL,IAAK,GAAM,CAAC,EAAa,CAAC,EAAa,MAAY,OAAO,QAAQ,CAAkB,EAAG,CACrF,IAAM,EAAW,SAAS,iBAA8B,sBAAsB,EAAY,uBAAuB,EAC3G,EAAa,QAAQ,EAAS,cAAc,OAAO,SAAS,EAAO,OAEzE,IAAK,IAAM,KAAW,EACpB,EAAQ,UAAY,EAAc,CAEtC,CAVA,CAWF,EAEM,GAAiB,EAAiB,IAAsD,CAC5F,IAAK,IAAM,KAAgB,EAErB,EAAa,eACf,EAAa,QAAU,CAAC,EAG9B,EAEM,EAA0C,SAAS,iBAA8B,oBAAoB,EAC3G,IAAK,IAAM,KAAiB,EAC1B,EAAO,aAAc,EAAe,CAAsB,EAG5D,IAAM,EAA8C,SAAS,iBAC3D,mDACF,EAEM,EAA4C,SAAS,iBAA8B,qBAAqB,EAC9G,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,MAAc,EAAc,GAAM,CAAa,CAAC,EAGlE,IAAM,EAA6C,SAAS,iBAA8B,sBAAsB,EAChH,IAAK,IAAM,KAAU,EACnB,EAAO,QAAS,MAAc,EAAc,GAAO,CAAa,CAAC,EAGnE,EAAO,QAAS,aAAc,gBAAmC,CAC/D,IAAM,EAAS,KAAK,eAAe,cAA8B,KAAK,EAGtE,GAFA,EAAc,CAAM,EAEhB,OAAO,gBACT,MAAM,UAAU,UAAU,UAAU,EAAO,SAAS,MAC/C,CACL,IAAM,EAAY,OAAO,aAAa,EACtC,GAAI,EAAW,CACb,IAAM,EAAQ,SAAS,YAAY,EACnC,EAAM,mBAAmB,CAAM,EAC/B,EAAU,gBAAgB,EAC1B,EAAU,SAAS,CAAK,EACxB,SAAS,YAAY,MAAM,CAC7B,CACF,CAEI,KAAK,QAAQ,aACf,KAAK,UAAY,KAAK,QAAQ,WAElC,CAAC"}
|
||||||
11
searx/static/themes/simple/chunk/od7pNHfk.min.js
vendored
Normal file
11
searx/static/themes/simple/chunk/od7pNHfk.min.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import{i as e,n as t,r as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js";
|
||||||
|
/*!
|
||||||
|
* swiped-events.js - v@version@
|
||||||
|
* Pure JavaScript swipe events
|
||||||
|
* https://github.com/john-doherty/swiped-events
|
||||||
|
* @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element
|
||||||
|
* @author John Doherty <www.johndoherty.info>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
(function(e,t){typeof e.CustomEvent!=`function`&&(e.CustomEvent=function(e,n){n||={bubbles:!1,cancelable:!1,detail:void 0};var r=t.createEvent(`CustomEvent`);return r.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),r},e.CustomEvent.prototype=e.Event.prototype),t.addEventListener(`touchstart`,u,!1),t.addEventListener(`touchmove`,d,!1),t.addEventListener(`touchend`,l,!1);var n=null,r=null,i=null,a=null,o=null,s=null,c=0;function l(e){if(s===e.target){var l=parseInt(f(s,`data-swipe-threshold`,`20`),10),u=f(s,`data-swipe-unit`,`px`),d=parseInt(f(s,`data-swipe-timeout`,`500`),10),p=Date.now()-o,m=``,h=e.changedTouches||e.touches||[];if(u===`vh`&&(l=Math.round(l/100*t.documentElement.clientHeight)),u===`vw`&&(l=Math.round(l/100*t.documentElement.clientWidth)),Math.abs(i)>Math.abs(a)?Math.abs(i)>l&&p<d&&(m=i>0?`swiped-left`:`swiped-right`):Math.abs(a)>l&&p<d&&(m=a>0?`swiped-up`:`swiped-down`),m!==``){var g={dir:m.replace(/swiped-/,``),touchType:(h[0]||{}).touchType||`direct`,fingers:c,xStart:parseInt(n,10),xEnd:parseInt((h[0]||{}).clientX||-1,10),yStart:parseInt(r,10),yEnd:parseInt((h[0]||{}).clientY||-1,10)};s.dispatchEvent(new CustomEvent(`swiped`,{bubbles:!0,cancelable:!0,detail:g})),s.dispatchEvent(new CustomEvent(m,{bubbles:!0,cancelable:!0,detail:g}))}n=null,r=null,o=null}}function u(e){e.target.getAttribute(`data-swipe-ignore`)!==`true`&&(s=e.target,o=Date.now(),n=e.touches[0].clientX,r=e.touches[0].clientY,i=0,a=0,c=e.touches.length)}function d(e){if(!(!n||!r)){var t=e.touches[0].clientX,o=e.touches[0].clientY;i=n-t,a=r-o}}function f(e,n,r){for(;e&&e!==t.documentElement;){var i=e.getAttribute(n);if(i)return i;e=e.parentNode}return r}})(window,document);var i,a=t=>{i&&clearTimeout(i);let n=t.querySelector(`.result-images-source img`);if(!n)return;let r=t.querySelector(`.image_thumbnail`);if(r){if(r.src===`${e.theme_static_path}/img/img_load_error.svg`)return;n.onerror=()=>{n.src=r.src},n.src=r.src}let a=n.getAttribute(`data-src`);a&&(i=setTimeout(()=>{n.src=a,n.removeAttribute(`data-src`)},1e3))},o=document.querySelectorAll(`#urls img.image_thumbnail, img.thumbnail`);for(let t of o)t.complete&&t.naturalWidth===0&&(t.src=`${e.theme_static_path}/img/img_load_error.svg`),t.onerror=()=>{t.src=`${e.theme_static_path}/img/img_load_error.svg`};document.querySelector(`#search_url button#copy_url`)?.style.setProperty(`display`,`block`),n.selectImage=e=>{document.getElementById(`results`)?.classList.add(`image-detail-open`),window.location.hash=`#image-viewer`,n.scrollPageToSelected?.(),e&&a(e)},n.closeDetail=()=>{document.getElementById(`results`)?.classList.remove(`image-detail-open`),window.location.hash===`#image-viewer`&&window.history.back(),n.scrollPageToSelected?.()},t(`click`,`.btn-collapse`,function(){let e=this.getAttribute(`data-btn-text-collapsed`),t=this.getAttribute(`data-btn-text-not-collapsed`),n=this.getAttribute(`data-target`);if(!(n&&e&&t))return;let i=document.querySelector(n);r(i);let a=this.classList.contains(`collapsed`),o=a?t:e,s=a?e:t;this.innerHTML=this.innerHTML.replace(s,o),this.classList.toggle(`collapsed`),i.classList.toggle(`invisible`)}),t(`click`,`.media-loader`,function(){let e=this.getAttribute(`data-target`);if(!e)return;let t=document.querySelector(`${e} > iframe`);if(r(t),!t.getAttribute(`src`)){let e=t.getAttribute(`data-src`);e&&t.setAttribute(`src`,e)}}),t(`click`,`#copy_url`,async function(){let e=this.parentElement?.querySelector(`pre`);if(r(e),window.isSecureContext)await navigator.clipboard.writeText(e.innerText);else{let t=window.getSelection();if(t){let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),document.execCommand(`copy`)}}this.dataset.copiedText&&(this.innerText=this.dataset.copiedText)}),t(`click`,`.result-detail-close`,e=>{e.preventDefault(),n.closeDetail?.()}),t(`click`,`.result-detail-previous`,e=>{e.preventDefault(),n.selectPrevious?.(!1)}),t(`click`,`.result-detail-next`,e=>{e.preventDefault(),n.selectNext?.(!1)}),window.addEventListener(`hashchange`,()=>{window.location.hash!==`#image-viewer`&&n.closeDetail?.()});var s=document.querySelectorAll(`.swipe-horizontal`);for(let e of s)t(`swiped-left`,e,()=>{n.selectNext?.(!1)}),t(`swiped-right`,e,()=>{n.selectPrevious?.(!1)});window.addEventListener(`scroll`,()=>{let e=document.getElementById(`backToTop`),t=document.getElementById(`results`);if(e&&t){let e=(document.documentElement.scrollTop||document.body.scrollTop)>=100;t.classList.toggle(`scrolling`,e)}},!0);
|
||||||
|
//# sourceMappingURL=od7pNHfk.min.js.map
|
||||||
1
searx/static/themes/simple/chunk/od7pNHfk.min.js.map
Normal file
1
searx/static/themes/simple/chunk/od7pNHfk.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -57,7 +57,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/js/main/results.ts": {
|
"src/js/main/results.ts": {
|
||||||
"file": "chunk/B8prKeWj.min.js",
|
"file": "chunk/od7pNHfk.min.js",
|
||||||
"name": "results",
|
"name": "results",
|
||||||
"src": "src/js/main/results.ts",
|
"src": "src/js/main/results.ts",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/js/plugin/Calculator.ts": {
|
"src/js/plugin/Calculator.ts": {
|
||||||
"file": "chunk/CTP0QVHn.min.js",
|
"file": "chunk/C8c7HJzp.min.js",
|
||||||
"name": "calculator",
|
"name": "calculator",
|
||||||
"src": "src/js/plugin/Calculator.ts",
|
"src": "src/js/plugin/Calculator.ts",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/js/plugin/MapView.ts": {
|
"src/js/plugin/MapView.ts": {
|
||||||
"file": "chunk/U6YV4Y8e.min.js",
|
"file": "chunk/BnnvKC7b.min.js",
|
||||||
"name": "mapview",
|
"name": "mapview",
|
||||||
"src": "src/js/plugin/MapView.ts",
|
"src": "src/js/plugin/MapView.ts",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
|
|||||||
4
searx/static/themes/simple/sxng-core.min.js
vendored
4
searx/static/themes/simple/sxng-core.min.js
vendored
@@ -1,3 +1,3 @@
|
|||||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chunk/U6YV4Y8e.min.js","./sxng-mapview.min.css","./chunk/DpvWr1cn.min.js","./chunk/DK4yUVpy.min.js","./chunk/DcK-mo-Y.min.js","./chunk/CTP0QVHn.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/DvCYLbJr.min.js","./chunk/B8prKeWj.min.js","./chunk/e2-9fzwE.min.js"])))=>i.map(i=>d[i]);
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chunk/BnnvKC7b.min.js","./sxng-mapview.min.css","./chunk/DpvWr1cn.min.js","./chunk/DK4yUVpy.min.js","./chunk/DcK-mo-Y.min.js","./chunk/C8c7HJzp.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/DvCYLbJr.min.js","./chunk/od7pNHfk.min.js","./chunk/e2-9fzwE.min.js"])))=>i.map(i=>d[i]);
|
||||||
var e=class{id;constructor(e){this.id=e,queueMicrotask(()=>this.invoke())}async invoke(){try{console.debug(`[PLUGIN] ${this.id}: Running...`);let e=await this.run();if(!e)return;console.debug(`[PLUGIN] ${this.id}: Running post-exec...`),await this.post(e)}catch(e){console.error(`[PLUGIN] ${this.id}:`,e)}finally{console.debug(`[PLUGIN] ${this.id}: Done.`)}}},t={index:`index`,results:`results`,preferences:`preferences`,unknown:`unknown`},n={closeDetail:void 0,scrollPageToSelected:void 0,selectImage:void 0,selectNext:void 0,selectPrevious:void 0},r=()=>{let e=document.querySelector(`meta[name="endpoint"]`)?.getAttribute(`content`);return e&&e in t?e:t.unknown},i=()=>{let e=document.querySelector(`script[client_settings]`)?.getAttribute(`client_settings`);if(!e)return{};try{return JSON.parse(atob(e))}catch(e){return console.error(`Failed to load client_settings:`,e),{}}},a=async(e,t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),n?.timeout??3e4),a=await fetch(t,{body:n?.body,method:e,signal:r.signal}).finally(()=>clearTimeout(i));if(!a.ok)throw Error(a.statusText);return a},o=(e,t,n,r)=>{if(typeof t!=`string`){t.addEventListener(e,n,r);return}document.addEventListener(e,e=>{for(let r of e.composedPath())if(r instanceof HTMLElement&&r.matches(t)){try{n.call(r,e)}catch(e){console.error(e)}break}},r)},s=(e,t)=>{for(let e of t?.on??[])if(!e)return;document.readyState===`loading`?o(`DOMContentLoaded`,document,e,{once:!0}):e()},c=r(),l=i(),u=(e,t)=>{d(t)&&e()},d=e=>{switch(e.on){case`global`:return!0;case`endpoint`:return!!e.where.includes(c)}},f=`modulepreload`,p=function(e,t){return new URL(e,t).href},m={},h=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=p(t,n),t in m)return;m[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:f,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};s(()=>{document.documentElement.classList.remove(`no-js`),document.documentElement.classList.add(`js`),o(`click`,`.close`,function(){this.parentNode?.classList.add(`invisible`)}),o(`click`,`.searxng_init_map`,async function(e){e.preventDefault(),this.classList.remove(`searxng_init_map`),u(()=>h(async()=>{let{default:e}=await import(`./chunk/U6YV4Y8e.min.js`);return{default:e}},__vite__mapDeps([0,1]),import.meta.url).then(({default:e})=>new e(this)),{on:`endpoint`,where:[t.results]})}),l.plugins?.includes(`infiniteScroll`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/DpvWr1cn.min.js`);return{default:e}},__vite__mapDeps([2,3,4]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]}),l.plugins?.includes(`calculator`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/CTP0QVHn.min.js`);return{default:e}},__vite__mapDeps([5,4,3]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]})}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.index]}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/B8prKeWj.min.js`),__vite__mapDeps([9,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.results]}),s(()=>{h(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([10,3]),import.meta.url)},{on:[c===t.preferences]});export{e as a,l as i,o as n,n as r,a as t};
|
var e=class{id;constructor(e){this.id=e,queueMicrotask(()=>this.invoke())}async invoke(){try{console.debug(`[PLUGIN] ${this.id}: Running...`);let e=await this.run();if(!e)return;console.debug(`[PLUGIN] ${this.id}: Running post-exec...`),await this.post(e)}catch(e){console.error(`[PLUGIN] ${this.id}:`,e)}finally{console.debug(`[PLUGIN] ${this.id}: Done.`)}}},t={index:`index`,results:`results`,preferences:`preferences`,unknown:`unknown`},n={closeDetail:void 0,scrollPageToSelected:void 0,selectImage:void 0,selectNext:void 0,selectPrevious:void 0},r=()=>{let e=document.querySelector(`meta[name="endpoint"]`)?.getAttribute(`content`);return e&&e in t?e:t.unknown},i=()=>{let e=document.querySelector(`script[client_settings]`)?.getAttribute(`client_settings`);if(!e)return{};try{return JSON.parse(atob(e))}catch(e){return console.error(`Failed to load client_settings:`,e),{}}},a=async(e,t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),n?.timeout??3e4),a=await fetch(t,{body:n?.body,method:e,signal:r.signal}).finally(()=>clearTimeout(i));if(!a.ok)throw Error(a.statusText);return a},o=(e,t,n,r)=>{if(typeof t!=`string`){t.addEventListener(e,n,r);return}document.addEventListener(e,e=>{for(let r of e.composedPath())if(r instanceof HTMLElement&&r.matches(t)){try{n.call(r,e)}catch(e){console.error(e)}break}},r)},s=(e,t)=>{for(let e of t?.on??[])if(!e)return;document.readyState===`loading`?o(`DOMContentLoaded`,document,e,{once:!0}):e()},c=r(),l=i(),u=(e,t)=>{d(t)&&e()},d=e=>{switch(e.on){case`global`:return!0;case`endpoint`:return!!e.where.includes(c)}},f=`modulepreload`,p=function(e,t){return new URL(e,t).href},m={},h=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=p(t,n),t=s(t),t in m)return;m[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:f,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};s(()=>{document.documentElement.classList.remove(`no-js`),document.documentElement.classList.add(`js`),o(`click`,`.close`,function(){this.parentNode?.classList.add(`invisible`)}),o(`click`,`.searxng_init_map`,async function(e){e.preventDefault(),this.classList.remove(`searxng_init_map`),u(()=>h(async()=>{let{default:e}=await import(`./chunk/BnnvKC7b.min.js`);return{default:e}},__vite__mapDeps([0,1]),import.meta.url).then(({default:e})=>new e(this)),{on:`endpoint`,where:[t.results]})}),l.plugins?.includes(`infiniteScroll`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/DpvWr1cn.min.js`);return{default:e}},__vite__mapDeps([2,3,4]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]}),l.plugins?.includes(`calculator`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/C8c7HJzp.min.js`);return{default:e}},__vite__mapDeps([5,4,3]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]})}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.index]}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/od7pNHfk.min.js`),__vite__mapDeps([9,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.results]}),s(()=>{h(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([10,3]),import.meta.url)},{on:[c===t.preferences]});export{e as a,l as i,o as n,n as r,a as t};
|
||||||
//# sourceMappingURL=sxng-core.min.js.map
|
//# sourceMappingURL=sxng-core.min.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -60,7 +60,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="result-filesize">{{ _label(_("Filesize"), result.filesize) }}</p>
|
<p class="result-filesize">{{ _label(_("Filesize"), result.filesize) }}</p>
|
||||||
<p class="result-source">{{ _label(_("Source"), result.source) }}</p>
|
<p class="result-source">{{ _label(_("Source"), result.source) }}</p>
|
||||||
<p class="result-engine">{{ _label(_("Engine"), result.engine) }}</p>
|
<p class="result-engines">{{ _label(_("Engines"), ", ".join(result.engines)) }}</p>
|
||||||
<p class="result-url"><span>{{ _("View source") }}:</span>{{- "" -}}
|
<p class="result-url"><span>{{ _("View source") }}:</span>{{- "" -}}
|
||||||
<a {{ _target(results_on_new_tab) }} href="{{ result.url }}">{{ result.url }}</a>
|
<a {{ _target(results_on_new_tab) }} href="{{ result.url }}">{{ result.url }}</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Binary file not shown.
@@ -23,17 +23,16 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-06-19 05:08+0000\n"
|
"PO-Revision-Date: 2026-06-19 05:08+0000\n"
|
||||||
"Last-Translator: Raithlin <raithlin@noreply.codeberg.org>\n"
|
"Last-Translator: Raithlin <raithlin@noreply.codeberg.org>\n"
|
||||||
"Language-Team: Afrikaans <https://translate.codeberg.org/projects/searxng/"
|
|
||||||
"searxng/af/>\n"
|
|
||||||
"Language: af\n"
|
"Language: af\n"
|
||||||
|
"Language-Team: Afrikaans "
|
||||||
|
"<https://translate.codeberg.org/projects/searxng/searxng/af/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"X-Generator: Weblate 2026.6.1\n"
|
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -77,7 +76,7 @@ msgid "videos"
|
|||||||
msgstr "videos"
|
msgstr "videos"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "radio"
|
msgstr "radio"
|
||||||
|
|
||||||
@@ -551,7 +550,7 @@ msgstr "geantwoord"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Geen item gevind"
|
msgstr "Geen item gevind"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Bron"
|
msgstr "Bron"
|
||||||
@@ -647,7 +646,7 @@ msgstr "Genereer verskillende ewekansige waardes"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "Bereken {func} van die opsies"
|
msgstr "Bereken {func} van die opsies"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr "Geplaas deur {author}"
|
msgstr "Geplaas deur {author}"
|
||||||
@@ -665,19 +664,19 @@ msgstr "{title} (UITGEDIEN)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Hierdie inskrywing was vervang deur"
|
msgstr "Hierdie inskrywing was vervang deur"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Kanaal"
|
msgstr "Kanaal"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "bitsnelheid"
|
msgstr "bitsnelheid"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "stemme"
|
msgstr "stemme"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "klikke"
|
msgstr "klikke"
|
||||||
|
|
||||||
@@ -713,15 +712,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Die prent kon nie afgelaai word nie."
|
msgstr "Die prent kon nie afgelaai word nie."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Taal"
|
msgstr "Taal"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "boekgradering"
|
msgstr "boekgradering"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Lêer kwaliteit"
|
msgstr "Lêer kwaliteit"
|
||||||
|
|
||||||
@@ -1014,6 +1013,7 @@ msgid "Privacy"
|
|||||||
msgstr "Privaatheid"
|
msgstr "Privaatheid"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Enjins"
|
msgstr "Enjins"
|
||||||
|
|
||||||
@@ -1656,10 +1656,6 @@ msgstr "Beeldformate"
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr "oorspronklike formaat"
|
msgstr "oorspronklike formaat"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Enjin"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Bekyk bron"
|
msgstr "Bekyk bron"
|
||||||
@@ -2166,3 +2162,7 @@ msgstr "versteek video"
|
|||||||
|
|
||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Formaat"
|
#~ msgstr "Formaat"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Enjin"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -28,13 +28,14 @@
|
|||||||
# DZDevelopers <dzdevelopers@noreply.codeberg.org>, 2025.
|
# DZDevelopers <dzdevelopers@noreply.codeberg.org>, 2025.
|
||||||
# youtherthyf <youtherthyf@noreply.codeberg.org>, 2025.
|
# youtherthyf <youtherthyf@noreply.codeberg.org>, 2025.
|
||||||
# mustafa-phd <mustafa-phd@noreply.codeberg.org>, 2026.
|
# mustafa-phd <mustafa-phd@noreply.codeberg.org>, 2026.
|
||||||
|
# nebras <nebras@noreply.codeberg.org>, 2026.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-05-27 12:07+0000\n"
|
"PO-Revision-Date: 2026-06-28 18:07+0000\n"
|
||||||
"Last-Translator: mustafa-phd <mustafa-phd@noreply.codeberg.org>\n"
|
"Last-Translator: nebras <nebras@noreply.codeberg.org>\n"
|
||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
"Language-Team: Arabic "
|
"Language-Team: Arabic "
|
||||||
"<https://translate.codeberg.org/projects/searxng/searxng/ar/>\n"
|
"<https://translate.codeberg.org/projects/searxng/searxng/ar/>\n"
|
||||||
@@ -86,7 +87,7 @@ msgid "videos"
|
|||||||
msgstr "ڤيديوهات"
|
msgstr "ڤيديوهات"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "إذاعة"
|
msgstr "إذاعة"
|
||||||
|
|
||||||
@@ -560,7 +561,7 @@ msgstr "تمت الإجابة"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "لم يتم العثور على عنصر"
|
msgstr "لم يتم العثور على عنصر"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "مصدر"
|
msgstr "مصدر"
|
||||||
@@ -656,7 +657,7 @@ msgstr "توليد قِيم عشوائية مختلفة"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "حساب {func} من الحجج"
|
msgstr "حساب {func} من الحجج"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr "منشور بواسطة {author}"
|
msgstr "منشور بواسطة {author}"
|
||||||
@@ -674,19 +675,19 @@ msgstr "{title} (قديم)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "تم استبدال هذا الإدخال بـ"
|
msgstr "تم استبدال هذا الإدخال بـ"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "القناة"
|
msgstr "القناة"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "معدل البت"
|
msgstr "معدل البت"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "تصويتات"
|
msgstr "تصويتات"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "نقرات"
|
msgstr "نقرات"
|
||||||
|
|
||||||
@@ -720,15 +721,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "لا يمكن تنزيل الصورة."
|
msgstr "لا يمكن تنزيل الصورة."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "اللغة"
|
msgstr "اللغة"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "تقييم الكتاب"
|
msgstr "تقييم الكتاب"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "جودة الملف"
|
msgstr "جودة الملف"
|
||||||
|
|
||||||
@@ -1020,6 +1021,7 @@ msgid "Privacy"
|
|||||||
msgstr "الخصوصية"
|
msgstr "الخصوصية"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "المحركات"
|
msgstr "المحركات"
|
||||||
|
|
||||||
@@ -1653,15 +1655,11 @@ msgstr "الدقة"
|
|||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:55
|
#: searx/templates/simple/result_templates/images.html:55
|
||||||
msgid "Image formats"
|
msgid "Image formats"
|
||||||
msgstr ""
|
msgstr "صيغ الصور"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:56
|
#: searx/templates/simple/result_templates/images.html:56
|
||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr ""
|
msgstr "الصيغة الاصلية"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "محرك"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
@@ -2403,3 +2401,6 @@ msgstr "إخفاء الفيديو"
|
|||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "صيغة"
|
#~ msgstr "صيغة"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "محرك"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -21,18 +21,19 @@
|
|||||||
# muha7a <muha7a@noreply.codeberg.org>, 2025.
|
# muha7a <muha7a@noreply.codeberg.org>, 2025.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
"PO-Revision-Date: 2026-07-17 12:20+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
|
"Language-Team: Bulgarian <https://translate.codeberg.org/projects/searxng/"
|
||||||
|
"searxng/bg/>\n"
|
||||||
"Language: bg\n"
|
"Language: bg\n"
|
||||||
"Language-Team: Bulgarian "
|
|
||||||
"<https://translate.codeberg.org/projects/searxng/searxng/bg/>\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
"X-Generator: Weblate 2026.6.1\n"
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -76,7 +77,7 @@ msgid "videos"
|
|||||||
msgstr "видео"
|
msgstr "видео"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "радио"
|
msgstr "радио"
|
||||||
|
|
||||||
@@ -550,7 +551,7 @@ msgstr "Отговорено"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Не е намерен артикул"
|
msgstr "Не е намерен артикул"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Източник"
|
msgstr "Източник"
|
||||||
@@ -646,7 +647,7 @@ msgstr "Генерирайте различни произволни стойн
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "Изчислете {func} на аргументите"
|
msgstr "Изчислете {func} на аргументите"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -664,19 +665,19 @@ msgstr "{title} (ОСТАРЯЛО)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Този запис е заменен от"
|
msgstr "Този запис е заменен от"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Канал"
|
msgstr "Канал"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "Скорост"
|
msgstr "Скорост"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "Гласове"
|
msgstr "Гласове"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "клика"
|
msgstr "клика"
|
||||||
|
|
||||||
@@ -712,15 +713,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Снимката не може да бъде свалена."
|
msgstr "Снимката не може да бъде свалена."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Език"
|
msgstr "Език"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Рейтинг на книги"
|
msgstr "Рейтинг на книги"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Качество на файл"
|
msgstr "Качество на файл"
|
||||||
|
|
||||||
@@ -1006,6 +1007,7 @@ msgid "Privacy"
|
|||||||
msgstr "Поверителност"
|
msgstr "Поверителност"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Търсачки"
|
msgstr "Търсачки"
|
||||||
|
|
||||||
@@ -1015,7 +1017,7 @@ msgstr "Използвани търсачки в момента"
|
|||||||
|
|
||||||
#: searx/templates/simple/preferences.html:246
|
#: searx/templates/simple/preferences.html:246
|
||||||
msgid "Special Queries"
|
msgid "Special Queries"
|
||||||
msgstr "Специялни Запитвания"
|
msgstr "Специални Запитвания"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:254
|
#: searx/templates/simple/preferences.html:254
|
||||||
msgid "Cookies"
|
msgid "Cookies"
|
||||||
@@ -1657,10 +1659,6 @@ msgstr ""
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Търсачка"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Покажи източник"
|
msgstr "Покажи източник"
|
||||||
@@ -2404,3 +2402,5 @@ msgstr "скрий видеото"
|
|||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Формат"
|
#~ msgstr "Формат"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Търсачка"
|
||||||
|
|||||||
Binary file not shown.
@@ -29,7 +29,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
"Language: bn\n"
|
"Language: bn\n"
|
||||||
@@ -82,7 +82,7 @@ msgid "videos"
|
|||||||
msgstr "ভিডিও"
|
msgstr "ভিডিও"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "বেতার"
|
msgstr "বেতার"
|
||||||
|
|
||||||
@@ -556,7 +556,7 @@ msgstr "উত্তরকৃত"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "কোন আইটেম পাওয়া যায়নি"
|
msgstr "কোন আইটেম পাওয়া যায়নি"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "উৎস"
|
msgstr "উৎস"
|
||||||
@@ -652,7 +652,7 @@ msgstr "বিভিন্ন এলোমেলো মান তৈরি ক
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "{func} এই আদেশ কম্পিউট করো"
|
msgstr "{func} এই আদেশ কম্পিউট করো"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -670,19 +670,19 @@ msgstr "{title} (অচল)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "এই এনট্রিটি দ্বারা বাতিল করা হয়েছে৷"
|
msgstr "এই এনট্রিটি দ্বারা বাতিল করা হয়েছে৷"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "চ্যানেল"
|
msgstr "চ্যানেল"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "বিটরেট"
|
msgstr "বিটরেট"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "ভোট"
|
msgstr "ভোট"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "ক্লিক সংখ্যা"
|
msgstr "ক্লিক সংখ্যা"
|
||||||
|
|
||||||
@@ -717,15 +717,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "ছবিটি ডাউনলোড করা যায়নি ।"
|
msgstr "ছবিটি ডাউনলোড করা যায়নি ।"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "ভাষা"
|
msgstr "ভাষা"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "বই পর্যালোচনা"
|
msgstr "বই পর্যালোচনা"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "নথি মান"
|
msgstr "নথি মান"
|
||||||
|
|
||||||
@@ -1013,6 +1013,7 @@ msgid "Privacy"
|
|||||||
msgstr "গোপনীয়তা"
|
msgstr "গোপনীয়তা"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "ইঞ্জিন"
|
msgstr "ইঞ্জিন"
|
||||||
|
|
||||||
@@ -1649,10 +1650,6 @@ msgstr ""
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "ইঞ্জিন"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "উৎস দেখুন"
|
msgstr "উৎস দেখুন"
|
||||||
@@ -2162,3 +2159,6 @@ msgstr "ভিডিও লুকিয়ে ফেলুন"
|
|||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "সজ্জা"
|
#~ msgstr "সজ্জা"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "ইঞ্জিন"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -13,7 +13,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
"Language: bo\n"
|
"Language: bo\n"
|
||||||
@@ -66,7 +66,7 @@ msgid "videos"
|
|||||||
msgstr "བརྙན་ཟློས།"
|
msgstr "བརྙན་ཟློས།"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -540,7 +540,7 @@ msgstr ""
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "རྣམ་གྲངས་གང་ཡང་རྙེད་རྒྱུ་མ་བྱུང་།"
|
msgstr "རྣམ་གྲངས་གང་ཡང་རྙེད་རྒྱུ་མ་བྱུང་།"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -636,7 +636,7 @@ msgstr "ངེས་མེད་གྲངས་ཀ་ཁ་ཤས་ཐོབ་
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -654,19 +654,19 @@ msgstr ""
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "འཚོལ་བྱང་འདི་གཞན་གྱིས་ཚབ་བྱེད་འདུག"
|
msgstr "འཚོལ་བྱང་འདི་གཞན་གྱིས་ཚབ་བྱེད་འདུག"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -694,15 +694,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -980,6 +980,7 @@ msgid "Privacy"
|
|||||||
msgstr "མི་སྒེར་གསང་དོན།"
|
msgstr "མི་སྒེར་གསང་དོན།"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "སྒུལ་བྱེད།"
|
msgstr "སྒུལ་བྱེད།"
|
||||||
|
|
||||||
@@ -1606,10 +1607,6 @@ msgstr ""
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "ཡོངས་ཁུངས་ལ་ལྟ།"
|
msgstr "ཡོངས་ཁུངས་ལ་ལྟ།"
|
||||||
@@ -2295,3 +2292,6 @@ msgstr "རྙན་ཟློས་སྦས།"
|
|||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -29,19 +29,18 @@
|
|||||||
# MaCl0wSt <macl0wst@noreply.codeberg.org>, 2026.
|
# MaCl0wSt <macl0wst@noreply.codeberg.org>, 2026.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-06-17 20:19+0000\n"
|
"PO-Revision-Date: 2026-06-17 20:19+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
"Language-Team: Catalan <https://translate.codeberg.org/projects/searxng/"
|
|
||||||
"searxng/ca/>\n"
|
|
||||||
"Language: ca\n"
|
"Language: ca\n"
|
||||||
|
"Language-Team: Catalan "
|
||||||
|
"<https://translate.codeberg.org/projects/searxng/searxng/ca/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"X-Generator: Weblate 2026.6.1\n"
|
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -85,7 +84,7 @@ msgid "videos"
|
|||||||
msgstr "vídeos"
|
msgstr "vídeos"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "radio"
|
msgstr "radio"
|
||||||
|
|
||||||
@@ -559,7 +558,7 @@ msgstr "contestat"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "No s'ha trobat cap element"
|
msgstr "No s'ha trobat cap element"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Origen"
|
msgstr "Origen"
|
||||||
@@ -655,7 +654,7 @@ msgstr "Genera diferents valors aleatoris"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -673,19 +672,19 @@ msgstr "{title} (OBSOLET)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Aquesta entrada ha estat substituïda per"
|
msgstr "Aquesta entrada ha estat substituïda per"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Canal"
|
msgstr "Canal"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "tasa de bits"
|
msgstr "tasa de bits"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "vots"
|
msgstr "vots"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "clics"
|
msgstr "clics"
|
||||||
|
|
||||||
@@ -720,15 +719,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "No s'ha pogut baixar la imatge."
|
msgstr "No s'ha pogut baixar la imatge."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Llengua"
|
msgstr "Llengua"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Valoració de llibre"
|
msgstr "Valoració de llibre"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Qualitat del fitxer"
|
msgstr "Qualitat del fitxer"
|
||||||
|
|
||||||
@@ -1013,6 +1012,7 @@ msgid "Privacy"
|
|||||||
msgstr "Privadesa"
|
msgstr "Privadesa"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Motors de cerca"
|
msgstr "Motors de cerca"
|
||||||
|
|
||||||
@@ -1658,10 +1658,6 @@ msgstr ""
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr "format original"
|
msgstr "format original"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Cercador"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Veure el codi font"
|
msgstr "Veure el codi font"
|
||||||
@@ -2424,3 +2420,7 @@ msgstr "oculta el vídeo"
|
|||||||
|
|
||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Format"
|
#~ msgstr "Format"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Cercador"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -25,20 +25,19 @@
|
|||||||
# radekjuthner <radekjuthner@noreply.codeberg.org>, 2025.
|
# radekjuthner <radekjuthner@noreply.codeberg.org>, 2025.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-06-16 07:07+0000\n"
|
"PO-Revision-Date: 2026-06-16 07:07+0000\n"
|
||||||
"Last-Translator: Fjuro <fjuro@noreply.codeberg.org>\n"
|
"Last-Translator: Fjuro <fjuro@noreply.codeberg.org>\n"
|
||||||
"Language-Team: Czech <https://translate.codeberg.org/projects/searxng/"
|
|
||||||
"searxng/cs/>\n"
|
|
||||||
"Language: cs\n"
|
"Language: cs\n"
|
||||||
|
"Language-Team: Czech "
|
||||||
|
"<https://translate.codeberg.org/projects/searxng/searxng/cs/>\n"
|
||||||
|
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && "
|
||||||
|
"n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
|
|
||||||
"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
|
|
||||||
"X-Generator: Weblate 2026.6.1\n"
|
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -82,7 +81,7 @@ msgid "videos"
|
|||||||
msgstr "videa"
|
msgstr "videa"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "rádio"
|
msgstr "rádio"
|
||||||
|
|
||||||
@@ -556,7 +555,7 @@ msgstr "zodpovězené"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Nic nenalezeno"
|
msgstr "Nic nenalezeno"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "zdroj"
|
msgstr "zdroj"
|
||||||
@@ -652,7 +651,7 @@ msgstr "Generování náhodných hodnot"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "Vypočítat {func} argumentů"
|
msgstr "Vypočítat {func} argumentů"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr "Autor: {author}"
|
msgstr "Autor: {author}"
|
||||||
@@ -670,19 +669,19 @@ msgstr "{title} (ZASTARALÉ)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Tato položka byla nahrazena položkou"
|
msgstr "Tato položka byla nahrazena položkou"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Kanál"
|
msgstr "Kanál"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "datový tok"
|
msgstr "datový tok"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "hlasy"
|
msgstr "hlasy"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "kliknutí"
|
msgstr "kliknutí"
|
||||||
|
|
||||||
@@ -717,15 +716,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Obrázek se nepodařilo stáhnout."
|
msgstr "Obrázek se nepodařilo stáhnout."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Jazyk"
|
msgstr "Jazyk"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Hodnocení knih"
|
msgstr "Hodnocení knih"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Množství souborů"
|
msgstr "Množství souborů"
|
||||||
|
|
||||||
@@ -1016,6 +1015,7 @@ msgid "Privacy"
|
|||||||
msgstr "Soukromí"
|
msgstr "Soukromí"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Vyhledávače"
|
msgstr "Vyhledávače"
|
||||||
|
|
||||||
@@ -1659,10 +1659,6 @@ msgstr "Formáty obrázků"
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr "původní formát"
|
msgstr "původní formát"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Vyhledávač"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Zobrazit zdroj"
|
msgstr "Zobrazit zdroj"
|
||||||
@@ -2410,3 +2406,7 @@ msgstr "skrýt video"
|
|||||||
|
|
||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Formát"
|
#~ msgstr "Formát"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Vyhledávač"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -20,7 +20,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
"PO-Revision-Date: 2026-05-19 12:07+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
"Language: cy\n"
|
"Language: cy\n"
|
||||||
@@ -74,7 +74,7 @@ msgid "videos"
|
|||||||
msgstr "fideos"
|
msgstr "fideos"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "radio"
|
msgstr "radio"
|
||||||
|
|
||||||
@@ -548,7 +548,7 @@ msgstr "wedi'i ateb"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Ni chanfuwyd eitem"
|
msgstr "Ni chanfuwyd eitem"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Ffynhonnell"
|
msgstr "Ffynhonnell"
|
||||||
@@ -644,7 +644,7 @@ msgstr "Cynhyrchu gwahanol werthoedd ar hap"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -662,19 +662,19 @@ msgstr "{title} (OBSOLETE)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Mae'r cofnod hwn wedi ei ddisodli gan"
|
msgstr "Mae'r cofnod hwn wedi ei ddisodli gan"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Sianel"
|
msgstr "Sianel"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "cyfradd didau"
|
msgstr "cyfradd didau"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "pleidleisiau"
|
msgstr "pleidleisiau"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "cliciau"
|
msgstr "cliciau"
|
||||||
|
|
||||||
@@ -710,15 +710,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Doedd dim modd islwytho'r ddelwedd."
|
msgstr "Doedd dim modd islwytho'r ddelwedd."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Iaith"
|
msgstr "Iaith"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Gradd llyfr"
|
msgstr "Gradd llyfr"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "ansawdd ffeil"
|
msgstr "ansawdd ffeil"
|
||||||
|
|
||||||
@@ -1003,6 +1003,7 @@ msgid "Privacy"
|
|||||||
msgstr "Preifatrwydd"
|
msgstr "Preifatrwydd"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Peiriannau"
|
msgstr "Peiriannau"
|
||||||
|
|
||||||
@@ -1638,10 +1639,6 @@ msgstr ""
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Peiriant"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Gweld y ffynhonnell"
|
msgstr "Gweld y ffynhonnell"
|
||||||
@@ -2363,3 +2360,6 @@ msgstr "cuddio'r fideo"
|
|||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Fformat"
|
#~ msgstr "Fformat"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Peiriant"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -17,19 +17,18 @@
|
|||||||
# return42 <return42@noreply.codeberg.org>, 2025, 2026.
|
# return42 <return42@noreply.codeberg.org>, 2025, 2026.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-06-16 07:07+0000\n"
|
"PO-Revision-Date: 2026-06-16 07:07+0000\n"
|
||||||
"Last-Translator: AndersNordh <andersnordh@noreply.codeberg.org>\n"
|
"Last-Translator: AndersNordh <andersnordh@noreply.codeberg.org>\n"
|
||||||
"Language-Team: Danish <https://translate.codeberg.org/projects/searxng/"
|
|
||||||
"searxng/da/>\n"
|
|
||||||
"Language: da\n"
|
"Language: da\n"
|
||||||
|
"Language-Team: Danish "
|
||||||
|
"<https://translate.codeberg.org/projects/searxng/searxng/da/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"X-Generator: Weblate 2026.6.1\n"
|
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -73,7 +72,7 @@ msgid "videos"
|
|||||||
msgstr "videoer"
|
msgstr "videoer"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "Radio"
|
msgstr "Radio"
|
||||||
|
|
||||||
@@ -547,7 +546,7 @@ msgstr "svaret"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Intet fundet"
|
msgstr "Intet fundet"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Kilde"
|
msgstr "Kilde"
|
||||||
@@ -643,7 +642,7 @@ msgstr "Generér forskellige tilfældige værdier"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "Beregn {func} af argumenterne"
|
msgstr "Beregn {func} af argumenterne"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr "Indsendt af {author}"
|
msgstr "Indsendt af {author}"
|
||||||
@@ -661,19 +660,19 @@ msgstr "{title} (FORÆLDET)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Denne værdi er blevet overskrevet af"
|
msgstr "Denne værdi er blevet overskrevet af"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Kanal"
|
msgstr "Kanal"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "Bitrate"
|
msgstr "Bitrate"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "Stemmer"
|
msgstr "Stemmer"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "Klik"
|
msgstr "Klik"
|
||||||
|
|
||||||
@@ -709,15 +708,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Dette billede kunne ikke downloades."
|
msgstr "Dette billede kunne ikke downloades."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprog"
|
msgstr "Sprog"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Bogbedømmelse"
|
msgstr "Bogbedømmelse"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Filkvalitet"
|
msgstr "Filkvalitet"
|
||||||
|
|
||||||
@@ -1010,6 +1009,7 @@ msgid "Privacy"
|
|||||||
msgstr "Privatliv"
|
msgstr "Privatliv"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Søgemaskiner"
|
msgstr "Søgemaskiner"
|
||||||
|
|
||||||
@@ -1655,10 +1655,6 @@ msgstr "Billedformater"
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr "originalt format"
|
msgstr "originalt format"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Maskine"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Vis kilde"
|
msgstr "Vis kilde"
|
||||||
@@ -2419,3 +2415,7 @@ msgstr "skjul video"
|
|||||||
|
|
||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Format"
|
#~ msgstr "Format"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Maskine"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -32,19 +32,18 @@
|
|||||||
# Serpensin <serpensin@noreply.codeberg.org>, 2026.
|
# Serpensin <serpensin@noreply.codeberg.org>, 2026.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: searx\n"
|
"Project-Id-Version: searx\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-06-13 11:31+0000\n"
|
"POT-Creation-Date: 2026-07-15 15:45+0000\n"
|
||||||
"PO-Revision-Date: 2026-06-17 20:19+0000\n"
|
"PO-Revision-Date: 2026-06-17 20:19+0000\n"
|
||||||
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
"Last-Translator: return42 <return42@noreply.codeberg.org>\n"
|
||||||
"Language-Team: German <https://translate.codeberg.org/projects/searxng/"
|
|
||||||
"searxng/de/>\n"
|
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
"Language-Team: German "
|
||||||
|
"<https://translate.codeberg.org/projects/searxng/searxng/de/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
|
||||||
"X-Generator: Weblate 2026.6.1\n"
|
|
||||||
"Generated-By: Babel 2.18.0\n"
|
"Generated-By: Babel 2.18.0\n"
|
||||||
|
|
||||||
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
#. CONSTANT_NAMES['NO_SUBGROUPING']
|
||||||
@@ -88,7 +87,7 @@ msgid "videos"
|
|||||||
msgstr "Videos"
|
msgstr "Videos"
|
||||||
|
|
||||||
#. CATEGORY_NAMES['RADIO']
|
#. CATEGORY_NAMES['RADIO']
|
||||||
#: searx/engines/radio_browser.py:159 searx/searxng.msg
|
#: searx/engines/radio_browser.py:160 searx/searxng.msg
|
||||||
msgid "radio"
|
msgid "radio"
|
||||||
msgstr "Radio"
|
msgstr "Radio"
|
||||||
|
|
||||||
@@ -562,7 +561,7 @@ msgstr "beantwortet"
|
|||||||
msgid "No item found"
|
msgid "No item found"
|
||||||
msgstr "Keine Einträge gefunden"
|
msgstr "Keine Einträge gefunden"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:258
|
#: searx/engines/qwant.py:286
|
||||||
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
#: searx/templates/simple/result_templates/images.html:62 searx/webapp.py:328
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "Quelle"
|
msgstr "Quelle"
|
||||||
@@ -658,7 +657,7 @@ msgstr "Erzeugt diverse Zufallswerte"
|
|||||||
msgid "Compute {func} of the arguments"
|
msgid "Compute {func} of the arguments"
|
||||||
msgstr "Berechne {func} zu den Argumenten"
|
msgstr "Berechne {func} zu den Argumenten"
|
||||||
|
|
||||||
#: searx/engines/boardreader.py:107
|
#: searx/engines/boardreader.py:108
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Posted by {author}"
|
msgid "Posted by {author}"
|
||||||
msgstr "Beitrag von {author}"
|
msgstr "Beitrag von {author}"
|
||||||
@@ -676,19 +675,19 @@ msgstr "{title} (OBSOLET)"
|
|||||||
msgid "This entry has been superseded by"
|
msgid "This entry has been superseded by"
|
||||||
msgstr "Dieser Eintrag wurde überschrieben von"
|
msgstr "Dieser Eintrag wurde überschrieben von"
|
||||||
|
|
||||||
#: searx/engines/qwant.py:260
|
#: searx/engines/qwant.py:288
|
||||||
msgid "Channel"
|
msgid "Channel"
|
||||||
msgstr "Kanal"
|
msgstr "Kanal"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:161
|
#: searx/engines/radio_browser.py:162
|
||||||
msgid "bitrate"
|
msgid "bitrate"
|
||||||
msgstr "Bitrate"
|
msgstr "Bitrate"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:162
|
#: searx/engines/radio_browser.py:163
|
||||||
msgid "votes"
|
msgid "votes"
|
||||||
msgstr "Stimmen"
|
msgstr "Stimmen"
|
||||||
|
|
||||||
#: searx/engines/radio_browser.py:163
|
#: searx/engines/radio_browser.py:164
|
||||||
msgid "clicks"
|
msgid "clicks"
|
||||||
msgstr "Clicks"
|
msgstr "Clicks"
|
||||||
|
|
||||||
@@ -724,15 +723,15 @@ msgstr ""
|
|||||||
msgid "The image could not be downloaded."
|
msgid "The image could not be downloaded."
|
||||||
msgstr "Das Bild konnte nicht heruntergeladen werden."
|
msgstr "Das Bild konnte nicht heruntergeladen werden."
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:79
|
#: searx/engines/zlibrary.py:80
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprache"
|
msgstr "Sprache"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:80
|
#: searx/engines/zlibrary.py:81
|
||||||
msgid "Book rating"
|
msgid "Book rating"
|
||||||
msgstr "Buchbewertung"
|
msgstr "Buchbewertung"
|
||||||
|
|
||||||
#: searx/engines/zlibrary.py:81
|
#: searx/engines/zlibrary.py:82
|
||||||
msgid "File quality"
|
msgid "File quality"
|
||||||
msgstr "Dateiqualität"
|
msgstr "Dateiqualität"
|
||||||
|
|
||||||
@@ -1031,6 +1030,7 @@ msgid "Privacy"
|
|||||||
msgstr "Privatsphäre"
|
msgstr "Privatsphäre"
|
||||||
|
|
||||||
#: searx/templates/simple/preferences.html:235
|
#: searx/templates/simple/preferences.html:235
|
||||||
|
#: searx/templates/simple/result_templates/images.html:63
|
||||||
msgid "Engines"
|
msgid "Engines"
|
||||||
msgstr "Suchmaschinen"
|
msgstr "Suchmaschinen"
|
||||||
|
|
||||||
@@ -1674,10 +1674,6 @@ msgstr "Bildformate"
|
|||||||
msgid "original format"
|
msgid "original format"
|
||||||
msgstr "Originalformat"
|
msgstr "Originalformat"
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:63
|
|
||||||
msgid "Engine"
|
|
||||||
msgstr "Suchmaschine"
|
|
||||||
|
|
||||||
#: searx/templates/simple/result_templates/images.html:64
|
#: searx/templates/simple/result_templates/images.html:64
|
||||||
msgid "View source"
|
msgid "View source"
|
||||||
msgstr "Seite besuchen"
|
msgstr "Seite besuchen"
|
||||||
@@ -2466,3 +2462,7 @@ msgstr "Video verstecken"
|
|||||||
|
|
||||||
#~ msgid "Format"
|
#~ msgid "Format"
|
||||||
#~ msgstr "Format"
|
#~ msgstr "Format"
|
||||||
|
|
||||||
|
#~ msgid "Engine"
|
||||||
|
#~ msgstr "Suchmaschine"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user