├── .editorconfig
├── .eslintrc.json
├── .gitattributes
├── .github
├── CODEOWNERS
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ ├── feature_request.md
│ └── mime_request.md
├── dependabot.yml
└── workflows
│ ├── block-merge-freeze.yml
│ ├── block-unconventional-commits.yml
│ ├── command-compile.yml
│ ├── cypress-snapshot-update.yml
│ ├── cypress.yml
│ ├── dependabot-approve-merge.yml
│ ├── fixup.yml
│ ├── lint-eslint.yml
│ ├── lint-php-cs.yml
│ ├── lint-php.yml
│ ├── lint-stylelint.yml
│ ├── node.yml
│ ├── npm-audit-fix.yml
│ ├── pr-feedback.yml
│ ├── psalm.yml
│ └── reuse.yml
├── .gitignore
├── .l10nignore
├── .npmignore
├── .php-cs-fixer.dist.php
├── .stylelintignore
├── .tx
└── config
├── AUTHORS.md
├── COPYING
├── LICENSES
├── AGPL-3.0-or-later.txt
├── Apache-2.0.txt
├── BSD-3-Clause.txt
├── CC0-1.0.txt
├── GPL-3.0-or-later.txt
├── ISC.txt
├── LicenseRef-NextcloudTrademarks.txt
├── LicenseRef-Unsplash.txt
├── MIT.txt
└── MPL-2.0.txt
├── README.md
├── REUSE.toml
├── appinfo
└── info.xml
├── composer.json
├── composer.lock
├── composer
├── autoload.php
├── composer.json
└── composer
│ ├── ClassLoader.php
│ ├── LICENSE
│ ├── autoload_classmap.php
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── autoload_real.php
│ └── autoload_static.php
├── css
├── NcActionButton-DndYZcrz.chunk.css
├── NcActionLink-Cay-IPuV.chunk.css
├── index-DCp30a-3.chunk.css
├── init-BcY_9rzn.chunk.css
├── logger-60RCWKf0.chunk.css
├── main-BwzbmUGl.chunk.css
├── viewer-init.css
└── viewer-main.css
├── cypress.config.ts
├── cypress
├── .eslintrc.json
├── e2e
│ ├── a11y.cy.ts
│ ├── actions
│ │ ├── delete.cy.ts
│ │ ├── download.cy.ts
│ │ └── sidebar.cy.ts
│ ├── audios
│ │ ├── audio.mpeg.cy.ts
│ │ ├── audio.ogg.cy.ts
│ │ └── audios.cy.ts
│ ├── download-forbidden.cy.ts
│ ├── files.cy.ts
│ ├── images
│ │ ├── image-apng.cy.ts
│ │ ├── image-small.png.cy.ts
│ │ ├── image.gif.cy.ts
│ │ ├── image.ico.cy.ts
│ │ ├── image.png.cy.ts
│ │ ├── image.svg.cy.ts
│ │ ├── image.webp.cy.ts
│ │ ├── images-custom-list-loadmore.cy.ts
│ │ ├── images-custom-list.cy.ts
│ │ └── images.cy.ts
│ ├── mixins
│ │ ├── audio.ts
│ │ ├── image.ts
│ │ ├── oddname.ts
│ │ └── video.ts
│ ├── navigation.cy.ts
│ ├── non-dav-files.cy.ts
│ ├── oddname
│ │ ├── oddname-audio.cy.ts
│ │ ├── oddname-image.cy.ts
│ │ ├── oddname-sidebar.cy.ts
│ │ └── oddname-video.cy.ts
│ ├── sharing
│ │ ├── download-share-disabled.cy.ts
│ │ ├── download-share.cy.ts
│ │ ├── files-shares.cy.ts
│ │ └── single-file-share.cy.ts
│ ├── videos
│ │ ├── video.mkv.cy.ts
│ │ ├── video.mp4.cy.ts
│ │ ├── video.ogv.cy.ts
│ │ ├── video.webm.cy.ts
│ │ └── videos.cy.ts
│ └── visual-regression.cy.ts
├── fixtures
│ ├── audio.mp3
│ ├── audio.ogg
│ ├── image-apng.png
│ ├── image-small.png
│ ├── image.bmp
│ ├── image.gif
│ ├── image.heic
│ ├── image.ico
│ ├── image.png
│ ├── image.svg
│ ├── image.webp
│ ├── image1.jpg
│ ├── image2.jpg
│ ├── image3.jpg
│ ├── image4.jpg
│ ├── test-card.mp4
│ ├── test-card.png
│ ├── video.mkv
│ ├── video.ogv
│ ├── video.webm
│ ├── video1.mp4
│ └── video2.mp4
├── snapshots
│ └── base
│ │ └── cypress
│ │ └── e2e
│ │ └── visual-regression.cy.ts
│ │ ├── image.png
│ │ ├── image2.png
│ │ ├── non-dav.png
│ │ └── video.png
├── support
│ ├── commands.ts
│ └── e2e.ts
└── tsconfig.json
├── img
├── app.svg
└── blank.mp4
├── js
├── NcActionButton-qdAUHyGz.chunk.mjs
├── NcActionButton-qdAUHyGz.chunk.mjs.license
├── NcActionButton-qdAUHyGz.chunk.mjs.map
├── NcActionButton-qdAUHyGz.chunk.mjs.map.license
├── NcActionLink-TR7mwuor.chunk.mjs
├── NcActionLink-TR7mwuor.chunk.mjs.license
├── NcActionLink-TR7mwuor.chunk.mjs.map
├── NcActionLink-TR7mwuor.chunk.mjs.map.license
├── actionText-fFcUPi2g-gjw6zxAU.chunk.mjs
├── actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.license
├── actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.map
├── actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.map.license
├── index-Dly6xalz.chunk.mjs.license
├── index-Dly6xalz.chunk.mjs.map.license
├── index-DtIMqdu8.chunk.mjs
├── index-DtIMqdu8.chunk.mjs.license
├── index-DtIMqdu8.chunk.mjs.map
├── index-DtIMqdu8.chunk.mjs.map.license
├── index.esm-CAkhAkGw.chunk.mjs
├── index.esm-CAkhAkGw.chunk.mjs.license
├── index.esm-CAkhAkGw.chunk.mjs.map
├── index.esm-CAkhAkGw.chunk.mjs.map.license
├── logger-Bw8oxZ_4.chunk.mjs
├── logger-Bw8oxZ_4.chunk.mjs.license
├── logger-Bw8oxZ_4.chunk.mjs.map
├── logger-Bw8oxZ_4.chunk.mjs.map.license
├── viewer-init.mjs
├── viewer-init.mjs.license
├── viewer-init.mjs.map
├── viewer-init.mjs.map.license
├── viewer-main.mjs
├── viewer-main.mjs.license
├── viewer-main.mjs.map
└── viewer-main.mjs.map.license
├── l10n
├── .gitkeep
├── af.js
├── af.json
├── ar.js
├── ar.json
├── ast.js
├── ast.json
├── az.js
├── az.json
├── bg.js
├── bg.json
├── bn_BD.js
├── bn_BD.json
├── br.js
├── br.json
├── bs.js
├── bs.json
├── ca.js
├── ca.json
├── cs.js
├── cs.json
├── cy_GB.js
├── cy_GB.json
├── da.js
├── da.json
├── de.js
├── de.json
├── de_DE.js
├── de_DE.json
├── el.js
├── el.json
├── en_GB.js
├── en_GB.json
├── eo.js
├── eo.json
├── es.js
├── es.json
├── es_419.js
├── es_419.json
├── es_AR.js
├── es_AR.json
├── es_CL.js
├── es_CL.json
├── es_CO.js
├── es_CO.json
├── es_CR.js
├── es_CR.json
├── es_DO.js
├── es_DO.json
├── es_EC.js
├── es_EC.json
├── es_GT.js
├── es_GT.json
├── es_HN.js
├── es_HN.json
├── es_MX.js
├── es_MX.json
├── es_NI.js
├── es_NI.json
├── es_PA.js
├── es_PA.json
├── es_PE.js
├── es_PE.json
├── es_PR.js
├── es_PR.json
├── es_PY.js
├── es_PY.json
├── es_SV.js
├── es_SV.json
├── es_UY.js
├── es_UY.json
├── et_EE.js
├── et_EE.json
├── eu.js
├── eu.json
├── fa.js
├── fa.json
├── fi.js
├── fi.json
├── fr.js
├── fr.json
├── ga.js
├── ga.json
├── gd.js
├── gd.json
├── gl.js
├── gl.json
├── he.js
├── he.json
├── hr.js
├── hr.json
├── hu.js
├── hu.json
├── hy.js
├── hy.json
├── ia.js
├── ia.json
├── id.js
├── id.json
├── is.js
├── is.json
├── it.js
├── it.json
├── ja.js
├── ja.json
├── ka.js
├── ka.json
├── ka_GE.js
├── ka_GE.json
├── kab.js
├── kab.json
├── km.js
├── km.json
├── kn.js
├── kn.json
├── ko.js
├── ko.json
├── lb.js
├── lb.json
├── lo.js
├── lo.json
├── lt_LT.js
├── lt_LT.json
├── lv.js
├── lv.json
├── mk.js
├── mk.json
├── mn.js
├── mn.json
├── ms_MY.js
├── ms_MY.json
├── nb.js
├── nb.json
├── nl.js
├── nl.json
├── nn_NO.js
├── nn_NO.json
├── oc.js
├── oc.json
├── pl.js
├── pl.json
├── ps.js
├── ps.json
├── pt_BR.js
├── pt_BR.json
├── pt_PT.js
├── pt_PT.json
├── ro.js
├── ro.json
├── ru.js
├── ru.json
├── sc.js
├── sc.json
├── si.js
├── si.json
├── sk.js
├── sk.json
├── sl.js
├── sl.json
├── sq.js
├── sq.json
├── sr.js
├── sr.json
├── sr@latin.js
├── sr@latin.json
├── sv.js
├── sv.json
├── ta.js
├── ta.json
├── th.js
├── th.json
├── tk.js
├── tk.json
├── tr.js
├── tr.json
├── ug.js
├── ug.json
├── uk.js
├── uk.json
├── ur_PK.js
├── ur_PK.json
├── uz.js
├── uz.json
├── vi.js
├── vi.json
├── zh_CN.js
├── zh_CN.json
├── zh_HK.js
├── zh_HK.json
├── zh_TW.js
└── zh_TW.json
├── lib
├── AppInfo
│ └── Application.php
├── Event
│ └── LoadViewer.php
└── Listener
│ └── LoadViewerScript.php
├── package-lock.json
├── package.json
├── psalm.xml
├── renovate.json
├── src
├── assets
│ └── menu-sidebar-white.svg
├── components
│ ├── Audios.vue
│ ├── Error.vue
│ ├── ImageEditor.vue
│ ├── Images.vue
│ └── Videos.vue
├── files_actions
│ └── viewerAction.ts
├── global.d.ts
├── init.ts
├── main.js
├── mixins
│ ├── Mime.js
│ ├── Plyr.scss
│ └── PreviewUrl.js
├── models
│ ├── audios.js
│ ├── editorTranslations.js
│ ├── file.js
│ ├── images.js
│ └── videos.js
├── services
│ ├── FileInfo.ts
│ ├── FileList.ts
│ ├── FileSortingConfig.ts
│ ├── Viewer.js
│ ├── WebdavClient.ts
│ ├── logger.js
│ └── mediaPreloader.ts
├── shims.d.ts
├── utils
│ ├── CancelableRequest.js
│ ├── canDownload.ts
│ ├── fileUtils.ts
│ ├── livePhotoUtils.ts
│ ├── models.ts
│ ├── numberUtil.ts
│ └── previewUtils.ts
└── views
│ └── Viewer.vue
├── stylelint.config.cjs
├── tests
└── psalm-baseline.xml
├── tsconfig.json
└── vite.config.ts
/.editorconfig:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = tab
8 | indent_size = 4
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "globals": {
3 | "appName": true,
4 | "appVersion": true,
5 | "PLYR_ICONS": true,
6 | "oc_defaults": true,
7 | "__dirname": true
8 | },
9 | "extends": [
10 | "@nextcloud/eslint-config/typescript"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | /js/* binary
4 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | /appinfo/info.xml @skjnldsv @szaimen
2 |
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | custom: https://nextcloud.com/include/
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: 0. Needs triage, bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Browser log**
38 | ```
39 | Open your console, reload your page and/or do the action leading to this issue and copy/paste the log in this thread.
40 | ```
41 |
42 |
43 | How to access your browser console (Click to expand)
44 |
45 | # Chrome
46 | - Press either CTRL + SHIFT + J to open the “console” tab of the Developer Tools.
47 | - Alternative method:
48 | 1. Press either CTRL + SHIFT + I or F12 to open the Developer Tools.
49 | 2. Click the “console” tab.
50 |
51 | # Safari
52 | - Press CMD + ALT + I to open the Web Inspector.
53 | - See Chrome’s step 2. (Chrome and Safari have pretty much identical dev tools.)
54 |
55 | # IE9
56 | 1. Press F12 to open the developer tools.
57 | 2. Click the “console” tab.
58 |
59 | # Firefox
60 | - Press CTRL + SHIFT + K to open the Web console (COMMAND + SHIFT + K on Macs).
61 | - or, if Firebug is installed (recommended):
62 | 1. Press F12 to open Firebug.
63 | 2. Click on the “console” tab.
64 |
65 | # Opera
66 | 1. Press CTRL + SHIFT + I to open Dragonfly.
67 | 2. Click on the “console” tab.
68 |
69 |
70 | **Additional context**
71 | Add any other context about the problem here.
72 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Image editor feature request
4 | url: https://github.com/scaleflex/filerobot-image-editor/issues
5 | about: Please open an issue in this repository directly
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: 0. Needs triage, enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/mime_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: File support request
3 | about: Request support for a file type currently not supported
4 | title: Add support for xxx files
5 | labels: enhancement, 0. Needs triage, file support request
6 | assignees: ''
7 |
8 | ---
9 |
10 | **What file type**
11 | e.g. image/jpeg
12 |
13 | **What application is using it**
14 | e.g. Gimp
15 |
16 | **Please attach a sample file here** (or a direct external link to one)
17 | [jpeg sample file](https://upload.wikimedia.org/wikipedia/commons/0/0e/Felis_silvestris_silvestris.jpg)
18 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | version: 2
4 | updates:
5 | - package-ecosystem: github-actions
6 | directory: "/"
7 | schedule:
8 | interval: daily
9 | timezone: Europe/Paris
10 | labels:
11 | - "3. to review"
12 | - "dependencies"
13 |
14 | - package-ecosystem: composer
15 | directory: "/"
16 | schedule:
17 | interval: weekly
18 | day: saturday
19 | time: "03:00"
20 | timezone: Europe/Paris
21 | open-pull-requests-limit: 10
22 | labels:
23 | - "3. to review"
24 | - "dependencies"
25 |
--------------------------------------------------------------------------------
/.github/workflows/block-merge-freeze.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Block merges during freezes
10 |
11 | on:
12 | pull_request:
13 | types: [opened, ready_for_review, reopened, synchronize]
14 |
15 | permissions:
16 | contents: read
17 |
18 | concurrency:
19 | group: block-merge-freeze-${{ github.head_ref || github.run_id }}
20 | cancel-in-progress: true
21 |
22 | jobs:
23 | block-merges-during-freeze:
24 | name: Block merges during freezes
25 |
26 | if: github.event.pull_request.draft == false
27 |
28 | runs-on: ubuntu-latest-low
29 |
30 | steps:
31 | - name: Register server reference to fallback to master branch
32 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
33 | with:
34 | github-token: ${{secrets.GITHUB_TOKEN}}
35 | script: |
36 | const baseRef = context.payload.pull_request.base.ref
37 | if (baseRef === 'main' || baseRef === 'master') {
38 | core.exportVariable('server_ref', 'master');
39 | console.log('Setting server_ref to master');
40 | } else {
41 | const regex = /^stable(\d+)$/
42 | const match = baseRef.match(regex)
43 | if (match) {
44 | core.exportVariable('server_ref', match[0]);
45 | console.log('Setting server_ref to ' + match[0]);
46 | } else {
47 | console.log('Not based on master/main/stable*, so skipping freeze check');
48 | }
49 | }
50 |
51 | - name: Download version.php from ${{ env.server_ref }}
52 | if: ${{ env.server_ref != '' }}
53 | run: curl 'https://raw.githubusercontent.com/nextcloud/server/${{ env.server_ref }}/version.php' --output version.php
54 |
55 | - name: Run check
56 | if: ${{ env.server_ref != '' }}
57 | run: cat version.php | grep 'OC_VersionString' | grep -i -v 'RC'
58 |
--------------------------------------------------------------------------------
/.github/workflows/block-unconventional-commits.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Block unconventional commits
10 |
11 | on:
12 | pull_request:
13 | types: [opened, ready_for_review, reopened, synchronize]
14 |
15 | permissions:
16 | contents: read
17 |
18 | concurrency:
19 | group: block-unconventional-commits-${{ github.head_ref || github.run_id }}
20 | cancel-in-progress: true
21 |
22 | jobs:
23 | block-unconventional-commits:
24 | name: Block unconventional commits
25 |
26 | runs-on: ubuntu-latest-low
27 |
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
31 | with:
32 | persist-credentials: false
33 |
34 | - uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 # v1.3.0
35 | with:
36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37 |
--------------------------------------------------------------------------------
/.github/workflows/cypress-snapshot-update.yml:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: MIT
3 | name: Cypress snapshot update
4 |
5 | on:
6 | workflow_dispatch:
7 | schedule:
8 | # At 2:30 on Sundays
9 | - cron: '20 1 * * 0'
10 |
11 | jobs:
12 | update:
13 | runs-on: ubuntu-latest
14 |
15 | strategy:
16 | fail-fast: false
17 | matrix:
18 | branches: ["master", "stable30", "stable31"]
19 |
20 | name: cypress-snapshot-update-${{ matrix.branches }}
21 |
22 | steps:
23 | - name: Checkout app
24 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
25 | with:
26 | ref: ${{ matrix.branches }}
27 |
28 | - name: Read package.json node and npm engines version
29 | uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
30 | id: versions
31 | with:
32 | fallbackNode: "^20"
33 | fallbackNpm: "^10"
34 |
35 | - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
36 | uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
37 | with:
38 | node-version: ${{ steps.versions.outputs.nodeVersion }}
39 |
40 | - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
41 | run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
42 |
43 | - name: Install node dependencies & build app
44 | run: |
45 | npm ci
46 | npm run build --if-present
47 |
48 | - name: Snapshot update
49 | run: npm run cypress:update-snapshots
50 |
51 | - name: Create Pull Request
52 | if: always()
53 | uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v5
54 | with:
55 | token: ${{ secrets.COMMAND_BOT_PAT }}
56 | commit-message: "chore(deps): cypress snapshot update"
57 | committer: GitHub
58 | author: nextcloud-command
59 | signoff: true
60 | branch: automated/noid/${{ matrix.branches }}-cypress-snapshot-update
61 | title: "[${{ matrix.branches }}] Update cypress snapshots"
62 | body: |
63 | Auto-generated update of cypress snapshots
64 | labels: |
65 | dependencies
66 | 3. to review
67 | add-paths: |
68 | cypress/snapshots
69 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot-approve-merge.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Dependabot
10 |
11 | on:
12 | pull_request_target: # zizmor: ignore[dangerous-triggers]
13 | branches:
14 | - main
15 | - master
16 | - stable*
17 |
18 | permissions:
19 | contents: read
20 |
21 | concurrency:
22 | group: dependabot-approve-merge-${{ github.head_ref || github.run_id }}
23 | cancel-in-progress: true
24 |
25 | jobs:
26 | auto-approve-merge:
27 | if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'renovate[bot]'
28 | runs-on: ubuntu-latest-low
29 | permissions:
30 | # for hmarr/auto-approve-action to approve PRs
31 | pull-requests: write
32 |
33 | steps:
34 | - name: Disabled on forks
35 | if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
36 | run: |
37 | echo 'Can not approve PRs from forks'
38 | exit 1
39 |
40 | # GitHub actions bot approve
41 | - uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2
42 | with:
43 | github-token: ${{ secrets.GITHUB_TOKEN }}
44 |
45 | # Nextcloud bot approve and merge request
46 | - uses: ahmadnassri/action-dependabot-auto-merge@45fc124d949b19b6b8bf6645b6c9d55f4f9ac61a # v2
47 | with:
48 | target: minor
49 | github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}
50 |
--------------------------------------------------------------------------------
/.github/workflows/fixup.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Block fixup and squash commits
10 |
11 | on:
12 | pull_request:
13 | types: [opened, ready_for_review, reopened, synchronize]
14 |
15 | permissions:
16 | contents: read
17 |
18 | concurrency:
19 | group: fixup-${{ github.head_ref || github.run_id }}
20 | cancel-in-progress: true
21 |
22 | jobs:
23 | commit-message-check:
24 | if: github.event.pull_request.draft == false
25 |
26 | permissions:
27 | pull-requests: write
28 | name: Block fixup and squash commits
29 |
30 | runs-on: ubuntu-latest-low
31 |
32 | steps:
33 | - name: Run check
34 | uses: skjnldsv/block-fixup-merge-action@c138ea99e45e186567b64cf065ce90f7158c236a # v2
35 | with:
36 | repo-token: ${{ secrets.GITHUB_TOKEN }}
37 |
--------------------------------------------------------------------------------
/.github/workflows/lint-php-cs.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Lint php-cs
10 |
11 | on: pull_request
12 |
13 | permissions:
14 | contents: read
15 |
16 | concurrency:
17 | group: lint-php-cs-${{ github.head_ref || github.run_id }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | lint:
22 | runs-on: ubuntu-latest
23 |
24 | name: php-cs
25 |
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
29 | with:
30 | persist-credentials: false
31 |
32 | - name: Get php version
33 | id: versions
34 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
35 |
36 | - name: Set up php${{ steps.versions.outputs.php-min }}
37 | uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1
38 | with:
39 | php-version: ${{ steps.versions.outputs.php-min }}
40 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
41 | coverage: none
42 | ini-file: development
43 | env:
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 |
46 | - name: Install dependencies
47 | run: |
48 | composer remove nextcloud/ocp --dev
49 | composer i
50 |
51 | - name: Lint
52 | run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
53 |
--------------------------------------------------------------------------------
/.github/workflows/lint-php.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Lint php
10 |
11 | on: pull_request
12 |
13 | permissions:
14 | contents: read
15 |
16 | concurrency:
17 | group: lint-php-${{ github.head_ref || github.run_id }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | matrix:
22 | runs-on: ubuntu-latest-low
23 | outputs:
24 | php-versions: ${{ steps.versions.outputs.php-versions }}
25 | steps:
26 | - name: Checkout app
27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
28 | with:
29 | persist-credentials: false
30 |
31 | - name: Get version matrix
32 | id: versions
33 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.0.0
34 |
35 | php-lint:
36 | runs-on: ubuntu-latest
37 | needs: matrix
38 | strategy:
39 | matrix:
40 | php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}}
41 |
42 | name: php-lint
43 |
44 | steps:
45 | - name: Checkout
46 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
47 | with:
48 | persist-credentials: false
49 |
50 | - name: Set up php ${{ matrix.php-versions }}
51 | uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1
52 | with:
53 | php-version: ${{ matrix.php-versions }}
54 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
55 | coverage: none
56 | ini-file: development
57 | env:
58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59 |
60 | - name: Lint
61 | run: composer run lint
62 |
63 | summary:
64 | permissions:
65 | contents: none
66 | runs-on: ubuntu-latest-low
67 | needs: php-lint
68 |
69 | if: always()
70 |
71 | name: php-lint-summary
72 |
73 | steps:
74 | - name: Summary status
75 | run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi
76 |
--------------------------------------------------------------------------------
/.github/workflows/lint-stylelint.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Lint stylelint
10 |
11 | on: pull_request
12 |
13 | permissions:
14 | contents: read
15 |
16 | concurrency:
17 | group: lint-stylelint-${{ github.head_ref || github.run_id }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | lint:
22 | runs-on: ubuntu-latest
23 |
24 | name: stylelint
25 |
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
29 | with:
30 | persist-credentials: false
31 |
32 | - name: Read package.json node and npm engines version
33 | uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
34 | id: versions
35 | with:
36 | fallbackNode: '^20'
37 | fallbackNpm: '^10'
38 |
39 | - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
40 | uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
41 | with:
42 | node-version: ${{ steps.versions.outputs.nodeVersion }}
43 |
44 | - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
45 | run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
46 |
47 | - name: Install dependencies
48 | env:
49 | CYPRESS_INSTALL_BINARY: 0
50 | run: npm ci
51 |
52 | - name: Lint
53 | run: npm run stylelint
54 |
--------------------------------------------------------------------------------
/.github/workflows/psalm.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 | #
6 | # SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
7 | # SPDX-License-Identifier: MIT
8 |
9 | name: Static analysis
10 |
11 | on: pull_request
12 |
13 | concurrency:
14 | group: psalm-${{ github.head_ref || github.run_id }}
15 | cancel-in-progress: true
16 |
17 | permissions:
18 | contents: read
19 |
20 | jobs:
21 | static-analysis:
22 | runs-on: ubuntu-latest
23 |
24 | name: static-psalm-analysis
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
28 | with:
29 | persist-credentials: false
30 |
31 | - name: Get php version
32 | id: versions
33 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
34 |
35 | - name: Check enforcement of minimum PHP version ${{ steps.versions.outputs.php-min }} in psalm.xml
36 | run: grep 'phpVersion="${{ steps.versions.outputs.php-min }}' psalm.xml
37 |
38 | - name: Set up php${{ steps.versions.outputs.php-available }}
39 | uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1
40 | with:
41 | php-version: ${{ steps.versions.outputs.php-available }}
42 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
43 | coverage: none
44 | ini-file: development
45 | # Temporary workaround for missing pcntl_* in PHP 8.3
46 | ini-values: disable_functions=
47 | env:
48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49 |
50 | - name: Install dependencies
51 | run: |
52 | composer remove nextcloud/ocp --dev
53 | composer i
54 |
55 | - name: Install nextcloud/ocp
56 | run: composer require --dev nextcloud/ocp:dev-${{ steps.versions.outputs.branches-max }} --ignore-platform-reqs --with-dependencies
57 |
58 | - name: Run coding standards check
59 | run: composer run psalm -- --threads=1 --monochrome --no-progress --output-format=github
60 |
--------------------------------------------------------------------------------
/.github/workflows/reuse.yml:
--------------------------------------------------------------------------------
1 | # This workflow is provided via the organization template repository
2 | #
3 | # https://github.com/nextcloud/.github
4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5 |
6 | # SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V.
7 | #
8 | # SPDX-License-Identifier: CC0-1.0
9 |
10 | name: REUSE Compliance Check
11 |
12 | on: [pull_request]
13 |
14 | permissions:
15 | contents: read
16 |
17 | jobs:
18 | reuse-compliance-check:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
23 | with:
24 | persist-credentials: false
25 |
26 | - name: REUSE Compliance Check
27 | uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5.0.0
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | css/fonts/
4 |
5 | .DS_Store
6 | node_modules/
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 |
11 | # Editor directories and files
12 | .idea
13 | .vscode
14 | *.suo
15 | *.ntvs*
16 | *.njsproj
17 | *.sln
18 |
19 | .marginalia
20 |
21 | build/
22 | coverage/
23 |
24 | vendor
25 | .php_cs.cache
26 |
27 | # Cypress files
28 | js/*roboto*
29 | cypress/downloads
30 | cypress/screenshots
31 | cypress/snapshots
32 | cypress/videos
33 | cypress/snapshots/actual
34 | cypress/snapshots/diff
35 |
36 | # RelativeCI webpack bundle stats
37 | webpack-stats.json
38 | *.orig
39 |
--------------------------------------------------------------------------------
/.l10nignore:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | js/
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | node_modules
--------------------------------------------------------------------------------
/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | getFinder()
17 | ->notPath('build')
18 | ->notPath('l10n')
19 | ->notPath('src')
20 | ->notPath('vendor')
21 | ->notPath('composer')
22 | ->in(__DIR__);
23 | return $config;
24 |
--------------------------------------------------------------------------------
/.stylelintignore:
--------------------------------------------------------------------------------
1 | # SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
2 | # SPDX-License-Identifier: AGPL-3.0-or-later
3 | src/assets
--------------------------------------------------------------------------------
/.tx/config:
--------------------------------------------------------------------------------
1 | [main]
2 | host = https://www.transifex.com
3 | lang_map = fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs
4 |
5 | [o:nextcloud:p:nextcloud:r:viewer]
6 | file_filter = translationfiles//viewer.po
7 | source_file = translationfiles/templates/viewer.pot
8 | source_lang = en
9 | type = PO
10 |
11 |
--------------------------------------------------------------------------------
/LICENSES/BSD-3-Clause.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) .
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 |
5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 |
7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 |
9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10 |
11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 |
--------------------------------------------------------------------------------
/LICENSES/ISC.txt:
--------------------------------------------------------------------------------
1 | ISC License:
2 |
3 | Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
4 | Copyright (c) 1995-2003 by Internet Software Consortium
5 |
6 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9 |
--------------------------------------------------------------------------------
/LICENSES/LicenseRef-NextcloudTrademarks.txt:
--------------------------------------------------------------------------------
1 | The Nextcloud marks
2 | Nextcloud and the Nextcloud logo is a registered trademark of Nextcloud GmbH in Germany and/or other countries.
3 | These guidelines cover the following marks pertaining both to the product names and the logo: “Nextcloud”
4 | and the blue/white cloud logo with or without the word Nextcloud; the service “Nextcloud Enterprise”;
5 | and our products: “Nextcloud Files”; “Nextcloud Groupware” and “Nextcloud Talk”.
6 | This set of marks is collectively referred to as the “Nextcloud marks.”
7 |
8 | Use of Nextcloud logos and other marks is only permitted under the guidelines provided by the Nextcloud GmbH.
9 | A copy can be found at https://nextcloud.com/trademarks/
10 |
--------------------------------------------------------------------------------
/LICENSES/LicenseRef-Unsplash.txt:
--------------------------------------------------------------------------------
1 | License
2 |
3 | Unsplash visuals are made to be used freely. Our license reflects that.
4 |
5 | * All images can be downloaded and used for free
6 | * Commercial and non-commercial purposes
7 | * No permission needed (though attribution is appreciated!)
8 |
9 | What is not permitted 👎
10 |
11 | * Images cannot be sold without significant modification.
12 | * Compiling images from Unsplash to replicate a similar or competing service.
13 |
14 |
15 | Longform
16 |
17 | Unsplash grants you an irrevocable, nonexclusive, worldwide copyright license to download, copy, modify, distribute, perform, and use images from Unsplash for free, including for commercial purposes, without permission from or attributing the photographer or Unsplash. This license does not include the right to compile images from Unsplash to replicate a similar or competing service.
18 |
--------------------------------------------------------------------------------
/LICENSES/MIT.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/appinfo/info.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 | viewer
9 | Viewer
10 | Simple file viewer with slideshow for media
11 |
12 | 5.0.0-dev.0
13 | agpl
14 | John Molakvoæ
15 | Viewer
16 | tools
17 | https://github.com/nextcloud/viewer
18 | https://raw.githubusercontent.com/nextcloud/screenshots/master/apps/Viewer/viewer.png
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextcloud/viewer",
3 | "config": {
4 | "optimize-autoloader": true,
5 | "classmap-authoritative": true,
6 | "platform": {
7 | "php": "8.1"
8 | }
9 | },
10 | "scripts": {
11 | "cs:fix": "php-cs-fixer fix",
12 | "cs:check": "php-cs-fixer fix --dry-run --diff",
13 | "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './composer/*' -print0 | xargs -0 -n1 php -l",
14 | "psalm": "psalm --threads=1",
15 | "psalm:update-baseline": "psalm --threads=1 --update-baseline",
16 | "psalm:clear": "psalm --clear-cache && psalm --clear-global-cache",
17 | "psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType"
18 | },
19 | "require-dev": {
20 | "nextcloud/coding-standard": "^1.2.0",
21 | "phpunit/phpunit": "^9",
22 | "vimeo/psalm": "^5.25.0",
23 | "nextcloud/ocp": "dev-master"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/composer/autoload.php:
--------------------------------------------------------------------------------
1 | $vendorDir . '/composer/InstalledVersions.php',
10 | 'OCA\\Viewer\\AppInfo\\Application' => $baseDir . '/lib/AppInfo/Application.php',
11 | 'OCA\\Viewer\\Event\\LoadViewer' => $baseDir . '/lib/Event/LoadViewer.php',
12 | 'OCA\\Viewer\\Listener\\LoadViewerScript' => $baseDir . '/lib/Listener/LoadViewerScript.php',
13 | );
14 |
--------------------------------------------------------------------------------
/composer/composer/autoload_namespaces.php:
--------------------------------------------------------------------------------
1 | array($baseDir . '/lib'),
10 | );
11 |
--------------------------------------------------------------------------------
/composer/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | setClassMapAuthoritative(true);
33 | $loader->register(true);
34 |
35 | return $loader;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/composer/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'OCA\\Viewer\\' => 11,
13 | ),
14 | );
15 |
16 | public static $prefixDirsPsr4 = array (
17 | 'OCA\\Viewer\\' =>
18 | array (
19 | 0 => __DIR__ . '/../..' . '/lib',
20 | ),
21 | );
22 |
23 | public static $classMap = array (
24 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
25 | 'OCA\\Viewer\\AppInfo\\Application' => __DIR__ . '/../..' . '/lib/AppInfo/Application.php',
26 | 'OCA\\Viewer\\Event\\LoadViewer' => __DIR__ . '/../..' . '/lib/Event/LoadViewer.php',
27 | 'OCA\\Viewer\\Listener\\LoadViewerScript' => __DIR__ . '/../..' . '/lib/Listener/LoadViewerScript.php',
28 | );
29 |
30 | public static function getInitializer(ClassLoader $loader)
31 | {
32 | return \Closure::bind(function () use ($loader) {
33 | $loader->prefixLengthsPsr4 = ComposerStaticInitViewer::$prefixLengthsPsr4;
34 | $loader->prefixDirsPsr4 = ComposerStaticInitViewer::$prefixDirsPsr4;
35 | $loader->classMap = ComposerStaticInitViewer::$classMap;
36 |
37 | }, null, ClassLoader::class);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/css/NcActionButton-DndYZcrz.chunk.css:
--------------------------------------------------------------------------------
1 | .material-design-icon[data-v-02eeec54]{display:flex;align-self:center;justify-self:center;align-items:center;justify-content:center}li.action[data-v-02eeec54]:hover,li.action.active[data-v-02eeec54]{border-radius:6px;padding:0}li.action[data-v-02eeec54]:hover{background-color:var(--color-background-hover)}.action--disabled[data-v-02eeec54]{pointer-events:none;opacity:.5}.action--disabled[data-v-02eeec54]:hover,.action--disabled[data-v-02eeec54]:focus{cursor:default;opacity:.5}.action--disabled *[data-v-02eeec54]{opacity:1!important}.action-button[data-v-02eeec54]{display:flex;align-items:flex-start;width:100%;height:auto;margin:0;padding:0;padding-inline-end:calc((var(--default-clickable-area) - 16px) / 2);box-sizing:border-box;cursor:pointer;white-space:nowrap;color:var(--color-main-text);border:0;border-radius:0;background-color:transparent;box-shadow:none;font-weight:400;font-size:var(--default-font-size);line-height:var(--default-clickable-area)}.action-button>span[data-v-02eeec54]{cursor:pointer;white-space:nowrap}.action-button__icon[data-v-02eeec54]{width:var(--default-clickable-area);height:var(--default-clickable-area);opacity:1;background-position:calc((var(--default-clickable-area) - 16px) / 2) center;background-size:16px;background-repeat:no-repeat}.action-button[data-v-02eeec54] .material-design-icon{width:var(--default-clickable-area);height:var(--default-clickable-area);opacity:1}.action-button[data-v-02eeec54] .material-design-icon .material-design-icon__svg{vertical-align:middle}.action-button__longtext-wrapper[data-v-02eeec54],.action-button__longtext[data-v-02eeec54]{max-width:220px;line-height:1.6em;padding:calc((var(--default-clickable-area) - 1.6em) / 2) 0;cursor:pointer;text-align:start;overflow:hidden;text-overflow:ellipsis}.action-button__longtext[data-v-02eeec54]{cursor:pointer;white-space:pre-wrap!important}.action-button__name[data-v-02eeec54]{font-weight:700;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%;display:block}.action-button__description[data-v-02eeec54]{display:block;white-space:pre-wrap;font-size:var(--font-size-small);line-height:var(--default-line-height);color:var(--color-text-maxcontrast);cursor:pointer}.action-button__menu-icon[data-v-02eeec54],.action-button__pressed-icon[data-v-02eeec54]{margin-inline:auto calc((var(--default-clickable-area) - 16px) / 2 * -1)}
2 |
--------------------------------------------------------------------------------
/css/NcActionLink-Cay-IPuV.chunk.css:
--------------------------------------------------------------------------------
1 | .material-design-icon[data-v-30c015f0]{display:flex;align-self:center;justify-self:center;align-items:center;justify-content:center}li.action[data-v-30c015f0]:hover,li.action.active[data-v-30c015f0]{border-radius:6px;padding:0}li.action[data-v-30c015f0]:hover{background-color:var(--color-background-hover)}.action-link[data-v-30c015f0]{display:flex;align-items:flex-start;width:100%;height:auto;margin:0;padding:0;padding-inline-end:calc((var(--default-clickable-area) - 16px) / 2);box-sizing:border-box;cursor:pointer;white-space:nowrap;color:var(--color-main-text);border:0;border-radius:0;background-color:transparent;box-shadow:none;font-weight:400;font-size:var(--default-font-size);line-height:var(--default-clickable-area)}.action-link>span[data-v-30c015f0]{cursor:pointer;white-space:nowrap}.action-link__icon[data-v-30c015f0]{width:var(--default-clickable-area);height:var(--default-clickable-area);opacity:1;background-position:calc((var(--default-clickable-area) - 16px) / 2) center;background-size:16px;background-repeat:no-repeat}.action-link[data-v-30c015f0] .material-design-icon{width:var(--default-clickable-area);height:var(--default-clickable-area);opacity:1}.action-link[data-v-30c015f0] .material-design-icon .material-design-icon__svg{vertical-align:middle}.action-link__longtext-wrapper[data-v-30c015f0],.action-link__longtext[data-v-30c015f0]{max-width:220px;line-height:1.6em;padding:calc((var(--default-clickable-area) - 1.6em) / 2) 0;cursor:pointer;text-align:start;overflow:hidden;text-overflow:ellipsis}.action-link__longtext[data-v-30c015f0]{cursor:pointer;white-space:pre-wrap!important}.action-link__name[data-v-30c015f0]{font-weight:700;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-width:100%;display:block}.action-link__description[data-v-30c015f0]{display:block;white-space:pre-wrap;font-size:var(--font-size-small);line-height:var(--default-line-height);color:var(--color-text-maxcontrast);cursor:pointer}.action-link__menu-icon[data-v-30c015f0]{margin-inline:auto calc((var(--default-clickable-area) - 16px) / 2 * -1)}
2 |
--------------------------------------------------------------------------------
/css/viewer-init.css:
--------------------------------------------------------------------------------
1 | /* extracted by css-entry-points-plugin */
2 | @import './init-BcY_9rzn.chunk.css';
3 | @import './logger-60RCWKf0.chunk.css';
4 | @import './NcActionButton-DndYZcrz.chunk.css';
5 | @import './NcActionLink-Cay-IPuV.chunk.css';
--------------------------------------------------------------------------------
/css/viewer-main.css:
--------------------------------------------------------------------------------
1 | /* extracted by css-entry-points-plugin */
2 | @import './main-BwzbmUGl.chunk.css';
3 | @import './logger-60RCWKf0.chunk.css';
--------------------------------------------------------------------------------
/cypress/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "cypress/globals": true
4 | },
5 | "plugins": [
6 | "cypress"
7 | ],
8 | "extends": [
9 | "plugin:cypress/recommended"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/cypress/e2e/actions/delete.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | describe('Delete image.png in viewer', function() {
7 | before(function() {
8 | // Init user
9 | cy.createRandomUser().then(user => {
10 | // Upload test files
11 | cy.uploadFile(user, 'image.png', 'image/png')
12 |
13 | // Visit nextcloud
14 | cy.login(user)
15 | cy.visit('/apps/files')
16 | })
17 | })
18 | after(function() {
19 | cy.logout()
20 | })
21 |
22 | it('See image.png in the list', function() {
23 | cy.getFile('image.png', { timeout: 10000 })
24 | .should('contain', 'image .png')
25 | })
26 |
27 | it('Open the viewer on file click', function() {
28 | cy.openFile('image.png')
29 | cy.get('body > .viewer').should('be.visible')
30 | })
31 |
32 | it('Does not see a loading animation', function() {
33 | cy.get('body > .viewer', { timeout: 10000 })
34 | .should('be.visible')
35 | .and('have.class', 'modal-mask')
36 | .and('not.have.class', 'icon-loading')
37 | })
38 |
39 | it('Delete the image and close viewer', function() {
40 | // open the menu
41 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').click()
42 | // delete the file
43 | cy.get('.action-button:contains(\'Delete\')').click()
44 | })
45 |
46 | it('Does not see the viewer anymore', function() {
47 | cy.get('body > .viewer', { timeout: 10000 })
48 | .should('not.exist')
49 | })
50 |
51 | it('Does not see image.png in the list anymore', function() {
52 | cy.visit('/apps/files')
53 | cy.getFile('image.png', { timeout: 10000 })
54 | .should('not.exist')
55 | })
56 | })
57 |
--------------------------------------------------------------------------------
/cypress/e2e/actions/download.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import * as path from 'path'
7 |
8 | const fileName = 'image.png'
9 |
10 | describe(`Download ${fileName} in viewer`, function() {
11 | before(function() {
12 | // Init user
13 | cy.createRandomUser().then(user => {
14 | // Upload test files
15 | cy.uploadFile(user, fileName, 'image/png')
16 |
17 | // Visit nextcloud
18 | cy.login(user)
19 | cy.visit('/apps/files')
20 | })
21 | })
22 |
23 | after(function() {
24 | cy.logout()
25 | })
26 |
27 | it(`See "${fileName}" in the list`, function() {
28 | cy.getFile(fileName, { timeout: 10000 })
29 | .should('contain', fileName.replace(/(.*)\./, '$1 .'))
30 | })
31 |
32 | it('Open the viewer on file click', function() {
33 | cy.openFile(fileName)
34 | cy.get('body > .viewer').should('be.visible')
35 | })
36 |
37 | it('Does not see a loading animation', function() {
38 | cy.get('body > .viewer', { timeout: 10000 })
39 | .should('be.visible')
40 | .and('have.class', 'modal-mask')
41 | .and('not.have.class', 'icon-loading')
42 | })
43 |
44 | it('Download the image', function() {
45 | // open the menu
46 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').click()
47 | // download the file
48 | cy.get('.action-link .download-icon').click()
49 | })
50 |
51 | it('Compare downloaded file with asset by size', function() {
52 | const downloadsFolder = Cypress.config('downloadsFolder')
53 | const fixturesFolder = Cypress.config('fixturesFolder')
54 |
55 | const downloadedFilePath = path.join(downloadsFolder, fileName)
56 | const fixtureFilePath = path.join(fixturesFolder, fileName)
57 |
58 | cy.readFile(fixtureFilePath, 'binary', { timeout: 5000 }).then(fixtureBuffer => {
59 | cy.readFile(downloadedFilePath, 'binary', { timeout: 5000 })
60 | .should(downloadedBuffer => {
61 | if (downloadedBuffer.length !== fixtureBuffer.length) {
62 | throw new Error(`File size ${downloadedBuffer.length} is not ${fixtureBuffer.length}`)
63 | }
64 | })
65 | })
66 | })
67 | })
68 |
--------------------------------------------------------------------------------
/cypress/e2e/audios/audio.mpeg.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import audioTest from '../mixins/audio'
7 |
8 | describe('Open audio.mp3 in viewer', function() {
9 | audioTest('audio.mp3', 'audio/mpeg')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/audios/audio.ogg.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import audioTest from '../mixins/audio'
6 |
7 | describe('Open audio.ogg in viewer', function() {
8 | audioTest('audio.ogg', 'audio/ogg')
9 | })
10 |
--------------------------------------------------------------------------------
/cypress/e2e/download-forbidden.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import type { User } from '@nextcloud/cypress'
7 | import { ShareType } from '@nextcloud/sharing'
8 |
9 | describe('Disable download button if forbidden', { testIsolation: true }, () => {
10 | let sharee: User
11 |
12 | before(() => {
13 | cy.createRandomUser().then((user) => { sharee = user })
14 | cy.createRandomUser().then((user) => {
15 | // Upload test files
16 | cy.createFolder(user, '/Photos')
17 | cy.uploadFile(user, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg')
18 |
19 | cy.login(user)
20 | cy.createShare('/Photos',
21 | { shareWith: sharee.userId, shareType: ShareType.User, attributes: [{ scope: 'permissions', key: 'download', value: false }] },
22 | )
23 | cy.logout()
24 | })
25 | })
26 |
27 | beforeEach(() => {
28 | cy.login(sharee)
29 | cy.visit('/apps/files')
30 | cy.openFile('Photos')
31 | })
32 |
33 | it('See the shared folder and images in files list', () => {
34 | cy.getFile('image1.jpg', { timeout: 10000 })
35 | .should('contain', 'image1 .jpg')
36 | })
37 |
38 | // TODO: Fix no-download files on server
39 | it.skip('See the image can be shown', () => {
40 | cy.getFile('image1.jpg').should('be.visible')
41 | cy.openFile('image1.jpg')
42 | cy.get('body > .viewer').should('be.visible')
43 |
44 | cy.get('body > .viewer', { timeout: 10000 })
45 | .should('be.visible')
46 | .and('have.class', 'modal-mask')
47 | .and('not.have.class', 'icon-loading')
48 | })
49 |
50 | it('See the title on the viewer header but not the Download nor the menu button', () => {
51 | cy.getFile('image1.jpg').should('be.visible')
52 | cy.openFile('image1.jpg')
53 | cy.get('body > .viewer .modal-header__name').should('contain', 'image1.jpg')
54 |
55 | cy.get('[role="dialog"]')
56 | .should('be.visible')
57 | .find('button[aria-label="Actions"]')
58 | .click()
59 |
60 | cy.get('[role="menu"]:visible')
61 | .find('button')
62 | .should('have.length', 2)
63 | .each(($el) => {
64 | expect($el.text()).to.match(/(Full screen|Open sidebar)/i)
65 | })
66 | })
67 | })
68 |
--------------------------------------------------------------------------------
/cypress/e2e/files.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import { User } from '@nextcloud/cypress'
7 |
8 | describe('Files default view', function() {
9 | const user = new User('admin', 'admin')
10 |
11 | before(function() {
12 | cy.login(user)
13 | })
14 |
15 | after(function() {
16 | cy.logout()
17 | })
18 |
19 | it('See the default files list', function() {
20 | cy.visit('/apps/files')
21 | cy.getFile('welcome.txt').should('contain', 'welcome .txt')
22 | })
23 |
24 | it('Take screenshot', function() {
25 | cy.screenshot()
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image-apng.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image-apng.png in viewer', function() {
9 | imageTest('image-apng.png', 'image/png')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image-small.png.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image-small.png in viewer', function() {
9 | imageTest('image-small.png', 'image/png')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image.gif.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import imageTest from '../mixins/image'
6 |
7 | describe('Open image.gif in viewer', function() {
8 | imageTest('image.gif', 'image/gif', '/remote.php/dav/files')
9 | })
10 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image.ico.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image.ico in viewer', function() {
9 | imageTest('image.ico', 'image/x-icon', '/remote.php/dav/files')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image.png.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image.png in viewer', function() {
9 | imageTest('image.png', 'image/png')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image.svg.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image.svg in viewer', function() {
9 | imageTest('image.svg', 'image/svg+xml', 'data:image/svg+xml;base64')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/images/image.webp.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import imageTest from '../mixins/image'
7 |
8 | describe('Open image.webp in viewer', function() {
9 | imageTest('image.webp', 'image/webp')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/mixins/audio.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | /**
7 | * Generate an audio cypress test
8 | *
9 | * @param {string} fileName the audio to upload and test against
10 | * @param {string} mimeType the audio mime type
11 | */
12 | export default function(fileName = 'audio.ogg', mimeType = 'audio/ogg') {
13 | let randUser
14 |
15 | before(function() {
16 | // Init user
17 | cy.createRandomUser().then(user => {
18 | randUser = user
19 |
20 | // Upload test files
21 | cy.uploadFile(user, fileName, mimeType)
22 |
23 | // Visit nextcloud
24 | cy.login(user)
25 | cy.visit('/apps/files')
26 | })
27 | })
28 | after(function() {
29 | cy.logout()
30 | })
31 |
32 | it(`See ${fileName} in the list`, function() {
33 | cy.getFile(fileName, { timeout: 10000 })
34 | .should('contain', fileName.replace(/(.*)\./, '$1 .'))
35 | })
36 |
37 | it('Open the viewer on file click and wait for loading to end', function() {
38 | // Match audio request
39 | cy.intercept('GET', `/remote.php/dav/files/${randUser.userId}/${fileName}`).as('source')
40 |
41 | // Open the file and check Viewer existence
42 | cy.openFile(fileName)
43 | cy.get('body > .viewer').should('be.visible')
44 |
45 | // Make sure loading is finished
46 | cy.wait('@source').its('response.statusCode').should('eq', 206)
47 | cy.get('body > .viewer', { timeout: 10000 })
48 | .should('be.visible')
49 | .and('have.class', 'modal-mask')
50 | .and('not.have.class', 'icon-loading')
51 | })
52 |
53 | it('See the menu icon and title on the viewer header', function() {
54 | cy.get('body > .viewer .modal-header__name').should('contain', fileName)
55 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible')
56 | cy.get('body > .viewer .modal-header button.header-close').should('be.visible')
57 | })
58 |
59 | it('Does not see navigation arrows', function() {
60 | cy.get('body > .viewer button.prev').should('not.be.visible')
61 | cy.get('body > .viewer button.next').should('not.be.visible')
62 | })
63 |
64 | it('The audio source is the remote url', function() {
65 | cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active audio')
66 | .should('have.attr', 'src')
67 | .and('contain', `/remote.php/dav/files/${randUser.userId}/${fileName}`)
68 | })
69 | }
70 |
--------------------------------------------------------------------------------
/cypress/e2e/mixins/image.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | /**
7 | * Generate an image cypress test
8 | *
9 | * @param {string} fileName the image to upload and test against
10 | * @param {string} mimeType the image mime type
11 | * @param {string} source the optional custom source to check against
12 | */
13 | export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg', source = null) {
14 | before(function() {
15 | // Init user
16 | cy.createRandomUser().then(user => {
17 | // Upload test files
18 | cy.uploadFile(user, fileName, mimeType)
19 |
20 | // Visit nextcloud
21 | cy.login(user)
22 | cy.visit('/apps/files')
23 | })
24 | })
25 | after(function() {
26 | cy.logout()
27 | })
28 |
29 | it(`See ${fileName} in the list`, function() {
30 | cy.getFile(fileName, { timeout: 10000 })
31 | .should('contain', fileName.replace(/(.*)\./, '$1 .'))
32 | })
33 |
34 | it('Open the viewer on file click and wait for loading to end', function() {
35 | // Match image request
36 | cy.getFileId(fileName).then(fileId => {
37 | const matchRoute = source
38 | ? `/remote.php/dav/files/*/${fileName}`
39 | : `/index.php/core/preview*fileId=${fileId}*`
40 | cy.intercept('GET', matchRoute).as('image')
41 | })
42 |
43 | // Open the file and check Viewer existence
44 | cy.openFile(fileName)
45 | cy.get('body > .viewer').should('be.visible')
46 |
47 | // Make sure loading is finished
48 | cy.wait('@image').its('response.statusCode').should('eq', 200)
49 | cy.get('body > .viewer', { timeout: 10000 })
50 | .should('be.visible')
51 | .and('have.class', 'modal-mask')
52 | .and('not.have.class', 'icon-loading')
53 | })
54 |
55 | it('See the menu icon and title on the viewer header', function() {
56 | cy.get('body > .viewer .modal-header__name').should('contain', fileName)
57 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible')
58 | cy.get('body > .viewer .modal-header button.header-close').should('be.visible')
59 | })
60 |
61 | it('Does not see navigation arrows', function() {
62 | cy.get('body > .viewer button.prev').should('not.be.visible')
63 | cy.get('body > .viewer button.next').should('not.be.visible')
64 | })
65 |
66 | it(`The image source is the ${source ? 'remote' : 'preview'} url`, function() {
67 | cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active img')
68 | .should('have.attr', 'src')
69 | .and('contain', source ?? '/index.php/core/preview')
70 | })
71 | }
72 |
--------------------------------------------------------------------------------
/cypress/e2e/mixins/video.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | /**
7 | * Generate a video cypress test
8 | *
9 | * @param {string} fileName the video to upload and test against
10 | * @param {string} mimeType the video mime type
11 | */
12 | export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') {
13 | let randUser
14 |
15 | before(function() {
16 | // Init user
17 | cy.createRandomUser().then(user => {
18 | randUser = user
19 |
20 | // Upload test files
21 | cy.uploadFile(user, fileName, mimeType)
22 |
23 | // Visit nextcloud
24 | cy.login(user)
25 | cy.visit('/apps/files')
26 | })
27 | })
28 | after(function() {
29 | cy.logout()
30 | })
31 |
32 | it(`See ${fileName} in the list`, function() {
33 | cy.getFile(fileName, { timeout: 10000 })
34 | .should('contain', fileName.replace(/(.*)\./, '$1 .'))
35 | })
36 |
37 | it('Open the viewer on file click and wait for loading to end', function() {
38 | // Match audio request
39 | cy.intercept('GET', `/remote.php/dav/files/${randUser.userId}/${fileName}`).as('source')
40 |
41 | // Open the file and check Viewer existence
42 | cy.openFile(fileName)
43 | cy.get('body > .viewer').should('be.visible')
44 |
45 | // Make sure loading is finished
46 | cy.wait('@source').its('response.statusCode').should('eq', 206)
47 | cy.get('body > .viewer', { timeout: 10000 })
48 | .should('be.visible')
49 | .and('have.class', 'modal-mask')
50 | .and('not.have.class', 'icon-loading')
51 | })
52 |
53 | it('See the menu icon and title on the viewer header', function() {
54 | cy.get('body > .viewer .modal-header__name').should('contain', fileName)
55 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible')
56 | cy.get('body > .viewer .modal-header button.header-close').should('be.visible')
57 | })
58 |
59 | it('Does not see navigation arrows', function() {
60 | cy.get('body > .viewer button.prev').should('not.be.visible')
61 | cy.get('body > .viewer button.next').should('not.be.visible')
62 | })
63 |
64 | it('The video source is the remote url', function() {
65 | cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active video')
66 | .should('have.attr', 'src')
67 | .and('contain', `/remote.php/dav/files/${randUser.userId}/${fileName}`)
68 | })
69 | }
70 |
--------------------------------------------------------------------------------
/cypress/e2e/navigation.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | describe('Browser navigation', function() {
7 | before(function() {
8 | // Init user
9 | cy.createRandomUser().then(user => {
10 | // Upload test files
11 | cy.uploadFile(user, 'image.png', 'image/png', '/image1.png')
12 |
13 | // Visit nextcloud
14 | cy.login(user)
15 | cy.visit('/apps/files')
16 | })
17 | })
18 | after(function() {
19 | cy.logout()
20 | })
21 |
22 | it('Navigating back to the files overview', function() {
23 | cy.getFile('image1.png', { timeout: 10000 })
24 | cy.openFile('image1.png')
25 | cy.get('body > .viewer').should('be.visible')
26 | cy.go('back')
27 | cy.get('body > .viewer').should('not.exist')
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/cypress/e2e/non-dav-files.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import { basename as pathBasename } from '@nextcloud/paths'
7 |
8 | const source = '/apps/theming/img/background/anatoly-mikhaltsov-butterfly-wing-scale.jpg'
9 | const basename = pathBasename(source)
10 |
11 | describe('Open non-dav files in viewer', function() {
12 | before(function() {
13 | // Init user
14 | cy.createRandomUser().then(user => {
15 | // Upload test files
16 | cy.uploadFile(user, 'test-card.mp4', 'video/mp4')
17 |
18 | // Visit nextcloud
19 | cy.login(user)
20 | cy.visit('/apps/files')
21 | })
22 | })
23 | after(function() {
24 | cy.logout()
25 | })
26 |
27 | it('Open background', function() {
28 | const fileInfo = {
29 | filename: source,
30 | basename,
31 | mime: 'image/jpeg',
32 | source,
33 | etag: 'abc',
34 | hasPreview: false,
35 | fileid: 123,
36 | }
37 |
38 | cy.window().then((win) => {
39 | win.OCA.Viewer.open({
40 | fileInfo,
41 | list: [fileInfo],
42 | })
43 | })
44 | })
45 |
46 | it('Does not see a loading animation', function() {
47 | cy.get('body > .viewer', { timeout: 10000 })
48 | .should('be.visible')
49 | .and('have.class', 'modal-mask')
50 | .and('not.have.class', 'icon-loading')
51 | })
52 |
53 | it('See the title and close button on the viewer header', function() {
54 | cy.get('body > .viewer .modal-header__name').should('contain', basename)
55 | cy.get('body > .viewer .modal-header button.header-close').should('be.visible')
56 | })
57 |
58 | it('Does not see navigation arrows', function() {
59 | cy.get('body > .viewer button.prev').should('not.be.visible')
60 | cy.get('body > .viewer button.next').should('not.be.visible')
61 | })
62 |
63 | it('See the menu but does not see the sidebar button', function() {
64 | // Menu exists
65 | cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible')
66 | cy.get('.action-button__icon.icon-menu-sidebar').should('not.exist')
67 | })
68 |
69 | it('The image source is the remote url', function() {
70 | cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active img')
71 | .should('have.attr', 'src')
72 | .and('contain', source)
73 | })
74 | })
75 |
--------------------------------------------------------------------------------
/cypress/e2e/oddname/oddname-audio.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import runTest from '../mixins/oddname'
6 |
7 | for (const [file, type] of [
8 | ['audio.mp3', 'audio/mpeg'],
9 | ['audio.ogg', 'audio/ogg'],
10 | ]) {
11 | runTest(file, type)
12 | }
13 |
--------------------------------------------------------------------------------
/cypress/e2e/oddname/oddname-image.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import runTest from '../mixins/oddname'
6 |
7 | for (const [file, type] of [
8 | ['image1.jpg', 'image/jpeg'],
9 | ['image.gif', 'image/gif'],
10 | ['image.png', 'image/png'],
11 | ['image-small.png', 'image/png'],
12 | ['image.svg', 'image/svg'],
13 | ]) {
14 | runTest(file, type)
15 | }
16 |
--------------------------------------------------------------------------------
/cypress/e2e/oddname/oddname-sidebar.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import runTest from '../mixins/oddname'
6 |
7 | runTest('image.png', 'image/png', true)
8 |
--------------------------------------------------------------------------------
/cypress/e2e/oddname/oddname-video.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import runTest from '../mixins/oddname'
6 |
7 | for (const [file, type] of [
8 | ['video1.mp4', 'video/mp4'],
9 | ['video.mkv', 'video/mkv'],
10 | ['video.ogv', 'video/ogv'],
11 | ['video.webm', 'video/webm'],
12 | ]) {
13 | runTest(file, type)
14 | }
15 |
--------------------------------------------------------------------------------
/cypress/e2e/videos/video.mkv.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import videoTest from '../mixins/video'
7 |
8 | describe('Open video.mkv in viewer', function() {
9 | videoTest('video.mkv', 'image/mkv')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/videos/video.mp4.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import videoTest from '../mixins/video'
7 |
8 | describe('Open video1.mp4 in viewer', function() {
9 | videoTest('video1.mp4', 'video/mp4')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/videos/video.ogv.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import videoTest from '../mixins/video'
7 |
8 | describe('Open video.ogv in viewer', function() {
9 | videoTest('video.ogv', 'video/ogv')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/e2e/videos/video.webm.cy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import videoTest from '../mixins/video'
7 |
8 | describe('Open video.webm in viewer', function() {
9 | videoTest('video.webm', 'video/webm')
10 | })
11 |
--------------------------------------------------------------------------------
/cypress/fixtures/audio.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/audio.mp3
--------------------------------------------------------------------------------
/cypress/fixtures/audio.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/audio.ogg
--------------------------------------------------------------------------------
/cypress/fixtures/image-apng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image-apng.png
--------------------------------------------------------------------------------
/cypress/fixtures/image-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image-small.png
--------------------------------------------------------------------------------
/cypress/fixtures/image.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.bmp
--------------------------------------------------------------------------------
/cypress/fixtures/image.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.gif
--------------------------------------------------------------------------------
/cypress/fixtures/image.heic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.heic
--------------------------------------------------------------------------------
/cypress/fixtures/image.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.ico
--------------------------------------------------------------------------------
/cypress/fixtures/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.png
--------------------------------------------------------------------------------
/cypress/fixtures/image.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/cypress/fixtures/image.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image.webp
--------------------------------------------------------------------------------
/cypress/fixtures/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image1.jpg
--------------------------------------------------------------------------------
/cypress/fixtures/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image2.jpg
--------------------------------------------------------------------------------
/cypress/fixtures/image3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image3.jpg
--------------------------------------------------------------------------------
/cypress/fixtures/image4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/image4.jpg
--------------------------------------------------------------------------------
/cypress/fixtures/test-card.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/test-card.mp4
--------------------------------------------------------------------------------
/cypress/fixtures/test-card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/test-card.png
--------------------------------------------------------------------------------
/cypress/fixtures/video.mkv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/video.mkv
--------------------------------------------------------------------------------
/cypress/fixtures/video.ogv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/video.ogv
--------------------------------------------------------------------------------
/cypress/fixtures/video.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/video.webm
--------------------------------------------------------------------------------
/cypress/fixtures/video1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/video1.mp4
--------------------------------------------------------------------------------
/cypress/fixtures/video2.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/fixtures/video2.mp4
--------------------------------------------------------------------------------
/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/image.png
--------------------------------------------------------------------------------
/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/image2.png
--------------------------------------------------------------------------------
/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/non-dav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/non-dav.png
--------------------------------------------------------------------------------
/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/cypress/snapshots/base/cypress/e2e/visual-regression.cy.ts/video.png
--------------------------------------------------------------------------------
/cypress/support/e2e.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | // ***********************************************************
6 | // This example support/index.js is processed and
7 | // loaded automatically before your test files.
8 | //
9 | // This is a great place to put global configuration and
10 | // behavior that modifies Cypress.
11 | //
12 | // You can change the location of this file or turn off
13 | // automatically serving support files with the
14 | // 'supportFile' configuration option.
15 | //
16 | // You can read more here:
17 | // https://on.cypress.io/configuration
18 | // ***********************************************************
19 |
20 | // Import commands.js using ES2015 syntax:
21 | import './commands'
22 |
--------------------------------------------------------------------------------
/cypress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": ["../*.ts", "."],
4 | "compilerOptions": {
5 | "rootDir": "..",
6 | "types": [
7 | "cypress",
8 | "dockerode",
9 | "node"
10 | ]
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/img/app.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/img/blank.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/img/blank.mp4
--------------------------------------------------------------------------------
/js/NcActionButton-qdAUHyGz.chunk.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/NcActionButton-qdAUHyGz.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/NcActionLink-TR7mwuor.chunk.mjs:
--------------------------------------------------------------------------------
1 | import{A as a}from"./actionText-fFcUPi2g-gjw6zxAU.chunk.mjs";import{n as e}from"./logger-Bw8oxZ_4.chunk.mjs";const i={name:"NcActionLink",mixins:[a],inject:{isInSemanticMenu:{from:"NcActions:isSemanticMenu",default:!1}},props:{href:{type:String,default:"#",required:!0,validator:t=>{try{return new URL(t)}catch{return t.startsWith("#")||t.startsWith("/")}}},download:{type:String,default:null},target:{type:String,default:"_self",validator:t=>t&&(!t.startsWith("_")||["_blank","_self","_parent","_top"].indexOf(t)>-1)},title:{type:String,default:null},ariaHidden:{type:Boolean,default:null}}};var s=function(){var t=this,n=t._self._c;return n("li",{staticClass:"action",attrs:{role:t.isInSemanticMenu&&"presentation"}},[n("a",{staticClass:"action-link focusable",attrs:{download:t.download,href:t.href,"aria-label":t.ariaLabel,target:t.target,title:t.title,rel:"nofollow noreferrer noopener",role:t.isInSemanticMenu&&"menuitem"},on:{click:t.onClick}},[t._t("icon",function(){return[n("span",{staticClass:"action-link__icon",class:[t.isIconUrl?"action-link__icon--url":t.icon],style:{backgroundImage:t.isIconUrl?`url(${t.icon})`:null},attrs:{"aria-hidden":"true"}})]}),t.name?n("span",{staticClass:"action-link__longtext-wrapper"},[n("strong",{staticClass:"action-link__name"},[t._v(" "+t._s(t.name)+" ")]),n("br"),n("span",{staticClass:"action-link__longtext",domProps:{textContent:t._s(t.text)}})]):t.isLongText?n("span",{staticClass:"action-link__longtext",domProps:{textContent:t._s(t.text)}}):n("span",{staticClass:"action-link__text"},[t._v(t._s(t.text))]),t._e()],2)])},l=[],o=e(i,s,l,!1,null,"30c015f0");const _=o.exports;export{_ as default};
2 | //# sourceMappingURL=NcActionLink-TR7mwuor.chunk.mjs.map
3 |
--------------------------------------------------------------------------------
/js/NcActionLink-TR7mwuor.chunk.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/NcActionLink-TR7mwuor.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/actionText-fFcUPi2g-gjw6zxAU.chunk.mjs:
--------------------------------------------------------------------------------
1 | const n={beforeUpdate(){this.text=this.getText()},data(){return{text:this.getText()}},computed:{isLongText(){return this.text&&this.text.trim().length>20}},methods:{getText(){return this.$slots.default?this.$slots.default[0].text.trim():""}}},o=function(i,t){let e=i.$parent;for(;e;){if(e.$options.name===t)return e;e=e.$parent}},s={mixins:[n],props:{icon:{type:String,default:""},name:{type:String,default:""},title:{type:String,default:""},closeAfterClick:{type:Boolean,default:!1},ariaLabel:{type:String,default:null},ariaHidden:{type:Boolean,default:null}},emits:["click"],computed:{isIconUrl(){try{return!!new URL(this.icon,this.icon.startsWith("/")?window.location.origin:void 0)}catch{return!1}}},methods:{onClick(i){if(this.$emit("click",i),this.closeAfterClick){const t=o(this,"NcActions");t&&t.closeMenu&&t.closeMenu(!1)}}}};export{s as A};
2 | //# sourceMappingURL=actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.map
3 |
--------------------------------------------------------------------------------
/js/actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/actionText-fFcUPi2g-gjw6zxAU.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @nextcloud/vue
6 | - version: 8.27.0
7 | - license: AGPL-3.0-or-later
8 |
--------------------------------------------------------------------------------
/js/index-Dly6xalz.chunk.mjs.license:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | This file is generated from multiple sources. Included packages:
5 |
--------------------------------------------------------------------------------
/js/index-Dly6xalz.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | This file is generated from multiple sources. Included packages:
5 |
--------------------------------------------------------------------------------
/js/index-DtIMqdu8.chunk.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: 0BSD
2 | SPDX-License-Identifier: MIT
3 | SPDX-FileCopyrightText: @emotion/unitless developers
4 | SPDX-FileCopyrightText: Anton Lavrenov
5 | SPDX-FileCopyrightText: Cody Bennett (https://github.com/codyjasonbennett)
6 | SPDX-FileCopyrightText: Federico Zivolo
7 | SPDX-FileCopyrightText: Glen Maddern
8 | SPDX-FileCopyrightText: John-David Dalton
9 | SPDX-FileCopyrightText: Microsoft Corp.
10 | SPDX-FileCopyrightText: Scaleflex
11 | SPDX-FileCopyrightText: Sultan Tarimo
12 | SPDX-FileCopyrightText: The Babel Team (https://babel.dev/team)
13 | SPDX-FileCopyrightText: prop-types developers
14 | SPDX-FileCopyrightText: react developers
15 | SPDX-FileCopyrightText: react-dom developers
16 | SPDX-FileCopyrightText: react-konva developers
17 | SPDX-FileCopyrightText: react-reconciler developers
18 | SPDX-FileCopyrightText: scaleflex
19 | SPDX-FileCopyrightText: scheduler developers
20 |
21 | This file is generated from multiple sources. Included packages:
22 | - @babel/runtime
23 | - version: 7.27.4
24 | - license: MIT
25 | - @emotion/unitless
26 | - version: 0.8.1
27 | - license: MIT
28 | - @popperjs/core
29 | - version: 2.11.8
30 | - license: MIT
31 | - @scaleflex/icons
32 | - version: 2.10.27
33 | - license: MIT
34 | - @scaleflex/ui
35 | - version: 2.10.27
36 | - license: MIT
37 | - filerobot-image-editor
38 | - version: 4.8.1
39 | - license: MIT
40 | - its-fine
41 | - version: 2.0.0
42 | - license: MIT
43 | - konva
44 | - version: 9.3.6
45 | - license: MIT
46 | - konva
47 | - version: 9.3.20
48 | - license: MIT
49 | - lodash.merge
50 | - version: 4.6.2
51 | - license: MIT
52 | - prop-types
53 | - version: 15.7.2
54 | - license: MIT
55 | - react
56 | - version: 18.3.1
57 | - license: MIT
58 | - react
59 | - version: 19.1.0
60 | - license: MIT
61 | - react-dom
62 | - version: 18.3.1
63 | - license: MIT
64 | - react-dom
65 | - version: 19.1.0
66 | - license: MIT
67 | - react-filerobot-image-editor
68 | - version: 4.9.1
69 | - license: MIT
70 | - react-konva
71 | - version: 19.0.4
72 | - license: MIT
73 | - react-reconciler
74 | - version: 0.32.0
75 | - license: MIT
76 | - scheduler
77 | - version: 0.23.2
78 | - license: MIT
79 | - scheduler
80 | - version: 0.26.0
81 | - license: MIT
82 | - styled-components
83 | - version: 6.1.18
84 | - license: MIT
85 | - stylis
86 | - version: 4.3.2
87 | - license: MIT
88 | - tslib
89 | - version: 2.6.2
90 | - license: 0BSD
91 |
--------------------------------------------------------------------------------
/js/index-DtIMqdu8.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: 0BSD
2 | SPDX-License-Identifier: MIT
3 | SPDX-FileCopyrightText: @emotion/unitless developers
4 | SPDX-FileCopyrightText: Anton Lavrenov
5 | SPDX-FileCopyrightText: Cody Bennett (https://github.com/codyjasonbennett)
6 | SPDX-FileCopyrightText: Federico Zivolo
7 | SPDX-FileCopyrightText: Glen Maddern
8 | SPDX-FileCopyrightText: John-David Dalton
9 | SPDX-FileCopyrightText: Microsoft Corp.
10 | SPDX-FileCopyrightText: Scaleflex
11 | SPDX-FileCopyrightText: Sultan Tarimo
12 | SPDX-FileCopyrightText: The Babel Team (https://babel.dev/team)
13 | SPDX-FileCopyrightText: prop-types developers
14 | SPDX-FileCopyrightText: react developers
15 | SPDX-FileCopyrightText: react-dom developers
16 | SPDX-FileCopyrightText: react-konva developers
17 | SPDX-FileCopyrightText: react-reconciler developers
18 | SPDX-FileCopyrightText: scaleflex
19 | SPDX-FileCopyrightText: scheduler developers
20 |
21 | This file is generated from multiple sources. Included packages:
22 | - @babel/runtime
23 | - version: 7.27.4
24 | - license: MIT
25 | - @emotion/unitless
26 | - version: 0.8.1
27 | - license: MIT
28 | - @popperjs/core
29 | - version: 2.11.8
30 | - license: MIT
31 | - @scaleflex/icons
32 | - version: 2.10.27
33 | - license: MIT
34 | - @scaleflex/ui
35 | - version: 2.10.27
36 | - license: MIT
37 | - filerobot-image-editor
38 | - version: 4.8.1
39 | - license: MIT
40 | - its-fine
41 | - version: 2.0.0
42 | - license: MIT
43 | - konva
44 | - version: 9.3.6
45 | - license: MIT
46 | - konva
47 | - version: 9.3.20
48 | - license: MIT
49 | - lodash.merge
50 | - version: 4.6.2
51 | - license: MIT
52 | - prop-types
53 | - version: 15.7.2
54 | - license: MIT
55 | - react
56 | - version: 18.3.1
57 | - license: MIT
58 | - react
59 | - version: 19.1.0
60 | - license: MIT
61 | - react-dom
62 | - version: 18.3.1
63 | - license: MIT
64 | - react-dom
65 | - version: 19.1.0
66 | - license: MIT
67 | - react-filerobot-image-editor
68 | - version: 4.9.1
69 | - license: MIT
70 | - react-konva
71 | - version: 19.0.4
72 | - license: MIT
73 | - react-reconciler
74 | - version: 0.32.0
75 | - license: MIT
76 | - scheduler
77 | - version: 0.23.2
78 | - license: MIT
79 | - scheduler
80 | - version: 0.26.0
81 | - license: MIT
82 | - styled-components
83 | - version: 6.1.18
84 | - license: MIT
85 | - stylis
86 | - version: 4.3.2
87 | - license: MIT
88 | - tslib
89 | - version: 2.6.2
90 | - license: 0BSD
91 |
--------------------------------------------------------------------------------
/js/index.esm-CAkhAkGw.chunk.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: MIT
2 | SPDX-FileCopyrightText: Gabe Dunn
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @skjnldsv/vue-plyr
6 | - version: 7.5.0
7 | - license: MIT
8 |
--------------------------------------------------------------------------------
/js/index.esm-CAkhAkGw.chunk.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: MIT
2 | SPDX-FileCopyrightText: Gabe Dunn
3 |
4 | This file is generated from multiple sources. Included packages:
5 | - @skjnldsv/vue-plyr
6 | - version: 7.5.0
7 | - license: MIT
8 |
--------------------------------------------------------------------------------
/js/viewer-main.mjs.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-License-Identifier: MIT
3 | SPDX-FileCopyrightText: Javier Blanco
4 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
5 | SPDX-FileCopyrightText: John Molakvoæ
6 | SPDX-FileCopyrightText: Rob Cresswell
7 |
8 | This file is generated from multiple sources. Included packages:
9 | - @nextcloud/vue
10 | - version: 8.27.0
11 | - license: AGPL-3.0-or-later
12 | - path-parse
13 | - version: 1.0.7
14 | - license: MIT
15 | - viewer
16 | - version: 5.0.0-dev.0
17 | - license: AGPL-3.0-or-later
18 | - vue-material-design-icons
19 | - version: 5.3.1
20 | - license: MIT
21 |
--------------------------------------------------------------------------------
/js/viewer-main.mjs.map.license:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: AGPL-3.0-or-later
2 | SPDX-License-Identifier: MIT
3 | SPDX-FileCopyrightText: Javier Blanco
4 | SPDX-FileCopyrightText: John Molakvoæ (skjnldsv)
5 | SPDX-FileCopyrightText: John Molakvoæ
6 | SPDX-FileCopyrightText: Rob Cresswell
7 |
8 | This file is generated from multiple sources. Included packages:
9 | - @nextcloud/vue
10 | - version: 8.27.0
11 | - license: AGPL-3.0-or-later
12 | - path-parse
13 | - version: 1.0.7
14 | - license: MIT
15 | - viewer
16 | - version: 5.0.0-dev.0
17 | - license: AGPL-3.0-or-later
18 | - vue-material-design-icons
19 | - version: 5.3.1
20 | - license: MIT
21 |
--------------------------------------------------------------------------------
/l10n/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nextcloud/viewer/dc73ca59b4012b44b79568b8a5edb0b98b740660/l10n/.gitkeep
--------------------------------------------------------------------------------
/l10n/af.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Bekyker",
5 | "Simple file viewer with slideshow for media" : "Kyk maklik na lêers met skyfievertonings vir media",
6 | "Your browser does not support audio." : "U blaaier ondersteun nie oudio nie.",
7 | "Error loading {name}" : "Laaifout vir {name}",
8 | "Your browser does not support videos." : "U blaaier ondersteun nie video’s nie.",
9 | "There is no plugin available to display this file type" : "Daar is geen beskikbare inprop om hierdie lêertipe te vertoon nie",
10 | "Edit" : "Wysig",
11 | "Open sidebar" : "Open kantbalk",
12 | "Download" : "Laai af",
13 | "Delete" : "Skrap",
14 | "View" : "Bekyk",
15 | "Name" : "Naam",
16 | "Save" : "Bewaar",
17 | "Back" : "Terug",
18 | "Loading …" : "Laai …",
19 | "Reset" : "Herstel",
20 | "Cancel" : "Kanselleer",
21 | "Confirm" : "Bevestig",
22 | "Original" : "Oorspronklik",
23 | "Custom" : "Eie",
24 | "Value" : "Waarde",
25 | "Text" : "Teks",
26 | "Size" : "Grootte",
27 | "Position" : "Posisie",
28 | "Quality" : "Kwaliteit",
29 | "Menu" : "Kieslys"
30 | },
31 | "nplurals=2; plural=(n != 1);");
32 |
--------------------------------------------------------------------------------
/l10n/af.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Bekyker",
3 | "Simple file viewer with slideshow for media" : "Kyk maklik na lêers met skyfievertonings vir media",
4 | "Your browser does not support audio." : "U blaaier ondersteun nie oudio nie.",
5 | "Error loading {name}" : "Laaifout vir {name}",
6 | "Your browser does not support videos." : "U blaaier ondersteun nie video’s nie.",
7 | "There is no plugin available to display this file type" : "Daar is geen beskikbare inprop om hierdie lêertipe te vertoon nie",
8 | "Edit" : "Wysig",
9 | "Open sidebar" : "Open kantbalk",
10 | "Download" : "Laai af",
11 | "Delete" : "Skrap",
12 | "View" : "Bekyk",
13 | "Name" : "Naam",
14 | "Save" : "Bewaar",
15 | "Back" : "Terug",
16 | "Loading …" : "Laai …",
17 | "Reset" : "Herstel",
18 | "Cancel" : "Kanselleer",
19 | "Confirm" : "Bevestig",
20 | "Original" : "Oorspronklik",
21 | "Custom" : "Eie",
22 | "Value" : "Waarde",
23 | "Text" : "Teks",
24 | "Size" : "Grootte",
25 | "Position" : "Posisie",
26 | "Quality" : "Kwaliteit",
27 | "Menu" : "Kieslys"
28 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
29 | }
--------------------------------------------------------------------------------
/l10n/az.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Dəyişiklik et",
5 | "Download" : "Yüklə",
6 | "Delete" : "Sil",
7 | "Name" : "Ad",
8 | "Save" : "Saxla",
9 | "Back" : "Geri",
10 | "Reset" : "Sıfırla",
11 | "Cancel" : "Dayandır",
12 | "Warning" : "Xəbərdarlıq",
13 | "Confirm" : "Təsdiq edin",
14 | "Size" : "Həcm",
15 | "Menu" : "Menyu"
16 | },
17 | "nplurals=2; plural=(n != 1);");
18 |
--------------------------------------------------------------------------------
/l10n/az.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Dəyişiklik et",
3 | "Download" : "Yüklə",
4 | "Delete" : "Sil",
5 | "Name" : "Ad",
6 | "Save" : "Saxla",
7 | "Back" : "Geri",
8 | "Reset" : "Sıfırla",
9 | "Cancel" : "Dayandır",
10 | "Warning" : "Xəbərdarlıq",
11 | "Confirm" : "Təsdiq edin",
12 | "Size" : "Həcm",
13 | "Menu" : "Menyu"
14 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
15 | }
--------------------------------------------------------------------------------
/l10n/bn_BD.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "সম্পাদনা",
5 | "Download" : "ডাউনলোড",
6 | "Delete" : "মুছে",
7 | "Name" : "নাম",
8 | "Save" : "সংরক্ষণ",
9 | "Back" : "পেছনে যাও",
10 | "Reset" : "পূণঃনির্ধানণ",
11 | "Cancel" : "বাতির",
12 | "Warning" : "সতর্কবাণী",
13 | "Size" : "আকার"
14 | },
15 | "nplurals=2; plural=(n != 1);");
16 |
--------------------------------------------------------------------------------
/l10n/bn_BD.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "সম্পাদনা",
3 | "Download" : "ডাউনলোড",
4 | "Delete" : "মুছে",
5 | "Name" : "নাম",
6 | "Save" : "সংরক্ষণ",
7 | "Back" : "পেছনে যাও",
8 | "Reset" : "পূণঃনির্ধানণ",
9 | "Cancel" : "বাতির",
10 | "Warning" : "সতর্কবাণী",
11 | "Size" : "আকার"
12 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
13 | }
--------------------------------------------------------------------------------
/l10n/br.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Gweller",
5 | "Simple file viewer with slideshow for media" : "Ur seller restroù simpl gant un diaporama evit ar mediaoù",
6 | "Error loading {name}" : "Ur fazi zo bet en ur kargañ {name}",
7 | "LIVE" : "WAR-EEUN",
8 | "Your browser does not support videos." : "Ne doug ket ho furcher ar videoioù.",
9 | "Edit" : "Cheñch",
10 | "Open sidebar" : "Digori ar varenn gostez",
11 | "Download" : "Pellgargañ",
12 | "Delete" : "Dilemel",
13 | "View" : "Gwell",
14 | "Name" : "Anv",
15 | "Save" : "Enrollañ",
16 | "Back" : "Distro",
17 | "Loading …" : "O Kargañ ...",
18 | "Cancel" : "Nullañ",
19 | "Apply" : "Lakaat",
20 | "Warning" : "Kemenadenn",
21 | "Confirm" : "Kadarnaat",
22 | "Original" : "Orin",
23 | "Text" : "Testenn",
24 | "Size" : "Ment",
25 | "Menu" : "Roll"
26 | },
27 | "nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);");
28 |
--------------------------------------------------------------------------------
/l10n/br.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Gweller",
3 | "Simple file viewer with slideshow for media" : "Ur seller restroù simpl gant un diaporama evit ar mediaoù",
4 | "Error loading {name}" : "Ur fazi zo bet en ur kargañ {name}",
5 | "LIVE" : "WAR-EEUN",
6 | "Your browser does not support videos." : "Ne doug ket ho furcher ar videoioù.",
7 | "Edit" : "Cheñch",
8 | "Open sidebar" : "Digori ar varenn gostez",
9 | "Download" : "Pellgargañ",
10 | "Delete" : "Dilemel",
11 | "View" : "Gwell",
12 | "Name" : "Anv",
13 | "Save" : "Enrollañ",
14 | "Back" : "Distro",
15 | "Loading …" : "O Kargañ ...",
16 | "Cancel" : "Nullañ",
17 | "Apply" : "Lakaat",
18 | "Warning" : "Kemenadenn",
19 | "Confirm" : "Kadarnaat",
20 | "Original" : "Orin",
21 | "Text" : "Testenn",
22 | "Size" : "Ment",
23 | "Menu" : "Roll"
24 | },"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"
25 | }
--------------------------------------------------------------------------------
/l10n/bs.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Izmjeni",
5 | "Download" : "Preuzmi",
6 | "Delete" : "Obriši",
7 | "Name" : "Ime",
8 | "Save" : "Spremi",
9 | "Cancel" : "Otkaži",
10 | "Warning" : "Upozorenje",
11 | "Size" : "Veličina"
12 | },
13 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
14 |
--------------------------------------------------------------------------------
/l10n/bs.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Izmjeni",
3 | "Download" : "Preuzmi",
4 | "Delete" : "Obriši",
5 | "Name" : "Ime",
6 | "Save" : "Spremi",
7 | "Cancel" : "Otkaži",
8 | "Warning" : "Upozorenje",
9 | "Size" : "Veličina"
10 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
11 | }
--------------------------------------------------------------------------------
/l10n/cy_GB.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Golygu",
5 | "Open sidebar" : "Agor y bar ochr",
6 | "Download" : "Llwytho i lawr",
7 | "Delete" : "Dileu",
8 | "View" : "Golwg",
9 | "Name" : "Enw",
10 | "Save" : "Cadw",
11 | "Back" : "Nôl",
12 | "Loading …" : "Yn llwytho …",
13 | "Cancel" : "Diddymu",
14 | "Warning" : "Rhybudd",
15 | "Confirm" : "Cadarnhau",
16 | "Undo" : "Dadwneud",
17 | "Custom" : "Cyfaddas",
18 | "Size" : "Maint"
19 | },
20 | "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;");
21 |
--------------------------------------------------------------------------------
/l10n/cy_GB.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Golygu",
3 | "Open sidebar" : "Agor y bar ochr",
4 | "Download" : "Llwytho i lawr",
5 | "Delete" : "Dileu",
6 | "View" : "Golwg",
7 | "Name" : "Enw",
8 | "Save" : "Cadw",
9 | "Back" : "Nôl",
10 | "Loading …" : "Yn llwytho …",
11 | "Cancel" : "Diddymu",
12 | "Warning" : "Rhybudd",
13 | "Confirm" : "Cadarnhau",
14 | "Undo" : "Dadwneud",
15 | "Custom" : "Cyfaddas",
16 | "Size" : "Maint"
17 | },"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"
18 | }
--------------------------------------------------------------------------------
/l10n/el.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Πρόγραμμα προβολής",
5 | "Simple file viewer with slideshow for media" : "Απλό πρόγραμμα προβολής αρχείων με παρουσίαση διαφανειών για πολυμέσα",
6 | "Your browser does not support audio." : "Το πρόγραμμα περιήγησής σας δεν υποστηρίζει ήχο.",
7 | "Error loading {name}" : "Σφάλμα φόρτωσης {name}",
8 | "Image saved" : "Η εικόνα αποθηκεύτηκε",
9 | "Your browser does not support videos." : "Ο περιηγητής σας δεν υποστηρίζει βίντεο.",
10 | "There is no plugin available to display this file type" : "Δεν υπάρχει διαθέσιμο πρόσθετο για την προβολή αυτού του τύπου αρχείου",
11 | "Edit" : "Επεξεργασία",
12 | "Open sidebar" : "Άνοιγμα πλευρικής στήλης",
13 | "Download" : "Λήψη",
14 | "Delete" : "Διαγραφή",
15 | "View" : "Προβολή",
16 | "Name" : "Όνομα",
17 | "Save" : "Αποθήκευση",
18 | "Save as" : "Αποθήκευση ως",
19 | "Back" : "Πίσω",
20 | "Loading …" : "Φόρτωση …",
21 | "Reset" : "Επαναφορά",
22 | "Cancel" : "Ακύρωση",
23 | "Apply" : "Εφαρμογή",
24 | "Warning" : "Προειδοποίηση",
25 | "Confirm" : "Επιβεβαίωση",
26 | "Undo" : "Ακύρωση ενέργειας",
27 | "Redo" : "Ξανακάντε",
28 | "Zoom in" : "Εστίαση",
29 | "Zoom out" : "Σμίκρυνση",
30 | "Adjust" : "Ρύθμιση",
31 | "Filters" : "Φίλτρα",
32 | "Watermark" : "Υδατόσημο",
33 | "Draw" : "Σχεδίαση",
34 | "Resize" : "Αλλαγή μεγέθους",
35 | "Crop" : "Περικοπή",
36 | "Original" : "Πρωτότυπο",
37 | "Custom" : "Προσαρμοσμένο",
38 | "Square" : "Τετράγωνο",
39 | "Landscape" : "Οριζόντια",
40 | "Portrait" : "Κάθετα",
41 | "Ellipse" : "Έλλειψη",
42 | "Arrow" : "Βέλος",
43 | "Brightness" : "Φωτεινότητα",
44 | "Contrast" : "Αντίθεση",
45 | "Hue" : "Απόχρωση",
46 | "Saturation" : "Κορεσμός",
47 | "Value" : "Τιμή",
48 | "Image" : "Εικόνα",
49 | "Line" : "Γραμμή",
50 | "Polygon" : "Πολύγωνο",
51 | "Rotate" : "Περιστροφή",
52 | "Text" : "Κείμενο",
53 | "Size" : "Μέγεθος",
54 | "Padding" : "Γέμισμα",
55 | "Vertical" : "Κάθετα",
56 | "Opacity" : "Διαφάνεια",
57 | "Position" : "Θέση",
58 | "Stroke" : "Πινελιά",
59 | "Save image as" : "Αποθήκευση εικόνας ως",
60 | "Extension" : "Επέκταση",
61 | "Name is required." : "Απαιτείται όνομα.",
62 | "Quality" : "Ποιότητα",
63 | "Fit size" : "Προσαρμογή στο μέγεθος",
64 | "Menu" : "Μενού",
65 | "Height" : "Ύψος"
66 | },
67 | "nplurals=2; plural=(n != 1);");
68 |
--------------------------------------------------------------------------------
/l10n/el.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Πρόγραμμα προβολής",
3 | "Simple file viewer with slideshow for media" : "Απλό πρόγραμμα προβολής αρχείων με παρουσίαση διαφανειών για πολυμέσα",
4 | "Your browser does not support audio." : "Το πρόγραμμα περιήγησής σας δεν υποστηρίζει ήχο.",
5 | "Error loading {name}" : "Σφάλμα φόρτωσης {name}",
6 | "Image saved" : "Η εικόνα αποθηκεύτηκε",
7 | "Your browser does not support videos." : "Ο περιηγητής σας δεν υποστηρίζει βίντεο.",
8 | "There is no plugin available to display this file type" : "Δεν υπάρχει διαθέσιμο πρόσθετο για την προβολή αυτού του τύπου αρχείου",
9 | "Edit" : "Επεξεργασία",
10 | "Open sidebar" : "Άνοιγμα πλευρικής στήλης",
11 | "Download" : "Λήψη",
12 | "Delete" : "Διαγραφή",
13 | "View" : "Προβολή",
14 | "Name" : "Όνομα",
15 | "Save" : "Αποθήκευση",
16 | "Save as" : "Αποθήκευση ως",
17 | "Back" : "Πίσω",
18 | "Loading …" : "Φόρτωση …",
19 | "Reset" : "Επαναφορά",
20 | "Cancel" : "Ακύρωση",
21 | "Apply" : "Εφαρμογή",
22 | "Warning" : "Προειδοποίηση",
23 | "Confirm" : "Επιβεβαίωση",
24 | "Undo" : "Ακύρωση ενέργειας",
25 | "Redo" : "Ξανακάντε",
26 | "Zoom in" : "Εστίαση",
27 | "Zoom out" : "Σμίκρυνση",
28 | "Adjust" : "Ρύθμιση",
29 | "Filters" : "Φίλτρα",
30 | "Watermark" : "Υδατόσημο",
31 | "Draw" : "Σχεδίαση",
32 | "Resize" : "Αλλαγή μεγέθους",
33 | "Crop" : "Περικοπή",
34 | "Original" : "Πρωτότυπο",
35 | "Custom" : "Προσαρμοσμένο",
36 | "Square" : "Τετράγωνο",
37 | "Landscape" : "Οριζόντια",
38 | "Portrait" : "Κάθετα",
39 | "Ellipse" : "Έλλειψη",
40 | "Arrow" : "Βέλος",
41 | "Brightness" : "Φωτεινότητα",
42 | "Contrast" : "Αντίθεση",
43 | "Hue" : "Απόχρωση",
44 | "Saturation" : "Κορεσμός",
45 | "Value" : "Τιμή",
46 | "Image" : "Εικόνα",
47 | "Line" : "Γραμμή",
48 | "Polygon" : "Πολύγωνο",
49 | "Rotate" : "Περιστροφή",
50 | "Text" : "Κείμενο",
51 | "Size" : "Μέγεθος",
52 | "Padding" : "Γέμισμα",
53 | "Vertical" : "Κάθετα",
54 | "Opacity" : "Διαφάνεια",
55 | "Position" : "Θέση",
56 | "Stroke" : "Πινελιά",
57 | "Save image as" : "Αποθήκευση εικόνας ως",
58 | "Extension" : "Επέκταση",
59 | "Name is required." : "Απαιτείται όνομα.",
60 | "Quality" : "Ποιότητα",
61 | "Fit size" : "Προσαρμογή στο μέγεθος",
62 | "Menu" : "Μενού",
63 | "Height" : "Ύψος"
64 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
65 | }
--------------------------------------------------------------------------------
/l10n/eo.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Vidigilo",
5 | "Simple file viewer with slideshow for media" : "Simpla dosiervidigilo kun lumbilda prezento por aŭdvidaĵoj",
6 | "Error loading {name}" : "Eraro dum ŝargo de {name}",
7 | "Your browser does not support videos." : "Via retumilo ne subtenas la vidaĵojn",
8 | "Edit" : "Modifi",
9 | "Open sidebar" : "Malfermi flankopanelon",
10 | "Download" : "Elŝuti",
11 | "Delete" : "Forigi",
12 | "View" : "Vidi",
13 | "Name" : "Nomo",
14 | "Save" : "Konservi",
15 | "Back" : "Antaŭen",
16 | "Loading …" : "Ŝargas …",
17 | "Reset" : "Restarigi",
18 | "Cancel" : "Nuligi",
19 | "Apply" : "Validigi",
20 | "Warning" : "Averto",
21 | "Confirm" : "Konfirmi",
22 | "Undo" : "Malfari",
23 | "Redo" : "Refari",
24 | "Custom" : "Propra",
25 | "Text" : "Teksto",
26 | "Size" : "Grando",
27 | "Position" : "Loko",
28 | "Extension" : "Dosiersufikso"
29 | },
30 | "nplurals=2; plural=(n != 1);");
31 |
--------------------------------------------------------------------------------
/l10n/eo.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Vidigilo",
3 | "Simple file viewer with slideshow for media" : "Simpla dosiervidigilo kun lumbilda prezento por aŭdvidaĵoj",
4 | "Error loading {name}" : "Eraro dum ŝargo de {name}",
5 | "Your browser does not support videos." : "Via retumilo ne subtenas la vidaĵojn",
6 | "Edit" : "Modifi",
7 | "Open sidebar" : "Malfermi flankopanelon",
8 | "Download" : "Elŝuti",
9 | "Delete" : "Forigi",
10 | "View" : "Vidi",
11 | "Name" : "Nomo",
12 | "Save" : "Konservi",
13 | "Back" : "Antaŭen",
14 | "Loading …" : "Ŝargas …",
15 | "Reset" : "Restarigi",
16 | "Cancel" : "Nuligi",
17 | "Apply" : "Validigi",
18 | "Warning" : "Averto",
19 | "Confirm" : "Konfirmi",
20 | "Undo" : "Malfari",
21 | "Redo" : "Refari",
22 | "Custom" : "Propra",
23 | "Text" : "Teksto",
24 | "Size" : "Grando",
25 | "Position" : "Loko",
26 | "Extension" : "Dosiersufikso"
27 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
28 | }
--------------------------------------------------------------------------------
/l10n/es_419.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restaurar",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Deshacer",
15 | "Custom" : "Personalizado",
16 | "Value" : "Valor",
17 | "Text" : "Texto",
18 | "Size" : "Tamaño",
19 | "Position" : "Posición",
20 | "Menu" : "Menú"
21 | },
22 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
23 |
--------------------------------------------------------------------------------
/l10n/es_419.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restaurar",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Confirm" : "Confirmar",
12 | "Undo" : "Deshacer",
13 | "Custom" : "Personalizado",
14 | "Value" : "Valor",
15 | "Text" : "Texto",
16 | "Size" : "Tamaño",
17 | "Position" : "Posición",
18 | "Menu" : "Menú"
19 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
20 | }
--------------------------------------------------------------------------------
/l10n/es_AR.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "LIVE" : "EN VIVO",
5 | "Edit" : "Editar",
6 | "Open sidebar" : "Abrir barra lateral",
7 | "Download" : "Descargar",
8 | "Delete" : "Eliminar",
9 | "View" : "Ver",
10 | "Name" : "Nombre",
11 | "Save" : "Guardar",
12 | "Back" : "Atrás",
13 | "Loading …" : "Cargando …",
14 | "Reset" : "Restablecer",
15 | "Cancel" : "Cancelar",
16 | "Apply" : "Aplicar",
17 | "Warning" : "Advertencia",
18 | "Confirm" : "Confirmar",
19 | "Undo" : "Deshacer",
20 | "Custom" : "Personalizado",
21 | "Value" : "Valor",
22 | "Line" : "Linea",
23 | "Text" : "Texto",
24 | "Size" : "Tamaño",
25 | "Position" : "Posición",
26 | "Menu" : "Menú"
27 | },
28 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
29 |
--------------------------------------------------------------------------------
/l10n/es_AR.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "LIVE" : "EN VIVO",
3 | "Edit" : "Editar",
4 | "Open sidebar" : "Abrir barra lateral",
5 | "Download" : "Descargar",
6 | "Delete" : "Eliminar",
7 | "View" : "Ver",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Loading …" : "Cargando …",
12 | "Reset" : "Restablecer",
13 | "Cancel" : "Cancelar",
14 | "Apply" : "Aplicar",
15 | "Warning" : "Advertencia",
16 | "Confirm" : "Confirmar",
17 | "Undo" : "Deshacer",
18 | "Custom" : "Personalizado",
19 | "Value" : "Valor",
20 | "Line" : "Linea",
21 | "Text" : "Texto",
22 | "Size" : "Tamaño",
23 | "Position" : "Posición",
24 | "Menu" : "Menú"
25 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
26 | }
--------------------------------------------------------------------------------
/l10n/es_CL.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Loading …" : "Cargando …",
12 | "Reset" : "Restablecer",
13 | "Cancel" : "Cancelar",
14 | "Apply" : "Aplicar",
15 | "Warning" : "Advertencia",
16 | "Confirm" : "Confirmar",
17 | "Undo" : "Deshacer",
18 | "Custom" : "Personalizado",
19 | "Value" : "Valor",
20 | "Text" : "Texto",
21 | "Size" : "Tamaño",
22 | "Position" : "Posición",
23 | "Menu" : "Menú"
24 | },
25 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
26 |
--------------------------------------------------------------------------------
/l10n/es_CL.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Loading …" : "Cargando …",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Warning" : "Advertencia",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
23 | }
--------------------------------------------------------------------------------
/l10n/es_CO.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Reset" : "Reiniciar",
12 | "Cancel" : "Cancelar",
13 | "Apply" : "Aplicar",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_CO.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Reset" : "Reiniciar",
10 | "Cancel" : "Cancelar",
11 | "Apply" : "Aplicar",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_CR.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Reset" : "Restablecer",
12 | "Cancel" : "Cancelar",
13 | "Apply" : "Aplicar",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_CR.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Reset" : "Restablecer",
10 | "Cancel" : "Cancelar",
11 | "Apply" : "Aplicar",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_DO.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Reset" : "Restablecer",
12 | "Cancel" : "Cancelar",
13 | "Apply" : "Aplicar",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_DO.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Reset" : "Restablecer",
10 | "Cancel" : "Cancelar",
11 | "Apply" : "Aplicar",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_GT.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Reset" : "Restablecer",
12 | "Cancel" : "Cancelar",
13 | "Apply" : "Aplicar",
14 | "Warning" : "Advertencia",
15 | "Confirm" : "Confirmar",
16 | "Undo" : "Deshacer",
17 | "Custom" : "Personalizado",
18 | "Value" : "Valor",
19 | "Text" : "Texto",
20 | "Size" : "Tamaño",
21 | "Position" : "Posición",
22 | "Menu" : "Menú"
23 | },
24 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
25 |
--------------------------------------------------------------------------------
/l10n/es_GT.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Reset" : "Restablecer",
10 | "Cancel" : "Cancelar",
11 | "Apply" : "Aplicar",
12 | "Warning" : "Advertencia",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Deshacer",
15 | "Custom" : "Personalizado",
16 | "Value" : "Valor",
17 | "Text" : "Texto",
18 | "Size" : "Tamaño",
19 | "Position" : "Posición",
20 | "Menu" : "Menú"
21 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
22 | }
--------------------------------------------------------------------------------
/l10n/es_HN.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Warning" : "Advertencia",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_HN.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Warning" : "Advertencia",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_NI.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Deshacer",
15 | "Custom" : "Personalizado",
16 | "Value" : "Valor",
17 | "Text" : "Texto",
18 | "Size" : "Tamaño",
19 | "Position" : "Posición",
20 | "Menu" : "Menú"
21 | },
22 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
23 |
--------------------------------------------------------------------------------
/l10n/es_NI.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Confirm" : "Confirmar",
12 | "Undo" : "Deshacer",
13 | "Custom" : "Personalizado",
14 | "Value" : "Valor",
15 | "Text" : "Texto",
16 | "Size" : "Tamaño",
17 | "Position" : "Posición",
18 | "Menu" : "Menú"
19 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
20 | }
--------------------------------------------------------------------------------
/l10n/es_PA.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Deshacer",
15 | "Custom" : "Personalizado",
16 | "Value" : "Valor",
17 | "Text" : "Texto",
18 | "Size" : "Tamaño",
19 | "Position" : "Posición",
20 | "Menu" : "Menú"
21 | },
22 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
23 |
--------------------------------------------------------------------------------
/l10n/es_PA.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Confirm" : "Confirmar",
12 | "Undo" : "Deshacer",
13 | "Custom" : "Personalizado",
14 | "Value" : "Valor",
15 | "Text" : "Texto",
16 | "Size" : "Tamaño",
17 | "Position" : "Posición",
18 | "Menu" : "Menú"
19 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
20 | }
--------------------------------------------------------------------------------
/l10n/es_PE.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Warning" : "Advertencia",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_PE.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Warning" : "Advertencia",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_PR.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Deshacer",
15 | "Custom" : "Personalizado",
16 | "Value" : "Valor",
17 | "Text" : "Texto",
18 | "Size" : "Tamaño",
19 | "Position" : "Posición",
20 | "Menu" : "Menú"
21 | },
22 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
23 |
--------------------------------------------------------------------------------
/l10n/es_PR.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Confirm" : "Confirmar",
12 | "Undo" : "Deshacer",
13 | "Custom" : "Personalizado",
14 | "Value" : "Valor",
15 | "Text" : "Texto",
16 | "Size" : "Tamaño",
17 | "Position" : "Posición",
18 | "Menu" : "Menú"
19 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
20 | }
--------------------------------------------------------------------------------
/l10n/es_PY.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Visor",
5 | "Error loading {name}" : "Se presentó un error al cargar {name}",
6 | "Your browser does not support videos." : "Tu navegador no soporta videos.",
7 | "Edit" : "Editar",
8 | "Open sidebar" : "Abrir barra lateral",
9 | "Download" : "Descargar",
10 | "Delete" : "Borrar",
11 | "Name" : "Nombre",
12 | "Save" : "Guardar",
13 | "Back" : "Atrás",
14 | "Reset" : "Restablecer",
15 | "Cancel" : "Cancelar",
16 | "Apply" : "Aplicar",
17 | "Confirm" : "Confirmar",
18 | "Undo" : "Deshacer",
19 | "Custom" : "Personalizado",
20 | "Value" : "Valor",
21 | "Text" : "Texto",
22 | "Size" : "Tamaño",
23 | "Position" : "Posición",
24 | "Menu" : "Menú"
25 | },
26 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
27 |
--------------------------------------------------------------------------------
/l10n/es_PY.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Visor",
3 | "Error loading {name}" : "Se presentó un error al cargar {name}",
4 | "Your browser does not support videos." : "Tu navegador no soporta videos.",
5 | "Edit" : "Editar",
6 | "Open sidebar" : "Abrir barra lateral",
7 | "Download" : "Descargar",
8 | "Delete" : "Borrar",
9 | "Name" : "Nombre",
10 | "Save" : "Guardar",
11 | "Back" : "Atrás",
12 | "Reset" : "Restablecer",
13 | "Cancel" : "Cancelar",
14 | "Apply" : "Aplicar",
15 | "Confirm" : "Confirmar",
16 | "Undo" : "Deshacer",
17 | "Custom" : "Personalizado",
18 | "Value" : "Valor",
19 | "Text" : "Texto",
20 | "Size" : "Tamaño",
21 | "Position" : "Posición",
22 | "Menu" : "Menú"
23 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
24 | }
--------------------------------------------------------------------------------
/l10n/es_SV.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imagen guardada",
5 | "Edit" : "Editar",
6 | "Download" : "Descargar",
7 | "Delete" : "Borrar",
8 | "Name" : "Nombre",
9 | "Save" : "Guardar",
10 | "Back" : "Atrás",
11 | "Reset" : "Restablecer",
12 | "Cancel" : "Cancelar",
13 | "Apply" : "Aplicar",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_SV.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imagen guardada",
3 | "Edit" : "Editar",
4 | "Download" : "Descargar",
5 | "Delete" : "Borrar",
6 | "Name" : "Nombre",
7 | "Save" : "Guardar",
8 | "Back" : "Atrás",
9 | "Reset" : "Restablecer",
10 | "Cancel" : "Cancelar",
11 | "Apply" : "Aplicar",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/es_UY.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Editar",
5 | "Download" : "Descargar",
6 | "Delete" : "Borrar",
7 | "Name" : "Nombre",
8 | "Save" : "Guardar",
9 | "Back" : "Atrás",
10 | "Reset" : "Restablecer",
11 | "Cancel" : "Cancelar",
12 | "Apply" : "Aplicar",
13 | "Warning" : "Advertencia",
14 | "Confirm" : "Confirmar",
15 | "Undo" : "Deshacer",
16 | "Custom" : "Personalizado",
17 | "Value" : "Valor",
18 | "Text" : "Texto",
19 | "Size" : "Tamaño",
20 | "Position" : "Posición",
21 | "Menu" : "Menú"
22 | },
23 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
24 |
--------------------------------------------------------------------------------
/l10n/es_UY.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Editar",
3 | "Download" : "Descargar",
4 | "Delete" : "Borrar",
5 | "Name" : "Nombre",
6 | "Save" : "Guardar",
7 | "Back" : "Atrás",
8 | "Reset" : "Restablecer",
9 | "Cancel" : "Cancelar",
10 | "Apply" : "Aplicar",
11 | "Warning" : "Advertencia",
12 | "Confirm" : "Confirmar",
13 | "Undo" : "Deshacer",
14 | "Custom" : "Personalizado",
15 | "Value" : "Valor",
16 | "Text" : "Texto",
17 | "Size" : "Tamaño",
18 | "Position" : "Posición",
19 | "Menu" : "Menú"
20 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
21 | }
--------------------------------------------------------------------------------
/l10n/gd.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Deasaich",
5 | "Open sidebar" : "Fosgail am bàr-taoibh",
6 | "Download" : "Luchdaich a-nuas",
7 | "Delete" : "Sguab às",
8 | "Name" : "Ainm",
9 | "Save" : "Sàbhail",
10 | "Back" : "Air ais",
11 | "Cancel" : "Sguir dheth",
12 | "Undo" : "Neo-dhèan"
13 | },
14 | "nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;");
15 |
--------------------------------------------------------------------------------
/l10n/gd.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Deasaich",
3 | "Open sidebar" : "Fosgail am bàr-taoibh",
4 | "Download" : "Luchdaich a-nuas",
5 | "Delete" : "Sguab às",
6 | "Name" : "Ainm",
7 | "Save" : "Sàbhail",
8 | "Back" : "Air ais",
9 | "Cancel" : "Sguir dheth",
10 | "Undo" : "Neo-dhèan"
11 | },"pluralForm" :"nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;"
12 | }
--------------------------------------------------------------------------------
/l10n/he.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "מציג",
5 | "Simple file viewer with slideshow for media" : "מציג קבצים פשוט עם תמיכה במצגות למדיה",
6 | "Your browser does not support audio." : "הדפדפן שלך אינו תומך בשמע.",
7 | "Error loading {name}" : "שגיאה בטעינת {name}",
8 | "Image saved" : "תמונה נשמרה",
9 | "Your browser does not support videos." : "הדפדפן שלך לא תומך בסרטונים.",
10 | "There is no plugin available to display this file type" : "אין תוסף זמין להצגת סוג הקובץ הזה",
11 | "Edit" : "עריכה",
12 | "Open sidebar" : "פתיחת סרגל הצד",
13 | "Download" : "הורדה",
14 | "Delete" : "מחיקה",
15 | "View" : "צפייה",
16 | "Name" : "שם",
17 | "Save" : "שמירה",
18 | "Back" : "חזרה",
19 | "Loading …" : "בטעינה…",
20 | "Reset" : "איפוס",
21 | "Cancel" : "ביטול",
22 | "Apply" : "החלה",
23 | "Warning" : "אזהרה",
24 | "Confirm" : "אישור",
25 | "Undo" : "ביטול",
26 | "Redo" : "שחזור",
27 | "Zoom in" : "התקרבות",
28 | "Custom" : "מותאם אישית",
29 | "Value" : "ערך",
30 | "Image" : "תמונה",
31 | "Text" : "טקסט",
32 | "Size" : "גודל",
33 | "Position" : "מיקום",
34 | "Extension" : "הרחבה",
35 | "Name is required." : "נדרש שם.",
36 | "Quality" : "איכות",
37 | "Menu" : "תפריט",
38 | "Height" : "גובה"
39 | },
40 | "nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;");
41 |
--------------------------------------------------------------------------------
/l10n/he.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "מציג",
3 | "Simple file viewer with slideshow for media" : "מציג קבצים פשוט עם תמיכה במצגות למדיה",
4 | "Your browser does not support audio." : "הדפדפן שלך אינו תומך בשמע.",
5 | "Error loading {name}" : "שגיאה בטעינת {name}",
6 | "Image saved" : "תמונה נשמרה",
7 | "Your browser does not support videos." : "הדפדפן שלך לא תומך בסרטונים.",
8 | "There is no plugin available to display this file type" : "אין תוסף זמין להצגת סוג הקובץ הזה",
9 | "Edit" : "עריכה",
10 | "Open sidebar" : "פתיחת סרגל הצד",
11 | "Download" : "הורדה",
12 | "Delete" : "מחיקה",
13 | "View" : "צפייה",
14 | "Name" : "שם",
15 | "Save" : "שמירה",
16 | "Back" : "חזרה",
17 | "Loading …" : "בטעינה…",
18 | "Reset" : "איפוס",
19 | "Cancel" : "ביטול",
20 | "Apply" : "החלה",
21 | "Warning" : "אזהרה",
22 | "Confirm" : "אישור",
23 | "Undo" : "ביטול",
24 | "Redo" : "שחזור",
25 | "Zoom in" : "התקרבות",
26 | "Custom" : "מותאם אישית",
27 | "Value" : "ערך",
28 | "Image" : "תמונה",
29 | "Text" : "טקסט",
30 | "Size" : "גודל",
31 | "Position" : "מיקום",
32 | "Extension" : "הרחבה",
33 | "Name is required." : "נדרש שם.",
34 | "Quality" : "איכות",
35 | "Menu" : "תפריט",
36 | "Height" : "גובה"
37 | },"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"
38 | }
--------------------------------------------------------------------------------
/l10n/hr.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Preglednik",
5 | "Simple file viewer with slideshow for media" : "Jednostavan preglednik datoteka s mogućnošću prezentacije medijski datoteka",
6 | "Your browser does not support audio." : "Vaš preglednik ne podržava zvuk.",
7 | "Error loading {name}" : "Pogreška pri učitavanju {name}",
8 | "Image saved" : "Slika je spremljena",
9 | "Your browser does not support videos." : "Vaš preglednik ne podržava videozapise.",
10 | "There is no plugin available to display this file type" : "Nema dostupnog dodatka za prikazivanje ove vrste datoteke",
11 | "Edit" : "Uredi",
12 | "Open sidebar" : "Otvori bočnu traku",
13 | "Download" : "Preuzmi",
14 | "Delete" : "Izbriši",
15 | "View" : "Pregledaj",
16 | "Name" : "Naziv",
17 | "Save" : "Spremi",
18 | "Back" : "Natrag",
19 | "Loading …" : "Učitavanje…",
20 | "Reset" : "Resetiraj",
21 | "Cancel" : "Odustani",
22 | "Apply" : "Potvrdi",
23 | "Warning" : "Upozorenje",
24 | "Confirm" : "Potvrdi",
25 | "Undo" : "Poništi",
26 | "Redo" : "Ponovno",
27 | "Zoom in" : "Uvećaj",
28 | "Original" : "Izvornik",
29 | "Custom" : "Prilagođeno",
30 | "Value" : "Vrijednost",
31 | "Image" : "Slika",
32 | "Text" : "Tekst",
33 | "Size" : "Veličina",
34 | "Position" : "Položaj",
35 | "Extension" : "Proširenje",
36 | "Name is required." : "Ime je obavezno.",
37 | "Quality" : "Kvaliteta",
38 | "Menu" : "Izbornik",
39 | "Height" : "Visina"
40 | },
41 | "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");
42 |
--------------------------------------------------------------------------------
/l10n/hr.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Preglednik",
3 | "Simple file viewer with slideshow for media" : "Jednostavan preglednik datoteka s mogućnošću prezentacije medijski datoteka",
4 | "Your browser does not support audio." : "Vaš preglednik ne podržava zvuk.",
5 | "Error loading {name}" : "Pogreška pri učitavanju {name}",
6 | "Image saved" : "Slika je spremljena",
7 | "Your browser does not support videos." : "Vaš preglednik ne podržava videozapise.",
8 | "There is no plugin available to display this file type" : "Nema dostupnog dodatka za prikazivanje ove vrste datoteke",
9 | "Edit" : "Uredi",
10 | "Open sidebar" : "Otvori bočnu traku",
11 | "Download" : "Preuzmi",
12 | "Delete" : "Izbriši",
13 | "View" : "Pregledaj",
14 | "Name" : "Naziv",
15 | "Save" : "Spremi",
16 | "Back" : "Natrag",
17 | "Loading …" : "Učitavanje…",
18 | "Reset" : "Resetiraj",
19 | "Cancel" : "Odustani",
20 | "Apply" : "Potvrdi",
21 | "Warning" : "Upozorenje",
22 | "Confirm" : "Potvrdi",
23 | "Undo" : "Poništi",
24 | "Redo" : "Ponovno",
25 | "Zoom in" : "Uvećaj",
26 | "Original" : "Izvornik",
27 | "Custom" : "Prilagođeno",
28 | "Value" : "Vrijednost",
29 | "Image" : "Slika",
30 | "Text" : "Tekst",
31 | "Size" : "Veličina",
32 | "Position" : "Položaj",
33 | "Extension" : "Proširenje",
34 | "Name is required." : "Ime je obavezno.",
35 | "Quality" : "Kvaliteta",
36 | "Menu" : "Izbornik",
37 | "Height" : "Visina"
38 | },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
39 | }
--------------------------------------------------------------------------------
/l10n/hy.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "մշակել",
5 | "Download" : "Ներբեռնել",
6 | "Delete" : "հեռացնել",
7 | "Name" : "Անուն",
8 | "Save" : "Պահպանել",
9 | "Cancel" : "ընդհատել",
10 | "Warning" : "Զգուշացում",
11 | "Size" : "Չափս"
12 | },
13 | "nplurals=2; plural=(n != 1);");
14 |
--------------------------------------------------------------------------------
/l10n/hy.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "մշակել",
3 | "Download" : "Ներբեռնել",
4 | "Delete" : "հեռացնել",
5 | "Name" : "Անուն",
6 | "Save" : "Պահպանել",
7 | "Cancel" : "ընդհատել",
8 | "Warning" : "Զգուշացում",
9 | "Size" : "Չափս"
10 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
11 | }
--------------------------------------------------------------------------------
/l10n/ia.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Modificar",
5 | "Download" : "Discargar",
6 | "Delete" : "Deler",
7 | "View" : "Vider",
8 | "Name" : "Nomine",
9 | "Save" : "Salveguardar",
10 | "Back" : "Retro",
11 | "Reset" : "Re-fixar",
12 | "Cancel" : "Cancellar",
13 | "Apply" : "Applicar",
14 | "Warning" : "Aviso",
15 | "Confirm" : "Confirmar",
16 | "Undo" : "Disfacer",
17 | "Custom" : "Personalisate",
18 | "Size" : "Dimension",
19 | "Menu" : "Menu"
20 | },
21 | "nplurals=2; plural=(n != 1);");
22 |
--------------------------------------------------------------------------------
/l10n/ia.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Modificar",
3 | "Download" : "Discargar",
4 | "Delete" : "Deler",
5 | "View" : "Vider",
6 | "Name" : "Nomine",
7 | "Save" : "Salveguardar",
8 | "Back" : "Retro",
9 | "Reset" : "Re-fixar",
10 | "Cancel" : "Cancellar",
11 | "Apply" : "Applicar",
12 | "Warning" : "Aviso",
13 | "Confirm" : "Confirmar",
14 | "Undo" : "Disfacer",
15 | "Custom" : "Personalisate",
16 | "Size" : "Dimension",
17 | "Menu" : "Menu"
18 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
19 | }
--------------------------------------------------------------------------------
/l10n/ka.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "LIVE" : "LIVE",
5 | "Edit" : "Edit",
6 | "Open sidebar" : "Open sidebar",
7 | "Download" : "Download",
8 | "Delete" : "Delete",
9 | "View" : "View",
10 | "Name" : "Name",
11 | "Save" : "Save",
12 | "Back" : "Back",
13 | "Loading …" : "Loading …",
14 | "Reset" : "Reset",
15 | "Cancel" : "Cancel",
16 | "Warning" : "Warning",
17 | "Confirm" : "Confirm",
18 | "Discard changes" : "Discard changes",
19 | "Undo" : "Undo",
20 | "Custom" : "Custom",
21 | "Blur" : "Blur",
22 | "Value" : "Value",
23 | "Image" : "Image",
24 | "Text" : "Text",
25 | "Size" : "Size",
26 | "Position" : "Position",
27 | "Menu" : "Menu"
28 | },
29 | "nplurals=2; plural=(n!=1);");
30 |
--------------------------------------------------------------------------------
/l10n/ka.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "LIVE" : "LIVE",
3 | "Edit" : "Edit",
4 | "Open sidebar" : "Open sidebar",
5 | "Download" : "Download",
6 | "Delete" : "Delete",
7 | "View" : "View",
8 | "Name" : "Name",
9 | "Save" : "Save",
10 | "Back" : "Back",
11 | "Loading …" : "Loading …",
12 | "Reset" : "Reset",
13 | "Cancel" : "Cancel",
14 | "Warning" : "Warning",
15 | "Confirm" : "Confirm",
16 | "Discard changes" : "Discard changes",
17 | "Undo" : "Undo",
18 | "Custom" : "Custom",
19 | "Blur" : "Blur",
20 | "Value" : "Value",
21 | "Image" : "Image",
22 | "Text" : "Text",
23 | "Size" : "Size",
24 | "Position" : "Position",
25 | "Menu" : "Menu"
26 | },"pluralForm" :"nplurals=2; plural=(n!=1);"
27 | }
--------------------------------------------------------------------------------
/l10n/ka_GE.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "შეცვლა",
5 | "Download" : "ჩამოტვირთვა",
6 | "Delete" : "წაშლა",
7 | "Name" : "სახელი",
8 | "Save" : "შენახვა",
9 | "Back" : "უკან",
10 | "Reset" : "საწყის მდოგმარეობაში დაბრუნება",
11 | "Cancel" : "უარყოფა",
12 | "Apply" : "გამოყენება",
13 | "Warning" : "გაფრთხილება",
14 | "Confirm" : "დადასტურება",
15 | "Undo" : "დაბრუნება",
16 | "Custom" : "ინდივიდუალური",
17 | "Value" : "მნიშვნელობა",
18 | "Text" : "ტექსტი",
19 | "Size" : "ზომა",
20 | "Position" : "პოზიცია",
21 | "Menu" : "მენიუ"
22 | },
23 | "nplurals=2; plural=(n!=1);");
24 |
--------------------------------------------------------------------------------
/l10n/ka_GE.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "შეცვლა",
3 | "Download" : "ჩამოტვირთვა",
4 | "Delete" : "წაშლა",
5 | "Name" : "სახელი",
6 | "Save" : "შენახვა",
7 | "Back" : "უკან",
8 | "Reset" : "საწყის მდოგმარეობაში დაბრუნება",
9 | "Cancel" : "უარყოფა",
10 | "Apply" : "გამოყენება",
11 | "Warning" : "გაფრთხილება",
12 | "Confirm" : "დადასტურება",
13 | "Undo" : "დაბრუნება",
14 | "Custom" : "ინდივიდუალური",
15 | "Value" : "მნიშვნელობა",
16 | "Text" : "ტექსტი",
17 | "Size" : "ზომა",
18 | "Position" : "პოზიცია",
19 | "Menu" : "მენიუ"
20 | },"pluralForm" :"nplurals=2; plural=(n!=1);"
21 | }
--------------------------------------------------------------------------------
/l10n/kab.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Ẓreg",
5 | "Download" : "Sider",
6 | "Delete" : "Kkes",
7 | "Name" : "Nom",
8 | "Save" : "Sekles",
9 | "Back" : "Retour",
10 | "Loading …" : "Asali ...",
11 | "Cancel" : "Sefsex",
12 | "Warning" : "Alɣu",
13 | "Confirm" : "Serggeg",
14 | "Size" : "Teɣzi"
15 | },
16 | "nplurals=2; plural=(n != 1);");
17 |
--------------------------------------------------------------------------------
/l10n/kab.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Ẓreg",
3 | "Download" : "Sider",
4 | "Delete" : "Kkes",
5 | "Name" : "Nom",
6 | "Save" : "Sekles",
7 | "Back" : "Retour",
8 | "Loading …" : "Asali ...",
9 | "Cancel" : "Sefsex",
10 | "Warning" : "Alɣu",
11 | "Confirm" : "Serggeg",
12 | "Size" : "Teɣzi"
13 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
14 | }
--------------------------------------------------------------------------------
/l10n/km.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "កែប្រែ",
5 | "Download" : "ទាញយក",
6 | "Delete" : "លុប",
7 | "Name" : "ឈ្មោះ",
8 | "Save" : "រក្សាទុក",
9 | "Back" : "ត្រឡប់ក្រោយ",
10 | "Cancel" : "បោះបង់",
11 | "Apply" : "អនុវត្ត",
12 | "Warning" : "បម្រាម",
13 | "Value" : "តម្លៃ",
14 | "Line" : "បន្ទាត់",
15 | "Size" : "ទំហំ"
16 | },
17 | "nplurals=1; plural=0;");
18 |
--------------------------------------------------------------------------------
/l10n/km.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "កែប្រែ",
3 | "Download" : "ទាញយក",
4 | "Delete" : "លុប",
5 | "Name" : "ឈ្មោះ",
6 | "Save" : "រក្សាទុក",
7 | "Back" : "ត្រឡប់ក្រោយ",
8 | "Cancel" : "បោះបង់",
9 | "Apply" : "អនុវត្ត",
10 | "Warning" : "បម្រាម",
11 | "Value" : "តម្លៃ",
12 | "Line" : "បន្ទាត់",
13 | "Size" : "ទំហំ"
14 | },"pluralForm" :"nplurals=1; plural=0;"
15 | }
--------------------------------------------------------------------------------
/l10n/kn.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "ಸಂಪಾದಿಸು",
5 | "Download" : "ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ",
6 | "Delete" : "ಅಳಿಸಿ",
7 | "Name" : "ಹೆಸರು",
8 | "Save" : "ಉಳಿಸಿ",
9 | "Reset" : "ಮರುಹೊಂದಿಸಿ",
10 | "Cancel" : "ರದ್ದು",
11 | "Warning" : "ಎಚ್ಚರಿಕೆ",
12 | "Size" : " ಗಾತ್ರ"
13 | },
14 | "nplurals=2; plural=(n > 1);");
15 |
--------------------------------------------------------------------------------
/l10n/kn.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "ಸಂಪಾದಿಸು",
3 | "Download" : "ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ",
4 | "Delete" : "ಅಳಿಸಿ",
5 | "Name" : "ಹೆಸರು",
6 | "Save" : "ಉಳಿಸಿ",
7 | "Reset" : "ಮರುಹೊಂದಿಸಿ",
8 | "Cancel" : "ರದ್ದು",
9 | "Warning" : "ಎಚ್ಚರಿಕೆ",
10 | "Size" : " ಗಾತ್ರ"
11 | },"pluralForm" :"nplurals=2; plural=(n > 1);"
12 | }
--------------------------------------------------------------------------------
/l10n/lb.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Änneren",
5 | "Download" : "Eroflueden",
6 | "Delete" : "Läschen",
7 | "Name" : "Numm",
8 | "Save" : "Späicheren",
9 | "Back" : "Zeréck",
10 | "Reset" : "Zeréck setzen",
11 | "Cancel" : "Ofbriechen",
12 | "Apply" : "Uwenden",
13 | "Warning" : "Warnung",
14 | "Confirm" : "Konfirméieren",
15 | "Custom" : "Individualiséier",
16 | "Size" : "Gréisst",
17 | "Menu" : "Menü"
18 | },
19 | "nplurals=2; plural=(n != 1);");
20 |
--------------------------------------------------------------------------------
/l10n/lb.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Änneren",
3 | "Download" : "Eroflueden",
4 | "Delete" : "Läschen",
5 | "Name" : "Numm",
6 | "Save" : "Späicheren",
7 | "Back" : "Zeréck",
8 | "Reset" : "Zeréck setzen",
9 | "Cancel" : "Ofbriechen",
10 | "Apply" : "Uwenden",
11 | "Warning" : "Warnung",
12 | "Confirm" : "Konfirméieren",
13 | "Custom" : "Individualiséier",
14 | "Size" : "Gréisst",
15 | "Menu" : "Menü"
16 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
17 | }
--------------------------------------------------------------------------------
/l10n/lo.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "ແກ້ໄຂ",
5 | "Open sidebar" : "ເປີດແທບດ້ານຂ້າງ",
6 | "Download" : "ດາວໂຫລດ",
7 | "Delete" : "ລຶບ",
8 | "Name" : "ຊື່",
9 | "Save" : "ບັນທຶກ",
10 | "Back" : "ຫຼັງ",
11 | "Loading …" : "ກຳລັງໂຫຼດ",
12 | "Cancel" : "ຍົກເລີກ",
13 | "Confirm" : "ຢືນຢັນ",
14 | "Original" : "ຕົ້ນສະບັບ",
15 | "Size" : "ຂະຫນາດ"
16 | },
17 | "nplurals=1; plural=0;");
18 |
--------------------------------------------------------------------------------
/l10n/lo.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "ແກ້ໄຂ",
3 | "Open sidebar" : "ເປີດແທບດ້ານຂ້າງ",
4 | "Download" : "ດາວໂຫລດ",
5 | "Delete" : "ລຶບ",
6 | "Name" : "ຊື່",
7 | "Save" : "ບັນທຶກ",
8 | "Back" : "ຫຼັງ",
9 | "Loading …" : "ກຳລັງໂຫຼດ",
10 | "Cancel" : "ຍົກເລີກ",
11 | "Confirm" : "ຢືນຢັນ",
12 | "Original" : "ຕົ້ນສະບັບ",
13 | "Size" : "ຂະຫນາດ"
14 | },"pluralForm" :"nplurals=1; plural=0;"
15 | }
--------------------------------------------------------------------------------
/l10n/lv.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Skatītājs",
5 | "Simple file viewer with slideshow for media" : "Vienkāršs datņu skatītājs ar slīdrādi informācijas nesējiem",
6 | "Error loading {name}" : "Kļūda ielādējot {name}",
7 | "Your browser does not support videos." : "Pārlūks nenodrošina video",
8 | "Edit" : "Labot",
9 | "Exit full screen" : "Iziet no pilnekrāna",
10 | "Open sidebar" : "Atvērt sānjoslu",
11 | "Download" : "Lejupielādēt",
12 | "Delete" : "Izdzēst",
13 | "View" : "Skats",
14 | "Name" : "Vārds",
15 | "Save" : "Saglabāt",
16 | "Save as" : "Saglabāt kā",
17 | "Back" : "Atpakaļ",
18 | "Loading …" : "Ielādē…",
19 | "Reset" : "Atiestatīt",
20 | "Cancel" : "Atcelt",
21 | "Apply" : "Apstiprināt",
22 | "Warning" : "Brīdinājums",
23 | "Confirm" : "Apstiprināt",
24 | "Undo" : "Atsaukt",
25 | "Redo" : "Atcelt atsaukšanu",
26 | "Filters" : "Filtri",
27 | "Watermark" : "Ūdenszīme",
28 | "are not images" : "nav attēli",
29 | "is not an image" : "nav attēls",
30 | "Original" : "Oriģināls",
31 | "Custom" : "Pielāgots",
32 | "Landscape" : "Ainava",
33 | "Portrait" : "Portrets",
34 | "Value" : "Vērtība",
35 | "Image" : "Attēli",
36 | "Text" : "Teksts",
37 | "Size" : "Izmērs",
38 | "Save image as" : "Saglabāt attēlu kā",
39 | "Name is required." : "Vārds ir nepieciešams.",
40 | "Quality" : "Kvalitāte",
41 | "Saved image size (width x height)" : "Saglabātā attēla izmērs (platums x augstums)",
42 | "Actual size (100%)" : "Faktiskais izmērs (100%)",
43 | "Fit size" : "Atbilst izmēram",
44 | "Menu" : "Izvēlne"
45 | },
46 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");
47 |
--------------------------------------------------------------------------------
/l10n/lv.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Skatītājs",
3 | "Simple file viewer with slideshow for media" : "Vienkāršs datņu skatītājs ar slīdrādi informācijas nesējiem",
4 | "Error loading {name}" : "Kļūda ielādējot {name}",
5 | "Your browser does not support videos." : "Pārlūks nenodrošina video",
6 | "Edit" : "Labot",
7 | "Exit full screen" : "Iziet no pilnekrāna",
8 | "Open sidebar" : "Atvērt sānjoslu",
9 | "Download" : "Lejupielādēt",
10 | "Delete" : "Izdzēst",
11 | "View" : "Skats",
12 | "Name" : "Vārds",
13 | "Save" : "Saglabāt",
14 | "Save as" : "Saglabāt kā",
15 | "Back" : "Atpakaļ",
16 | "Loading …" : "Ielādē…",
17 | "Reset" : "Atiestatīt",
18 | "Cancel" : "Atcelt",
19 | "Apply" : "Apstiprināt",
20 | "Warning" : "Brīdinājums",
21 | "Confirm" : "Apstiprināt",
22 | "Undo" : "Atsaukt",
23 | "Redo" : "Atcelt atsaukšanu",
24 | "Filters" : "Filtri",
25 | "Watermark" : "Ūdenszīme",
26 | "are not images" : "nav attēli",
27 | "is not an image" : "nav attēls",
28 | "Original" : "Oriģināls",
29 | "Custom" : "Pielāgots",
30 | "Landscape" : "Ainava",
31 | "Portrait" : "Portrets",
32 | "Value" : "Vērtība",
33 | "Image" : "Attēli",
34 | "Text" : "Teksts",
35 | "Size" : "Izmērs",
36 | "Save image as" : "Saglabāt attēlu kā",
37 | "Name is required." : "Vārds ir nepieciešams.",
38 | "Quality" : "Kvalitāte",
39 | "Saved image size (width x height)" : "Saglabātā attēla izmērs (platums x augstums)",
40 | "Actual size (100%)" : "Faktiskais izmērs (100%)",
41 | "Fit size" : "Atbilst izmēram",
42 | "Menu" : "Izvēlne"
43 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
44 | }
--------------------------------------------------------------------------------
/l10n/mn.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "засварлах",
5 | "Download" : "Татах",
6 | "Delete" : "Устгах",
7 | "Name" : "Нэр",
8 | "Save" : "Хадгалах",
9 | "Back" : "буцах",
10 | "Loading …" : "Уншиж байна...",
11 | "Reset" : "тохируулах",
12 | "Cancel" : "болиулах",
13 | "Apply" : "хэрэглэх",
14 | "Confirm" : "Батлах",
15 | "Undo" : "буцах",
16 | "Custom" : "Дурын",
17 | "Value" : "Үнийн дүн",
18 | "Size" : "Хэмжээ",
19 | "Position" : "Байр"
20 | },
21 | "nplurals=2; plural=(n != 1);");
22 |
--------------------------------------------------------------------------------
/l10n/mn.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "засварлах",
3 | "Download" : "Татах",
4 | "Delete" : "Устгах",
5 | "Name" : "Нэр",
6 | "Save" : "Хадгалах",
7 | "Back" : "буцах",
8 | "Loading …" : "Уншиж байна...",
9 | "Reset" : "тохируулах",
10 | "Cancel" : "болиулах",
11 | "Apply" : "хэрэглэх",
12 | "Confirm" : "Батлах",
13 | "Undo" : "буцах",
14 | "Custom" : "Дурын",
15 | "Value" : "Үнийн дүн",
16 | "Size" : "Хэмжээ",
17 | "Position" : "Байр"
18 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
19 | }
--------------------------------------------------------------------------------
/l10n/ms_MY.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Sunting",
5 | "Download" : "Muat turun",
6 | "Delete" : "Padam",
7 | "Name" : "Nama",
8 | "Save" : "Simpan",
9 | "Back" : "Kembali",
10 | "Cancel" : "Batal",
11 | "Warning" : "Amaran",
12 | "Value" : "Nilai",
13 | "Size" : "Saiz"
14 | },
15 | "nplurals=1; plural=0;");
16 |
--------------------------------------------------------------------------------
/l10n/ms_MY.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Sunting",
3 | "Download" : "Muat turun",
4 | "Delete" : "Padam",
5 | "Name" : "Nama",
6 | "Save" : "Simpan",
7 | "Back" : "Kembali",
8 | "Cancel" : "Batal",
9 | "Warning" : "Amaran",
10 | "Value" : "Nilai",
11 | "Size" : "Saiz"
12 | },"pluralForm" :"nplurals=1; plural=0;"
13 | }
--------------------------------------------------------------------------------
/l10n/nn_NO.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Rediger",
5 | "Open sidebar" : "Opne sidestolpe",
6 | "Download" : "Last ned",
7 | "Delete" : "Ta bort",
8 | "Name" : "Namn",
9 | "Save" : "Lagre",
10 | "Back" : "Tilbake",
11 | "Cancel" : "Avbryt",
12 | "Apply" : "Anvend",
13 | "Warning" : "Åtvaring",
14 | "Value" : "Verdi",
15 | "Size" : "Storleik"
16 | },
17 | "nplurals=2; plural=(n != 1);");
18 |
--------------------------------------------------------------------------------
/l10n/nn_NO.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Rediger",
3 | "Open sidebar" : "Opne sidestolpe",
4 | "Download" : "Last ned",
5 | "Delete" : "Ta bort",
6 | "Name" : "Namn",
7 | "Save" : "Lagre",
8 | "Back" : "Tilbake",
9 | "Cancel" : "Avbryt",
10 | "Apply" : "Anvend",
11 | "Warning" : "Åtvaring",
12 | "Value" : "Verdi",
13 | "Size" : "Storleik"
14 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
15 | }
--------------------------------------------------------------------------------
/l10n/oc.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Visualizaira",
5 | "Simple file viewer with slideshow for media" : "Visionador de fichièrs simples amb diaporama pels mèdias",
6 | "Your browser does not support audio." : "Vòstre navigador pren pas encarga l’àudio.",
7 | "Error loading {name}" : "Error en cargant {name}",
8 | "Your browser does not support videos." : "Vòstre navigador pren pas encarga las vidèos.",
9 | "There is no plugin available to display this file type" : "I a pas cap d’extension per afichar aqueste tipe de fichièr",
10 | "Edit" : "Modificar",
11 | "Open sidebar" : "Dobrir panèl lateral",
12 | "Download" : "Telecargar",
13 | "Delete" : "Suprimir",
14 | "View" : "Vista",
15 | "Name" : "Nom",
16 | "Save" : "Enregistrar",
17 | "Back" : "Retorn",
18 | "Loading …" : "Cargament…",
19 | "Reset" : "Reïnicializar",
20 | "Cancel" : "Anullar",
21 | "Apply" : "Aplicar",
22 | "Warning" : "Avertiment",
23 | "Confirm" : "Confirmar",
24 | "Undo" : "Desfar",
25 | "Redo" : "Refar",
26 | "Custom" : "Personalizar",
27 | "Portrait" : "Retrach",
28 | "Value" : "Valor",
29 | "Line" : "Linha",
30 | "Text" : "Tèxt",
31 | "Size" : "Talha",
32 | "Position" : "Posicion",
33 | "Extension" : "Extension",
34 | "Menu" : "Menú"
35 | },
36 | "nplurals=2; plural=(n > 1);");
37 |
--------------------------------------------------------------------------------
/l10n/oc.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Visualizaira",
3 | "Simple file viewer with slideshow for media" : "Visionador de fichièrs simples amb diaporama pels mèdias",
4 | "Your browser does not support audio." : "Vòstre navigador pren pas encarga l’àudio.",
5 | "Error loading {name}" : "Error en cargant {name}",
6 | "Your browser does not support videos." : "Vòstre navigador pren pas encarga las vidèos.",
7 | "There is no plugin available to display this file type" : "I a pas cap d’extension per afichar aqueste tipe de fichièr",
8 | "Edit" : "Modificar",
9 | "Open sidebar" : "Dobrir panèl lateral",
10 | "Download" : "Telecargar",
11 | "Delete" : "Suprimir",
12 | "View" : "Vista",
13 | "Name" : "Nom",
14 | "Save" : "Enregistrar",
15 | "Back" : "Retorn",
16 | "Loading …" : "Cargament…",
17 | "Reset" : "Reïnicializar",
18 | "Cancel" : "Anullar",
19 | "Apply" : "Aplicar",
20 | "Warning" : "Avertiment",
21 | "Confirm" : "Confirmar",
22 | "Undo" : "Desfar",
23 | "Redo" : "Refar",
24 | "Custom" : "Personalizar",
25 | "Portrait" : "Retrach",
26 | "Value" : "Valor",
27 | "Line" : "Linha",
28 | "Text" : "Tèxt",
29 | "Size" : "Talha",
30 | "Position" : "Posicion",
31 | "Extension" : "Extension",
32 | "Menu" : "Menú"
33 | },"pluralForm" :"nplurals=2; plural=(n > 1);"
34 | }
--------------------------------------------------------------------------------
/l10n/ps.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "شسیب",
5 | "Download" : "ښکته کول",
6 | "Delete" : "ړنګول",
7 | "Name" : "نوم",
8 | "Save" : "ساتل",
9 | "Cancel" : "پرېښول",
10 | "Size" : "کچه"
11 | },
12 | "nplurals=2; plural=(n != 1);");
13 |
--------------------------------------------------------------------------------
/l10n/ps.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "شسیب",
3 | "Download" : "ښکته کول",
4 | "Delete" : "ړنګول",
5 | "Name" : "نوم",
6 | "Save" : "ساتل",
7 | "Cancel" : "پرېښول",
8 | "Size" : "کچه"
9 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
10 | }
--------------------------------------------------------------------------------
/l10n/pt_PT.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Visualizador",
5 | "Simple file viewer with slideshow for media" : "Um visualizador de ficheiros com diaporamas para multimédia",
6 | "Your browser does not support audio." : "O seu navegador não suporta áudio.",
7 | "Error loading {name}" : "Erro ao carregar {name}",
8 | "Image saved" : "Imagem guardada",
9 | "LIVE" : "LIVE",
10 | "Your browser does not support videos." : "O seu navegador não suporta vídeos.",
11 | "Edit" : "Editar",
12 | "Open sidebar" : "Abrir barra lateral",
13 | "Download" : "Transferir",
14 | "Delete" : "Apagar",
15 | "View" : "Ver",
16 | "Name" : "Nome",
17 | "Save" : "Guardar",
18 | "Back" : "Anterior",
19 | "Loading …" : "A carregar...",
20 | "Reset" : "Reiniciar",
21 | "Cancel" : "Cancelar",
22 | "Apply" : "Aplicar",
23 | "Warning" : "Aviso",
24 | "Confirm" : "Confirmar",
25 | "Undo" : "Desfazer",
26 | "Redo" : "Repetir",
27 | "Filters" : "Filtros",
28 | "Original" : "Original",
29 | "Custom" : "Personalizado",
30 | "Value" : "Valor",
31 | "Image" : "Imagem",
32 | "Line" : "Linha",
33 | "Text" : "Texto",
34 | "Size" : "Altura",
35 | "Name is required." : "Nome é obrigatório.",
36 | "Quality" : "Qualidade",
37 | "Menu" : "Menu",
38 | "Height" : "Altura"
39 | },
40 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
41 |
--------------------------------------------------------------------------------
/l10n/pt_PT.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Visualizador",
3 | "Simple file viewer with slideshow for media" : "Um visualizador de ficheiros com diaporamas para multimédia",
4 | "Your browser does not support audio." : "O seu navegador não suporta áudio.",
5 | "Error loading {name}" : "Erro ao carregar {name}",
6 | "Image saved" : "Imagem guardada",
7 | "LIVE" : "LIVE",
8 | "Your browser does not support videos." : "O seu navegador não suporta vídeos.",
9 | "Edit" : "Editar",
10 | "Open sidebar" : "Abrir barra lateral",
11 | "Download" : "Transferir",
12 | "Delete" : "Apagar",
13 | "View" : "Ver",
14 | "Name" : "Nome",
15 | "Save" : "Guardar",
16 | "Back" : "Anterior",
17 | "Loading …" : "A carregar...",
18 | "Reset" : "Reiniciar",
19 | "Cancel" : "Cancelar",
20 | "Apply" : "Aplicar",
21 | "Warning" : "Aviso",
22 | "Confirm" : "Confirmar",
23 | "Undo" : "Desfazer",
24 | "Redo" : "Repetir",
25 | "Filters" : "Filtros",
26 | "Original" : "Original",
27 | "Custom" : "Personalizado",
28 | "Value" : "Valor",
29 | "Image" : "Imagem",
30 | "Line" : "Linha",
31 | "Text" : "Texto",
32 | "Size" : "Altura",
33 | "Name is required." : "Nome é obrigatório.",
34 | "Quality" : "Qualidade",
35 | "Menu" : "Menu",
36 | "Height" : "Altura"
37 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
38 | }
--------------------------------------------------------------------------------
/l10n/sc.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Visualizadore",
5 | "Simple file viewer with slideshow for media" : "Visualizadore de archìvios simpre cun presentatziones pro is media",
6 | "Your browser does not support audio." : "Su navigadore tuo non suportat s'àudio.",
7 | "Error loading {name}" : "Errore de carrigamentu de {name}",
8 | "Image saved" : "Immàgines sarvadas",
9 | "Your browser does not support videos." : "Su navigadore tuo non suportat vìdeos.",
10 | "There is no plugin available to display this file type" : "Non b'at peruna estensione pro visualizare custa genia de archìviu",
11 | "Edit" : "Modìfica",
12 | "Open sidebar" : "Aberi s'istanca laterale",
13 | "Download" : "Iscàrriga",
14 | "Delete" : "Cantzella",
15 | "View" : "Visualiza",
16 | "Name" : "Nùmene",
17 | "Save" : "Sarva",
18 | "Back" : "In segus",
19 | "Loading …" : "Carrigamentu …",
20 | "Reset" : "Ripristina",
21 | "Cancel" : "Annulla",
22 | "Apply" : "Àplica",
23 | "Warning" : "Avisu",
24 | "Confirm" : "Cunfirma",
25 | "Undo" : "Annulla",
26 | "Redo" : "Torra a fàghere",
27 | "Zoom in" : "Ammània",
28 | "Original" : "Originale",
29 | "Custom" : "Personaliza",
30 | "Value" : "Balore",
31 | "Image" : "Immàgine",
32 | "Text" : "Testu",
33 | "Size" : "Mannària",
34 | "Position" : "Positzione",
35 | "Extension" : "Estensione",
36 | "Name is required." : "Su nùmene est rechertu: ",
37 | "Quality" : "Calidade",
38 | "Menu" : "Menu",
39 | "Height" : "Altezza"
40 | },
41 | "nplurals=2; plural=(n != 1);");
42 |
--------------------------------------------------------------------------------
/l10n/sc.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Visualizadore",
3 | "Simple file viewer with slideshow for media" : "Visualizadore de archìvios simpre cun presentatziones pro is media",
4 | "Your browser does not support audio." : "Su navigadore tuo non suportat s'àudio.",
5 | "Error loading {name}" : "Errore de carrigamentu de {name}",
6 | "Image saved" : "Immàgines sarvadas",
7 | "Your browser does not support videos." : "Su navigadore tuo non suportat vìdeos.",
8 | "There is no plugin available to display this file type" : "Non b'at peruna estensione pro visualizare custa genia de archìviu",
9 | "Edit" : "Modìfica",
10 | "Open sidebar" : "Aberi s'istanca laterale",
11 | "Download" : "Iscàrriga",
12 | "Delete" : "Cantzella",
13 | "View" : "Visualiza",
14 | "Name" : "Nùmene",
15 | "Save" : "Sarva",
16 | "Back" : "In segus",
17 | "Loading …" : "Carrigamentu …",
18 | "Reset" : "Ripristina",
19 | "Cancel" : "Annulla",
20 | "Apply" : "Àplica",
21 | "Warning" : "Avisu",
22 | "Confirm" : "Cunfirma",
23 | "Undo" : "Annulla",
24 | "Redo" : "Torra a fàghere",
25 | "Zoom in" : "Ammània",
26 | "Original" : "Originale",
27 | "Custom" : "Personaliza",
28 | "Value" : "Balore",
29 | "Image" : "Immàgine",
30 | "Text" : "Testu",
31 | "Size" : "Mannària",
32 | "Position" : "Positzione",
33 | "Extension" : "Estensione",
34 | "Name is required." : "Su nùmene est rechertu: ",
35 | "Quality" : "Calidade",
36 | "Menu" : "Menu",
37 | "Height" : "Altezza"
38 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
39 | }
--------------------------------------------------------------------------------
/l10n/si.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Error loading {name}" : "{name} පූරණය කිරීමේ දෝෂයකි",
5 | "Edit" : "සංස්කරණය",
6 | "Download" : "බාගන්න",
7 | "Name" : "නම",
8 | "Save" : "සුරකින්න",
9 | "Back" : "ආපසු",
10 | "Loading …" : "පූරණය වෙමින් …",
11 | "Cancel" : "අවලංගු කරන්න",
12 | "Warning" : "අවවාදයයි",
13 | "Confirm" : "තහවුරු කරන්න",
14 | "Undo" : "පෙරසේ",
15 | "Value" : "අගය",
16 | "Size" : "ප්රමාණය"
17 | },
18 | "nplurals=2; plural=(n != 1);");
19 |
--------------------------------------------------------------------------------
/l10n/si.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Error loading {name}" : "{name} පූරණය කිරීමේ දෝෂයකි",
3 | "Edit" : "සංස්කරණය",
4 | "Download" : "බාගන්න",
5 | "Name" : "නම",
6 | "Save" : "සුරකින්න",
7 | "Back" : "ආපසු",
8 | "Loading …" : "පූරණය වෙමින් …",
9 | "Cancel" : "අවලංගු කරන්න",
10 | "Warning" : "අවවාදයයි",
11 | "Confirm" : "තහවුරු කරන්න",
12 | "Undo" : "පෙරසේ",
13 | "Value" : "අගය",
14 | "Size" : "ප්රමාණය"
15 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
16 | }
--------------------------------------------------------------------------------
/l10n/sq.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Imazhi u ruajt",
5 | "Edit" : "Përpuno",
6 | "Open sidebar" : "Hapni sidebar-in",
7 | "Download" : "Shkarko",
8 | "Delete" : "Delete",
9 | "View" : "Shiko",
10 | "Name" : "Emri",
11 | "Save" : "Ruaj",
12 | "Back" : "Prapa",
13 | "Reset" : "Rivendos",
14 | "Cancel" : "Anullo",
15 | "Apply" : "Apliko",
16 | "Warning" : "Kujdes",
17 | "Confirm" : "Konfirmo",
18 | "Undo" : "Ktheje pas",
19 | "Redo" : "Ribëj",
20 | "Custom" : "E përshtatur",
21 | "Value" : "Vlerë",
22 | "Text" : "Tekst",
23 | "Size" : "Madhësi",
24 | "Position" : "Pozicion",
25 | "Name is required." : "Emri është i domosdoshëm",
26 | "Menu" : "Menu"
27 | },
28 | "nplurals=2; plural=(n != 1);");
29 |
--------------------------------------------------------------------------------
/l10n/sq.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Imazhi u ruajt",
3 | "Edit" : "Përpuno",
4 | "Open sidebar" : "Hapni sidebar-in",
5 | "Download" : "Shkarko",
6 | "Delete" : "Delete",
7 | "View" : "Shiko",
8 | "Name" : "Emri",
9 | "Save" : "Ruaj",
10 | "Back" : "Prapa",
11 | "Reset" : "Rivendos",
12 | "Cancel" : "Anullo",
13 | "Apply" : "Apliko",
14 | "Warning" : "Kujdes",
15 | "Confirm" : "Konfirmo",
16 | "Undo" : "Ktheje pas",
17 | "Redo" : "Ribëj",
18 | "Custom" : "E përshtatur",
19 | "Value" : "Vlerë",
20 | "Text" : "Tekst",
21 | "Size" : "Madhësi",
22 | "Position" : "Pozicion",
23 | "Name is required." : "Emri është i domosdoshëm",
24 | "Menu" : "Menu"
25 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
26 | }
--------------------------------------------------------------------------------
/l10n/sr@latin.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Image saved" : "Slika sačuvana.",
5 | "Edit" : "Izmeni",
6 | "Open sidebar" : "Otvori bočnu traku",
7 | "Download" : "Preuzmi",
8 | "Delete" : "Obriši",
9 | "Name" : "Ime",
10 | "Save" : "Sačuvaj",
11 | "Back" : "Nazad",
12 | "Loading …" : "Učitavanje...",
13 | "Cancel" : "Otkaži",
14 | "Warning" : "Upozorenje",
15 | "Undo" : "Opozovi"
16 | },
17 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
18 |
--------------------------------------------------------------------------------
/l10n/sr@latin.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Image saved" : "Slika sačuvana.",
3 | "Edit" : "Izmeni",
4 | "Open sidebar" : "Otvori bočnu traku",
5 | "Download" : "Preuzmi",
6 | "Delete" : "Obriši",
7 | "Name" : "Ime",
8 | "Save" : "Sačuvaj",
9 | "Back" : "Nazad",
10 | "Loading …" : "Učitavanje...",
11 | "Cancel" : "Otkaži",
12 | "Warning" : "Upozorenje",
13 | "Undo" : "Opozovi"
14 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
15 | }
--------------------------------------------------------------------------------
/l10n/ta.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "தொகுக்க",
5 | "Download" : "பதிவிறக்குக",
6 | "Delete" : "நீக்குக",
7 | "Name" : "பெயர்",
8 | "Save" : "சேமிக்க ",
9 | "Back" : "பின்னுக்கு",
10 | "Cancel" : "இரத்து செய்க",
11 | "Value" : "Value",
12 | "Size" : "அளவு"
13 | },
14 | "nplurals=2; plural=(n != 1);");
15 |
--------------------------------------------------------------------------------
/l10n/ta.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "தொகுக்க",
3 | "Download" : "பதிவிறக்குக",
4 | "Delete" : "நீக்குக",
5 | "Name" : "பெயர்",
6 | "Save" : "சேமிக்க ",
7 | "Back" : "பின்னுக்கு",
8 | "Cancel" : "இரத்து செய்க",
9 | "Value" : "Value",
10 | "Size" : "அளவு"
11 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
12 | }
--------------------------------------------------------------------------------
/l10n/th.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "แก้ไข",
5 | "Open sidebar" : "เปิดแถบด้านข้าง",
6 | "Download" : "ดาวน์โหลด",
7 | "Delete" : "ลบ",
8 | "View" : "มุมมอง",
9 | "Name" : "ชื่อ",
10 | "Save" : "บันทึก",
11 | "Back" : "ย้อนกลับ",
12 | "Reset" : "รีเซ็ต",
13 | "Cancel" : "ยกเลิก",
14 | "Apply" : "นำไปใช้",
15 | "Warning" : "คำเตือน",
16 | "Confirm" : "ยืนยัน",
17 | "Undo" : "เลิกทำ",
18 | "Custom" : "กำหนดเอง",
19 | "Text" : "ข้อความ",
20 | "Size" : "ขนาด",
21 | "Position" : "ตำแหน่ง",
22 | "Menu" : "เมนู"
23 | },
24 | "nplurals=1; plural=0;");
25 |
--------------------------------------------------------------------------------
/l10n/th.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "แก้ไข",
3 | "Open sidebar" : "เปิดแถบด้านข้าง",
4 | "Download" : "ดาวน์โหลด",
5 | "Delete" : "ลบ",
6 | "View" : "มุมมอง",
7 | "Name" : "ชื่อ",
8 | "Save" : "บันทึก",
9 | "Back" : "ย้อนกลับ",
10 | "Reset" : "รีเซ็ต",
11 | "Cancel" : "ยกเลิก",
12 | "Apply" : "นำไปใช้",
13 | "Warning" : "คำเตือน",
14 | "Confirm" : "ยืนยัน",
15 | "Undo" : "เลิกทำ",
16 | "Custom" : "กำหนดเอง",
17 | "Text" : "ข้อความ",
18 | "Size" : "ขนาด",
19 | "Position" : "ตำแหน่ง",
20 | "Menu" : "เมนู"
21 | },"pluralForm" :"nplurals=1; plural=0;"
22 | }
--------------------------------------------------------------------------------
/l10n/tk.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Redaktirläň",
5 | "Open sidebar" : "Gapdal paneli açyň",
6 | "Download" : "Göçürip almak",
7 | "Delete" : "Pozmak",
8 | "Name" : "Ady",
9 | "Save" : "Saklamak",
10 | "Back" : "Yzyna",
11 | "Cancel" : "ýatyrmak"
12 | },
13 | "nplurals=2; plural=(n != 1);");
14 |
--------------------------------------------------------------------------------
/l10n/tk.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Redaktirläň",
3 | "Open sidebar" : "Gapdal paneli açyň",
4 | "Download" : "Göçürip almak",
5 | "Delete" : "Pozmak",
6 | "Name" : "Ady",
7 | "Save" : "Saklamak",
8 | "Back" : "Yzyna",
9 | "Cancel" : "ýatyrmak"
10 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
11 | }
--------------------------------------------------------------------------------
/l10n/ur_PK.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "تدوین کریں",
5 | "Download" : "ڈاؤن لوڈ",
6 | "Delete" : "حذف کریں",
7 | "Name" : "اسم",
8 | "Save" : "حفظ",
9 | "Reset" : "ری سیٹ",
10 | "Cancel" : "منسوخ کریں",
11 | "Warning" : "انتباہ"
12 | },
13 | "nplurals=2; plural=(n != 1);");
14 |
--------------------------------------------------------------------------------
/l10n/ur_PK.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "تدوین کریں",
3 | "Download" : "ڈاؤن لوڈ",
4 | "Delete" : "حذف کریں",
5 | "Name" : "اسم",
6 | "Save" : "حفظ",
7 | "Reset" : "ری سیٹ",
8 | "Cancel" : "منسوخ کریں",
9 | "Warning" : "انتباہ"
10 | },"pluralForm" :"nplurals=2; plural=(n != 1);"
11 | }
--------------------------------------------------------------------------------
/l10n/uz.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Edit" : "Tahrirlash",
5 | "Download" : "Download",
6 | "Delete" : "Delete",
7 | "Name" : "Name",
8 | "Save" : "Save",
9 | "Back" : "Orqaga",
10 | "Reset" : "Qayta tiklash",
11 | "Cancel" : "Cancel",
12 | "Confirm" : "Confirm",
13 | "Undo" : "Bekor qilish",
14 | "Custom" : "Boshqa",
15 | "Value" : "Qiymati",
16 | "Line" : "Chiziq",
17 | "Text" : "Matn",
18 | "Size" : "Size"
19 | },
20 | "nplurals=1; plural=0;");
21 |
--------------------------------------------------------------------------------
/l10n/uz.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Edit" : "Tahrirlash",
3 | "Download" : "Download",
4 | "Delete" : "Delete",
5 | "Name" : "Name",
6 | "Save" : "Save",
7 | "Back" : "Orqaga",
8 | "Reset" : "Qayta tiklash",
9 | "Cancel" : "Cancel",
10 | "Confirm" : "Confirm",
11 | "Undo" : "Bekor qilish",
12 | "Custom" : "Boshqa",
13 | "Value" : "Qiymati",
14 | "Line" : "Chiziq",
15 | "Text" : "Matn",
16 | "Size" : "Size"
17 | },"pluralForm" :"nplurals=1; plural=0;"
18 | }
--------------------------------------------------------------------------------
/l10n/vi.js:
--------------------------------------------------------------------------------
1 | OC.L10N.register(
2 | "viewer",
3 | {
4 | "Viewer" : "Trình xem",
5 | "Simple file viewer with slideshow for media" : "Trình xem tệp đơn giản có trình chiếu phương tiện",
6 | "Your browser does not support audio." : "Trình duyệt của bạn không hỗ trợ âm thanh.",
7 | "Error loading {name}" : "Lỗi khi tải {name}",
8 | "Image saved" : "Đã lưu hình ảnh",
9 | "Your browser does not support videos." : "Trình duyệt của bạn không hỗ trợ video.",
10 | "There is no plugin available to display this file type" : "Không có plugin nào để hiển thị loại tệp này",
11 | "Edit" : "Chỉnh sửa",
12 | "Open sidebar" : "Mở thanh bên",
13 | "Download" : "Tải xuống",
14 | "Delete" : "Xóa",
15 | "View" : "Xem",
16 | "Name" : "Tên",
17 | "Save" : "Lưu",
18 | "Back" : "Quay lại",
19 | "Loading …" : "Đang tải …",
20 | "Reset" : "Đặt lại",
21 | "Cancel" : "Hủy",
22 | "Apply" : "Áp dụng",
23 | "Warning" : "Cảnh báo",
24 | "Confirm" : "Xác nhận",
25 | "Undo" : "Hoàn tác",
26 | "Redo" : "Làm lại",
27 | "Custom" : "Tùy chỉnh",
28 | "Value" : "Giá trị",
29 | "Image" : "Hình ảnh",
30 | "Line" : "Hàng",
31 | "Text" : "Văn bản",
32 | "Size" : "Kích cỡ",
33 | "Extension" : "Tiện ích",
34 | "Name is required." : "Tên là bắt buộc."
35 | },
36 | "nplurals=1; plural=0;");
37 |
--------------------------------------------------------------------------------
/l10n/vi.json:
--------------------------------------------------------------------------------
1 | { "translations": {
2 | "Viewer" : "Trình xem",
3 | "Simple file viewer with slideshow for media" : "Trình xem tệp đơn giản có trình chiếu phương tiện",
4 | "Your browser does not support audio." : "Trình duyệt của bạn không hỗ trợ âm thanh.",
5 | "Error loading {name}" : "Lỗi khi tải {name}",
6 | "Image saved" : "Đã lưu hình ảnh",
7 | "Your browser does not support videos." : "Trình duyệt của bạn không hỗ trợ video.",
8 | "There is no plugin available to display this file type" : "Không có plugin nào để hiển thị loại tệp này",
9 | "Edit" : "Chỉnh sửa",
10 | "Open sidebar" : "Mở thanh bên",
11 | "Download" : "Tải xuống",
12 | "Delete" : "Xóa",
13 | "View" : "Xem",
14 | "Name" : "Tên",
15 | "Save" : "Lưu",
16 | "Back" : "Quay lại",
17 | "Loading …" : "Đang tải …",
18 | "Reset" : "Đặt lại",
19 | "Cancel" : "Hủy",
20 | "Apply" : "Áp dụng",
21 | "Warning" : "Cảnh báo",
22 | "Confirm" : "Xác nhận",
23 | "Undo" : "Hoàn tác",
24 | "Redo" : "Làm lại",
25 | "Custom" : "Tùy chỉnh",
26 | "Value" : "Giá trị",
27 | "Image" : "Hình ảnh",
28 | "Line" : "Hàng",
29 | "Text" : "Văn bản",
30 | "Size" : "Kích cỡ",
31 | "Extension" : "Tiện ích",
32 | "Name is required." : "Tên là bắt buộc."
33 | },"pluralForm" :"nplurals=1; plural=0;"
34 | }
--------------------------------------------------------------------------------
/lib/AppInfo/Application.php:
--------------------------------------------------------------------------------
1 | registerEventListener(LoadViewer::class, LoadViewerScript::class);
27 | }
28 |
29 | public function boot(IBootContext $context): void {
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/Event/LoadViewer.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class LoadViewerScript implements IEventListener {
24 | private IInitialState $initialStateService;
25 | private IPreview $previewManager;
26 |
27 | public function __construct(
28 | IInitialState $initialStateService,
29 | IPreview $previewManager,
30 | ) {
31 | $this->initialStateService = $initialStateService;
32 | $this->previewManager = $previewManager;
33 | }
34 |
35 | public function handle(Event $event): void {
36 | if (!($event instanceof LoadViewer || $event instanceof LoadAdditionalScriptsEvent)) {
37 | return;
38 | }
39 |
40 | Util::addStyle(Application::APP_ID, 'viewer-init');
41 | Util::addStyle(Application::APP_ID, 'viewer-main');
42 | Util::addInitScript(Application::APP_ID, 'viewer-init');
43 | Util::addScript(Application::APP_ID, 'viewer-main', 'files');
44 | $this->initialStateService->provideInitialState('enabled_preview_providers', array_keys($this->previewManager->getProviders()));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ],
6 | "timezone": "Europe/Berlin",
7 | "schedule": [
8 | "every weekend"
9 | ],
10 | "reviewers": [
11 | "skjnldsv"
12 | ],
13 | "labels": [
14 | "dependencies",
15 | "3. to review"
16 | ],
17 | "rangeStrategy": "bump",
18 | "rebaseWhen": "conflicted",
19 | "ignoreUnstable": false,
20 | "baseBranches": [
21 | "master",
22 | "stable31",
23 | "stable30"
24 | ],
25 | "enabledManagers": [
26 | "npm"
27 | ],
28 | "ignoreDeps": [
29 | "node",
30 | "npm"
31 | ],
32 | "lockFileMaintenance": {
33 | "enabled": true,
34 | "automerge": true
35 | },
36 | "packageRules": [
37 | {
38 | "groupName": "cypress",
39 | "matchPackageNames": [
40 | "/^@cypress//",
41 | "/cypress/",
42 | "/eslint-plugin-cypress/"
43 | ]
44 | },
45 | {
46 | "groupName": "nextcloud",
47 | "matchPackageNames": [
48 | "/^@nextcloud//"
49 | ]
50 | },
51 | {
52 | "groupName": "dockerode",
53 | "matchPackageNames": [
54 | "@types/dockerode",
55 | "dockerode"
56 | ]
57 | },
58 | {
59 | "groupName": "typescript",
60 | "matchPackageNames": [
61 | "tslib",
62 | "typescript"
63 | ]
64 | },
65 | {
66 | "matchUpdateTypes": [
67 | "major"
68 | ],
69 | "matchBaseBranches": [
70 | "stable31",
71 | "stable30"
72 | ],
73 | "enabled": false
74 | },
75 | {
76 | "matchPackageNames": [
77 | "vue"
78 | ],
79 | "allowedVersions": "<3"
80 | }
81 | ]
82 | }
83 |
--------------------------------------------------------------------------------
/src/assets/menu-sidebar-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/Error.vue:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 | {{ t('viewer', 'Error loading {name}', { name }) }}
11 |
12 |
13 |
14 |
15 |
27 |
28 |
35 |
--------------------------------------------------------------------------------
/src/files_actions/viewerAction.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import type { Node, View } from '@nextcloud/files'
6 |
7 | import { DefaultType, FileAction, Permission, registerFileAction } from '@nextcloud/files'
8 | import { t } from '@nextcloud/l10n'
9 | import svgEye from '@mdi/svg/svg/eye.svg?raw'
10 |
11 | /**
12 | * @param node The file to open
13 | * @param view any The files view
14 | * @param dir the directory path
15 | */
16 | function pushToHistory(node: Node, view: View, dir: string) {
17 | window.OCP.Files.Router.goToRoute(
18 | null,
19 | { view: view.id, fileid: String(node.fileid) },
20 | { dir, openfile: 'true' },
21 | true,
22 | )
23 | }
24 |
25 | const onPopState = () => {
26 | if (window.OCP.Files.Router.query.openfile !== 'true') {
27 | window.OCA.Viewer.close()
28 | window.removeEventListener('popstate', onPopState)
29 | }
30 | }
31 |
32 | /**
33 | * Execute the viewer files action
34 | * @param node The active node
35 | * @param view The current view
36 | * @param dir The current path
37 | */
38 | async function execAction(node: Node, view: View, dir: string): Promise {
39 | const onClose = () => {
40 | // This can sometime be called with the openfile set to true already. But we don't want to keep openfile when closing the viewer.
41 | const newQuery = { ...window.OCP.Files.Router.query }
42 | delete newQuery.openfile
43 | window.OCP.Files.Router.goToRoute(null, window.OCP.Files.Router.params, newQuery)
44 | }
45 |
46 | window.addEventListener('popstate', onPopState)
47 |
48 | pushToHistory(node, view, dir)
49 | window.OCA.Viewer.open({
50 | path: node.path,
51 | onPrev(fileInfo) {
52 | pushToHistory(fileInfo, view, dir)
53 | },
54 | onNext(fileInfo) {
55 | pushToHistory(fileInfo, view, dir)
56 | },
57 | onClose,
58 | })
59 |
60 | return null
61 | }
62 |
63 | /**
64 | * Register the viewer action on the files API
65 | */
66 | export function registerViewerAction() {
67 | registerFileAction(new FileAction({
68 | id: 'view',
69 | displayName: () => t('viewer', 'View'),
70 | iconSvgInline: () => svgEye,
71 | default: DefaultType.DEFAULT,
72 | enabled: (nodes) => {
73 | // Disable if not located in user root
74 | if (nodes.some(node => !(node.isDavRessource && node.root?.startsWith('/files')))) {
75 | return false
76 | }
77 |
78 | return nodes.every((node) =>
79 | Boolean(node.permissions & Permission.READ)
80 | && window.OCA.Viewer.mimetypes.includes(node.mime),
81 | )
82 | },
83 | exec: execAction,
84 | }))
85 | }
86 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | ///
6 |
7 | import type Viewer from './services/Viewer.js'
8 |
9 | declare global {
10 | interface Window {
11 | OCA: {
12 | Viewer: Viewer
13 | }
14 | OCP: Nextcloud.v29.OCP
15 | }
16 |
17 | const appVersion: string
18 | }
19 |
20 | export {}
21 |
--------------------------------------------------------------------------------
/src/init.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { registerViewerAction } from './files_actions/viewerAction'
6 | import ViewerService from './services/Viewer.js'
7 |
8 | // Register the files action
9 | registerViewerAction()
10 |
11 | // Init Viewer Service
12 | window.OCA = window.OCA ?? {}
13 | window.OCA.Viewer = new ViewerService()
14 | window.OCA.Viewer.version = appVersion
15 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { translate as t } from '@nextcloud/l10n'
6 | import Vue from 'vue'
7 |
8 | import ViewerComponent from './views/Viewer.vue'
9 |
10 | Vue.mixin({
11 | methods: {
12 | t,
13 | },
14 | })
15 |
16 | Vue.prototype.OC = window.OC
17 | Vue.prototype.OCA = window.OCA
18 |
19 | // Create document root
20 | const ViewerRoot = document.createElement('div')
21 | ViewerRoot.id = 'viewer'
22 | document.body.appendChild(ViewerRoot)
23 |
24 | // Put controls for video viewer
25 | // Needed as Firefox CSP blocks the loading of the svg through the normal plyr system
26 | const VideoControls = document.createElement('div')
27 | VideoControls.innerHTML = PLYR_ICONS
28 | VideoControls.style.display = 'none'
29 | document.body.appendChild(VideoControls)
30 |
31 | // Init vue
32 | export default new Vue({
33 | el: '#viewer',
34 | // When debugging the page, it's easier to find which app
35 | // is which. Especially when there is multiple apps
36 | // roots mounted o the same page!
37 | // eslint-disable-next-line vue/match-component-file-name
38 | name: 'ViewerRoot',
39 | render: h => h(ViewerComponent),
40 | })
41 |
--------------------------------------------------------------------------------
/src/mixins/PreviewUrl.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { getPreviewIfAny } from '../utils/previewUtils.ts'
6 | import { getDavPath } from '../utils/fileUtils.ts'
7 |
8 | export default {
9 | computed: {
10 | /**
11 | * Link to the preview path if the file have a preview
12 | *
13 | * @return {string}
14 | */
15 | previewPath() {
16 | return this.getPreviewIfAny({
17 | fileid: this.fileid,
18 | filename: this.filename,
19 | previewUrl: this.previewUrl,
20 | hasPreview: this.hasPreview,
21 | davPath: this.davPath,
22 | etag: this.$attrs.etag,
23 | })
24 | },
25 |
26 | /**
27 | * Absolute dav remote path of the file
28 | *
29 | * @return {string}
30 | */
31 | davPath() {
32 | return getDavPath({
33 | filename: this.filename,
34 | basename: this.basename,
35 | })
36 | },
37 | },
38 | methods: {
39 | /**
40 | * Return the preview url if the file have an existing
41 | * preview or the absolute dav remote path if none.
42 | *
43 | * @param {object} data destructuring object
44 | * @param {string} data.fileid the file id
45 | * @param {string} [data.previewUrl] URL of the file preview
46 | * @param {boolean} data.hasPreview have the file an existing preview ?
47 | * @param {string} data.davPath the absolute dav path
48 | * @param {string} data.filename the file name
49 | * @param {string|null} data.etag the etag of the file
50 | * @return {string} the absolute url
51 | */
52 | getPreviewIfAny(data) {
53 | return getPreviewIfAny(data)
54 | },
55 | },
56 | }
57 |
--------------------------------------------------------------------------------
/src/models/audios.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import Audios from '../components/Audios.vue'
7 |
8 | export default {
9 | id: 'audios',
10 | group: 'media',
11 | mimes: [
12 | 'audio/aac',
13 | 'audio/aacp',
14 | 'audio/flac',
15 | 'audio/mp4',
16 | 'audio/mpeg',
17 | 'audio/ogg',
18 | 'audio/vorbis',
19 | 'audio/wav',
20 | 'audio/webm',
21 | ],
22 | component: Audios,
23 | }
24 |
--------------------------------------------------------------------------------
/src/models/file.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { getDavPath } from '../utils/fileUtils.ts'
6 |
7 | /**
8 | * @param {object} fileInfo a FileInfo object
9 | * @param {string} mime the file mime type
10 | * @param {object} component the component to render
11 | */
12 | export default function(fileInfo, mime, component) {
13 | const data = {
14 | mime,
15 | modal: component,
16 | failed: false,
17 | loaded: false,
18 | davPath: getDavPath(fileInfo),
19 | source: fileInfo.source ?? getDavPath(fileInfo),
20 | }
21 |
22 | return Object.assign({}, fileInfo, data)
23 | }
24 |
--------------------------------------------------------------------------------
/src/models/images.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import { loadState } from '@nextcloud/initial-state'
7 | import logger from '../services/logger.js'
8 | import Images from '../components/Images.vue'
9 |
10 | const enabledPreviewProviders = loadState(appName, 'enabled_preview_providers', [])
11 |
12 | /**
13 | * Those mimes needs a proper preview to be displayed
14 | * if they are not enabled on the server, let's not activate them.
15 | */
16 | const previewSupportedMimes = [
17 | 'image/heic',
18 | 'image/heif',
19 | 'image/tiff',
20 | 'image/x-xbitmap',
21 | 'image/emf',
22 | ]
23 |
24 | /**
25 | * Those mimes are always supported by the browser
26 | * Since we fallback to the source image if there is no
27 | * preview, we can always include them.
28 | */
29 | const browserSupportedMimes = [
30 | 'image/apng',
31 | 'image/bmp',
32 | 'image/gif',
33 | 'image/jpeg',
34 | 'image/png',
35 | 'image/svg+xml',
36 | 'image/webp',
37 | 'image/x-icon',
38 | ]
39 |
40 | // Filter out supported mimes that are _not_
41 | // enabled in the preview API
42 | const filterEnabledMimes = () => {
43 | return previewSupportedMimes.filter(filter => {
44 | return enabledPreviewProviders.findIndex(mimeRegex => {
45 | // Remove leading and trailing slash from string regex
46 | const regex = new RegExp(mimeRegex.replace(/^\/|\/$/g, ''), 'i')
47 | return filter.match(regex)
48 | }) > -1
49 | })
50 | }
51 |
52 | const enabledMimes = filterEnabledMimes()
53 | const ignoredMimes = previewSupportedMimes.filter(x => !enabledMimes.includes(x))
54 | if (ignoredMimes.length > 0) {
55 | logger.warn('Some mimes were ignored because they are not enabled in the server previews config', { ignoredMimes })
56 | }
57 |
58 | export default {
59 | id: 'images',
60 | group: 'media',
61 | mimes: [
62 | ...browserSupportedMimes,
63 | ...enabledMimes,
64 | ],
65 | component: Images,
66 | }
67 |
--------------------------------------------------------------------------------
/src/models/videos.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import Videos from '../components/Videos.vue'
7 |
8 | export default {
9 | id: 'videos',
10 | group: 'media',
11 | mimes: [
12 | 'video/mpeg',
13 | 'video/ogg',
14 | 'video/webm',
15 | 'video/mp4',
16 | 'video/x-m4v',
17 | 'video/x-flv',
18 | 'video/quicktime',
19 | ],
20 | mimesAliases: {
21 | 'video/x-matroska': 'video/webm',
22 | },
23 | component: Videos,
24 | }
25 |
--------------------------------------------------------------------------------
/src/services/FileInfo.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import type { FileStat, ResponseDataDetailed } from 'webdav'
7 |
8 | import { client } from './WebdavClient'
9 | import { genFileInfo, type FileInfo } from '../utils/fileUtils'
10 | import { davGetClient, getDavNameSpaces, getDavProperties } from '@nextcloud/files'
11 |
12 | const statData = `
13 |
14 |
15 |
16 | ${getDavProperties()}
17 |
18 | `
19 |
20 | /**
21 | * Retrieve the files list
22 | * @param path
23 | * @param options
24 | */
25 | export default async function(path: string, options = {}): Promise {
26 | const response = await client.stat(path, Object.assign({
27 | data: statData,
28 | details: true,
29 | }, options)) as ResponseDataDetailed
30 | return genFileInfo(response.data)
31 | }
32 |
33 | /**
34 | * Retrieve the files list
35 | * @param origin
36 | * @param path
37 | * @param options
38 | */
39 | export async function rawStat(origin: string, path: string, options = {}) {
40 | const response = await davGetClient(origin).stat(path, {
41 | ...options,
42 | data: statData,
43 | details: true,
44 | }) as ResponseDataDetailed
45 |
46 | return response.data
47 | }
48 |
--------------------------------------------------------------------------------
/src/services/FileList.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import { getDavNameSpaces, getDavProperties } from '@nextcloud/files'
7 | import { client } from './WebdavClient'
8 | import { genFileInfo, type FileInfo } from '../utils/fileUtils'
9 | import type { FileStat, ResponseDataDetailed } from 'webdav'
10 |
11 | /**
12 | * Retrieve the files list
13 | * @param path
14 | * @param options
15 | */
16 | export default async function(path: string, options = {}): Promise {
17 | const response = await client.getDirectoryContents(path, Object.assign({
18 | data: `
19 |
20 |
21 |
22 | ${getDavProperties()}
23 |
24 | `,
25 | details: true,
26 | }, options)) as ResponseDataDetailed
27 |
28 | return response.data.map(genFileInfo)
29 | }
30 |
--------------------------------------------------------------------------------
/src/services/FileSortingConfig.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import axios from '@nextcloud/axios'
7 | import { generateUrl } from '@nextcloud/router'
8 | import { isPublicShare } from '@nextcloud/sharing/public'
9 |
10 | /**
11 | * @return {object}
12 | */
13 | export default async function getSortingConfig() {
14 | const viewConfigs = await getViewConfigs()
15 |
16 | if (!viewConfigs) {
17 | return { key: 'basename', asc: true }
18 | }
19 |
20 | const keyMap = { mtime: 'lastmod' }
21 | const key = keyMap[viewConfigs.sorting_mode] || viewConfigs.sorting_mode || 'basename'
22 | const asc = viewConfigs.sorting_direction === 'asc' || !viewConfigs.sorting_direction
23 |
24 | return { key, asc }
25 | }
26 |
27 | /**
28 | * @return {object}
29 | */
30 | async function getViewConfigs() {
31 | if (isPublicShare()) {
32 | return null
33 | }
34 | const url = generateUrl('apps/files/api/v1/views')
35 | return await axios.get(url)
36 | .then((response) => {
37 | return response.data.data?.files
38 | })
39 | .catch(() => {
40 | return null
41 | })
42 | }
43 |
--------------------------------------------------------------------------------
/src/services/WebdavClient.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import { davGetClient, davRootPath, davGetRemoteURL } from '@nextcloud/files'
7 |
8 | const davRemote = davGetRemoteURL()
9 |
10 | export const client = davGetClient(`${davRemote}${davRootPath}`)
11 |
--------------------------------------------------------------------------------
/src/services/logger.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { getLoggerBuilder } from '@nextcloud/logger'
6 |
7 | // Set up logger
8 | const logger = getLoggerBuilder()
9 | .setApp(appName)
10 | .detectUser()
11 | .build()
12 |
13 | export default logger
14 |
--------------------------------------------------------------------------------
/src/services/mediaPreloader.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | /* eslint-disable jsdoc/require-jsdoc */
7 |
8 | import type { ResponseDataDetailed, WebDAVClient } from 'webdav'
9 |
10 | import { getClient, getRootPath } from '@nextcloud/files/dav'
11 |
12 | // Manually load a WebDAV media from its filename, then expose the received Blob as an object URL.
13 | // This is needed for E2EE files that will error when loading them directly from the HTML element's src attribute.
14 | // Can be removed if we ever move the E2EE proxy to a service worker.
15 | export async function preloadMedia(filename: string): Promise {
16 | const client = getClient() as WebDAVClient
17 | const response = await client.getFileContents(`${getRootPath()}${filename}`, { details: true }) as ResponseDataDetailed
18 | return URL.createObjectURL(new Blob([response.data], { type: response.headers['content-type'] }))
19 | }
20 |
--------------------------------------------------------------------------------
/src/shims.d.ts:
--------------------------------------------------------------------------------
1 | /*!
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | declare module '*.svg?raw' {
7 | const content: string
8 | export default content
9 | }
10 |
--------------------------------------------------------------------------------
/src/utils/CancelableRequest.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | /**
7 | * Creates a cancelable axios 'request object'.
8 | *
9 | * @param {Function} request the axios promise request
10 | * @return {object}
11 | */
12 | const CancelableRequest = function(request) {
13 | const controller = new AbortController()
14 |
15 | /**
16 | * Execute the request
17 | *
18 | * @param {string} url the url to send the request to
19 | * @param {object} [options] optional config for the request
20 | */
21 | const fetch = async function(url, options) {
22 | return request(
23 | url,
24 | { ...options, signal: controller.signal },
25 | )
26 | }
27 | return {
28 | request: fetch,
29 | cancel: () => controller.abort(),
30 | }
31 | }
32 |
33 | export default CancelableRequest
34 |
--------------------------------------------------------------------------------
/src/utils/canDownload.ts:
--------------------------------------------------------------------------------
1 | /*!
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import type { FileInfo } from './fileUtils'
7 |
8 | /**
9 | * Check if download permissions are granted for a file
10 | * @param fileInfo The file info to check
11 | */
12 | export function canDownload(fileInfo: FileInfo) {
13 | if (fileInfo.hideDownload) {
14 | return false
15 | }
16 |
17 | // TODO: This should probably be part of `@nextcloud/sharing`
18 | // check share attributes
19 | const shareAttributes = typeof fileInfo?.shareAttributes === 'string' ? JSON.parse(fileInfo.shareAttributes || '[]') : fileInfo?.shareAttributes
20 |
21 | if (shareAttributes && shareAttributes.length > 0) {
22 | const downloadAttribute = shareAttributes.find(({ scope, key }) => scope === 'permissions' && key === 'download')
23 | // We only forbid download if the attribute is *explicitly* set to 'false'
24 | return downloadAttribute?.value !== false
25 | }
26 | // otherwise return true (as the file needs read permission otherwise we would not have opened it)
27 | return true
28 | }
29 |
--------------------------------------------------------------------------------
/src/utils/livePhotoUtils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import type { BasicFileInfo } from './models'
7 |
8 | const livePictureExt = ['jpg', 'jpeg', 'png']
9 | const livePictureExtRegex = new RegExp(`\\.(${livePictureExt.join('|')})$`, 'i')
10 |
11 | /**
12 | * Return the peer live photo from a list of files based on its fileId
13 | * @param peerFileId
14 | * @param fileList
15 | */
16 | export function findLivePhotoPeerFromFileId(peerFileId: number, fileList: BasicFileInfo[]): BasicFileInfo | undefined {
17 | return fileList.find(file => file.fileid === peerFileId)
18 | }
19 |
20 | /**
21 | * Return the peer live photo from a list of files based on the original file name.
22 | * @param referenceFile
23 | * @param fileList
24 | */
25 | export function findLivePhotoPeerFromName(referenceFile: BasicFileInfo, fileList: BasicFileInfo[]): BasicFileInfo | undefined {
26 | return fileList.find(comparedFile => {
27 | // if same filename and extension is allowed
28 | return comparedFile.filename !== referenceFile.filename
29 | && (comparedFile.basename.startsWith(referenceFile.name) && livePictureExtRegex.test(comparedFile.basename))
30 | })
31 | }
32 |
--------------------------------------------------------------------------------
/src/utils/models.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | export interface BasicFileInfo {
7 | fileid: number // The file id
8 | filename: string // The file name, ex: /a/b/c/file.txt
9 | basename: string // The base name, ex: file.txt
10 | name: string // The name, ex: file
11 | source?: string // The source of the file, ex: https://example.org/remote.php/dav/files/userId/fileName.jpg
12 | previewUrl?: string // Optional URL of the file preview
13 | hasPreview: boolean // Does the file has an existing preview ?
14 | davPath: string // The absolute dav path
15 | etag: string|null // The etag of the file
16 | metadataFilesLivePhoto?: number // The id of the peer live photo
17 | }
18 |
--------------------------------------------------------------------------------
/src/utils/numberUtil.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | const isNumber = function(num): boolean {
7 | if (!num) {
8 | return false
9 | }
10 | return Number(num).toString() === num.toString()
11 | }
12 |
13 | export { isNumber }
14 |
--------------------------------------------------------------------------------
/src/utils/previewUtils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 |
6 | import type { BasicFileInfo } from './models'
7 | import { encodePath } from '@nextcloud/paths'
8 | import { generateUrl } from '@nextcloud/router'
9 | import { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'
10 |
11 | /**
12 | * @param root0
13 | * @param root0.fileid
14 | * @param root0.filename
15 | * @param root0.previewUrl
16 | * @param root0.hasPreview
17 | * @param root0.davPath
18 | * @param root0.etag
19 | * @return the preview url if the file have an existing preview or the absolute dav remote path if none.
20 | */
21 | export function getPreviewIfAny({ fileid, filename, previewUrl, hasPreview, davPath, etag }: BasicFileInfo): string {
22 | if (previewUrl) {
23 | return previewUrl
24 | }
25 |
26 | const searchParams = `fileId=${fileid}`
27 | + `&x=${Math.floor(screen.width * devicePixelRatio)}`
28 | + `&y=${Math.floor(screen.height * devicePixelRatio)}`
29 | + '&a=true'
30 | + (etag !== null ? `&etag=${etag.replace(/"/g, '')}` : '')
31 |
32 | if (hasPreview) {
33 | // TODO: find a nicer standard way of doing this?
34 | if (isPublicShare()) {
35 | return generateUrl(`/apps/files_sharing/publicpreview/${getSharingToken()}?file=${encodePath(filename)}&${searchParams}`)
36 | }
37 | return generateUrl(`/core/preview?${searchParams}`)
38 | }
39 | return davPath
40 | }
41 |
--------------------------------------------------------------------------------
/stylelint.config.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | const stylelintConfig = require('@nextcloud/stylelint-config')
6 |
7 | // Disable nested scss import
8 | stylelintConfig.rules['no-invalid-position-at-import-rule'] = null
9 |
10 | module.exports = stylelintConfig
11 |
--------------------------------------------------------------------------------
/tests/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.json",
3 | "include": ["./src"],
4 | "compilerOptions": {
5 | "lib": [
6 | "DOM",
7 | "ES2015"
8 | ],
9 | "rootDir": "src",
10 | "noImplicitAny": false,
11 | },
12 | "vueCompilerOptions": {
13 | "target": 2.7
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3 | * SPDX-License-Identifier: AGPL-3.0-or-later
4 | */
5 | import { createAppConfig } from '@nextcloud/vite-config'
6 | import { readFileSync } from 'node:fs'
7 | import { join } from 'node:path'
8 |
9 | const isProduction = process.env.NODE_ENV === 'production'
10 | const plyrIcons = readFileSync(
11 | join(__dirname, 'node_modules', 'plyr', 'dist', 'plyr.svg'),
12 | { encoding: 'utf8' },
13 | )
14 |
15 | export default createAppConfig({
16 | main: 'src/main.js',
17 | init: 'src/init.ts',
18 | }, {
19 | replace: {
20 | PLYR_ICONS: JSON.stringify(plyrIcons),
21 | },
22 | minify: isProduction,
23 | // create REUSE compliant license information for compiled assets
24 | extractLicenseInformation: {
25 | includeSourceMaps: true,
26 | },
27 | // disable BOM because we already have the `.license` files
28 | thirdPartyLicense: false,
29 | // ensure that every JS entry point has a matching CSS file
30 | createEmptyCSSEntryPoints: true,
31 | // Make sure we also clear the CSS directory
32 | emptyOutputDirectory: {
33 | additionalDirectories: ['css'],
34 | },
35 | })
36 |
--------------------------------------------------------------------------------