Compare commits
No commits in common. "master" and "1.7.6" have entirely different histories.
2
.github/workflows/release.yml
vendored
|
@ -43,7 +43,7 @@ jobs:
|
||||||
actions: read
|
actions: read
|
||||||
id-token: write
|
id-token: write
|
||||||
contents: write
|
contents: write
|
||||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
|
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
|
||||||
with:
|
with:
|
||||||
base64-subjects: "${{ needs.release.outputs.hashes }}"
|
base64-subjects: "${{ needs.release.outputs.hashes }}"
|
||||||
draft-release: true
|
draft-release: true
|
||||||
|
|
2
.github/workflows/test-results.yml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download and Extract Artifacts
|
- name: Download and Extract Artifacts
|
||||||
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5
|
uses: dawidd6/action-download-artifact@20319c5641d495c8a52e688b7dc5fada6c3a9fbc
|
||||||
with:
|
with:
|
||||||
run_id: ${{ github.event.workflow_run.id }}
|
run_id: ${{ github.event.workflow_run.id }}
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
|
2
.github/workflows/tests.yml
vendored
|
@ -121,7 +121,7 @@ jobs:
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '20'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: 'js/package-lock.json'
|
cache-dependency-path: 'js/package-lock.json'
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ RewriteEngine on
|
||||||
RewriteCond !%{HTTP_USER_AGENT} "Let's Encrypt validation server" [NC]
|
RewriteCond !%{HTTP_USER_AGENT} "Let's Encrypt validation server" [NC]
|
||||||
RewriteCond %{HTTP_USER_AGENT} ^.*(bot|spider|crawl|https?://|WhatsApp|SkypeUriPreview|facebookexternalhit) [NC]
|
RewriteCond %{HTTP_USER_AGENT} ^.*(bot|spider|crawl|https?://|WhatsApp|SkypeUriPreview|facebookexternalhit) [NC]
|
||||||
RewriteRule .* - [R=403,L]
|
RewriteRule .* - [R=403,L]
|
||||||
AddType application/wasm .wasm
|
|
||||||
|
|
||||||
<IfModule mod_php7.c>
|
<IfModule mod_php7.c>
|
||||||
php_value max_execution_time 30
|
php_value max_execution_time 30
|
||||||
|
|
22
CHANGELOG.md
|
@ -1,27 +1,5 @@
|
||||||
# PrivateBin version history
|
# PrivateBin version history
|
||||||
|
|
||||||
## 2.0.0 (not yet released)
|
|
||||||
* CHANGED: Remove page template (#265)
|
|
||||||
* FIXED: Name mismatches in attached files (#1584)
|
|
||||||
* FIXED: Unable to paste attachments from clipboard (#1589)
|
|
||||||
|
|
||||||
## 1.7.8 (2025-06-30)
|
|
||||||
* FIXED: Duplicate attachment for every comment (#1577)
|
|
||||||
* FIXED: Attachments with empty file names (#1577)
|
|
||||||
* FIXED: Page template scripts loading order (#1579)
|
|
||||||
|
|
||||||
## 1.7.7 (2025-06-28)
|
|
||||||
* ADDED: Switching templates using the web ui (#1501)
|
|
||||||
* ADDED: Show file name and size on download page (#603)
|
|
||||||
* CHANGED: Passing large data structures by reference to reduce memory consumption (#858)
|
|
||||||
* CHANGED: Removed use of ctype functions and polyfill library for ctype
|
|
||||||
* CHANGED: Upgrading libraries to: DOMpurify 3.2.6, ip-lib 1.20.0
|
|
||||||
* CHANGED: Support for multiple file uploads (#1060)
|
|
||||||
* CHANGED: Documented CSP change necessary to allow PDF attachment preview (#1552)
|
|
||||||
* FIXED: Hide Reply button in the discussions once clicked to avoid losing the text input (#1508)
|
|
||||||
* FIXED: Bump zlib library suffix, ensuring cache refresh for WASM streaming change
|
|
||||||
* FIXED: Handle undefined globals in file based persisted values (#1544)
|
|
||||||
|
|
||||||
## 1.7.6 (2025-02-01)
|
## 1.7.6 (2025-02-01)
|
||||||
* ADDED: Ability to copy the paste by clicking the copy icon button or using the keyboard shortcut ctrl+c/cmd+c (#1390 & #12)
|
* ADDED: Ability to copy the paste by clicking the copy icon button or using the keyboard shortcut ctrl+c/cmd+c (#1390 & #12)
|
||||||
* CHANGED: Allow toggling tab-key-support using `[Ctrl]+[m]` or `[Esc]` in textarea for keyboard navigation (#1386)
|
* CHANGED: Allow toggling tab-key-support using `[Ctrl]+[m]` or `[Esc]` in textarea for keyboard navigation (#1386)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
* Simon Rupf - current developer and maintainer
|
* Simon Rupf - current developer and maintainer
|
||||||
* rugk - security review, doc improvment, JS refactoring & various other stuff
|
* rugk - security review, doc improvment, JS refactoring & various other stuff
|
||||||
* R4SAS - python client, compression, blob URI to support larger attachments
|
* R4SAS - python client, compression, blob URI to support larger attachments
|
||||||
* Mikhail Romanov - UI improvements, theme switching, clipboard support, multi-file upload, bugfixes, code refactoring
|
|
||||||
|
|
||||||
## Past contributions
|
## Past contributions
|
||||||
|
|
||||||
|
@ -34,6 +33,7 @@
|
||||||
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
||||||
* Felipe Nakandakari - enabled AWS SDK to use default credential provider chain in the S3 Storage backend
|
* Felipe Nakandakari - enabled AWS SDK to use default credential provider chain in the S3 Storage backend
|
||||||
* Aaron Sherber - cache control headers for API calls & use of `shortenviayourls` in query parameters
|
* Aaron Sherber - cache control headers for API calls & use of `shortenviayourls` in query parameters
|
||||||
|
* Mikhail Romanov - copying to clipboard, UI/UX improvements
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
* Hexalyse - French
|
* Hexalyse - French
|
||||||
|
|
4
Makefile
|
@ -1,7 +1,7 @@
|
||||||
.PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
|
.PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
|
||||||
|
|
||||||
CURRENT_VERSION = 1.7.8
|
CURRENT_VERSION = 1.7.6
|
||||||
VERSION ?= 2.0.0
|
VERSION ?= 1.7.7
|
||||||
VERSION_FILES = README.md SECURITY.md doc/Installation.md js/package*.json lib/Controller.php Makefile
|
VERSION_FILES = README.md SECURITY.md doc/Installation.md js/package*.json lib/Controller.php Makefile
|
||||||
REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
|
REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
|
||||||
REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")
|
REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# [](https://privatebin.info/)
|
# [](https://privatebin.info/)
|
||||||
|
|
||||||
*Current version: 1.7.8*
|
*Current version: 1.7.6*
|
||||||
|
|
||||||
**PrivateBin** is a minimalist, open source online
|
**PrivateBin** is a minimalist, open source online
|
||||||
[pastebin](https://en.wikipedia.org/wiki/Pastebin)
|
[pastebin](https://en.wikipedia.org/wiki/Pastebin)
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ------------------ |
|
| ------- | ------------------ |
|
||||||
| 1.7.8 | :heavy_check_mark: |
|
| 1.7.6 | :heavy_check_mark: |
|
||||||
| < 1.7.8 | :x: |
|
| < 1.7.6 | :x: |
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
@ -14,8 +14,5 @@ a response within a week (usually during the next weekend). The respondee will
|
||||||
reply from their personal address and can offer you their GPG public key to
|
reply from their personal address and can offer you their GPG public key to
|
||||||
support end-to-end encrypted communication on sensitive topics or attachments.
|
support end-to-end encrypted communication on sensitive topics or attachments.
|
||||||
|
|
||||||
You can also [use the corresponding GitHub form](https://github.com/PrivateBin/PrivateBin/security/advisories/new)
|
|
||||||
to report a new vulnerability directly on GitHub.
|
|
||||||
|
|
||||||
You can also contact us via the regular issue tracker if the risk of early
|
You can also contact us via the regular issue tracker if the risk of early
|
||||||
publication is low or you would request input from other PrivateBin users.
|
publication is low or you would request input from other PrivateBin users.
|
||||||
|
|
|
@ -72,35 +72,6 @@ class Administration
|
||||||
exit("paste $pasteId successfully deleted" . PHP_EOL);
|
exit("paste $pasteId successfully deleted" . PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* lists all stored paste IDs
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _list_ids()
|
|
||||||
{
|
|
||||||
$ids = $this->_store->getAllPastes();
|
|
||||||
foreach ($ids as $pasteid) {
|
|
||||||
echo $pasteid, PHP_EOL;
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* deletes all stored pastes (regardless of expiration)
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _delete_all()
|
|
||||||
{
|
|
||||||
$ids = $this->_store->getAllPastes();
|
|
||||||
foreach ($ids as $pasteid) {
|
|
||||||
echo "Deleting paste ID: $pasteid" . PHP_EOL;
|
|
||||||
$this->_store->delete($pasteid);
|
|
||||||
}
|
|
||||||
exit("All pastes successfully deleted" . PHP_EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes empty directories, if current storage model uses Filesystem
|
* removes empty directories, if current storage model uses Filesystem
|
||||||
*
|
*
|
||||||
|
@ -153,15 +124,13 @@ class Administration
|
||||||
{
|
{
|
||||||
echo <<<'EOT'
|
echo <<<'EOT'
|
||||||
Usage:
|
Usage:
|
||||||
administration [--delete <paste id> | --delete-all | --empty-dirs | --help | --list-ids | --purge | --statistics]
|
administration [--delete <paste id> | --empty-dirs | --help | --purge | --statistics]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d, --delete deletes the requested paste ID
|
-d, --delete deletes the requested paste ID
|
||||||
--delete-all deletes all paste IDs
|
|
||||||
-e, --empty-dirs removes empty directories (only if Filesystem storage is
|
-e, --empty-dirs removes empty directories (only if Filesystem storage is
|
||||||
configured)
|
configured)
|
||||||
-h, --help displays this help message
|
-h, --help displays this help message
|
||||||
-l, --list-ids lists all paste IDs
|
|
||||||
-p, --purge purge all expired pastes
|
-p, --purge purge all expired pastes
|
||||||
-s, --statistics reads all stored pastes and comments and reports statistics
|
-s, --statistics reads all stored pastes and comments and reports statistics
|
||||||
EOT, PHP_EOL;
|
EOT, PHP_EOL;
|
||||||
|
@ -208,8 +177,7 @@ EOT, PHP_EOL;
|
||||||
self::_help(2);
|
self::_help(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_opts = getopt('hd:epsl', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics', 'list-ids', 'delete-all'));
|
$this->_opts = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics'));
|
||||||
|
|
||||||
if (!$this->_opts) {
|
if (!$this->_opts) {
|
||||||
self::_error_echo('unsupported arguments given');
|
self::_error_echo('unsupported arguments given');
|
||||||
echo PHP_EOL;
|
echo PHP_EOL;
|
||||||
|
@ -340,12 +308,6 @@ EOT, PHP_EOL;
|
||||||
$class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model');
|
$class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model');
|
||||||
$this->_store = new $class($this->_conf->getSection('model_options'));
|
$this->_store = new $class($this->_conf->getSection('model_options'));
|
||||||
|
|
||||||
if ($this->_option('l', 'list-ids') !== null) {
|
|
||||||
$this->_list_ids();
|
|
||||||
}
|
|
||||||
if ($this->_option(null, 'delete-all') !== null) {
|
|
||||||
$this->_delete_all();
|
|
||||||
}
|
|
||||||
if (($pasteId = $this->_option('d', 'delete')) !== null) {
|
if (($pasteId = $this->_option('d', 'delete')) !== null) {
|
||||||
$this->_delete($pasteId);
|
$this->_delete($pasteId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,14 +164,14 @@ new ConfigurationTestGenerator(array(
|
||||||
),
|
),
|
||||||
'main/template' => array(
|
'main/template' => array(
|
||||||
array(
|
array(
|
||||||
'setting' => 'bootstrap5',
|
'setting' => 'page',
|
||||||
'tests' => array(
|
'tests' => array(
|
||||||
array(
|
array(
|
||||||
'type' => 'MatchesRegularExpression',
|
'type' => 'MatchesRegularExpression',
|
||||||
'args' => array(
|
'args' => array(
|
||||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/bootstrap5/privatebin\.css\\?\d[\d\.]+\d+"[^>]*/>#',
|
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/privatebin\.css\\?\d[\d\.]+\d+"[^>]*/>#',
|
||||||
'$content',
|
'$content',
|
||||||
'outputs "bootstrap5" stylesheet correctly',
|
'outputs "page" stylesheet correctly',
|
||||||
),
|
),
|
||||||
), array(
|
), array(
|
||||||
'type' => 'DoesNotMatchRegularExpression',
|
'type' => 'DoesNotMatchRegularExpression',
|
||||||
|
@ -189,9 +189,9 @@ new ConfigurationTestGenerator(array(
|
||||||
array(
|
array(
|
||||||
'type' => 'DoesNotMatchRegularExpression',
|
'type' => 'DoesNotMatchRegularExpression',
|
||||||
'args' => array(
|
'args' => array(
|
||||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/bootstrap5/privatebin\.css\\?\d[\d\.]+\d+"[^>]*/>#',
|
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/privatebin\.css\\?\d[\d\.]+\d+"[^>]*/>#',
|
||||||
'$content',
|
'$content',
|
||||||
'removes "bootstrap5" stylesheet correctly',
|
'removes "page" stylesheet correctly',
|
||||||
),
|
),
|
||||||
), array(
|
), array(
|
||||||
'type' => 'MatchesRegularExpression',
|
'type' => 'MatchesRegularExpression',
|
||||||
|
|
|
@ -42,26 +42,13 @@ defaultformatter = "plaintext"
|
||||||
; size limit per paste or comment in bytes, defaults to 10 Mebibytes
|
; size limit per paste or comment in bytes, defaults to 10 Mebibytes
|
||||||
sizelimit = 10485760
|
sizelimit = 10485760
|
||||||
|
|
||||||
; by default PrivateBin use "bootstrap" template (tpl/bootstrap.php).
|
; template to include, default is "bootstrap" (tpl/bootstrap.php), also
|
||||||
; Optionally you can enable the template selection menu, which uses
|
; available are "page" (tpl/page.php), the classic ZeroBin style and several
|
||||||
; a session cookie to store the choice until the browser is closed.
|
|
||||||
templateselection = false
|
|
||||||
|
|
||||||
; List of available for selection templates when "templateselection" option is enabled
|
|
||||||
availabletemplates[] = "bootstrap5"
|
|
||||||
availabletemplates[] = "bootstrap"
|
|
||||||
availabletemplates[] = "bootstrap-page"
|
|
||||||
availabletemplates[] = "bootstrap-dark"
|
|
||||||
availabletemplates[] = "bootstrap-dark-page"
|
|
||||||
availabletemplates[] = "bootstrap-compact"
|
|
||||||
availabletemplates[] = "bootstrap-compact-page"
|
|
||||||
|
|
||||||
; set the template your installs defaults to, defaults to "bootstrap" (tpl/bootstrap.php), also
|
|
||||||
; bootstrap variants: "bootstrap-dark", "bootstrap-compact", "bootstrap-page",
|
; bootstrap variants: "bootstrap-dark", "bootstrap-compact", "bootstrap-page",
|
||||||
; which can be combined with "-dark" and "-compact" for "bootstrap-dark-page",
|
; which can be combined with "-dark" and "-compact" for "bootstrap-dark-page"
|
||||||
; "bootstrap-compact-page" and finally "bootstrap5" (tpl/bootstrap5.php) - previews at:
|
; and finally "bootstrap-compact-page" - previews at:
|
||||||
; https://privatebin.info/screenshots.html
|
; https://privatebin.info/screenshots.html
|
||||||
; template = "bootstrap"
|
template = "bootstrap"
|
||||||
|
|
||||||
; (optional) info text to display
|
; (optional) info text to display
|
||||||
; use single, instead of double quotes for HTML attributes
|
; use single, instead of double quotes for HTML attributes
|
||||||
|
@ -106,6 +93,8 @@ languageselection = false
|
||||||
; scripts or run your site behind certain DDoS-protection services.
|
; scripts or run your site behind certain DDoS-protection services.
|
||||||
; Check the documentation at https://content-security-policy.com/
|
; Check the documentation at https://content-security-policy.com/
|
||||||
; Notes:
|
; Notes:
|
||||||
|
; - If you use any bootstrap theme, you can remove the allow-popups from the
|
||||||
|
; sandbox restrictions.
|
||||||
; - If you use the bootstrap5 theme, you must change default-src to 'self' to
|
; - If you use the bootstrap5 theme, you must change default-src to 'self' to
|
||||||
; enable display of the svg icons
|
; enable display of the svg icons
|
||||||
; - By default this disallows to load images from third-party servers, e.g. when
|
; - By default this disallows to load images from third-party servers, e.g. when
|
||||||
|
@ -114,15 +103,7 @@ languageselection = false
|
||||||
; for details.
|
; for details.
|
||||||
; - The 'wasm-unsafe-eval' is used to enable webassembly support (used for zlib
|
; - The 'wasm-unsafe-eval' is used to enable webassembly support (used for zlib
|
||||||
; compression). You can remove it if compression doesn't need to be supported.
|
; compression). You can remove it if compression doesn't need to be supported.
|
||||||
; - The 'unsafe-inline' style-src is used by Chrome when displaying PDF previews
|
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
|
||||||
; and can be omitted if attachment upload is disabled (which is the default).
|
|
||||||
; See https://issues.chromium.org/issues/343754409
|
|
||||||
; - To allow displaying PDF previews in Firefox or Chrome, sandboxing must also
|
|
||||||
; get turned off. The following CSP allows PDF previews:
|
|
||||||
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; frame-ancestors 'none'; frame-src blob:; img-src 'self' data: blob:; media-src blob:; object-src blob:"
|
|
||||||
;
|
|
||||||
; The recommended and default used CSP is:
|
|
||||||
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; frame-src blob:; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads"
|
|
||||||
|
|
||||||
; stay compatible with PrivateBin Alpha 0.19, less secure
|
; stay compatible with PrivateBin Alpha 0.19, less secure
|
||||||
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
|
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
|
||||||
|
|
|
@ -26,8 +26,9 @@
|
||||||
"require" : {
|
"require" : {
|
||||||
"php": "^7.3 || ^8.0",
|
"php": "^7.3 || ^8.0",
|
||||||
"jdenticon/jdenticon": "1.0.2",
|
"jdenticon/jdenticon": "1.0.2",
|
||||||
"mlocati/ip-lib": "1.20.0",
|
"mlocati/ip-lib": "1.18.1",
|
||||||
"symfony/polyfill-php80": "1.31.0",
|
"symfony/polyfill-ctype": "^1.31",
|
||||||
|
"symfony/polyfill-php80": "^1.31",
|
||||||
"yzalis/identicon": "2.0.0"
|
"yzalis/identicon": "2.0.0"
|
||||||
},
|
},
|
||||||
"suggest" : {
|
"suggest" : {
|
||||||
|
|
105
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "6c7e6dea19e8bfd5641b220cb68c4b65",
|
"content-hash": "0fdf0f08646fa2a4cf9c076131f529f5",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "jdenticon/jdenticon",
|
"name": "jdenticon/jdenticon",
|
||||||
|
@ -57,16 +57,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mlocati/ip-lib",
|
"name": "mlocati/ip-lib",
|
||||||
"version": "1.20.0",
|
"version": "1.18.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/mlocati/ip-lib.git",
|
"url": "https://github.com/mlocati/ip-lib.git",
|
||||||
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4"
|
"reference": "08bb43b4949069c543ebdf099a6b2c322d0172ab"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/fd45fc3bf08ed6c7e665e2e70562082ac954afd4",
|
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/08bb43b4949069c543ebdf099a6b2c322d0172ab",
|
||||||
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4",
|
"reference": "08bb43b4949069c543ebdf099a6b2c322d0172ab",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/mlocati/ip-lib/issues",
|
"issues": "https://github.com/mlocati/ip-lib/issues",
|
||||||
"source": "https://github.com/mlocati/ip-lib/tree/1.20.0"
|
"source": "https://github.com/mlocati/ip-lib/tree/1.18.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,86 @@
|
||||||
"type": "other"
|
"type": "other"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-02-04T17:30:58+00:00"
|
"time": "2024-10-29T15:44:19+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-ctype",
|
||||||
|
"version": "v1.31.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
|
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||||
|
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-ctype": "*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/polyfill",
|
||||||
|
"name": "symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gert de Pagter",
|
||||||
|
"email": "BackEndTea@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for ctype functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"ctype",
|
||||||
|
"polyfill",
|
||||||
|
"portable"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
|
@ -337,16 +416,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "myclabs/deep-copy",
|
"name": "myclabs/deep-copy",
|
||||||
"version": "1.13.0",
|
"version": "1.12.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414"
|
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
|
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414",
|
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -385,7 +464,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
|
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -393,7 +472,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-02-12T12:17:51+00:00"
|
"time": "2024-11-08T17:47:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
|
|
|
@ -8,12 +8,6 @@
|
||||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#attachmentPreview {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#attachmentPreview img {
|
#attachmentPreview img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
460
css/privatebin.css
Normal file
|
@ -0,0 +1,460 @@
|
||||||
|
/**
|
||||||
|
* PrivateBin
|
||||||
|
*
|
||||||
|
* Cascading style sheets for page template.
|
||||||
|
*
|
||||||
|
* @link https://github.com/PrivateBin/PrivateBin
|
||||||
|
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||||
|
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import url("common.css");
|
||||||
|
|
||||||
|
/* CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved.
|
||||||
|
Licensed under the BSD License. - http://yuilibrary.com/license/ */
|
||||||
|
html{color:#000;background:#fff}body,div,dl,dt,dd,ul,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{font-size:100%;}legend{color:#000}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-color: #455463;
|
||||||
|
color: #fff;
|
||||||
|
min-height: 100%;
|
||||||
|
background-image: linear-gradient(bottom, #0f1823 0, #455463 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #0f1823 0, #455463 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #0f1823 0, #455463 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #0f1823 0, #455463 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #0f1823 0, #455463 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0f1823), color-stop(1, #455463));
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 0.9em;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding-left: 60px;
|
||||||
|
padding-right: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a { color: #0f388f; cursor:pointer; }
|
||||||
|
|
||||||
|
h1.title {
|
||||||
|
font-size: 3.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
position: relative;
|
||||||
|
display: inline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.title:before {
|
||||||
|
content: attr(title);
|
||||||
|
position: absolute;
|
||||||
|
color: rgba(255,255,255,0.15);
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2.title {
|
||||||
|
color: #000;
|
||||||
|
font-size: 1em;
|
||||||
|
display: inline;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
position: relative;
|
||||||
|
bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.title {
|
||||||
|
color: #94a3b4;
|
||||||
|
font-size: 0.7em;
|
||||||
|
display: inline;
|
||||||
|
margin-top: 10px;
|
||||||
|
position: relative;
|
||||||
|
bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#aboutbox {
|
||||||
|
color: #94a3b4;
|
||||||
|
padding: 4px 8px 4px 16px;
|
||||||
|
position: relative;
|
||||||
|
top: 10px;
|
||||||
|
border-left: 2px solid #94a3b4;
|
||||||
|
float: right;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#aboutbox a { color: #94a3b4; }
|
||||||
|
|
||||||
|
#message, #cleartext, #prettymessage, #attachment, .replymessage {
|
||||||
|
position: relative;
|
||||||
|
clear: both;
|
||||||
|
color: #000;
|
||||||
|
background-color: #fff;
|
||||||
|
font-size: 9pt;
|
||||||
|
border: 1px solid #28343F;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
-o-box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message, .replymessage {
|
||||||
|
padding: 5px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: Consolas, "Lucida Console", "DejaVu Sans Mono", Monaco, monospace;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status {
|
||||||
|
clear: both;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pasteresult {
|
||||||
|
background-color: #1F2833;
|
||||||
|
color: #fff;
|
||||||
|
padding: 4px 12px;
|
||||||
|
clear: both;
|
||||||
|
-moz-box-shadow: inset 0 2px 2px #000;
|
||||||
|
-webkit-box-shadow: inset 0 2px 2px #000;
|
||||||
|
box-shadow: inset 0 2px 2px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pasteresult a { color: #fff; }
|
||||||
|
|
||||||
|
#pasteresult button { margin-left: 11px; }
|
||||||
|
|
||||||
|
#message, #plaintext, #prettymessage, #toolbar, #status { margin-bottom: 5px; }
|
||||||
|
|
||||||
|
#copyhint { color: #666; font-size: 0.85em }
|
||||||
|
|
||||||
|
button, .button {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #323b47;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center left;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 1em;
|
||||||
|
margin-right: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
background-image: linear-gradient(bottom, #323b47 0, #51606e 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #323b47 0, #51606e 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #323b47 0, #51606e 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #323b47 0, #51606e 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #323b47 0, #51606e 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #323b47), color-stop(1, #51606e));
|
||||||
|
border: 1px solid #28343F;
|
||||||
|
-moz-box-shadow: inset 0 1px 2px #647384;
|
||||||
|
-webkit-box-shadow: inset 0 1px 2px #647384;
|
||||||
|
box-shadow: inset 0 1px 2px #647384;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
-moz-background-clip: padding;
|
||||||
|
-webkit-background-clip: padding-box;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-image: linear-gradient(bottom, #424b57 0%, #61707e 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #424b57 0%, #61707e 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #424b57 0%, #61707e 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #424b57 0%, #61707e 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #424b57 0%, #61707e 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #424b57), color-stop(1, #61707e));
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background-image: linear-gradient(bottom, #51606e 0, #323b47 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #51606e 0, #323b47 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #51606e 0, #323b47 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #51606e 0, #323b47 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #51606e 0, #323b47 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #51606e), color-stop(1, #323b47));
|
||||||
|
position:relative;
|
||||||
|
top:1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled, .buttondisabled {
|
||||||
|
background: #ccc;
|
||||||
|
color: #888;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button img {
|
||||||
|
margin-right: 8px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background-color: #414d5a;
|
||||||
|
padding: 6px 8px;
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
position: relative;
|
||||||
|
bottom: 1px; /* WTF ? Why is this shifted by 1 pixel ? */
|
||||||
|
}
|
||||||
|
|
||||||
|
.button select {
|
||||||
|
color: #eee;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.button select option {
|
||||||
|
color:#eee;
|
||||||
|
background: #414d5a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rawtextbutton img {
|
||||||
|
padding: 1px 0 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#downloadtextbutton img {
|
||||||
|
padding: 1px 0 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#remainingtime, #password {
|
||||||
|
color: #94a3b4;
|
||||||
|
display: inline;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#newbutton {
|
||||||
|
float: right;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
color: #777;
|
||||||
|
font-size: 1em;
|
||||||
|
padding: 6px;
|
||||||
|
border: 1px solid #28343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blink {
|
||||||
|
text-decoration: blink;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #a4b3c4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foryoureyesonly {
|
||||||
|
color: #ff0 !important;
|
||||||
|
font-size: 1em !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#attachmentPreview, .nonworking {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10pt;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
|
#ienotice {
|
||||||
|
background-color: #7e98af;
|
||||||
|
color: #000;
|
||||||
|
font-size: 0.85em;
|
||||||
|
padding: 3px 5px;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ienotice a { color: #000; }
|
||||||
|
|
||||||
|
#oldnotice, #httpnotice { display: none; }
|
||||||
|
|
||||||
|
#errormessage, .errorMessage {
|
||||||
|
background-color: #f77 !important;
|
||||||
|
color:#ff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- discussion related CSS ------- */
|
||||||
|
|
||||||
|
#discussion { /* Discussion container */
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: -30px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4.title {
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #94a3b4;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment /* One single reply */
|
||||||
|
{
|
||||||
|
background-color: #ceced6;
|
||||||
|
color: #000;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: Consolas,"Lucida Console","DejaVu Sans Mono",Monaco,monospace;
|
||||||
|
font-size: 9pt;
|
||||||
|
border-left: 1px solid #859AAE;
|
||||||
|
border-top: 1px solid #859AAE;
|
||||||
|
padding: 5px 0px 5px 5px;
|
||||||
|
margin-left: 30px;
|
||||||
|
-moz-box-shadow: -3px -3px 5px rgba(0,0,0,0.15);
|
||||||
|
-webkit-box-shadow: -3px -3px 5px rgba(0,0,0,0.15);
|
||||||
|
box-shadow: -3px -3px 5px rgba(0,0,0,0.15);
|
||||||
|
min-width: 200px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply { margin: 5px 0 0 30px; }
|
||||||
|
|
||||||
|
#replystatus {
|
||||||
|
display: inline;
|
||||||
|
padding: 1px 7px;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment button {
|
||||||
|
color: #446;
|
||||||
|
background-color: #aab;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center left;
|
||||||
|
padding: 0 2px;
|
||||||
|
font-size: 0.73em;
|
||||||
|
margin: 3px 5px 3px 0;
|
||||||
|
display: inline;
|
||||||
|
background-image: linear-gradient(bottom, #aab 0, #ccc 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #aab 0, #ccc 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #aab 0, #ccc 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #aab 0, #ccc 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #aab 0, #ccc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #aab), color-stop(1, #ccc));
|
||||||
|
border: 1px solid #ccd;
|
||||||
|
-moz-box-shadow: inset 0 1px 2px #ddd;
|
||||||
|
-webkit-box-shadow: inset 0 1px 2px #fff;
|
||||||
|
box-shadow: inset 0 1px 2px #eee;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
-moz-background-clip: padding;
|
||||||
|
-webkit-background-clip: padding-box;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment button:hover {
|
||||||
|
background-image: linear-gradient(bottom, #ccd 0, #fff 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #ccd 0, #fff 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #ccd 0, #fff 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #ccd 0, #fff 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #ccd 0, #fff 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccd), color-stop(1, #fff));
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment button:active {
|
||||||
|
background-image: linear-gradient(bottom, #fff 0, #889 100%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #fff 0, #889 100%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #fff 0, #889 100%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #fff 0, #889 100%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #fff 0, #889 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(1, #889));
|
||||||
|
position:relative;
|
||||||
|
top:1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment input { padding: 2px; }
|
||||||
|
|
||||||
|
#replymessage { margin-top: 5px; }
|
||||||
|
|
||||||
|
.commentmeta {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #8ea0b2;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
padding: 0 0 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commentdate { color: #bfcede; }
|
||||||
|
|
||||||
|
img.vizhash {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
left: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prettyprint {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prettyprint.prettyprinted {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext * {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext ol {
|
||||||
|
list-style: auto;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext ul {
|
||||||
|
list-style: disc;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext h1, #cleartext h2, #cleartext h3, #cleartext h4, #cleartext h5, #cleartext h6 {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cleartext h3 {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right-to-left overrides */
|
||||||
|
html[dir="rtl"] #aboutbox, html[dir="rtl"] #deletelink, html[dir="rtl"] #newbutton {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] button, html[dir="rtl"] .button, html[dir="rtl"] button img {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] button img {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ for more information.
|
||||||
### Minimal Requirements
|
### Minimal Requirements
|
||||||
|
|
||||||
- PHP version 7.3 or above
|
- PHP version 7.3 or above
|
||||||
|
- ctype extension
|
||||||
- GD extension (when using identicon or vizhash icons, jdenticon works without it)
|
- GD extension (when using identicon or vizhash icons, jdenticon works without it)
|
||||||
- zlib extension
|
- zlib extension
|
||||||
- some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php)
|
- some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php)
|
||||||
|
@ -200,7 +201,7 @@ CREATE INDEX parent ON prefix_comment(pasteid);
|
||||||
CREATE TABLE prefix_config (
|
CREATE TABLE prefix_config (
|
||||||
id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id)
|
id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
INSERT INTO prefix_config VALUES('VERSION', '1.7.8');
|
INSERT INTO prefix_config VALUES('VERSION', '1.7.6');
|
||||||
```
|
```
|
||||||
|
|
||||||
In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns
|
In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns
|
||||||
|
|
|
@ -18,7 +18,7 @@ The parameters in detail:
|
||||||
an accidentally destructive test case in it.
|
an accidentally destructive test case in it.
|
||||||
- `--read-only` - This image supports running in read-only mode. Only /tmp
|
- `--read-only` - This image supports running in read-only mode. Only /tmp
|
||||||
may be written into.
|
may be written into.
|
||||||
- `--rm` - Remove the container after the run. This saves you doing a cleanup
|
- `-rm` - Remove the container after the run. This saves you doing a cleanup
|
||||||
on your docker environment, if you run the image frequently.
|
on your docker environment, if you run the image frequently.
|
||||||
|
|
||||||
You can also run just the php and javascript test suites instead of both:
|
You can also run just the php and javascript test suites instead of both:
|
||||||
|
|
41
i18n/ar.json
|
@ -164,25 +164,17 @@
|
||||||
"EiB": "إكسابايت",
|
"EiB": "إكسابايت",
|
||||||
"ZiB": "زيتابايت",
|
"ZiB": "زيتابايت",
|
||||||
"YiB": "يوتابايت",
|
"YiB": "يوتابايت",
|
||||||
"kB": "كيلوبايت",
|
|
||||||
"MB": "ميجابايت",
|
|
||||||
"GB": "جيجابايت",
|
|
||||||
"TB": "تيرابايت",
|
|
||||||
"PB": "بيتابايت",
|
|
||||||
"EB": "إكسابايت",
|
|
||||||
"ZB": "زيتابايت",
|
|
||||||
"YB": "يوتابايت",
|
|
||||||
"Format": "التنسيق",
|
"Format": "التنسيق",
|
||||||
"Plain Text": "نص عادي",
|
"Plain Text": "نص عادي",
|
||||||
"Source Code": "كود مصدر",
|
"Source Code": "كود مصدر",
|
||||||
"Markdown": "ماركداون",
|
"Markdown": "ماركداون",
|
||||||
"Download attachment": "نزّل المرفق",
|
"Download attachment": "تنزيل المرفقات",
|
||||||
"Cloned: '%s'": "مستنسخ: '%s'",
|
"Cloned: '%s'": "مستنسخ: '%s'",
|
||||||
"The cloned file '%s' was attached to this paste.": "تم إرفاق الملف المستنسخ '%s' بهذا اللصق.",
|
"The cloned file '%s' was attached to this paste.": "تم إرفاق المِلَفّ المستنسخ '%s' بهذا اللصق.",
|
||||||
"Attach a file": "أرفق ملف",
|
"Attach a file": "إرفاق مِلَفّ",
|
||||||
"alternatively drag & drop a file or paste an image from the clipboard": "بدلاً من ذلك، اسحب ملفًا وأسقطه أو الصق صورة من الحافظة",
|
"alternatively drag & drop a file or paste an image from the clipboard": "بدلاً من ذلك، اسحب ملفًا وأسقطه أو الصق صورة من الحافظة",
|
||||||
"File too large, to display a preview. Please download the attachment.": "الملف كبير جدًا، بحيث لا يمكن عرض معاينة. الرجاء تنزيل المرفق.",
|
"File too large, to display a preview. Please download the attachment.": "المِلَفّ كبير جدًا، بحيث لا يمكن عرض معاينة. الرجاء تنزيل المرفق.",
|
||||||
"Remove attachment": "أزِل المرفق",
|
"Remove attachment": "إزالة المرفق",
|
||||||
"Your browser does not support uploading encrypted files. Please use a newer browser.": "متصفحك لا يدعم رفع الملفات المشفرة. الرجاء استخدام متصفح أحدث.",
|
"Your browser does not support uploading encrypted files. Please use a newer browser.": "متصفحك لا يدعم رفع الملفات المشفرة. الرجاء استخدام متصفح أحدث.",
|
||||||
"Invalid attachment.": "مرفق غير صحيح.",
|
"Invalid attachment.": "مرفق غير صحيح.",
|
||||||
"Options": "الخيارات",
|
"Options": "الخيارات",
|
||||||
|
@ -223,17 +215,16 @@
|
||||||
"Trying to shorten a URL that isn't pointing at our instance.": "محاولة تقصير عنوان URL لا يشير إلى خادمنا.",
|
"Trying to shorten a URL that isn't pointing at our instance.": "محاولة تقصير عنوان URL لا يشير إلى خادمنا.",
|
||||||
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "خطأ في الاتصال بـ YOURLS. ربما تكون هناك مشكلة في التضبيط، مثل \"apiurl\" أو \"التوقيع\" الخاطئ أو المفقود.",
|
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "خطأ في الاتصال بـ YOURLS. ربما تكون هناك مشكلة في التضبيط، مثل \"apiurl\" أو \"التوقيع\" الخاطئ أو المفقود.",
|
||||||
"Error parsing YOURLS response.": "خطأ في تحليل استجابة YOURLS.",
|
"Error parsing YOURLS response.": "خطأ في تحليل استجابة YOURLS.",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "يمكن عرض هذه الرسالة السرية مرة واحدة فقط. هل ترغب في رؤيتها الآن؟",
|
"This secret message can only be displayed once. Would you like to see it now?": "لا يمكن عرض اللصق احرقه بعد قراءته إلا مرة واحدة عند تحميله. هل تريد فتحه الآن؟",
|
||||||
"Yes, see it": "نعم، دعني اراها",
|
"Yes, see it": "نعم، حمله",
|
||||||
"Dark Mode": "الوضع الداكن",
|
"Dark Mode": "الوضع الداكن",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "خطأ في ضغط اللصق، بسبب فقدان دعم WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "خطأ في فك ضغط اللصق، متصفحك لا يدعم WebAssembly. الرجاء استخدام متصفح آخر لعرض هذه اللصقة.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "ابدأ من جديد",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "نُسخ اللصق إلى الحافظة",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "لنسخ اللصق انقر على زر النسخ أو استخدم اختصار الحافظة <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "نسخ الرابط",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "نُسخ الرابط إلى الحافظة",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "لصق النص",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "مفتاح التبويب يعمل كشخصية (انقر <kbd>Ctrl</kbd>+<kbd>m</kbd> أو <kbd>Esc</kbd> للتبديل)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "السمة"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/bg.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Формат",
|
"Format": "Формат",
|
||||||
"Plain Text": "Чист текст",
|
"Plain Text": "Чист текст",
|
||||||
"Source Code": "Изходен код",
|
"Source Code": "Изходен код",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ca.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Text sense format",
|
"Plain Text": "Text sense format",
|
||||||
"Source Code": "Codi font",
|
"Source Code": "Codi font",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
27
i18n/co.json
|
@ -156,22 +156,14 @@
|
||||||
"Could not create paste: %s": "Ùn si pò micca creà l’appiccicu : %s",
|
"Could not create paste: %s": "Ùn si pò micca creà l’appiccicu : %s",
|
||||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Ùn si pò micca dicifrà l’appiccicu : A chjave di dicifratura hè assente in l’indirizzu. Averiate impiegatu un orientadore d’indirizzu o un riduttore chì ammuzzeghja una parte di l’indirizzu ?",
|
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Ùn si pò micca dicifrà l’appiccicu : A chjave di dicifratura hè assente in l’indirizzu. Averiate impiegatu un orientadore d’indirizzu o un riduttore chì ammuzzeghja una parte di l’indirizzu ?",
|
||||||
"B": "o",
|
"B": "o",
|
||||||
"KiB": "Kio",
|
"KiB": "Ko",
|
||||||
"MiB": "Mio",
|
"MiB": "Mo",
|
||||||
"GiB": "Gio",
|
"GiB": "Go",
|
||||||
"TiB": "Tio",
|
"TiB": "To",
|
||||||
"PiB": "Pio",
|
"PiB": "Po",
|
||||||
"EiB": "Eio",
|
"EiB": "Eo",
|
||||||
"ZiB": "Zio",
|
"ZiB": "Zo",
|
||||||
"YiB": "Yio",
|
"YiB": "Yo",
|
||||||
"kB": "Ko",
|
|
||||||
"MB": "Mo",
|
|
||||||
"GB": "Go",
|
|
||||||
"TB": "To",
|
|
||||||
"PB": "Po",
|
|
||||||
"EB": "Eo",
|
|
||||||
"ZB": "Zo",
|
|
||||||
"YB": "Yo",
|
|
||||||
"Format": "Furmatu",
|
"Format": "Furmatu",
|
||||||
"Plain Text": "Testu in chjaru",
|
"Plain Text": "Testu in chjaru",
|
||||||
"Source Code": "Codice di fonte",
|
"Source Code": "Codice di fonte",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Cupià u liame",
|
"Copy link": "Cupià u liame",
|
||||||
"Link copied to clipboard": "U liame hè statu cupiatu in u preme’papei",
|
"Link copied to clipboard": "U liame hè statu cupiatu in u preme’papei",
|
||||||
"Paste text": "Testu di l’appiccicu",
|
"Paste text": "Testu di l’appiccicu",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "U tastu di tabulazione ghjova cum’è un caratteru (Appughjate nant’à <kbd>Ctrl</kbd>+<kbd>m</kbd> o <kbd>Scapp</kbd> per scambià)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "U tastu di tabulazione ghjova cum’è un caratteru (Appughjate nant’à <kbd>Ctrl</kbd>+<kbd>m</kbd> o <kbd>Scapp</kbd> per scambià)"
|
||||||
"Theme": "Tema"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/cs.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formát",
|
"Format": "Formát",
|
||||||
"Plain Text": "Prostý text",
|
"Plain Text": "Prostý text",
|
||||||
"Source Code": "Zdrojový kód",
|
"Source Code": "Zdrojový kód",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/de.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Nur Text",
|
"Plain Text": "Nur Text",
|
||||||
"Source Code": "Quellcode",
|
"Source Code": "Quellcode",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Verknüpfung kopieren",
|
"Copy link": "Verknüpfung kopieren",
|
||||||
"Link copied to clipboard": "Verknüpfung wurde in die Zwischenablage kopiert.",
|
"Link copied to clipboard": "Verknüpfung wurde in die Zwischenablage kopiert.",
|
||||||
"Paste text": "Text",
|
"Paste text": "Text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortaste als Zeichen interpretieren (Umschalten durch <kbd>Strg</kbd>+<kbd>m</kbd> oder <kbd>Esc</kbd>)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortaste als Zeichen interpretieren (Umschalten durch <kbd>Strg</kbd>+<kbd>m</kbd> oder <kbd>Esc</kbd>)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/el.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Μορφοποίηση",
|
"Format": "Μορφοποίηση",
|
||||||
"Plain Text": "Απλό κείμενο",
|
"Plain Text": "Απλό κείμενο",
|
||||||
"Source Code": "Πηγαίος Κώδικας",
|
"Source Code": "Πηγαίος Κώδικας",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/en.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/es.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formato",
|
"Format": "Formato",
|
||||||
"Plain Text": "Texto sin formato",
|
"Plain Text": "Texto sin formato",
|
||||||
"Source Code": "Código fuente",
|
"Source Code": "Código fuente",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
25
i18n/et.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formaat",
|
"Format": "Formaat",
|
||||||
"Plain Text": "Lihttekst",
|
"Plain Text": "Lihttekst",
|
||||||
"Source Code": "Lähtekood",
|
"Source Code": "Lähtekood",
|
||||||
|
@ -223,17 +215,16 @@
|
||||||
"Trying to shorten a URL that isn't pointing at our instance.": "Püüame lühendada URL-i, mis ei viita meie instantsile.",
|
"Trying to shorten a URL that isn't pointing at our instance.": "Püüame lühendada URL-i, mis ei viita meie instantsile.",
|
||||||
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Viga YOURLS-i kutsumisel. Tõenäoliselt konfiguratsiooniprobleem, näiteks vale või puuduv \"apiurl\" või \"signature\".",
|
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Viga YOURLS-i kutsumisel. Tõenäoliselt konfiguratsiooniprobleem, näiteks vale või puuduv \"apiurl\" või \"signature\".",
|
||||||
"Error parsing YOURLS response.": "Viga YOURLS vastuse parsimisel.",
|
"Error parsing YOURLS response.": "Viga YOURLS vastuse parsimisel.",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "Seda turvalist sõnumit saab kuvada vaid ühe korra. \nKas soovid seda näha nüüd?",
|
"This secret message can only be displayed once. Would you like to see it now?": "This secret message can only be displayed once. Would you like to see it now?",
|
||||||
"Yes, see it": "Jah, vaata seda",
|
"Yes, see it": "Yes, see it",
|
||||||
"Dark Mode": "Tume režiim",
|
"Dark Mode": "Tume režiim",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "Alusta uuesti",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Kleebe kopeeriti lõikelauale",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopeeri link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link kopeeriti lõikelauale",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Kleebi tekst",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Teema"
|
|
||||||
}
|
}
|
||||||
|
|
27
i18n/fi.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formaatti",
|
"Format": "Formaatti",
|
||||||
"Plain Text": "Perusteksti",
|
"Plain Text": "Perusteksti",
|
||||||
"Source Code": "Lähdekoodi",
|
"Source Code": "Lähdekoodi",
|
||||||
|
@ -226,14 +218,13 @@
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "Tämä salainen viesti voidaan näyttää vain kerran. Haluatko nähdä sen nyt?",
|
"This secret message can only be displayed once. Would you like to see it now?": "Tämä salainen viesti voidaan näyttää vain kerran. Haluatko nähdä sen nyt?",
|
||||||
"Yes, see it": "Kyllä, näet sen",
|
"Yes, see it": "Kyllä, näet sen",
|
||||||
"Dark Mode": "Tumma tila",
|
"Dark Mode": "Tumma tila",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Virhe pakattaessa pastea, koska WebAssembly-tuki puuttuu.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Virhe pasten purkamisessa, selaimesi ei tue WebAssemblyä. Ole hyvä ja käytä toista selainta nähdäksesi tämä paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "Aloita alusta",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Paste kopioitu leikepöydälle",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Voit kopioida pasten painamalla kopioi-painiketta tai käyttämällä leikepöydän oikotietä <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopioi linkki",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Linkki kopioitu leikepöydälle",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Liitä teksti",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulaattori toimii merkkinä (Paina <kbd>Ctrl</kbd>+<kbd>m</kbd> tai <kbd>Esc</kbd> vaihtaaksesi)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Teema"
|
|
||||||
}
|
}
|
||||||
|
|
19
i18n/fr.json
|
@ -151,7 +151,7 @@
|
||||||
"server error or not responding": "Le serveur ne répond pas ou a rencontré une erreur",
|
"server error or not responding": "Le serveur ne répond pas ou a rencontré une erreur",
|
||||||
"Could not post comment: %s": "Impossible de poster le commentaire : %s",
|
"Could not post comment: %s": "Impossible de poster le commentaire : %s",
|
||||||
"Sending paste…": "Envoi du paste…",
|
"Sending paste…": "Envoi du paste…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd> pour copier)</span>",
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur <kbd>Ctrl</kbd>+<kbd>c</kbd> pour copier)</span>",
|
||||||
"Delete data": "Supprimer les données du paste",
|
"Delete data": "Supprimer les données du paste",
|
||||||
"Could not create paste: %s": "Impossible de créer le paste : %s",
|
"Could not create paste: %s": "Impossible de créer le paste : %s",
|
||||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Impossible de déchiffrer le paste : Clé de déchiffrement manquante dans l'URL (Avez-vous utilisé un redirecteur ou un site de réduction d'URL qui supprime une partie de l'URL ?)",
|
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Impossible de déchiffrer le paste : Clé de déchiffrement manquante dans l'URL (Avez-vous utilisé un redirecteur ou un site de réduction d'URL qui supprime une partie de l'URL ?)",
|
||||||
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "Eio",
|
"EiB": "Eio",
|
||||||
"ZiB": "Zio",
|
"ZiB": "Zio",
|
||||||
"YiB": "Yio",
|
"YiB": "Yio",
|
||||||
"kB": "ko",
|
|
||||||
"MB": "Mo",
|
|
||||||
"GB": "Go",
|
|
||||||
"TB": "To",
|
|
||||||
"PB": "Po",
|
|
||||||
"EB": "Eo",
|
|
||||||
"ZB": "Zo",
|
|
||||||
"YB": "Yo",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Texte brut",
|
"Plain Text": "Texte brut",
|
||||||
"Source Code": "Code source",
|
"Source Code": "Code source",
|
||||||
|
@ -229,11 +221,10 @@
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Erreur lors de la compression du paste, en raison du support de WebAssembly manquant.",
|
"Error compressing paste, due to missing WebAssembly support.": "Erreur lors de la compression du paste, en raison du support de WebAssembly manquant.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Erreur lors de la décompression du paste, votre navigateur ne supporte pas WebAssembly. Veuillez utiliser un autre navigateur pour voir ce paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Erreur lors de la décompression du paste, votre navigateur ne supporte pas WebAssembly. Veuillez utiliser un autre navigateur pour voir ce paste.",
|
||||||
"Start over": "Recommencer",
|
"Start over": "Recommencer",
|
||||||
"Paste copied to clipboard": "Paste copié dans le presse-papier",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Pour copier-coller appuyer sur le bouton To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Copier le lien",
|
"Copy link": "Copier le lien",
|
||||||
"Link copied to clipboard": "Lien copié dans le presse-papier",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Texte du paste",
|
"Paste text": "Texte du paste",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "La touche de tabulation sert de caractère (Presser <kbd>Ctrl</kbd>+<kbd>m</kbd> ou <kbd>Esc</kbd> pour basculer)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Thème"
|
|
||||||
}
|
}
|
||||||
|
|
137
i18n/he.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"PrivateBin": "PrivateBin",
|
"PrivateBin": "PrivateBin",
|
||||||
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s הוא שירות pastebin מקוון, מינימליסטי וקוד פתוח, שבו לשרת אין כל ידע על המידע שהודבק. הנתונים מוצפנים ומפוענחים %sבדפדפן%s באמצעות הצפנת AES ב-256 סיביות.",
|
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.",
|
||||||
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "מידע נוסף בדף <a href=\"https://privatebin.info/\">הפרויקט</a>.",
|
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "More information on the <a href=\"https://privatebin.info/\">project page</a>.",
|
||||||
"Because ignorance is bliss": "כיוון שבורות היא ברכה",
|
"Because ignorance is bliss": "כיוון שבורות היא ברכה",
|
||||||
"Paste does not exist, has expired or has been deleted.": "ההדבקה לא קיימת, פגה או נמחקה.",
|
"Paste does not exist, has expired or has been deleted.": "ההדבקה לא קיימת, פגה או נמחקה.",
|
||||||
"%s requires php %s or above to work. Sorry.": "%s דורש PHP %s כדי לפעול.",
|
"%s requires php %s or above to work. Sorry.": "%s דורש PHP %s כדי לפעול.",
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
"Create": "צור",
|
"Create": "צור",
|
||||||
"Clone": "שכפול",
|
"Clone": "שכפול",
|
||||||
"Raw text": "טקסט גולמי",
|
"Raw text": "טקסט גולמי",
|
||||||
"Expires": "יפוג ב",
|
"Expires": "Expires",
|
||||||
"Burn after reading": "קוראים-שורפים",
|
"Burn after reading": "קוראים-שורפים",
|
||||||
"Open discussion": "פתיחת דיון",
|
"Open discussion": "פתיחת דיון",
|
||||||
"Password (recommended)": "ססמה (מומלץ)",
|
"Password (recommended)": "ססמה (מומלץ)",
|
||||||
|
@ -53,11 +53,11 @@
|
||||||
],
|
],
|
||||||
"%d hours": [
|
"%d hours": [
|
||||||
"שעה אחת",
|
"שעה אחת",
|
||||||
"%d שעות",
|
"%d hours (1st plural)",
|
||||||
"%d שעות",
|
"%d hours (2nd plural)",
|
||||||
"%d שעות",
|
"%d hours (3rd plural)",
|
||||||
"%d שעות",
|
"%d hours (4th plural)",
|
||||||
"%d שעות"
|
"%d hours (5th plural)"
|
||||||
],
|
],
|
||||||
"%d days": [
|
"%d days": [
|
||||||
"יום אחד",
|
"יום אחד",
|
||||||
|
@ -94,44 +94,44 @@
|
||||||
"Never": "לעולם לא",
|
"Never": "לעולם לא",
|
||||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "הערה: זהו שירות בדקה: המידע לא ישמר.",
|
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "הערה: זהו שירות בדקה: המידע לא ישמר.",
|
||||||
"This document will expire in %d seconds.": [
|
"This document will expire in %d seconds.": [
|
||||||
"מסמך זה יפוג בעוד שנייה אחת.",
|
"This document will expire in %d second. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות."
|
"This document will expire in %d seconds. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d minutes.": [
|
"This document will expire in %d minutes.": [
|
||||||
"מסמך זה יפוג בעוד דקה אחת.",
|
"This document will expire in %d minute. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות."
|
"This document will expire in %d minutes. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d hours.": [
|
"This document will expire in %d hours.": [
|
||||||
"מסמך זה יפוג בעוד שעה אחת.",
|
"This document will expire in %d hour. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות."
|
"This document will expire in %d hours. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d days.": [
|
"This document will expire in %d days.": [
|
||||||
"מסמך זה יפוג בעוד יום אחד.",
|
"This document will expire in %d day. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים."
|
"This document will expire in %d days. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d months.": [
|
"This document will expire in %d months.": [
|
||||||
"מסמך זה יפוג בעוד חודש אחד.",
|
"This document will expire in %d month. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים."
|
"This document will expire in %d months. (5th plural)"
|
||||||
],
|
],
|
||||||
"Please enter the password for this paste:": "נא למלא את הססמה להדבקה הזו:",
|
"Please enter the password for this paste:": "נא למלא את הססמה להדבקה הזו:",
|
||||||
"Could not decrypt data (Wrong key?)": "לא ניתן לפענח את הנתונים (מפתח שגוי?)",
|
"Could not decrypt data (Wrong key?)": "לא ניתן לפענח את הנתונים (מפתח שגוי?)",
|
||||||
|
@ -164,43 +164,35 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "פורמט",
|
"Format": "פורמט",
|
||||||
"Plain Text": "טקסט פשוט",
|
"Plain Text": "טקסט פשוט",
|
||||||
"Source Code": "קוד מקור",
|
"Source Code": "קוד מקור",
|
||||||
"Markdown": "Markdown",
|
"Markdown": "Markdown",
|
||||||
"Download attachment": "הורדת קובץ מצורף",
|
"Download attachment": "הורדת קובץ מצורף",
|
||||||
"Cloned: '%s'": "שוכפל: '%s'",
|
"Cloned: '%s'": "שוכפל: '%s'",
|
||||||
"The cloned file '%s' was attached to this paste.": "הקובץ '%s' שהועתק צורף להדבקה זו.",
|
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
|
||||||
"Attach a file": "צירוף קובץ",
|
"Attach a file": "צירוף קובץ",
|
||||||
"alternatively drag & drop a file or paste an image from the clipboard": "לחלופין, ניתן לגרור ולשחרר קובץ או להדביק תמונה מהלוח.",
|
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
|
||||||
"File too large, to display a preview. Please download the attachment.": "הקובץ גדול מדי כדי להציג תצוגה מקדימה. אנא הורד את הקובץ המצורף.",
|
"File too large, to display a preview. Please download the attachment.": "File too large, to display a preview. Please download the attachment.",
|
||||||
"Remove attachment": "הסר קובץ מצורף",
|
"Remove attachment": "Remove attachment",
|
||||||
"Your browser does not support uploading encrypted files. Please use a newer browser.": "הדפדפן שלך אינו תומך בהעלאת קבצים מוצפנים. אנא השתמש בדפדפן עדכני יותר.",
|
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Your browser does not support uploading encrypted files. Please use a newer browser.",
|
||||||
"Invalid attachment.": "קובץ מצורף שגוי.",
|
"Invalid attachment.": "קובץ מצורף שגוי.",
|
||||||
"Options": "אפשרויות",
|
"Options": "אפשרויות",
|
||||||
"Shorten URL": "קיצור כתובת",
|
"Shorten URL": "קיצור כתובת",
|
||||||
"Editor": "עורך",
|
"Editor": "עורך",
|
||||||
"Preview": "תצוגה מקדימה",
|
"Preview": "תצוגה מקדימה",
|
||||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s דורש שה-PATH יסתיים ב-\"%s\". אנא עדכן את ה-PATH בקובץ index.php שלך.",
|
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
||||||
"Decrypt": "פענוח",
|
"Decrypt": "פענוח",
|
||||||
"Enter password": "נא למלא ססמה",
|
"Enter password": "נא למלא ססמה",
|
||||||
"Loading…": "בטעינה…",
|
"Loading…": "בטעינה…",
|
||||||
"Decrypting paste…": "ההדבקה מפוענחת…",
|
"Decrypting paste…": "ההדבקה מפוענחת…",
|
||||||
"Preparing new paste…": "ההדבקה החדשה בהכנות…",
|
"Preparing new paste…": "ההדבקה החדשה בהכנות…",
|
||||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "אם הודעה זו לא נעלמת, אנא עיין ב- <a href=\"%s\">שאלות נפוצות אלה למידע לפתרון בעיות</a>.",
|
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
|
||||||
"+++ no paste text +++": "+++ אין טקסט להדבקה +++",
|
"+++ no paste text +++": "+++ אין טקסט להדבקה +++",
|
||||||
"Could not get paste data: %s": "לא ניתן לקבל את נתוני ההדבקה: %s",
|
"Could not get paste data: %s": "לא ניתן לקבל את נתוני ההדבקה: %s",
|
||||||
"QR code": "קוד QR",
|
"QR code": "קוד QR",
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "האתר הזה משתמש בחיבור HTTP בלתי מאובטח! נא להשתמש בזה לבדיקות בלבד.",
|
"This website is using an insecure HTTP connection! Please use it only for testing.": "האתר הזה משתמש בחיבור HTTP בלתי מאובטח! נא להשתמש בזה לבדיקות בלבד.",
|
||||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "לפרטים נוספים <a href=\"%s\">עיין ברשומת שאלות נפוצות זו</a>.",
|
"For more information <a href=\"%s\">see this FAQ entry</a>.": "יש מידע נוסף <a href=\"%s\">ברשומה הזאת בשו״ת</a>.",
|
||||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "יכול להיות שהדפדפן שלך ידרוש חיבור HTTPS כדי לתמוך ב־API של WebCrypto. כדי לנסות <a href=\"%s\">לעבור ל־HTTPS</a>.",
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "יכול להיות שהדפדפן שלך ידרוש חיבור HTTPS כדי לתמוך ב־API של WebCrypto. כדי לנסות <a href=\"%s\">לעבור ל־HTTPS</a>.",
|
||||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "הדפדפן שלך לא תומך ב־WebAssembly שמשמש לדחיסת zlib. אפשר ליצור מסמכים בלתי מוצפנים אך אין אפשרות לקרוא מסמכים מוצפנים.",
|
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "הדפדפן שלך לא תומך ב־WebAssembly שמשמש לדחיסת zlib. אפשר ליצור מסמכים בלתי מוצפנים אך אין אפשרות לקרוא מסמכים מוצפנים.",
|
||||||
"waiting on user to provide a password": "בהמתנה למילוי הססמה מצד המשתמש",
|
"waiting on user to provide a password": "בהמתנה למילוי הססמה מצד המשתמש",
|
||||||
|
@ -217,23 +209,22 @@
|
||||||
"Close": "סגירה",
|
"Close": "סגירה",
|
||||||
"Encrypted note on %s": "%sהערה מוצפנת ב־",
|
"Encrypted note on %s": "%sהערה מוצפנת ב־",
|
||||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "נא לבקר בקישור כדי לצפות בהערה. מסירת הקישור לאנשים כלשהם תאפשר גם להם לגשת להערה.",
|
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "נא לבקר בקישור כדי לצפות בהערה. מסירת הקישור לאנשים כלשהם תאפשר גם להם לגשת להערה.",
|
||||||
"URL shortener may expose your decrypt key in URL.": "שירות קיצור כתובת URL עשוי לחשוף את מפתח הפענוח שלך בכתובת ה-URL.",
|
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||||
"Save paste": "שמור הדבקה",
|
"Save paste": "Save paste",
|
||||||
"Your IP is not authorized to create pastes.": "ה-IP שלך אינו מורשה ליצור הדבקות.",
|
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
|
||||||
"Trying to shorten a URL that isn't pointing at our instance.": "מנסים לקצר כתובת URL שאינה מצביעה על המערכת שלנו.",
|
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
|
||||||
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "שגיאה בעת קריאה ל-YOURLS. כנראה מדובר בבעיה בהגדרות, כמו \"apiurl\" או \"signature\" שגויים או חסרים.",
|
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
|
||||||
"Error parsing YOURLS response.": "שגיאה בניתוח התגובה מ-YOURLS.",
|
"Error parsing YOURLS response.": "Error parsing YOURLS response.",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "ההודעה הסודית הזו יכולה להוצג רק פעם אחת. האם תרצה לראות אותה עכשיו?",
|
"This secret message can only be displayed once. Would you like to see it now?": "This secret message can only be displayed once. Would you like to see it now?",
|
||||||
"Yes, see it": "כן, ראה אותה",
|
"Yes, see it": "Yes, see it",
|
||||||
"Dark Mode": "מצב כהה",
|
"Dark Mode": "Dark Mode",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "שגיאה בדחיסת ההדבקה, עקב חוסר תמיכה ב-WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "שגיאה בהפקת ההדבקה, הדפדפן שלך לא תומך ב-WebAssembly. אנא השתמש בדפדפן אחר כדי לצפות בהדבקה זו.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "להתחיל מחדש",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "ההדבקה הועתקה ללוח",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "על מנת להעתיק את ההדבקה, לחץ על כפתור ההעתקה או השתמש בקיצור הדרך ללוח <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "העתק קישור",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "הקישור הועתק ללוח",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "הדבק טקסט",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "משטח ה-tab פועל כמקש תו (לחץ על <kbd>Ctrl</kbd>+<kbd>m</kbd> או <kbd>Esc</kbd> להחלפה)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "נושא"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/hi.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/hu.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formátum",
|
"Format": "Formátum",
|
||||||
"Plain Text": "Egyszerű szöveg",
|
"Plain Text": "Egyszerű szöveg",
|
||||||
"Source Code": "Forráskód",
|
"Source Code": "Forráskód",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/id.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Teks Biasa",
|
"Plain Text": "Teks Biasa",
|
||||||
"Source Code": "Kode Sumber",
|
"Source Code": "Kode Sumber",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/it.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formato",
|
"Format": "Formato",
|
||||||
"Plain Text": "Solo Testo",
|
"Plain Text": "Solo Testo",
|
||||||
"Source Code": "Codice Sorgente",
|
"Source Code": "Codice Sorgente",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copia il link",
|
"Copy link": "Copia il link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Testo del messaggio",
|
"Paste text": "Testo del messaggio",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ja.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "形式",
|
"Format": "形式",
|
||||||
"Plain Text": "プレーンテキスト",
|
"Plain Text": "プレーンテキスト",
|
||||||
"Source Code": "ソースコード",
|
"Source Code": "ソースコード",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ko.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ku.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/la.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/lt.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formatas",
|
"Format": "Formatas",
|
||||||
"Plain Text": "Grynasis tekstas",
|
"Plain Text": "Grynasis tekstas",
|
||||||
"Source Code": "Pirminis kodas",
|
"Source Code": "Pirminis kodas",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
25
i18n/nl.json
|
@ -143,7 +143,7 @@
|
||||||
"Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
|
"Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
|
||||||
"Add comment": "Commentaar toevoegen",
|
"Add comment": "Commentaar toevoegen",
|
||||||
"Optional nickname…": "Optionele bijnaam…",
|
"Optional nickname…": "Optionele bijnaam…",
|
||||||
"Post comment": "Plaats commentaar",
|
"Post comment": "Plaats een commentaar",
|
||||||
"Sending comment…": "Commentaar verzenden…",
|
"Sending comment…": "Commentaar verzenden…",
|
||||||
"Comment posted.": "Commentaar geplaatst.",
|
"Comment posted.": "Commentaar geplaatst.",
|
||||||
"Could not refresh display: %s": "Kon de weergave niet vernieuwen: %s",
|
"Could not refresh display: %s": "Kon de weergave niet vernieuwen: %s",
|
||||||
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formaat",
|
"Format": "Formaat",
|
||||||
"Plain Text": "Platte tekst",
|
"Plain Text": "Platte tekst",
|
||||||
"Source Code": "Broncode",
|
"Source Code": "Broncode",
|
||||||
|
@ -228,12 +220,11 @@
|
||||||
"Dark Mode": "Donkere modus",
|
"Dark Mode": "Donkere modus",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Fout bij het comprimeren van notitie door ontbrekende ondersteuning voor WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Fout bij het comprimeren van notitie door ontbrekende ondersteuning voor WebAssembly.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Fout bij het decomprimeren van de notitie, uw browser ondersteunt WebAssembly niet. Gebruik een andere browser om deze notitie te bekijken.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Fout bij het decomprimeren van de notitie, uw browser ondersteunt WebAssembly niet. Gebruik een andere browser om deze notitie te bekijken.",
|
||||||
"Start over": "Opnieuw beginnen",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Notitie gekopieerd naar klembord",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Om te kopiëren en plakken druk je op de knop Kopiëren of gebruik je de sneltoets op het klembord <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopieer link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link gekopieerd naar klembord",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Tekst plakken",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortoets dient als teken (gebruik <kbd>Ctrl</kbd>+<kbd>m</kbd> of <kbd>Esc</kbd> om te schakelen)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/no.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Ren Tekst",
|
"Plain Text": "Ren Tekst",
|
||||||
"Source Code": "Kildekode",
|
"Source Code": "Kildekode",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/oc.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "Eio",
|
"EiB": "Eio",
|
||||||
"ZiB": "Zio",
|
"ZiB": "Zio",
|
||||||
"YiB": "Yio",
|
"YiB": "Yio",
|
||||||
"kB": "ko",
|
|
||||||
"MB": "Mo",
|
|
||||||
"GB": "Go",
|
|
||||||
"TB": "To",
|
|
||||||
"PB": "Po",
|
|
||||||
"EB": "Eo",
|
|
||||||
"ZB": "Zo",
|
|
||||||
"YB": "Yo",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Tèxte brut",
|
"Plain Text": "Tèxte brut",
|
||||||
"Source Code": "Còdi font",
|
"Source Code": "Còdi font",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
23
i18n/pl.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Czysty tekst",
|
"Plain Text": "Czysty tekst",
|
||||||
"Source Code": "Kod źródłowy",
|
"Source Code": "Kod źródłowy",
|
||||||
|
@ -228,12 +220,11 @@
|
||||||
"Dark Mode": "Ciemny motyw",
|
"Dark Mode": "Ciemny motyw",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Błąd kompresowania wklejenia przez brak obsługi WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Błąd kompresowania wklejenia przez brak obsługi WebAssembly.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Błąd dekompresowania wklejenia przez brak obsługi WebAssembly przez przeglądarkę. Użyj innej przeglądarki, aby zobaczyć to wklejenie.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Błąd dekompresowania wklejenia przez brak obsługi WebAssembly przez przeglądarkę. Użyj innej przeglądarki, aby zobaczyć to wklejenie.",
|
||||||
"Start over": "Zacznij od nowa",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Wklejka skopiowana do schowka",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Aby skopiować wklejkę, naciśnij przycisk kopiowania lub użyj skrótu schowka <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopiuj link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link został skopiowany do schowka",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Wklej tekst",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Klawisz Tabulatora służy jako znak (przytrzymaj <kbd>Ctrl</kbd>+<kbd>m</kbd> lub <kbd>Esc</kbd> aby przełączać)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Motyw"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/pt.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formato",
|
"Format": "Formato",
|
||||||
"Plain Text": "Texto sem formato",
|
"Plain Text": "Texto sem formato",
|
||||||
"Source Code": "Código fonte",
|
"Source Code": "Código fonte",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ro.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formatare",
|
"Format": "Formatare",
|
||||||
"Plain Text": "Text neformatat",
|
"Plain Text": "Text neformatat",
|
||||||
"Source Code": "Cod sursă",
|
"Source Code": "Cod sursă",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/ru.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "Эбайт",
|
"EiB": "Эбайт",
|
||||||
"ZiB": "Збайт",
|
"ZiB": "Збайт",
|
||||||
"YiB": "Йбайт",
|
"YiB": "Йбайт",
|
||||||
"kB": "кбайт",
|
|
||||||
"MB": "Мбайт",
|
|
||||||
"GB": "Гбайт",
|
|
||||||
"TB": "Тбайт",
|
|
||||||
"PB": "Пбайт",
|
|
||||||
"EB": "Эбайт",
|
|
||||||
"ZB": "Збайт",
|
|
||||||
"YB": "Йбайт",
|
|
||||||
"Format": "Формат",
|
"Format": "Формат",
|
||||||
"Plain Text": "Обычный текст",
|
"Plain Text": "Обычный текст",
|
||||||
"Source Code": "Исходный код",
|
"Source Code": "Исходный код",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Скопировать ссылку",
|
"Copy link": "Скопировать ссылку",
|
||||||
"Link copied to clipboard": "Ссылка скопирована в буфер обмена",
|
"Link copied to clipboard": "Ссылка скопирована в буфер обмена",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Тема"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/sk.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Formát",
|
"Format": "Formát",
|
||||||
"Plain Text": "Čistý text",
|
"Plain Text": "Čistý text",
|
||||||
"Source Code": "Zdrojový kód",
|
"Source Code": "Zdrojový kód",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/sl.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EB",
|
"EiB": "EB",
|
||||||
"ZiB": "ZB",
|
"ZiB": "ZB",
|
||||||
"YiB": "YB",
|
"YiB": "YB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Surov tekst",
|
"Plain Text": "Surov tekst",
|
||||||
"Source Code": "Odprta koda",
|
"Source Code": "Odprta koda",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/sv.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"Source Code": "Source Code",
|
"Source Code": "Source Code",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
21
i18n/th.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "รูปแบบ",
|
"Format": "รูปแบบ",
|
||||||
"Plain Text": "ข้อความล้วน",
|
"Plain Text": "ข้อความล้วน",
|
||||||
"Source Code": "ซอร์สโค้ด",
|
"Source Code": "ซอร์สโค้ด",
|
||||||
|
@ -229,11 +221,10 @@
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "ไม่สามารถบีบอัดข้อมูลที่คุณต้องการฝากโค้ดได้ เนื่องจากอุปกรณ์ของคุณขาดการรองรับ WebAssembly",
|
"Error compressing paste, due to missing WebAssembly support.": "ไม่สามารถบีบอัดข้อมูลที่คุณต้องการฝากโค้ดได้ เนื่องจากอุปกรณ์ของคุณขาดการรองรับ WebAssembly",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "ไม่สามารถอ่านข้อมูลที่คุณได้ฝากโค้ดไว้ เบราว์เซอร์ของคุณไม่รองรับ WebAssembly กรุณาลองเปลี่ยนใช้เบราว์เซอร์ตัวอื่นเพื่อดูการฝากโค้ดนี้อีกครั้ง",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "ไม่สามารถอ่านข้อมูลที่คุณได้ฝากโค้ดไว้ เบราว์เซอร์ของคุณไม่รองรับ WebAssembly กรุณาลองเปลี่ยนใช้เบราว์เซอร์ตัวอื่นเพื่อดูการฝากโค้ดนี้อีกครั้ง",
|
||||||
"Start over": "เริ่มใหม่",
|
"Start over": "เริ่มใหม่",
|
||||||
"Paste copied to clipboard": "คัดลอกการฝากโค้ดไปที่คลิปบอร์ดแล้ว",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "หากต้องการคัดลอกและวาง กรุณากดปุ่มคัดลอก หรือใช้ปุ่มลัด <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd> สำหรับคลิปบอร์ด",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "คัดลอกลิงก์",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "คัดลอกลิงก์ไปที่คลิปบอร์ดแล้ว",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "ฝากข้อความ",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "ปุ่ม Tabulator ใช้เป็นอักขระ (กด <kbd>Ctrl</kbd>+<kbd>m</kbd> หรือ <kbd>Esc</kbd> เพื่อสลับ)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "ธีม"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/tr.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Düz Yazı",
|
"Plain Text": "Düz Yazı",
|
||||||
"Source Code": "Kaynak Kodu",
|
"Source Code": "Kaynak Kodu",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
11
i18n/uk.json
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "Ебайт",
|
"EiB": "Ебайт",
|
||||||
"ZiB": "Збайт",
|
"ZiB": "Збайт",
|
||||||
"YiB": "Йбайт",
|
"YiB": "Йбайт",
|
||||||
"kB": "кбайт",
|
|
||||||
"MB": "Мбайт",
|
|
||||||
"GB": "Гбайт",
|
|
||||||
"TB": "Тбайт",
|
|
||||||
"PB": "Пбайт",
|
|
||||||
"EB": "Ебайт",
|
|
||||||
"ZB": "Збайт",
|
|
||||||
"YB": "Йбайт",
|
|
||||||
"Format": "Формат",
|
"Format": "Формат",
|
||||||
"Plain Text": "Звичайний текст",
|
"Plain Text": "Звичайний текст",
|
||||||
"Source Code": "Вихідний код",
|
"Source Code": "Вихідний код",
|
||||||
|
@ -234,6 +226,5 @@
|
||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
|
63
i18n/zh.json
|
@ -7,12 +7,12 @@
|
||||||
"%s requires php %s or above to work. Sorry.": "抱歉,%s 需要 PHP %s 及以上版本才能运行。",
|
"%s requires php %s or above to work. Sorry.": "抱歉,%s 需要 PHP %s 及以上版本才能运行。",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.": "%s 需要设置配置文件中的 [%s] 部分。",
|
"%s requires configuration section [%s] to be present in configuration file.": "%s 需要设置配置文件中的 [%s] 部分。",
|
||||||
"Please wait %d seconds between each post.": [
|
"Please wait %d seconds between each post.": [
|
||||||
"每 %d 秒只能创建一次粘贴。",
|
"每 %d 秒只能粘贴一次。",
|
||||||
"每 %d 秒只能创建一次粘贴。",
|
"每 %d 秒只能粘贴一次。",
|
||||||
"每 %d 秒只能创建一次粘贴。",
|
"每 %d 秒只能粘贴一次。",
|
||||||
"每 %d 秒只能创建一次粘贴。",
|
"每 %d 秒只能粘贴一次。",
|
||||||
"每 %d 秒只能创建一次粘贴。",
|
"每 %d 秒只能粘贴一次。",
|
||||||
"每 %d 秒只能创建一次粘贴。"
|
"每 %d 秒只能粘贴一次。"
|
||||||
],
|
],
|
||||||
"Paste is limited to %s of encrypted data.": "对于加密数据,上限为 %s。",
|
"Paste is limited to %s of encrypted data.": "对于加密数据,上限为 %s。",
|
||||||
"Invalid data.": "无效的数据。",
|
"Invalid data.": "无效的数据。",
|
||||||
|
@ -46,10 +46,10 @@
|
||||||
"%d minutes": [
|
"%d minutes": [
|
||||||
"%d 分钟",
|
"%d 分钟",
|
||||||
"%d 分钟",
|
"%d 分钟",
|
||||||
"%d 分钟",
|
"%d 秒",
|
||||||
"%d 分钟",
|
"%d 秒",
|
||||||
"%d 分钟",
|
"%d 秒",
|
||||||
"%d 分钟"
|
"%d 秒"
|
||||||
],
|
],
|
||||||
"%d hours": [
|
"%d hours": [
|
||||||
"%d 小时",
|
"%d 小时",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"Never": "永不过期",
|
"Never": "永不过期",
|
||||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "注意:这是一个测试服务,数据随时可能被删除。如果你滥用这个服务的话,小猫咪会死的。",
|
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "注意:这是一个测试服务,数据随时可能被删除。如果你滥用这个服务的话,小猫咪会死的。",
|
||||||
"This document will expire in %d seconds.": [
|
"This document will expire in %d seconds.": [
|
||||||
"这份文档将在 %d 秒后过期。",
|
"这份文档将在一秒后过期。",
|
||||||
"这份文档将在 %d 秒后过期。",
|
"这份文档将在 %d 秒后过期。",
|
||||||
"这份文档将在 %d 秒后过期。",
|
"这份文档将在 %d 秒后过期。",
|
||||||
"这份文档将在 %d 秒后过期。",
|
"这份文档将在 %d 秒后过期。",
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
"这份文档将在 %d 秒后过期。"
|
"这份文档将在 %d 秒后过期。"
|
||||||
],
|
],
|
||||||
"This document will expire in %d minutes.": [
|
"This document will expire in %d minutes.": [
|
||||||
"这份文档将在 %d 分钟后过期。",
|
"这份文档将在一分钟后过期。",
|
||||||
"这份文档将在 %d 分钟后过期。",
|
"这份文档将在 %d 分钟后过期。",
|
||||||
"这份文档将在 %d 分钟后过期。",
|
"这份文档将在 %d 分钟后过期。",
|
||||||
"这份文档将在 %d 分钟后过期。",
|
"这份文档将在 %d 分钟后过期。",
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
"这份文档将在 %d 分钟后过期。"
|
"这份文档将在 %d 分钟后过期。"
|
||||||
],
|
],
|
||||||
"This document will expire in %d hours.": [
|
"This document will expire in %d hours.": [
|
||||||
"这份文档将在 %d 小时后过期。",
|
"这份文档将在一小时后过期。",
|
||||||
"这份文档将在 %d 小时后过期。",
|
"这份文档将在 %d 小时后过期。",
|
||||||
"这份文档将在 %d 小时后过期。",
|
"这份文档将在 %d 小时后过期。",
|
||||||
"这份文档将在 %d 小时后过期。",
|
"这份文档将在 %d 小时后过期。",
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
"这份文档将在 %d 小时后过期。"
|
"这份文档将在 %d 小时后过期。"
|
||||||
],
|
],
|
||||||
"This document will expire in %d days.": [
|
"This document will expire in %d days.": [
|
||||||
"这份文档将在 %d 天后过期。",
|
"这份文档将在一天后过期。",
|
||||||
"这份文档将在 %d 天后过期。",
|
"这份文档将在 %d 天后过期。",
|
||||||
"这份文档将在 %d 天后过期。",
|
"这份文档将在 %d 天后过期。",
|
||||||
"这份文档将在 %d 天后过期。",
|
"这份文档将在 %d 天后过期。",
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
"这份文档将在 %d 天后过期。"
|
"这份文档将在 %d 天后过期。"
|
||||||
],
|
],
|
||||||
"This document will expire in %d months.": [
|
"This document will expire in %d months.": [
|
||||||
"这份文档将在 %d 个月后过期。",
|
"这份文档将在一个月后过期。",
|
||||||
"这份文档将在 %d 个月后过期。",
|
"这份文档将在 %d 个月后过期。",
|
||||||
"这份文档将在 %d 个月后过期。",
|
"这份文档将在 %d 个月后过期。",
|
||||||
"这份文档将在 %d 个月后过期。",
|
"这份文档将在 %d 个月后过期。",
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
"Please enter the password for this paste:": "请输入这份粘贴内容的密码:",
|
"Please enter the password for this paste:": "请输入这份粘贴内容的密码:",
|
||||||
"Could not decrypt data (Wrong key?)": "无法解密数据(密钥错误?)",
|
"Could not decrypt data (Wrong key?)": "无法解密数据(密钥错误?)",
|
||||||
"Could not delete the paste, it was not stored in burn after reading mode.": "无法删除此粘贴内容,它没有以阅后即焚模式保存。",
|
"Could not delete the paste, it was not stored in burn after reading mode.": "无法删除此粘贴内容,它没有以阅后即焚模式保存。",
|
||||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "睁大眼睛看清楚!不要关闭窗口,否则你再也见不到这条消息了。",
|
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "看!仔!细!了!不要关闭窗口,否则你再也见不到这条消息了。",
|
||||||
"Could not decrypt comment; Wrong key?": "无法解密评论;密钥错误?",
|
"Could not decrypt comment; Wrong key?": "无法解密评论;密钥错误?",
|
||||||
"Reply": "回复",
|
"Reply": "回复",
|
||||||
"Anonymous": "匿名",
|
"Anonymous": "匿名",
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
"unknown status": "未知状态",
|
"unknown status": "未知状态",
|
||||||
"server error or not responding": "服务器错误或无回应",
|
"server error or not responding": "服务器错误或无回应",
|
||||||
"Could not post comment: %s": "无法发送评论: %s",
|
"Could not post comment: %s": "无法发送评论: %s",
|
||||||
"Sending paste…": "正在发送粘贴内容…",
|
"Sending paste…": "粘贴内容提交中…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "您粘贴内容的链接是 <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(按下 <kbd>Ctrl</kbd>+<kbd>c</kbd> 以复制)</span>",
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "您粘贴内容的链接是 <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(按下 <kbd>Ctrl</kbd>+<kbd>c</kbd> 以复制)</span>",
|
||||||
"Delete data": "删除数据",
|
"Delete data": "删除数据",
|
||||||
"Could not create paste: %s": "无法创建粘贴:%s",
|
"Could not create paste: %s": "无法创建粘贴:%s",
|
||||||
|
@ -164,14 +164,6 @@
|
||||||
"EiB": "EiB",
|
"EiB": "EiB",
|
||||||
"ZiB": "ZiB",
|
"ZiB": "ZiB",
|
||||||
"YiB": "YiB",
|
"YiB": "YiB",
|
||||||
"kB": "kB",
|
|
||||||
"MB": "MB",
|
|
||||||
"GB": "GB",
|
|
||||||
"TB": "TB",
|
|
||||||
"PB": "PB",
|
|
||||||
"EB": "EB",
|
|
||||||
"ZB": "ZB",
|
|
||||||
"YB": "YB",
|
|
||||||
"Format": "格式",
|
"Format": "格式",
|
||||||
"Plain Text": "纯文本",
|
"Plain Text": "纯文本",
|
||||||
"Source Code": "源代码",
|
"Source Code": "源代码",
|
||||||
|
@ -193,8 +185,8 @@
|
||||||
"Decrypt": "解密",
|
"Decrypt": "解密",
|
||||||
"Enter password": "输入密码",
|
"Enter password": "输入密码",
|
||||||
"Loading…": "载入中…",
|
"Loading…": "载入中…",
|
||||||
"Decrypting paste…": "正在解密…",
|
"Decrypting paste…": "正在解密",
|
||||||
"Preparing new paste…": "正在准备新的粘贴内容…",
|
"Preparing new paste…": "正在准备新的粘贴内容",
|
||||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "如果此消息一直存在,请参考 <a href=\"%s\">这里的 FAQ(英文版)</a>排除故障。",
|
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "如果此消息一直存在,请参考 <a href=\"%s\">这里的 FAQ(英文版)</a>排除故障。",
|
||||||
"+++ no paste text +++": "+++ 无粘贴内容 +++",
|
"+++ no paste text +++": "+++ 无粘贴内容 +++",
|
||||||
"Could not get paste data: %s": "无法获取粘贴数据:%s",
|
"Could not get paste data: %s": "无法获取粘贴数据:%s",
|
||||||
|
@ -208,7 +200,7 @@
|
||||||
"Retry": "重试",
|
"Retry": "重试",
|
||||||
"Showing raw text…": "显示原始文字…",
|
"Showing raw text…": "显示原始文字…",
|
||||||
"Notice:": "注意:",
|
"Notice:": "注意:",
|
||||||
"This link will expire after %s.": "此链接将会在 %s 过期。",
|
"This link will expire after %s.": "这个链接将会在 %s 过期。",
|
||||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "此链接只能被访问一次,请勿使用浏览器中的返回和刷新按钮。",
|
"This link can only be accessed once, do not use back or refresh button in your browser.": "此链接只能被访问一次,请勿使用浏览器中的返回和刷新按钮。",
|
||||||
"Link:": "链接:",
|
"Link:": "链接:",
|
||||||
"Recipient may become aware of your timezone, convert time to UTC?": "收件人可能会知道您的时区,将时间转换为 UTC?",
|
"Recipient may become aware of your timezone, convert time to UTC?": "收件人可能会知道您的时区,将时间转换为 UTC?",
|
||||||
|
@ -225,15 +217,14 @@
|
||||||
"Error parsing YOURLS response.": "解析 YOURLS 响应时出错。",
|
"Error parsing YOURLS response.": "解析 YOURLS 响应时出错。",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "读取粘贴后只能在加载时显示一次。您想现在打开吗?",
|
"This secret message can only be displayed once. Would you like to see it now?": "读取粘贴后只能在加载时显示一次。您想现在打开吗?",
|
||||||
"Yes, see it": "是的,加载它",
|
"Yes, see it": "是的,加载它",
|
||||||
"Dark Mode": "夜间模式",
|
"Dark Mode": "暗黑模式",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "由于缺少 WebAssembly 支持,在压缩粘贴时出错。",
|
"Error compressing paste, due to missing WebAssembly support.": "由于缺少 WebAssembly 支持,在压缩粘贴时出错。",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "解压粘贴时出错,您的浏览器不支持 WebAssembly。请使用其他浏览器查看此粘贴。",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "解压粘贴时出错,您的浏览器不支持 WebAssembly。请使用其他浏览器查看此粘贴。",
|
||||||
"Start over": "重新开始",
|
"Start over": "重新开始",
|
||||||
"Paste copied to clipboard": "粘贴内容已复制到剪贴板",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "要复制粘贴内容,请点击复制按钮或使用快捷键 <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>。",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "复制链接",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "链接已复制到剪贴板",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "粘贴文本",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tab 键可作为字符(按 <kbd>Ctrl</kbd>+<kbd>m</kbd> 或 <kbd>Esc</kbd> 切换开关)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "主题"
|
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 253 B |
BIN
img/icon_new.png
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 157 B |
BIN
img/icon_qr.png
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 299 B |
BIN
img/icon_raw.png
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
17
js/common.js
|
@ -5,18 +5,19 @@ global.assert = require('assert');
|
||||||
global.jsc = require('jsverify');
|
global.jsc = require('jsverify');
|
||||||
global.jsdom = require('jsdom-global');
|
global.jsdom = require('jsdom-global');
|
||||||
global.cleanup = global.jsdom();
|
global.cleanup = global.jsdom();
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
global.fs = require('fs');
|
global.fs = require('fs');
|
||||||
global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
||||||
|
|
||||||
// application libraries to test
|
// application libraries to test
|
||||||
global.$ = global.jQuery = require('./jquery-3.7.1');
|
global.$ = global.jQuery = require('./jquery-3.7.1');
|
||||||
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
|
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
|
||||||
global.zlib = require('./zlib-1.3.1-1').zlib;
|
global.zlib = require('./zlib-1.3.1').zlib;
|
||||||
require('./prettify');
|
require('./prettify');
|
||||||
global.prettyPrint = window.PR.prettyPrint;
|
global.prettyPrint = window.PR.prettyPrint;
|
||||||
global.prettyPrintOne = window.PR.prettyPrintOne;
|
global.prettyPrintOne = window.PR.prettyPrintOne;
|
||||||
global.showdown = require('./showdown-2.1.0');
|
global.showdown = require('./showdown-2.1.0');
|
||||||
global.DOMPurify = require('./purify-3.2.6');
|
global.DOMPurify = require('./purify-3.2.4');
|
||||||
global.baseX = require('./base-x-4.0.0').baseX;
|
global.baseX = require('./base-x-4.0.0').baseX;
|
||||||
global.Legacy = require('./legacy').Legacy;
|
global.Legacy = require('./legacy').Legacy;
|
||||||
require('./bootstrap-3.4.1');
|
require('./bootstrap-3.4.1');
|
||||||
|
@ -78,16 +79,8 @@ function parseMime(line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// common testing helper functions
|
// common testing helper functions
|
||||||
// as of jsDOM 22 the base64 functions provided in the DOM are more restrictive
|
exports.atob = atob;
|
||||||
// than browser implementation and throw when being passed invalid unicode
|
exports.btoa = btoa;
|
||||||
// codepoints - as we use these in the encryption with binary data, we need
|
|
||||||
// these to be character encoding agnostic
|
|
||||||
exports.atob = function(encoded) {
|
|
||||||
return Buffer.from(encoded, 'base64').toString('binary');
|
|
||||||
}
|
|
||||||
exports.btoa = function(text) {
|
|
||||||
return Buffer.from(text, 'binary').toString('base64');
|
|
||||||
}
|
|
||||||
|
|
||||||
// provides random lowercase characters from a to z
|
// provides random lowercase characters from a to z
|
||||||
exports.jscA2zString = function() {
|
exports.jscA2zString = function() {
|
||||||
|
|
1992
js/package-lock.json
generated
|
@ -1,16 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "privatebin",
|
"name": "privatebin",
|
||||||
"version": "1.7.8",
|
"version": "1.7.6",
|
||||||
"description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).",
|
"description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).",
|
||||||
"main": "privatebin.js",
|
"main": "privatebin.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
"test": "test"
|
"test": "test"
|
||||||
},
|
},
|
||||||
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@peculiar/webcrypto": "^1.5.0",
|
"jsdom": "^9.12.0",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom-global": "^2.1.1",
|
||||||
"jsdom-global": "^3.0.2",
|
"jsdom-url": "^2.2.1",
|
||||||
"jsverify": "^0.8.3"
|
"jsverify": "^0.8.3",
|
||||||
|
"@peculiar/webcrypto": "^1.1.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
|
|
574
js/privatebin.js
|
@ -58,6 +58,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
const purifyHtmlConfig = {
|
const purifyHtmlConfig = {
|
||||||
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
|
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
|
||||||
|
SAFE_FOR_JQUERY: true,
|
||||||
USE_PROFILES: {
|
USE_PROFILES: {
|
||||||
html: true
|
html: true
|
||||||
}
|
}
|
||||||
|
@ -591,32 +592,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
return expirationDate;
|
return expirationDate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert Bytes to KiB/MiB/GiB
|
|
||||||
*
|
|
||||||
* @name Helper.formatBytes
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* @param {number} bytes
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
me.formatBytes = function (bytes)
|
|
||||||
{
|
|
||||||
let result = '';
|
|
||||||
const kilobyte = 1024;
|
|
||||||
const decimalPoint = 2;
|
|
||||||
const sizes = [I18n._('B'), I18n._('KiB'), I18n._('MiB'), I18n._('GiB')];
|
|
||||||
const index = Math.floor(Math.log(bytes) / Math.log(kilobyte));
|
|
||||||
|
|
||||||
if (bytes > 0) {
|
|
||||||
result = parseFloat((bytes / Math.pow(kilobyte, index)).toFixed(decimalPoint)) + ' ' + sizes[index];
|
|
||||||
} else {
|
|
||||||
result = `0 ${I18n._('B')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resets state, used for unit testing
|
* resets state, used for unit testing
|
||||||
*
|
*
|
||||||
|
@ -628,17 +603,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
baseUri = null;
|
baseUri = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* check if bootstrap5 object detected
|
|
||||||
*
|
|
||||||
* @name Helper.isBootstrap5
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
me.isBootstrap5 = function ()
|
|
||||||
{
|
|
||||||
return typeof bootstrap !== 'undefined';
|
|
||||||
};
|
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -2330,19 +2294,26 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.requestLoadConfirmation = function()
|
me.requestLoadConfirmation = function()
|
||||||
{
|
{
|
||||||
const $loadconfirmmodal = $('#loadconfirmmodal');
|
const $loadconfirmmodal = $('#loadconfirmmodal');
|
||||||
|
if ($loadconfirmmodal.length > 0) {
|
||||||
const $loadconfirmOpenNow = $loadconfirmmodal.find('#loadconfirm-open-now');
|
const $loadconfirmOpenNow = $loadconfirmmodal.find('#loadconfirm-open-now');
|
||||||
$loadconfirmOpenNow.off('click.loadPaste');
|
$loadconfirmOpenNow.off('click.loadPaste');
|
||||||
$loadconfirmOpenNow.on('click.loadPaste', PasteDecrypter.run);
|
$loadconfirmOpenNow.on('click.loadPaste', PasteDecrypter.run);
|
||||||
|
const $loadconfirmClose = $loadconfirmmodal.find('.close');
|
||||||
const $loadconfirmClose = $loadconfirmmodal.find('.close');
|
$loadconfirmClose.off('click.close');
|
||||||
$loadconfirmClose.off('click.close');
|
$loadconfirmClose.on('click.close', Controller.newPaste);
|
||||||
$loadconfirmClose.on('click.close', Controller.newPaste);
|
if (typeof bootstrap !== 'undefined' && bootstrap.Tooltip.VERSION) {
|
||||||
|
(new bootstrap.Modal($loadconfirmmodal[0])).show();
|
||||||
if (typeof bootstrap !== 'undefined' && bootstrap.Tooltip.VERSION) {
|
} else {
|
||||||
(new bootstrap.Modal($loadconfirmmodal[0])).show();
|
$loadconfirmmodal.modal('show');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$loadconfirmmodal.modal('show');
|
if (window.confirm(
|
||||||
|
I18n._('This secret message can only be displayed once. Would you like to see it now?')
|
||||||
|
)) {
|
||||||
|
PasteDecrypter.run();
|
||||||
|
} else {
|
||||||
|
Controller.newPaste();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2364,6 +2335,15 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fallback to old method for page template
|
||||||
|
password = prompt(I18n._('Please enter the password for this paste:'), '');
|
||||||
|
if (password === null) {
|
||||||
|
throw 'password prompt canceled';
|
||||||
|
}
|
||||||
|
if (password.length === 0) {
|
||||||
|
// recurse…
|
||||||
|
return me.requestPassword();
|
||||||
|
}
|
||||||
PasteDecrypter.run();
|
PasteDecrypter.run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2557,18 +2537,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// show preview
|
// show preview
|
||||||
PasteViewer.setText($message.val());
|
PasteViewer.setText($message.val());
|
||||||
if (AttachmentViewer.hasAttachmentData()) {
|
if (AttachmentViewer.hasAttachmentData()) {
|
||||||
const attachmentsData = AttachmentViewer.getAttachmentsData();
|
const attachment = AttachmentViewer.getAttachment();
|
||||||
|
AttachmentViewer.handleBlobAttachmentPreview(
|
||||||
attachmentsData.forEach(attachmentData => {
|
AttachmentViewer.getAttachmentPreview(),
|
||||||
const mimeType = AttachmentViewer.getAttachmentMimeType(attachmentData);
|
attachment[0], attachment[1]
|
||||||
|
);
|
||||||
AttachmentViewer.handleBlobAttachmentPreview(
|
|
||||||
AttachmentViewer.getAttachmentPreview(),
|
|
||||||
attachmentData, mimeType
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
AttachmentViewer.showAttachment();
|
|
||||||
}
|
}
|
||||||
PasteViewer.run();
|
PasteViewer.run();
|
||||||
|
|
||||||
|
@ -2953,12 +2926,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
const AttachmentViewer = (function () {
|
const AttachmentViewer = (function () {
|
||||||
const me = {};
|
const me = {};
|
||||||
|
|
||||||
let $attachmentPreview,
|
let $attachmentLink,
|
||||||
|
$attachmentPreview,
|
||||||
$attachment,
|
$attachment,
|
||||||
attachmentsData = [],
|
attachmentData,
|
||||||
files,
|
file,
|
||||||
$fileInput,
|
$fileInput,
|
||||||
$dragAndDropFileNames,
|
$dragAndDropFileName,
|
||||||
|
attachmentHasPreview = false,
|
||||||
$dropzone;
|
$dropzone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3000,30 +2975,26 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.setAttachment = function(attachmentData, fileName)
|
me.setAttachment = function(attachmentData, fileName)
|
||||||
{
|
{
|
||||||
// skip, if attachments got disabled
|
// skip, if attachments got disabled
|
||||||
if (!$attachment || !$attachmentPreview) return;
|
if (!$attachmentLink || !$attachmentPreview) return;
|
||||||
|
|
||||||
// data URI format: data:[<mimeType>][;base64],<data>
|
// data URI format: data:[<mimeType>][;base64],<data>
|
||||||
|
|
||||||
const template = Model.getTemplate('attachment');
|
|
||||||
const attachmentLink = template.find('a');
|
|
||||||
|
|
||||||
// position in data URI string of where data begins
|
// position in data URI string of where data begins
|
||||||
const base64Start = attachmentData.indexOf(',') + 1;
|
const base64Start = attachmentData.indexOf(',') + 1;
|
||||||
|
// position in data URI string of where mimeType ends
|
||||||
|
const mimeTypeEnd = attachmentData.indexOf(';');
|
||||||
|
|
||||||
const mimeType = me.getAttachmentMimeType(attachmentData);
|
// extract mimeType
|
||||||
|
const mimeType = attachmentData.substring(5, mimeTypeEnd);
|
||||||
// extract data and convert to binary
|
// extract data and convert to binary
|
||||||
const rawData = attachmentData.substring(base64Start);
|
const rawData = attachmentData.substring(base64Start);
|
||||||
const decodedData = rawData.length > 0 ? atob(rawData) : '';
|
const decodedData = rawData.length > 0 ? atob(rawData) : '';
|
||||||
|
|
||||||
let blobUrl = getBlobUrl(decodedData, mimeType);
|
let blobUrl = getBlobUrl(decodedData, mimeType);
|
||||||
attachmentLink.attr('href', blobUrl);
|
$attachmentLink.attr('href', blobUrl);
|
||||||
|
|
||||||
if (typeof fileName !== 'undefined') {
|
if (typeof fileName !== 'undefined') {
|
||||||
attachmentLink.attr('download', fileName);
|
$attachmentLink.attr('download', fileName);
|
||||||
|
|
||||||
const fileSize = Helper.formatBytes(decodedData.length);
|
|
||||||
template.append(`(${fileName}, ${fileSize})`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitize SVG preview
|
// sanitize SVG preview
|
||||||
|
@ -3038,9 +3009,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
blobUrl = getBlobUrl(sanitizedData, mimeType);
|
blobUrl = getBlobUrl(sanitizedData, mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
template.removeClass('hidden');
|
|
||||||
$attachment.append(template);
|
|
||||||
|
|
||||||
me.handleBlobAttachmentPreview($attachmentPreview, blobUrl, mimeType);
|
me.handleBlobAttachmentPreview($attachmentPreview, blobUrl, mimeType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3057,7 +3025,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
|
|
||||||
$attachment.removeClass('hidden');
|
$attachment.removeClass('hidden');
|
||||||
|
|
||||||
if (me.hasAttachmentPreview()) {
|
if (attachmentHasPreview) {
|
||||||
$attachmentPreview.removeClass('hidden');
|
$attachmentPreview.removeClass('hidden');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3078,9 +3046,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
}
|
}
|
||||||
me.hideAttachment();
|
me.hideAttachment();
|
||||||
me.hideAttachmentPreview();
|
me.hideAttachmentPreview();
|
||||||
$attachment.html('');
|
$attachmentLink.removeAttr('href');
|
||||||
|
$attachmentLink.removeAttr('download');
|
||||||
|
$attachmentLink.off('click');
|
||||||
$attachmentPreview.html('');
|
$attachmentPreview.html('');
|
||||||
$dragAndDropFileNames.html('');
|
$dragAndDropFileName.text('');
|
||||||
|
|
||||||
AttachmentViewer.removeAttachmentData();
|
AttachmentViewer.removeAttachmentData();
|
||||||
};
|
};
|
||||||
|
@ -3095,8 +3065,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
me.removeAttachmentData = function()
|
me.removeAttachmentData = function()
|
||||||
{
|
{
|
||||||
files = undefined;
|
file = undefined;
|
||||||
attachmentsData = [];
|
attachmentData = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3107,21 +3077,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
me.clearDragAndDrop = function()
|
me.clearDragAndDrop = function()
|
||||||
{
|
{
|
||||||
$dragAndDropFileNames.html('');
|
$dragAndDropFileName.text('');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Print file names added via drag & drop
|
|
||||||
*
|
|
||||||
* @name AttachmentViewer.printDragAndDropFileNames
|
|
||||||
* @private
|
|
||||||
* @function
|
|
||||||
* @param {array} fileNames
|
|
||||||
*/
|
|
||||||
function printDragAndDropFileNames(fileNames) {
|
|
||||||
$dragAndDropFileNames.html(fileNames.join("<br>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hides the attachment
|
* hides the attachment
|
||||||
*
|
*
|
||||||
|
@ -3150,18 +3108,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* checks if has any attachment preview
|
|
||||||
*
|
|
||||||
* @name AttachmentViewer.hasAttachmentPreview
|
|
||||||
* @function
|
|
||||||
* @return {JQuery}
|
|
||||||
*/
|
|
||||||
me.hasAttachmentPreview = function()
|
|
||||||
{
|
|
||||||
return $attachmentPreview.children().length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if there is an attachment displayed
|
* checks if there is an attachment displayed
|
||||||
*
|
*
|
||||||
|
@ -3173,7 +3119,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
if (!$attachment.length) {
|
if (!$attachment.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return [...$attachment.children()].length > 0;
|
const link = $attachmentLink.prop('href');
|
||||||
|
return (typeof link !== 'undefined' && link !== '');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3193,38 +3140,20 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the attachments
|
* return the attachment
|
||||||
*
|
*
|
||||||
* @name AttachmentViewer.getAttachments
|
* @name AttachmentViewer.getAttachment
|
||||||
* @function
|
* @function
|
||||||
* @returns {array}
|
* @returns {array}
|
||||||
*/
|
*/
|
||||||
me.getAttachments = function()
|
me.getAttachment = function()
|
||||||
{
|
{
|
||||||
return [...$attachment.find('a')].map(link => (
|
return [
|
||||||
[
|
$attachmentLink.prop('href'),
|
||||||
$(link).prop('href'),
|
$attachmentLink.prop('download')
|
||||||
$(link).prop('download')
|
];
|
||||||
]
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get attachment mime type
|
|
||||||
*
|
|
||||||
* @name AttachmentViewer.getAttachmentMimeType
|
|
||||||
* @function
|
|
||||||
* @param {string} attachmentData - Base64 string
|
|
||||||
*/
|
|
||||||
me.getAttachmentMimeType = function(attachmentData)
|
|
||||||
{
|
|
||||||
// position in data URI string of where mimeType ends
|
|
||||||
const mimeTypeEnd = attachmentData.indexOf(';');
|
|
||||||
|
|
||||||
// extract mimeType
|
|
||||||
return attachmentData.substring(5, mimeTypeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* moves the attachment link to another element
|
* moves the attachment link to another element
|
||||||
*
|
*
|
||||||
|
@ -3233,36 +3162,27 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @name AttachmentViewer.moveAttachmentTo
|
* @name AttachmentViewer.moveAttachmentTo
|
||||||
* @function
|
* @function
|
||||||
* @param {jQuery} $element - the wrapper/container element where this should be moved to
|
* @param {jQuery} $element - the wrapper/container element where this should be moved to
|
||||||
* @param {array} attachment - attachment data
|
|
||||||
* @param {string} label - the text to show (%s will be replaced with the file name), will automatically be translated
|
* @param {string} label - the text to show (%s will be replaced with the file name), will automatically be translated
|
||||||
*/
|
*/
|
||||||
me.moveAttachmentTo = function($element, attachment, label)
|
me.moveAttachmentTo = function($element, label)
|
||||||
{
|
{
|
||||||
const attachmentLink = $(document.createElement('a'))
|
|
||||||
.addClass('alert-link')
|
|
||||||
.prop('href', attachment[0])
|
|
||||||
.prop('download', attachment[1]);
|
|
||||||
|
|
||||||
// move elemement to new place
|
// move elemement to new place
|
||||||
attachmentLink.appendTo($element);
|
$attachmentLink.appendTo($element);
|
||||||
|
|
||||||
// update text - ensuring no HTML is inserted into the text node
|
// update text - ensuring no HTML is inserted into the text node
|
||||||
I18n._(attachmentLink, label, attachment[1]);
|
I18n._($attachmentLink, label, $attachmentLink.attr('download'));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read files data as data URL using the FileReader API
|
* read file data as data URL using the FileReader API
|
||||||
*
|
*
|
||||||
* @name AttachmentViewer.readFileData
|
* @name AttachmentViewer.readFileData
|
||||||
* @private
|
* @private
|
||||||
* @function
|
* @function
|
||||||
* @param {FileList[]} loadedFiles (optional) loaded files array
|
* @param {object} loadedFile (optional) loaded file object
|
||||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader#readAsDataURL()}
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader#readAsDataURL()}
|
||||||
*/
|
*/
|
||||||
function readFileData(loadedFiles) {
|
function readFileData(loadedFile) {
|
||||||
// Clear old cache
|
|
||||||
me.removeAttachmentData();
|
|
||||||
|
|
||||||
if (typeof FileReader === 'undefined') {
|
if (typeof FileReader === 'undefined') {
|
||||||
// revert loading status…
|
// revert loading status…
|
||||||
me.hideAttachment();
|
me.hideAttachment();
|
||||||
|
@ -3271,35 +3191,28 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadedFiles === undefined) {
|
const fileReader = new FileReader();
|
||||||
loadedFiles = [...$fileInput[0].files];
|
if (loadedFile === undefined) {
|
||||||
me.clearDragAndDrop();
|
loadedFile = $fileInput[0].files[0];
|
||||||
|
$dragAndDropFileName.text('');
|
||||||
} else {
|
} else {
|
||||||
const fileNames = loadedFiles.map((loadedFile => loadedFile.name));
|
$dragAndDropFileName.text(loadedFile.name);
|
||||||
printDragAndDropFileNames(fileNames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof loadedFiles !== 'undefined') {
|
if (typeof loadedFile !== 'undefined') {
|
||||||
files = loadedFiles;
|
file = loadedFile;
|
||||||
loadedFiles.forEach((loadedFile, index) => {
|
fileReader.onload = function (event) {
|
||||||
const fileReader = new FileReader();
|
const dataURL = event.target.result;
|
||||||
|
attachmentData = dataURL;
|
||||||
|
|
||||||
fileReader.onload = function (event) {
|
if (Editor.isPreview()) {
|
||||||
const dataURL = event.target.result;
|
me.handleAttachmentPreview($attachmentPreview, dataURL);
|
||||||
if (dataURL) {
|
$attachmentPreview.removeClass('hidden');
|
||||||
attachmentsData[index] = dataURL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (Editor.isPreview()) {
|
TopNav.highlightFileupload();
|
||||||
me.handleAttachmentPreview($attachmentPreview, dataURL);
|
};
|
||||||
$attachmentPreview.removeClass('hidden');
|
fileReader.readAsDataURL(loadedFile);
|
||||||
}
|
|
||||||
|
|
||||||
TopNav.highlightFileupload();
|
|
||||||
};
|
|
||||||
|
|
||||||
fileReader.readAsDataURL(loadedFile);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
me.removeAttachmentData();
|
me.removeAttachmentData();
|
||||||
}
|
}
|
||||||
|
@ -3315,17 +3228,16 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @argument {string} mime type
|
* @argument {string} mime type
|
||||||
*/
|
*/
|
||||||
me.handleBlobAttachmentPreview = function ($targetElement, blobUrl, mimeType) {
|
me.handleBlobAttachmentPreview = function ($targetElement, blobUrl, mimeType) {
|
||||||
const alreadyIncludesCurrentAttachment = $targetElement.find(`[src='${blobUrl}']`).length > 0;
|
if (blobUrl) {
|
||||||
|
attachmentHasPreview = true;
|
||||||
if (blobUrl && !alreadyIncludesCurrentAttachment) {
|
|
||||||
if (mimeType.match(/^image\//i)) {
|
if (mimeType.match(/^image\//i)) {
|
||||||
$targetElement.append(
|
$targetElement.html(
|
||||||
$(document.createElement('img'))
|
$(document.createElement('img'))
|
||||||
.attr('src', blobUrl)
|
.attr('src', blobUrl)
|
||||||
.attr('class', 'img-thumbnail')
|
.attr('class', 'img-thumbnail')
|
||||||
);
|
);
|
||||||
} else if (mimeType.match(/^video\//i)) {
|
} else if (mimeType.match(/^video\//i)) {
|
||||||
$targetElement.append(
|
$targetElement.html(
|
||||||
$(document.createElement('video'))
|
$(document.createElement('video'))
|
||||||
.attr('controls', 'true')
|
.attr('controls', 'true')
|
||||||
.attr('autoplay', 'true')
|
.attr('autoplay', 'true')
|
||||||
|
@ -3336,7 +3248,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
.attr('src', blobUrl))
|
.attr('src', blobUrl))
|
||||||
);
|
);
|
||||||
} else if (mimeType.match(/^audio\//i)) {
|
} else if (mimeType.match(/^audio\//i)) {
|
||||||
$targetElement.append(
|
$targetElement.html(
|
||||||
$(document.createElement('audio'))
|
$(document.createElement('audio'))
|
||||||
.attr('controls', 'true')
|
.attr('controls', 'true')
|
||||||
.attr('autoplay', 'true')
|
.attr('autoplay', 'true')
|
||||||
|
@ -3349,13 +3261,15 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// Fallback for browsers, that don't support the vh unit
|
// Fallback for browsers, that don't support the vh unit
|
||||||
const clientHeight = $(window).height();
|
const clientHeight = $(window).height();
|
||||||
|
|
||||||
$targetElement.append(
|
$targetElement.html(
|
||||||
$(document.createElement('embed'))
|
$(document.createElement('embed'))
|
||||||
.attr('src', blobUrl)
|
.attr('src', blobUrl)
|
||||||
.attr('type', 'application/pdf')
|
.attr('type', 'application/pdf')
|
||||||
.attr('class', 'pdfPreview')
|
.attr('class', 'pdfPreview')
|
||||||
.css('height', clientHeight)
|
.css('height', clientHeight)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
attachmentHasPreview = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3388,14 +3302,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fileInput) {
|
if ($fileInput) {
|
||||||
const files = [...evt.dataTransfer.files];
|
const file = evt.dataTransfer.files[0];
|
||||||
//Clear the file input:
|
//Clear the file input:
|
||||||
$fileInput.wrap('<form>').closest('form').get(0).reset();
|
$fileInput.wrap('<form>').closest('form').get(0).reset();
|
||||||
$fileInput.unwrap();
|
$fileInput.unwrap();
|
||||||
//Only works in Chrome:
|
//Only works in Chrome:
|
||||||
//fileInput[0].files = e.dataTransfer.files;
|
//fileInput[0].files = e.dataTransfer.files;
|
||||||
|
|
||||||
readFileData(files);
|
readFileData(file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3432,17 +3346,16 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
function addClipboardEventHandler() {
|
function addClipboardEventHandler() {
|
||||||
$(document).on('paste', function (event) {
|
$(document).on('paste', function (event) {
|
||||||
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||||
const files = [...items]
|
const lastItem = items[items.length - 1];
|
||||||
.filter(item => item.kind === 'file')
|
if (lastItem.kind === 'file') {
|
||||||
.map(item => item.getAsFile());
|
if (TopNav.isAttachmentReadonly()) {
|
||||||
|
event.stopPropagation();
|
||||||
if (TopNav.isAttachmentReadonly()) {
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
return false;
|
||||||
event.preventDefault();
|
} else {
|
||||||
return false;
|
readFileData(lastItem.getAsFile());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readFileData(files);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3450,12 +3363,23 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
/**
|
/**
|
||||||
* getter for attachment data
|
* getter for attachment data
|
||||||
*
|
*
|
||||||
* @name AttachmentViewer.getAttachmentsData
|
* @name AttachmentViewer.getAttachmentData
|
||||||
* @function
|
* @function
|
||||||
* @return {string[]}
|
* @return {jQuery}
|
||||||
*/
|
*/
|
||||||
me.getAttachmentsData = function () {
|
me.getAttachmentData = function () {
|
||||||
return attachmentsData;
|
return attachmentData;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getter for attachment link
|
||||||
|
*
|
||||||
|
* @name AttachmentViewer.getAttachmentLink
|
||||||
|
* @function
|
||||||
|
* @return {jQuery}
|
||||||
|
*/
|
||||||
|
me.getAttachmentLink = function () {
|
||||||
|
return $attachmentLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3470,14 +3394,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getter for files data, returns the file list
|
* getter for file data, returns the file contents
|
||||||
*
|
*
|
||||||
* @name AttachmentViewer.getFiles
|
* @name AttachmentViewer.getFile
|
||||||
* @function
|
* @function
|
||||||
* @return {FileList[]}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
me.getFiles = function () {
|
me.getFile = function () {
|
||||||
return files;
|
return file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3491,8 +3415,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.init = function()
|
me.init = function()
|
||||||
{
|
{
|
||||||
$attachment = $('#attachment');
|
$attachment = $('#attachment');
|
||||||
$dragAndDropFileNames = $('#dragAndDropFileName');
|
$dragAndDropFileName = $('#dragAndDropFileName');
|
||||||
$dropzone = $('#dropzone');
|
$dropzone = $('#dropzone');
|
||||||
|
$attachmentLink = $('#attachment a') || $('<a>');
|
||||||
if($attachment.length) {
|
if($attachment.length) {
|
||||||
$attachmentPreview = $('#attachmentPreview');
|
$attachmentPreview = $('#attachmentPreview');
|
||||||
|
|
||||||
|
@ -3553,12 +3478,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
{
|
{
|
||||||
const $source = $(event.target);
|
const $source = $(event.target);
|
||||||
|
|
||||||
// show all reply buttons
|
|
||||||
$commentContainer.find('button').removeClass('hidden');
|
|
||||||
|
|
||||||
// hide the current reply button
|
|
||||||
$source.addClass('hidden');
|
|
||||||
|
|
||||||
// clear input
|
// clear input
|
||||||
$replyMessage.val('');
|
$replyMessage.val('');
|
||||||
$replyNickname.val('');
|
$replyNickname.val('');
|
||||||
|
@ -4014,26 +3933,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
function setLanguage(event)
|
function setLanguage(event)
|
||||||
{
|
{
|
||||||
let lang = $(event.target).data('lang') || event.target.value;
|
document.cookie = 'lang=' + $(event.target).data('lang') + '; SameSite=Lax; Secure';
|
||||||
|
|
||||||
document.cookie = 'lang=' + lang + '; SameSite=Lax; Secure';
|
|
||||||
window.location.reload();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* save the template in a cookie and reloads the page
|
|
||||||
*
|
|
||||||
* @name TopNav.setTemplate
|
|
||||||
* @private
|
|
||||||
* @function
|
|
||||||
* @param {Event} event
|
|
||||||
*/
|
|
||||||
function setTemplate(event)
|
|
||||||
{
|
|
||||||
let template = $(event.target).data('template') || event.target.value;
|
|
||||||
|
|
||||||
document.cookie = 'template=' + template + '; SameSite=Lax; Secure';
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -4189,42 +4089,59 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
expirationDateRoundedToSecond.setUTCSeconds(0);
|
expirationDateRoundedToSecond.setUTCSeconds(0);
|
||||||
|
|
||||||
const $emailconfirmmodal = $('#emailconfirmmodal');
|
const $emailconfirmmodal = $('#emailconfirmmodal');
|
||||||
if (expirationDate !== null) {
|
if ($emailconfirmmodal.length > 0) {
|
||||||
const $emailconfirmTimezoneCurrent = $emailconfirmmodal.find('#emailconfirm-timezone-current');
|
if (expirationDate !== null) {
|
||||||
const $emailconfirmTimezoneUtc = $emailconfirmmodal.find('#emailconfirm-timezone-utc');
|
const $emailconfirmTimezoneCurrent = $emailconfirmmodal.find('#emailconfirm-timezone-current');
|
||||||
let localeConfiguration = { dateStyle: 'long', timeStyle: 'long' };
|
const $emailconfirmTimezoneUtc = $emailconfirmmodal.find('#emailconfirm-timezone-utc');
|
||||||
const bootstrap5EmailConfirmModal = typeof bootstrap !== 'undefined' && bootstrap.Tooltip.VERSION ?
|
let localeConfiguration = { dateStyle: 'long', timeStyle: 'long' };
|
||||||
new bootstrap.Modal($emailconfirmmodal[0]) : null;
|
const bootstrap5EmailConfirmModal = typeof bootstrap !== 'undefined' && bootstrap.Tooltip.VERSION ?
|
||||||
|
new bootstrap.Modal($emailconfirmmodal[0]) : null;
|
||||||
|
|
||||||
function sendEmailAndHideModal() {
|
function sendEmailAndHideModal() {
|
||||||
const emailBody = templateEmailBody(
|
const emailBody = templateEmailBody(
|
||||||
// we don't use Date.prototype.toUTCString() because we would like to avoid GMT
|
// we don't use Date.prototype.toUTCString() because we would like to avoid GMT
|
||||||
expirationDateRoundedToSecond.toLocaleString(
|
expirationDateRoundedToSecond.toLocaleString(
|
||||||
[], localeConfiguration
|
[], localeConfiguration
|
||||||
), isBurnafterreading
|
), isBurnafterreading
|
||||||
);
|
);
|
||||||
|
if (bootstrap5EmailConfirmModal) {
|
||||||
|
bootstrap5EmailConfirmModal.hide();
|
||||||
|
} else {
|
||||||
|
$emailconfirmmodal.modal('hide');
|
||||||
|
}
|
||||||
|
triggerEmailSend(emailBody);
|
||||||
|
};
|
||||||
|
|
||||||
|
$emailconfirmTimezoneCurrent.off('click.sendEmailCurrentTimezone');
|
||||||
|
$emailconfirmTimezoneCurrent.on('click.sendEmailCurrentTimezone', sendEmailAndHideModal);
|
||||||
|
$emailconfirmTimezoneUtc.off('click.sendEmailUtcTimezone');
|
||||||
|
$emailconfirmTimezoneUtc.on('click.sendEmailUtcTimezone', () => {
|
||||||
|
localeConfiguration.timeZone = 'UTC';
|
||||||
|
sendEmailAndHideModal();
|
||||||
|
});
|
||||||
if (bootstrap5EmailConfirmModal) {
|
if (bootstrap5EmailConfirmModal) {
|
||||||
bootstrap5EmailConfirmModal.hide();
|
bootstrap5EmailConfirmModal.show();
|
||||||
} else {
|
} else {
|
||||||
$emailconfirmmodal.modal('hide');
|
$emailconfirmmodal.modal('show');
|
||||||
}
|
}
|
||||||
triggerEmailSend(emailBody);
|
|
||||||
};
|
|
||||||
|
|
||||||
$emailconfirmTimezoneCurrent.off('click.sendEmailCurrentTimezone');
|
|
||||||
$emailconfirmTimezoneCurrent.on('click.sendEmailCurrentTimezone', sendEmailAndHideModal);
|
|
||||||
$emailconfirmTimezoneUtc.off('click.sendEmailUtcTimezone');
|
|
||||||
$emailconfirmTimezoneUtc.on('click.sendEmailUtcTimezone', () => {
|
|
||||||
localeConfiguration.timeZone = 'UTC';
|
|
||||||
sendEmailAndHideModal();
|
|
||||||
});
|
|
||||||
if (bootstrap5EmailConfirmModal) {
|
|
||||||
bootstrap5EmailConfirmModal.show();
|
|
||||||
} else {
|
} else {
|
||||||
$emailconfirmmodal.modal('show');
|
triggerEmailSend(templateEmailBody(null, isBurnafterreading));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
triggerEmailSend(templateEmailBody(null, isBurnafterreading));
|
let emailBody = '';
|
||||||
|
if (expirationDate !== null) {
|
||||||
|
const expirationDateString = window.confirm(
|
||||||
|
I18n._('Recipient may become aware of your timezone, convert time to UTC?')
|
||||||
|
) ? expirationDateRoundedToSecond.toLocaleString(
|
||||||
|
undefined,
|
||||||
|
// we don't use Date.prototype.toUTCString() because we would like to avoid GMT
|
||||||
|
{ timeZone: 'UTC', dateStyle: 'long', timeStyle: 'long' }
|
||||||
|
) : expirationDateRoundedToSecond.toLocaleString();
|
||||||
|
emailBody = templateEmailBody(expirationDateString, isBurnafterreading);
|
||||||
|
} else {
|
||||||
|
emailBody = templateEmailBody(null, isBurnafterreading);
|
||||||
|
}
|
||||||
|
triggerEmailSend(emailBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4643,11 +4560,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// visually indicate file uploaded
|
// visually indicate file uploaded
|
||||||
const $attachDropdownToggle = $attach.children('.dropdown-toggle');
|
const $attachDropdownToggle = $attach.children('.dropdown-toggle');
|
||||||
if ($attachDropdownToggle.attr('aria-expanded') === 'false') {
|
if ($attachDropdownToggle.attr('aria-expanded') === 'false') {
|
||||||
if (Helper.isBootstrap5()) {
|
$attachDropdownToggle.click();
|
||||||
new bootstrap.Dropdown($attachDropdownToggle).toggle();
|
|
||||||
} else {
|
|
||||||
$attachDropdownToggle.click();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$fileWrap.addClass('highlight');
|
$fileWrap.addClass('highlight');
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
@ -4711,9 +4624,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
|
|
||||||
// bootstrap template drop down
|
// bootstrap template drop down
|
||||||
$('#language ul.dropdown-menu li a').click(setLanguage);
|
$('#language ul.dropdown-menu li a').click(setLanguage);
|
||||||
|
// page template drop down
|
||||||
// bootstrap template drop down
|
$('#language select option').click(setLanguage);
|
||||||
$('#template ul.dropdown-menu li a').click(setTemplate);
|
|
||||||
|
|
||||||
// bind events
|
// bind events
|
||||||
$burnAfterReading.change(changeBurnAfterReading);
|
$burnAfterReading.change(changeBurnAfterReading);
|
||||||
|
@ -5194,7 +5106,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
const plainText = Editor.getText(),
|
const plainText = Editor.getText(),
|
||||||
format = PasteViewer.getFormat(),
|
format = PasteViewer.getFormat(),
|
||||||
// the methods may return different values if no files are attached (null, undefined or false)
|
// the methods may return different values if no files are attached (null, undefined or false)
|
||||||
files = TopNav.getFileList() || AttachmentViewer.getFiles() || AttachmentViewer.hasAttachment();
|
files = TopNav.getFileList() || AttachmentViewer.getFile() || AttachmentViewer.hasAttachment();
|
||||||
|
|
||||||
// do not send if there is no data
|
// do not send if there is no data
|
||||||
if (plainText.length === 0 && !files) {
|
if (plainText.length === 0 && !files) {
|
||||||
|
@ -5234,64 +5146,62 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
PasteViewer.setFormat(format);
|
PasteViewer.setFormat(format);
|
||||||
|
|
||||||
// prepare cypher message
|
// prepare cypher message
|
||||||
let attachmentsData = AttachmentViewer.getAttachmentsData(),
|
let file = AttachmentViewer.getAttachmentData(),
|
||||||
cipherMessage = {
|
cipherMessage = {
|
||||||
'paste': plainText
|
'paste': plainText
|
||||||
};
|
};
|
||||||
if (attachmentsData.length) {
|
if (typeof file !== 'undefined' && file !== null) {
|
||||||
cipherMessage['attachment'] = attachmentsData;
|
cipherMessage['attachment'] = file;
|
||||||
cipherMessage['attachment_name'] = AttachmentViewer.getFiles().map((fileInfo => fileInfo.name));
|
cipherMessage['attachment_name'] = AttachmentViewer.getFile().name;
|
||||||
} else if (AttachmentViewer.hasAttachment()) {
|
} else if (AttachmentViewer.hasAttachment()) {
|
||||||
// fall back to cloned part
|
// fall back to cloned part
|
||||||
let attachments = AttachmentViewer.getAttachments();
|
let attachment = AttachmentViewer.getAttachment();
|
||||||
cipherMessage['attachment'] = attachments.map(attachment => attachment[0]);
|
cipherMessage['attachment'] = attachment[0];
|
||||||
cipherMessage['attachment_name'] = attachments.map(attachment => attachment[1]);
|
cipherMessage['attachment_name'] = attachment[1];
|
||||||
|
|
||||||
cipherMessage['attachment'] = await Promise.all(cipherMessage['attachment'].map(async (attachment) => {
|
// we need to retrieve data from blob if browser already parsed it in memory
|
||||||
// we need to retrieve data from blob if browser already parsed it in memory
|
if (typeof attachment[0] === 'string' && attachment[0].startsWith('blob:')) {
|
||||||
if (typeof attachment === 'string' && attachment.startsWith('blob:')) {
|
Alert.showStatus(
|
||||||
Alert.showStatus(
|
[
|
||||||
[
|
'Retrieving cloned file \'%s\' from memory...',
|
||||||
'Retrieving cloned file \'%s\' from memory...',
|
attachment[1]
|
||||||
attachment[1]
|
],
|
||||||
],
|
'copy'
|
||||||
'copy'
|
);
|
||||||
);
|
try {
|
||||||
try {
|
const blobData = await $.ajax({
|
||||||
const blobData = await $.ajax({
|
type: 'GET',
|
||||||
type: 'GET',
|
url: `${attachment[0]}`,
|
||||||
url: `${attachment}`,
|
processData: false,
|
||||||
processData: false,
|
timeout: 10000,
|
||||||
timeout: 10000,
|
xhrFields: {
|
||||||
xhrFields: {
|
withCredentials: false,
|
||||||
withCredentials: false,
|
responseType: 'blob'
|
||||||
responseType: 'blob'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (blobData instanceof window.Blob) {
|
|
||||||
const fileReading = new Promise(function(resolve, reject) {
|
|
||||||
const fileReader = new FileReader();
|
|
||||||
fileReader.onload = function (event) {
|
|
||||||
resolve(event.target.result);
|
|
||||||
};
|
|
||||||
fileReader.onerror = function (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
fileReader.readAsDataURL(blobData);
|
|
||||||
});
|
|
||||||
|
|
||||||
return await fileReading;
|
|
||||||
} else {
|
|
||||||
const error = 'Cannot process attachment data.';
|
|
||||||
Alert.showError(error);
|
|
||||||
throw new TypeError(error);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
});
|
||||||
Alert.showError('Cannot retrieve attachment.');
|
if (blobData instanceof window.Blob) {
|
||||||
throw error;
|
const fileReading = new Promise(function(resolve, reject) {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onload = function (event) {
|
||||||
|
resolve(event.target.result);
|
||||||
|
};
|
||||||
|
fileReader.onerror = function (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
fileReader.readAsDataURL(blobData);
|
||||||
|
});
|
||||||
|
cipherMessage['attachment'] = await fileReading;
|
||||||
|
} else {
|
||||||
|
const error = 'Cannot process attachment data.';
|
||||||
|
Alert.showError(error);
|
||||||
|
throw new TypeError(error);
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
Alert.showError('Cannot retrieve attachment.');
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt message
|
// encrypt message
|
||||||
|
@ -5386,15 +5296,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// version 2 paste
|
// version 2 paste
|
||||||
const pasteMessage = JSON.parse(pastePlain);
|
const pasteMessage = JSON.parse(pastePlain);
|
||||||
if (pasteMessage.hasOwnProperty('attachment') && pasteMessage.hasOwnProperty('attachment_name')) {
|
if (pasteMessage.hasOwnProperty('attachment') && pasteMessage.hasOwnProperty('attachment_name')) {
|
||||||
if (Array.isArray(pasteMessage.attachment) && Array.isArray(pasteMessage.attachment_name)) {
|
AttachmentViewer.setAttachment(pasteMessage.attachment, pasteMessage.attachment_name);
|
||||||
pasteMessage.attachment.forEach((attachment, key) => {
|
|
||||||
const attachment_name = pasteMessage.attachment_name[key];
|
|
||||||
AttachmentViewer.setAttachment(attachment, attachment_name);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Continue to process attachment parameters as strings to ensure backward compatibility
|
|
||||||
AttachmentViewer.setAttachment(pasteMessage.attachment, pasteMessage.attachment_name);
|
|
||||||
}
|
|
||||||
AttachmentViewer.showAttachment();
|
AttachmentViewer.showAttachment();
|
||||||
}
|
}
|
||||||
pastePlain = pasteMessage.paste;
|
pastePlain = pasteMessage.paste;
|
||||||
|
@ -5485,7 +5387,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.run = function(paste)
|
me.run = function(paste)
|
||||||
{
|
{
|
||||||
Alert.hideMessages();
|
Alert.hideMessages();
|
||||||
Alert.setCustomHandler(null);
|
|
||||||
Alert.showLoading('Decrypting paste…', 'cloud-download');
|
Alert.showLoading('Decrypting paste…', 'cloud-download');
|
||||||
|
|
||||||
if (typeof paste === 'undefined' || paste.type === 'click') {
|
if (typeof paste === 'undefined' || paste.type === 'click') {
|
||||||
|
@ -5503,9 +5404,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
me.run(paste);
|
me.run(paste);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear attachments to prevent duplicates
|
|
||||||
AttachmentViewer.removeAttachment();
|
|
||||||
|
|
||||||
// decrypt paste & attachments
|
// decrypt paste & attachments
|
||||||
decryptionPromises.push(decryptPaste(paste, key, password));
|
decryptionPromises.push(decryptPaste(paste, key, password));
|
||||||
|
|
||||||
|
@ -5880,14 +5778,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
history.pushState({type: 'clone'}, document.title, Helper.baseUri());
|
history.pushState({type: 'clone'}, document.title, Helper.baseUri());
|
||||||
|
|
||||||
if (AttachmentViewer.hasAttachment()) {
|
if (AttachmentViewer.hasAttachment()) {
|
||||||
const attachments = AttachmentViewer.getAttachments();
|
AttachmentViewer.moveAttachmentTo(
|
||||||
attachments.forEach(attachment => {
|
TopNav.getCustomAttachment(),
|
||||||
AttachmentViewer.moveAttachmentTo(
|
'Cloned: \'%s\''
|
||||||
TopNav.getCustomAttachment(),
|
);
|
||||||
attachment,
|
|
||||||
'Cloned: \'%s\''
|
|
||||||
);
|
|
||||||
});
|
|
||||||
TopNav.hideFileSelector();
|
TopNav.hideFileSelector();
|
||||||
AttachmentViewer.hideAttachment();
|
AttachmentViewer.hideAttachment();
|
||||||
// NOTE: it also looks nice without removing the attachment
|
// NOTE: it also looks nice without removing the attachment
|
||||||
|
@ -5895,12 +5789,12 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
AttachmentViewer.hideAttachmentPreview();
|
AttachmentViewer.hideAttachmentPreview();
|
||||||
TopNav.showCustomAttachment();
|
TopNav.showCustomAttachment();
|
||||||
|
|
||||||
// show another status messages to make the user aware that the
|
// show another status message to make the user aware that the
|
||||||
// files were cloned too!
|
// file was cloned too!
|
||||||
Alert.showStatus(
|
Alert.showStatus(
|
||||||
[
|
[
|
||||||
'The cloned file \'%s\' was attached to this paste.',
|
'The cloned file \'%s\' was attached to this paste.',
|
||||||
attachments.map(attachment => attachment[1]).join(', '),
|
AttachmentViewer.getAttachment()[1]
|
||||||
],
|
],
|
||||||
'copy'
|
'copy'
|
||||||
);
|
);
|
||||||
|
|
2
js/purify-3.2.4.js
Normal file
|
@ -1,5 +1,5 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
var common = require('../common');
|
||||||
|
|
||||||
describe('AttachmentViewer', function () {
|
describe('AttachmentViewer', function () {
|
||||||
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
|
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
|
||||||
|
@ -14,12 +14,11 @@ describe('AttachmentViewer', function () {
|
||||||
'string',
|
'string',
|
||||||
function (mimeType, rawdata, filename, prefix, postfix) {
|
function (mimeType, rawdata, filename, prefix, postfix) {
|
||||||
let clean = jsdom(),
|
let clean = jsdom(),
|
||||||
data = 'data:' + mimeType + ';base64,' + common.btoa(rawdata),
|
data = 'data:' + mimeType + ';base64,' + btoa(rawdata),
|
||||||
mimePrefix = mimeType.substring(0, 6),
|
|
||||||
previewSupported = (
|
previewSupported = (
|
||||||
mimePrefix === 'image/' ||
|
mimeType.substring(0, 6) === 'image/' ||
|
||||||
mimePrefix === 'audio/' ||
|
mimeType.substring(0, 6) === 'audio/' ||
|
||||||
mimePrefix === 'video/' ||
|
mimeType.substring(0, 6) === 'video/' ||
|
||||||
mimeType.match(/\/pdf/i)
|
mimeType.match(/\/pdf/i)
|
||||||
),
|
),
|
||||||
results = [],
|
results = [],
|
||||||
|
@ -27,14 +26,11 @@ describe('AttachmentViewer', function () {
|
||||||
prefix = prefix.replace(/%(s|d)/g, '%%');
|
prefix = prefix.replace(/%(s|d)/g, '%%');
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%');
|
postfix = postfix.replace(/%(s|d)/g, '%%');
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="attachmentPreview" class="col-md-12 text-center hidden"></div>' +
|
'<div id="attachment" role="alert" class="hidden alert ' +
|
||||||
'<div id="attachment" class="hidden"></div>' +
|
'alert-info"><span class="glyphicon glyphicon-download-' +
|
||||||
'<div id="templates">' +
|
'alt" aria-hidden="true"></span> <a class="alert-link">' +
|
||||||
'<div id="attachmenttemplate" role="alert" class="attachment hidden alert alert-info">' +
|
'Download attachment</a></div><div id="attachmentPrevie' +
|
||||||
'<span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span>' +
|
'w" class="hidden"></div>'
|
||||||
'<a class="alert-link">Download attachment</a>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>'
|
|
||||||
);
|
);
|
||||||
// mock createObjectURL for jsDOM
|
// mock createObjectURL for jsDOM
|
||||||
if (typeof window.URL.createObjectURL === 'undefined') {
|
if (typeof window.URL.createObjectURL === 'undefined') {
|
||||||
|
@ -47,35 +43,29 @@ describe('AttachmentViewer', function () {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
$.PrivateBin.AttachmentViewer.init();
|
$.PrivateBin.AttachmentViewer.init();
|
||||||
$.PrivateBin.Model.init();
|
|
||||||
results.push(
|
results.push(
|
||||||
!$.PrivateBin.AttachmentViewer.hasAttachment() &&
|
!$.PrivateBin.AttachmentViewer.hasAttachment() &&
|
||||||
$('#attachment').hasClass('hidden') &&
|
$('#attachment').hasClass('hidden') &&
|
||||||
$('#attachment').children().length === 0 &&
|
|
||||||
$('#attachmenttemplate').hasClass('hidden') &&
|
|
||||||
$('#attachmentPreview').hasClass('hidden')
|
$('#attachmentPreview').hasClass('hidden')
|
||||||
);
|
);
|
||||||
global.atob = common.atob;
|
|
||||||
if (filename.length) {
|
if (filename.length) {
|
||||||
$.PrivateBin.AttachmentViewer.setAttachment(data, filename);
|
$.PrivateBin.AttachmentViewer.setAttachment(data, filename);
|
||||||
} else {
|
} else {
|
||||||
$.PrivateBin.AttachmentViewer.setAttachment(data);
|
$.PrivateBin.AttachmentViewer.setAttachment(data);
|
||||||
}
|
}
|
||||||
// // beyond this point we will get the blob URL instead of the data
|
// beyond this point we will get the blob URL instead of the data
|
||||||
data = window.URL.createObjectURL(data);
|
data = window.URL.createObjectURL(data);
|
||||||
const attachment = $.PrivateBin.AttachmentViewer.getAttachments();
|
const attachment = $.PrivateBin.AttachmentViewer.getAttachment();
|
||||||
results.push(
|
results.push(
|
||||||
$.PrivateBin.AttachmentViewer.hasAttachment() &&
|
$.PrivateBin.AttachmentViewer.hasAttachment() &&
|
||||||
$('#attachment').hasClass('hidden') &&
|
$('#attachment').hasClass('hidden') &&
|
||||||
$('#attachment').children().length > 0 &&
|
|
||||||
$('#attachmentPreview').hasClass('hidden') &&
|
$('#attachmentPreview').hasClass('hidden') &&
|
||||||
attachment[0][0] === data &&
|
attachment[0] === data &&
|
||||||
attachment[0][1] === filename
|
attachment[1] === filename
|
||||||
);
|
);
|
||||||
$.PrivateBin.AttachmentViewer.showAttachment();
|
$.PrivateBin.AttachmentViewer.showAttachment();
|
||||||
results.push(
|
results.push(
|
||||||
!$('#attachment').hasClass('hidden') &&
|
!$('#attachment').hasClass('hidden') &&
|
||||||
$('#attachment').children().length > 0 &&
|
|
||||||
(previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
|
(previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
|
||||||
);
|
);
|
||||||
$.PrivateBin.AttachmentViewer.hideAttachment();
|
$.PrivateBin.AttachmentViewer.hideAttachment();
|
||||||
|
@ -93,7 +83,7 @@ describe('AttachmentViewer', function () {
|
||||||
(previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
|
(previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
|
||||||
);
|
);
|
||||||
let element = $('<div>');
|
let element = $('<div>');
|
||||||
$.PrivateBin.AttachmentViewer.moveAttachmentTo(element, attachment[0], prefix + '%s' + postfix);
|
$.PrivateBin.AttachmentViewer.moveAttachmentTo(element, prefix + '%s' + postfix);
|
||||||
// messageIDs with links get a relaxed treatment
|
// messageIDs with links get a relaxed treatment
|
||||||
if (prefix.indexOf('<a') === -1 && postfix.indexOf('<a') === -1) {
|
if (prefix.indexOf('<a') === -1 && postfix.indexOf('<a') === -1) {
|
||||||
result = $('<textarea>').text((prefix + filename + postfix)).text();
|
result = $('<textarea>').text((prefix + filename + postfix)).text();
|
||||||
|
@ -107,17 +97,16 @@ describe('AttachmentViewer', function () {
|
||||||
}
|
}
|
||||||
if (filename.length) {
|
if (filename.length) {
|
||||||
results.push(
|
results.push(
|
||||||
element.find('a')[0].href === data &&
|
element.children()[0].href === data &&
|
||||||
element.find('a')[0].getAttribute('download') === filename &&
|
element.children()[0].getAttribute('download') === filename &&
|
||||||
element.find('a')[0].text === result
|
element.children()[0].text === result
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
results.push(element.find('a')[0].href === data);
|
results.push(element.children()[0].href === data);
|
||||||
}
|
}
|
||||||
$.PrivateBin.AttachmentViewer.removeAttachment();
|
$.PrivateBin.AttachmentViewer.removeAttachment();
|
||||||
results.push(
|
results.push(
|
||||||
$('#attachment').hasClass('hidden') &&
|
$('#attachment').hasClass('hidden') &&
|
||||||
$('#attachment').children().length === 0 &&
|
|
||||||
$('#attachmentPreview').hasClass('hidden')
|
$('#attachmentPreview').hasClass('hidden')
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
|
|
|
@ -19,9 +19,10 @@ describe('Check', function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Legacy.Check.init();
|
Legacy.Check.init();
|
||||||
const result = Legacy.Check.getInit() && !Legacy.Check.getStatus();
|
const result1 = Legacy.Check.getInit() && !Legacy.Check.getStatus(),
|
||||||
|
result2 = (document.getElementById('errormessage').className !== 'hidden');
|
||||||
clean();
|
clean();
|
||||||
return result;
|
return result1 && result2;
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 10});
|
{tests: 10});
|
||||||
|
@ -66,10 +67,7 @@ describe('Check', function () {
|
||||||
'url': (secureProtocol ? 'https' : 'http' ) + '://' + domain.join('') + '/'
|
'url': (secureProtocol ? 'https' : 'http' ) + '://' + domain.join('') + '/'
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
Legacy.Check.init();
|
Legacy.Check.init();
|
||||||
const result1 = Legacy.Check.getInit() && Legacy.Check.getStatus(),
|
const result1 = Legacy.Check.getInit() && Legacy.Check.getStatus(),
|
||||||
result2 = secureProtocol === (document.getElementById('httpnotice').className === 'hidden');
|
result2 = secureProtocol === (document.getElementById('httpnotice').className === 'hidden');
|
||||||
|
|
|
@ -4,136 +4,120 @@ const common = require('../common');
|
||||||
describe('CopyToClipboard', function() {
|
describe('CopyToClipboard', function() {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
|
||||||
describe ('Copy paste to clipboard', function () {
|
describe ('Copy paste co clipboard', function () {
|
||||||
jsc.property('Copy with button click',
|
jsc.property('Copy with button click', common.jscFormats(), 'nestring', async function (format, text) {
|
||||||
common.jscFormats(),
|
var clean = jsdom();
|
||||||
'nestring',
|
common.enableClipboard();
|
||||||
async function (format, text) {
|
|
||||||
var clean = jsdom();
|
$('body').html(
|
||||||
common.enableClipboard();
|
'<div id="placeholder" class="hidden">+++ no paste text ' +
|
||||||
|
'+++</div><div id="prettymessage" class="hidden">' +
|
||||||
|
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
||||||
|
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
||||||
|
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
||||||
|
'</div><div id="plaintext" class="hidden"></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
$.PrivateBin.PasteViewer.init();
|
||||||
|
$.PrivateBin.PasteViewer.setFormat(format);
|
||||||
|
$.PrivateBin.PasteViewer.setText(text);
|
||||||
|
$.PrivateBin.PasteViewer.run();
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
|
||||||
|
$('#prettyMessageCopyBtn').trigger('click');
|
||||||
|
|
||||||
$('body').html(
|
const savedToClipboardText = await navigator.clipboard.readText();
|
||||||
'<div id="placeholder" class="hidden">+++ no paste text ' +
|
|
||||||
'+++</div><div id="prettymessage" class="hidden">' +
|
clean();
|
||||||
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
|
||||||
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
return text === savedToClipboardText;
|
||||||
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
});
|
||||||
'</div><div id="plaintext" class="hidden"></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$.PrivateBin.PasteViewer.init();
|
|
||||||
$.PrivateBin.PasteViewer.setFormat(format);
|
|
||||||
$.PrivateBin.PasteViewer.setText(text);
|
|
||||||
$.PrivateBin.PasteViewer.run();
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
|
|
||||||
$('#prettyMessageCopyBtn').trigger('click');
|
|
||||||
|
|
||||||
const savedToClipboardText = await navigator.clipboard.readText();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return text === savedToClipboardText;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unfortunately in JSVerify impossible to check if copy with shortcut when user selected some text on the page
|
* Unfortunately in JSVerify impossible to check if copy with shortcut when user selected some text on the page
|
||||||
* (the copy paste to clipboard should not work in this case) due to lacking window.getSelection() in jsdom.
|
* (the copy paste to clipboard should not work in this case) due to lucking window.getSelection() in jsdom.
|
||||||
*/
|
*/
|
||||||
jsc.property('Copy with keyboard shortcut',
|
jsc.property('Copy with keyboard shortcut', common.jscFormats(), 'nestring', async function (format, text) {
|
||||||
common.jscFormats(),
|
|
||||||
'nestring',
|
|
||||||
async function (format, text) {
|
|
||||||
var clean = jsdom();
|
|
||||||
common.enableClipboard();
|
|
||||||
|
|
||||||
$('body').html(
|
|
||||||
'<div id="placeholder">+++ no paste text ' +
|
|
||||||
'+++</div><div id="prettymessage" class="hidden">' +
|
|
||||||
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
|
||||||
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
|
||||||
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
|
||||||
'</div><div id="plaintext" class="hidden"></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$.PrivateBin.PasteViewer.init();
|
|
||||||
$.PrivateBin.PasteViewer.setFormat(format);
|
|
||||||
$.PrivateBin.PasteViewer.setText(text);
|
|
||||||
$.PrivateBin.PasteViewer.run();
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
|
|
||||||
$('body').trigger('copy');
|
|
||||||
|
|
||||||
const copiedTextWithoutSelectedText = await navigator.clipboard.readText();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return copiedTextWithoutSelectedText === text;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
jsc.property('Copy link to clipboard',
|
|
||||||
'nestring',
|
|
||||||
async function (text) {
|
|
||||||
var clean = jsdom();
|
var clean = jsdom();
|
||||||
common.enableClipboard();
|
common.enableClipboard();
|
||||||
|
|
||||||
$('body').html('<button id="copyLink"></button>');
|
$('body').html(
|
||||||
|
'<div id="placeholder">+++ no paste text ' +
|
||||||
|
'+++</div><div id="prettymessage" class="hidden">' +
|
||||||
|
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
||||||
|
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
||||||
|
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
||||||
|
'</div><div id="plaintext" class="hidden"></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
$.PrivateBin.PasteViewer.init();
|
||||||
|
$.PrivateBin.PasteViewer.setFormat(format);
|
||||||
|
$.PrivateBin.PasteViewer.setText(text);
|
||||||
|
$.PrivateBin.PasteViewer.run();
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
$.PrivateBin.CopyToClipboard.setUrl(text);
|
|
||||||
|
|
||||||
$('#copyLink').trigger('click');
|
$('body').trigger('copy');
|
||||||
|
|
||||||
const copiedText = await navigator.clipboard.readText();
|
const copiedTextWithoutSelectedText = await navigator.clipboard.readText();
|
||||||
|
|
||||||
clean();
|
clean();
|
||||||
|
|
||||||
return text === copiedText;
|
return copiedTextWithoutSelectedText === text;
|
||||||
}
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
|
|
||||||
|
jsc.property('Copy link to clipboard', 'nestring', async function (text) {
|
||||||
|
var clean = jsdom();
|
||||||
|
common.enableClipboard();
|
||||||
|
|
||||||
|
$('body').html('<button id="copyLink"></button>');
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.setUrl(text);
|
||||||
|
|
||||||
|
$('#copyLink').trigger('click');
|
||||||
|
|
||||||
|
const copiedText = await navigator.clipboard.readText();
|
||||||
|
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return text === copiedText;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Keyboard shortcut hint', function () {
|
describe('Keyboard shortcut hint', function () {
|
||||||
jsc.property('Show hint',
|
jsc.property('Show hint', 'nestring', function (text) {
|
||||||
'nestring',
|
var clean = jsdom();
|
||||||
function (text) {
|
|
||||||
var clean = jsdom();
|
$('body').html('<small id="copyShortcutHintText"></small>');
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.showKeyboardShortcutHint();
|
||||||
|
|
||||||
|
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
||||||
|
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return keyboardShortcutHint.length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
$('body').html('<small id="copyShortcutHintText"></small>');
|
jsc.property('Hide hint', 'nestring', function (text) {
|
||||||
|
var clean = jsdom();
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
$.PrivateBin.CopyToClipboard.showKeyboardShortcutHint();
|
$('body').html('<small id="copyShortcutHintText">' + text + '</small>');
|
||||||
|
|
||||||
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.hideKeyboardShortcutHint();
|
||||||
clean();
|
|
||||||
|
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
||||||
return keyboardShortcutHint.length > 0;
|
|
||||||
}
|
clean();
|
||||||
);
|
|
||||||
|
return keyboardShortcutHint.length === 0;
|
||||||
jsc.property('Hide hint',
|
});
|
||||||
'nestring',
|
|
||||||
function (text) {
|
|
||||||
var clean = jsdom();
|
|
||||||
|
|
||||||
$('body').html('<small id="copyShortcutHintText">' + text + '</small>');
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
$.PrivateBin.CopyToClipboard.hideKeyboardShortcutHint();
|
|
||||||
|
|
||||||
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return keyboardShortcutHint.length === 0;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
|
||||||
describe('CryptTool', function () {
|
describe('CryptTool', function () {
|
||||||
describe('cipher & decipher', function () {
|
describe('cipher & decipher', function () {
|
||||||
|
@ -15,26 +15,21 @@ describe('CryptTool', function () {
|
||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
async function (key, password, message) {
|
async function (key, password, message) {
|
||||||
const clean = jsdom();
|
// pause to let async functions conclude
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
|
let clean = jsdom();
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
global.btoa = common.btoa;
|
|
||||||
message = message.trim();
|
message = message.trim();
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
key, password, cipherMessage
|
key, password, cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
return message === plaintext;
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 3});
|
{tests: 3});
|
||||||
|
@ -43,19 +38,15 @@ describe('CryptTool', function () {
|
||||||
// The below static unit tests are included to ensure deciphering of "classic"
|
// The below static unit tests are included to ensure deciphering of "classic"
|
||||||
// SJCL based pastes still works
|
// SJCL based pastes still works
|
||||||
it(
|
it(
|
||||||
'supports PrivateBin v1 ciphertext with password (SJCL & browser atob)',
|
'supports PrivateBin v1 ciphertext (SJCL & browser atob)',
|
||||||
async function () {
|
function () {
|
||||||
delete global.Base64;
|
delete global.Base64;
|
||||||
const clean = jsdom();
|
let clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
// Of course you can easily decipher the following texts, if you like.
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
// Bonus points for finding their sources and hidden meanings.
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
return $.PrivateBin.CryptTool.decipher(
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
// -- "That's amazing. I've got the same combination on my luggage."
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
||||||
|
@ -86,76 +77,53 @@ describe('CryptTool', function () {
|
||||||
'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
|
'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
|
||||||
'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
|
'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
|
||||||
'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
|
'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
|
||||||
);
|
).then(function (paste1) {
|
||||||
clean();
|
$.PrivateBin.CryptTool.decipher(
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
||||||
if (!result) console.log(paste);
|
'', // no password
|
||||||
assert.ok(result);
|
'{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
|
||||||
}
|
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
||||||
);
|
'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
|
||||||
|
'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
|
||||||
it(
|
'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
|
||||||
'supports PrivateBin v1 ciphertext no password (SJCL & browser atob)',
|
'/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
|
||||||
async function () {
|
'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
|
||||||
delete global.Base64;
|
'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
|
||||||
const clean = jsdom();
|
'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
|
||||||
// ensure zlib is getting loaded
|
'+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
|
||||||
$.PrivateBin.Controller.initZ();
|
'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
|
||||||
Object.defineProperty(window, 'crypto', {
|
'24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
|
||||||
value: new WebCrypto(),
|
'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
|
||||||
writeable: false,
|
'8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
|
||||||
|
'//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
|
||||||
|
'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
|
||||||
|
'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
|
||||||
|
'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
|
||||||
|
'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
|
||||||
|
'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
|
||||||
|
'99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
|
||||||
|
'MZtmnYpGAtAPg7AUG"}'
|
||||||
|
).then(function (paste2) {
|
||||||
|
clean();
|
||||||
|
assert.ok(
|
||||||
|
paste1.includes('securely packed in iron') &&
|
||||||
|
paste2.includes('Sol is right')
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
|
|
||||||
'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
|
|
||||||
'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
|
|
||||||
'/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
|
|
||||||
'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
|
|
||||||
'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
|
|
||||||
'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
|
|
||||||
'+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
|
|
||||||
'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
|
|
||||||
'24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
|
|
||||||
'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
|
|
||||||
'8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
|
|
||||||
'//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
|
|
||||||
'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
|
|
||||||
'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
|
|
||||||
'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
|
|
||||||
'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
|
|
||||||
'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
|
|
||||||
'99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
|
|
||||||
'MZtmnYpGAtAPg7AUG"}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it(
|
it(
|
||||||
'supports ZeroBin ciphertext with password (SJCL & Base64 1.7)',
|
'supports ZeroBin ciphertext (SJCL & Base64 1.7)',
|
||||||
async function () {
|
function () {
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
global.Base64 = require('../base64-1.7').Base64;
|
||||||
const clean = jsdom();
|
var clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
// Of course you can easily decipher the following texts, if you like.
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
// Bonus points for finding their sources and hidden meanings.
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
return $.PrivateBin.CryptTool.decipher(
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
// -- "That's amazing. I've got the same combination on my luggage."
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
||||||
|
@ -178,74 +146,54 @@ describe('CryptTool', function () {
|
||||||
'7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
|
'7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
|
||||||
'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
|
'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
|
||||||
'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
|
'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
|
||||||
);
|
).then(function (paste1) {
|
||||||
clean();
|
$.PrivateBin.CryptTool.decipher(
|
||||||
delete global.Base64;
|
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
'', // no password
|
||||||
if (!result) console.log(paste);
|
'{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
|
||||||
assert.ok(result);
|
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
||||||
}
|
'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
|
||||||
);
|
'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
|
||||||
|
'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
|
||||||
it(
|
'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
|
||||||
'supports ZeroBin ciphertext no password (SJCL & Base64 1.7)',
|
'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
|
||||||
async function () {
|
'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
|
||||||
const clean = jsdom();
|
'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
|
||||||
Object.defineProperty(window, 'crypto', {
|
'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
|
||||||
value: new WebCrypto(),
|
'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
|
||||||
writeable: false,
|
'7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
|
||||||
|
'7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
|
||||||
|
'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
|
||||||
|
).then(function (paste2) {
|
||||||
|
clean();
|
||||||
|
delete global.Base64;
|
||||||
|
assert.ok(
|
||||||
|
paste1.includes('securely packed in iron') &&
|
||||||
|
paste2.includes('Sol is right')
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
|
|
||||||
'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
|
|
||||||
'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
|
|
||||||
'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
|
|
||||||
'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
|
|
||||||
'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
|
|
||||||
'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
|
|
||||||
'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
|
|
||||||
'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
|
|
||||||
'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
|
|
||||||
'7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
|
|
||||||
'7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
|
|
||||||
'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
delete global.Base64;
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it('does not truncate messages', async function () {
|
it('does not truncate messages', async function () {
|
||||||
const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
|
let message = fs.readFileSync('test/compression-sample.txt', 'utf8'),
|
||||||
clean = jsdom();
|
clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
global.atob = common.atob;
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
global.btoa = common.btoa;
|
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
|
||||||
'foo', 'bar', message, []
|
'foo', 'bar', message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
'foo', 'bar', cipherMessage
|
'foo', 'bar', cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
assert.strictEqual(
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
message,
|
||||||
assert.ok(result);
|
plaintext
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can en- and decrypt a particular message (#260)', function () {
|
it('can en- and decrypt a particular message (#260)', function () {
|
||||||
|
@ -253,6 +201,8 @@ describe('CryptTool', function () {
|
||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
async function (key, password) {
|
async function (key, password) {
|
||||||
|
// pause to let async functions conclude
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
const message = `
|
const message = `
|
||||||
1 subgoal
|
1 subgoal
|
||||||
|
|
||||||
|
@ -275,23 +225,18 @@ isWhile : interp (while expr sBody) (MemElem mem) =
|
||||||
======================== ( 1 / 1 )
|
======================== ( 1 / 1 )
|
||||||
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
||||||
`;
|
`;
|
||||||
const clean = jsdom();
|
let clean = jsdom();
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
key, password, cipherMessage
|
key, password, cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
return message === plaintext;
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 3});
|
{tests: 3});
|
||||||
|
@ -299,27 +244,23 @@ conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getSymmetricKey', function () {
|
describe('getSymmetricKey', function () {
|
||||||
this.timeout(10000);
|
this.timeout(30000);
|
||||||
let keys = [];
|
var keys = [];
|
||||||
|
|
||||||
// the parameter is used to ensure the test is run more then one time
|
// the parameter is used to ensure the test is run more then one time
|
||||||
it('returns random, non-empty keys', function () {
|
jsc.property(
|
||||||
jsc.assert(jsc.forall(
|
'returns random, non-empty keys',
|
||||||
'integer',
|
'integer',
|
||||||
function(counter) {
|
function(counter) {
|
||||||
const clean = jsdom();
|
var clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
var key = $.PrivateBin.CryptTool.getSymmetricKey(),
|
||||||
writeable: false,
|
result = (key !== '' && keys.indexOf(key) === -1);
|
||||||
});
|
keys.push(key);
|
||||||
const key = $.PrivateBin.CryptTool.getSymmetricKey(),
|
clean();
|
||||||
result = (key !== '' && keys.indexOf(key) === -1);
|
return result;
|
||||||
keys.push(key);
|
}
|
||||||
clean();
|
);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
),
|
|
||||||
{tests: 10});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -229,30 +229,30 @@ describe('Helper', function () {
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* TODO test fails since jsDOM version 17 - document.cookie remains empty
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the requested cookie',
|
'returns the requested cookie',
|
||||||
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
||||||
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
||||||
function (labels, values) {
|
function (labels, values) {
|
||||||
let selectedKey = '', selectedValue = '';
|
var selectedKey = '', selectedValue = '',
|
||||||
const clean = jsdom();
|
cookieArray = [];
|
||||||
labels.forEach(function(item, i) {
|
labels.forEach(function(item, i) {
|
||||||
const key = item.join(''),
|
var key = item.join(''),
|
||||||
value = (values[i] || values[0]).join('');
|
value = (values[i] || values[0]).join('');
|
||||||
document.cookie = key + '=' + value;
|
cookieArray.push(key + '=' + value);
|
||||||
if (Math.random() < 1 / i || selectedKey === key)
|
if (Math.random() < 1 / i || selectedKey === key)
|
||||||
{
|
{
|
||||||
selectedKey = key;
|
selectedKey = key;
|
||||||
selectedValue = value;
|
selectedValue = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const result = $.PrivateBin.Helper.getCookie(selectedKey);
|
var clean = jsdom('', {cookie: cookieArray}),
|
||||||
|
result = $.PrivateBin.Helper.getCookie(selectedKey);
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
clean();
|
clean();
|
||||||
return result === selectedValue;
|
return result === selectedValue;
|
||||||
}
|
}
|
||||||
); */
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('baseUri', function () {
|
describe('baseUri', function () {
|
||||||
|
@ -290,44 +290,5 @@ describe('Helper', function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('formatBytes', function () {
|
|
||||||
jsc.property('returns 0 B for 0 bytes', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(0) === '0 B';
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('formats bytes < 1000 as B', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(500) === '500 B';
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('formats kibibytes correctly', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(1500) === '1.46 KiB';
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('formats mebibytes correctly', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(2 * 1000 * 1000) === '1.91 MiB';
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('formats gibibytes correctly', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(3.45 * 1000 * 1000 * 1000) === '3.21 GiB';
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('rounds to two decimal places', function () {
|
|
||||||
return $.PrivateBin.Helper.formatBytes(1234567) === '1.18 MiB';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('isBootstrap5', function () {
|
|
||||||
jsc.property('Bootstrap 5 has been detected', function () {
|
|
||||||
global.bootstrap = {};
|
|
||||||
return $.PrivateBin.Helper.isBootstrap5() === true;
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property('Bootstrap 5 has not been detected', function () {
|
|
||||||
delete global.bootstrap;
|
|
||||||
return $.PrivateBin.Helper.isBootstrap5() === false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ describe('Model', function () {
|
||||||
url.query = queryStart.concat(pasteId, queryEnd);
|
url.query = queryStart.concat(pasteId, queryEnd);
|
||||||
const pasteIdString = pasteId.join(''),
|
const pasteIdString = pasteId.join(''),
|
||||||
clean = jsdom('', {url: common.urlToString(url)});
|
clean = jsdom('', {url: common.urlToString(url)});
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
const result = $.PrivateBin.Model.getPasteId();
|
const result = $.PrivateBin.Model.getPasteId();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
clean();
|
clean();
|
||||||
|
@ -106,6 +107,7 @@ describe('Model', function () {
|
||||||
function (url) {
|
function (url) {
|
||||||
let clean = jsdom('', {url: common.urlToString(url)}),
|
let clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = false;
|
result = false;
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
try {
|
try {
|
||||||
$.PrivateBin.Model.getPasteId();
|
$.PrivateBin.Model.getPasteId();
|
||||||
}
|
}
|
||||||
|
@ -129,7 +131,7 @@ describe('Model', function () {
|
||||||
'returns the fragment of a v1 URL',
|
'returns the fragment of a v1 URL',
|
||||||
common.jscUrl(),
|
common.jscUrl(),
|
||||||
function (url) {
|
function (url) {
|
||||||
url.fragment = '0OIl'; // any non-base58 string
|
url.fragment = common.btoa(url.fragment.padStart(32, '\u0000'));
|
||||||
const clean = jsdom('', {url: common.urlToString(url)}),
|
const clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = $.PrivateBin.Model.getPasteKey();
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
|
@ -138,17 +140,17 @@ describe('Model', function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the fragment stripped of trailing query parts',
|
'returns the v1 fragment stripped of trailing query parts',
|
||||||
common.jscUrl(),
|
common.jscUrl(),
|
||||||
jsc.array(common.jscHashString()),
|
jsc.array(common.jscHashString()),
|
||||||
function (url, trail) {
|
function (url, trail) {
|
||||||
const fragment = url.fragment.padStart(32, '\u0000');
|
const fragmentString = common.btoa(url.fragment.padStart(32, '\u0000'));
|
||||||
url.fragment = $.PrivateBin.CryptTool.base58encode(fragment) + '&' + trail.join('');
|
url.fragment = fragmentString + '&' + trail.join('');
|
||||||
const clean = jsdom('', {url: common.urlToString(url)}),
|
const clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = $.PrivateBin.Model.getPasteKey();
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
clean();
|
clean();
|
||||||
return fragment === result;
|
return fragmentString === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
require('../common');
|
require('../common');
|
||||||
|
|
||||||
describe('Prompt', function () {
|
describe('Prompt', function () {
|
||||||
|
// TODO: this does not test the prompt() fallback, since that isn't available
|
||||||
|
// in nodejs -> replace the prompt in the "page" template with a modal
|
||||||
describe('requestPassword & getPassword', function () {
|
describe('requestPassword & getPassword', function () {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
|
||||||
|
@ -9,7 +11,7 @@ describe('Prompt', function () {
|
||||||
'returns the password fed into the dialog',
|
'returns the password fed into the dialog',
|
||||||
'string',
|
'string',
|
||||||
function (password) {
|
function (password) {
|
||||||
password = password.replace(/\r+|\n+/g, '');
|
password = password.replace(/\r+/g, '');
|
||||||
var clean = jsdom('', {url: 'ftp://example.com/?0000000000000000'});
|
var clean = jsdom('', {url: 'ftp://example.com/?0000000000000000'});
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="passwordmodal" class="modal fade" role="dialog">' +
|
'<div id="passwordmodal" class="modal fade" role="dialog">' +
|
||||||
|
@ -30,8 +32,7 @@ describe('Prompt', function () {
|
||||||
//var result = $.PrivateBin.Prompt.getPassword();
|
//var result = $.PrivateBin.Prompt.getPassword();
|
||||||
var result = $('#passworddecrypt').val();
|
var result = $('#passworddecrypt').val();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
// TODO triggers error messages in jsDOM since version 11
|
clean();
|
||||||
//clean();
|
|
||||||
return result === password;
|
return result === password;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -621,7 +621,7 @@ describe('TopNav', function () {
|
||||||
'returns the contents of the password input',
|
'returns the contents of the password input',
|
||||||
'string',
|
'string',
|
||||||
function (password) {
|
function (password) {
|
||||||
password = password.replace(/\r+|\n+/g, '');
|
password = password.replace(/\r+/g, '');
|
||||||
var results = [];
|
var results = [];
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<nav><div id="navbar"><ul><li><div id="password" ' +
|
'<nav><div id="navbar"><ul><li><div id="password" ' +
|
||||||
|
@ -727,11 +727,11 @@ describe('TopNav', function () {
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO triggers error messages in jsDOM since version 12, but passes
|
|
||||||
it(
|
it(
|
||||||
'displays raw text view correctly',
|
'displays raw text view correctly',
|
||||||
function () {
|
function () {
|
||||||
const clean = jsdom('', {url: 'https://privatebin.net/?0123456789abcdef#0'});
|
const clean = jsdom('', {url: 'https://privatebin.net/?0123456789abcdef#0'});
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
$('body').html('<button id="rawtextbutton"></button>');
|
$('body').html('<button id="rawtextbutton"></button>');
|
||||||
const sample = 'example';
|
const sample = 'example';
|
||||||
$.PrivateBin.PasteViewer.setText(sample);
|
$.PrivateBin.PasteViewer.setText(sample);
|
||||||
|
|
|
@ -18,6 +18,11 @@ describe('UiHelper', function () {
|
||||||
const expected = common.urlToString(url),
|
const expected = common.urlToString(url),
|
||||||
clean = jsdom('', {url: expected});
|
clean = jsdom('', {url: expected});
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.mockHistoryChange();
|
$.PrivateBin.UiHelper.mockHistoryChange();
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
var result = window.location.href;
|
var result = window.location.href;
|
||||||
|
@ -35,6 +40,11 @@ describe('UiHelper', function () {
|
||||||
const expected = common.urlToString(url),
|
const expected = common.urlToString(url),
|
||||||
clean = jsdom('', {url: expected});
|
clean = jsdom('', {url: expected});
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.mockHistoryChange([
|
$.PrivateBin.UiHelper.mockHistoryChange([
|
||||||
{type: 'newpaste'}, '', expected
|
{type: 'newpaste'}, '', expected
|
||||||
]);
|
]);
|
||||||
|
@ -47,8 +57,6 @@ describe('UiHelper', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('reloadHome', function () {
|
describe('reloadHome', function () {
|
||||||
// TODO triggers error messages in jsDOM since version 11
|
|
||||||
/*
|
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
before(function () {
|
before(function () {
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
|
@ -63,6 +71,11 @@ describe('UiHelper', function () {
|
||||||
delete(url.fragment);
|
delete(url.fragment);
|
||||||
const expected = common.urlToString(url);
|
const expected = common.urlToString(url);
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.reloadHome();
|
$.PrivateBin.UiHelper.reloadHome();
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
var result = window.location.href;
|
var result = window.location.href;
|
||||||
|
@ -70,7 +83,6 @@ describe('UiHelper', function () {
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isVisible', function () {
|
describe('isVisible', function () {
|
||||||
|
|
|
@ -45,17 +45,7 @@ class Configuration
|
||||||
'defaultformatter' => 'plaintext',
|
'defaultformatter' => 'plaintext',
|
||||||
'syntaxhighlightingtheme' => '',
|
'syntaxhighlightingtheme' => '',
|
||||||
'sizelimit' => 10485760,
|
'sizelimit' => 10485760,
|
||||||
'templateselection' => false,
|
|
||||||
'template' => 'bootstrap',
|
'template' => 'bootstrap',
|
||||||
'availabletemplates' => array(
|
|
||||||
'bootstrap5',
|
|
||||||
'bootstrap',
|
|
||||||
'bootstrap-page',
|
|
||||||
'bootstrap-dark',
|
|
||||||
'bootstrap-dark-page',
|
|
||||||
'bootstrap-compact',
|
|
||||||
'bootstrap-compact-page',
|
|
||||||
),
|
|
||||||
'info' => 'More information on the <a href=\'https://privatebin.info/\'>project page</a>.',
|
'info' => 'More information on the <a href=\'https://privatebin.info/\'>project page</a>.',
|
||||||
'notice' => '',
|
'notice' => '',
|
||||||
'languageselection' => false,
|
'languageselection' => false,
|
||||||
|
@ -64,7 +54,7 @@ class Configuration
|
||||||
'qrcode' => true,
|
'qrcode' => true,
|
||||||
'email' => true,
|
'email' => true,
|
||||||
'icon' => 'identicon',
|
'icon' => 'identicon',
|
||||||
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; frame-src blob:; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads',
|
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
||||||
'zerobincompatibility' => false,
|
'zerobincompatibility' => false,
|
||||||
'httpwarning' => true,
|
'httpwarning' => true,
|
||||||
'compression' => 'zlib',
|
'compression' => 'zlib',
|
||||||
|
@ -118,11 +108,11 @@ class Configuration
|
||||||
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
||||||
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
||||||
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
||||||
'js/privatebin.js' => 'sha512-9X1Ns+w/WPlWde118Mbl1UFDPsFmBcXK2zr6ny7oDOuZMVP1hFCPzXjKbC+59xDQW0Q+NmyT4NC6/5B6UzkkDw==',
|
'js/privatebin.js' => 'sha512-POa+8KNXFFwJFsqp7r9APmR5Rc1w2l363y+OScSzLCySrHN7UhOOgt1VH/o8mVddFvvUozj3FZVmdkTxRlrS5g==',
|
||||||
'js/purify-3.2.6.js' => 'sha512-zqwL4OoBLFx89QPewkz4Lz5CSA2ktU+f31fuECkF0iK3Id5qd3Zpq5dMby8KwHjIEpsUgOqwF58cnmcaNem0EA==',
|
'js/purify-3.2.4.js' => 'sha512-Mu9BqoHURMeycg6AgqTpokUv9guq88pajfaFqz53fx1OxohyROkydXPLEIbdKCQ7EdDs9hgcrYeZ9zTiPQQ4CA==',
|
||||||
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
|
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
|
||||||
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
||||||
'js/zlib-1.3.1-1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
'js/zlib-1.3.1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Controller
|
||||||
*
|
*
|
||||||
* @const string
|
* @const string
|
||||||
*/
|
*/
|
||||||
const VERSION = '1.7.8';
|
const VERSION = '1.7.6';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* minimal required PHP version
|
* minimal required PHP version
|
||||||
|
@ -112,12 +112,10 @@ class Controller
|
||||||
*
|
*
|
||||||
* initializes and runs PrivateBin
|
* initializes and runs PrivateBin
|
||||||
*
|
*
|
||||||
* @param ?Configuration $config
|
|
||||||
*
|
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(?Configuration $config = null)
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
|
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
|
||||||
error_log(I18n::_('%s requires php %s or above to work. Sorry.', I18n::_('PrivateBin'), self::MIN_PHP_VERSION));
|
error_log(I18n::_('%s requires php %s or above to work. Sorry.', I18n::_('PrivateBin'), self::MIN_PHP_VERSION));
|
||||||
|
@ -128,8 +126,7 @@ class Controller
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load config (using ini file by default) & initialize required classes
|
// load config from ini file, initialize required classes
|
||||||
$this->_conf = $config ?? new Configuration();
|
|
||||||
$this->_init();
|
$this->_init();
|
||||||
|
|
||||||
switch ($this->_request->getOperation()) {
|
switch ($this->_request->getOperation()) {
|
||||||
|
@ -177,21 +174,12 @@ class Controller
|
||||||
*/
|
*/
|
||||||
private function _init()
|
private function _init()
|
||||||
{
|
{
|
||||||
|
$this->_conf = new Configuration;
|
||||||
$this->_model = new Model($this->_conf);
|
$this->_model = new Model($this->_conf);
|
||||||
$this->_request = new Request;
|
$this->_request = new Request;
|
||||||
$this->_urlBase = $this->_request->getRequestUri();
|
$this->_urlBase = $this->_request->getRequestUri();
|
||||||
|
|
||||||
$this->_setDefaultLanguage();
|
// set default language
|
||||||
$this->_setDefaultTemplate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default language
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _setDefaultLanguage()
|
|
||||||
{
|
|
||||||
$lang = $this->_conf->getKey('languagedefault');
|
$lang = $this->_conf->getKey('languagedefault');
|
||||||
I18n::setLanguageFallback($lang);
|
I18n::setLanguageFallback($lang);
|
||||||
// force default language, if language selection is disabled and a default is set
|
// force default language, if language selection is disabled and a default is set
|
||||||
|
@ -201,25 +189,6 @@ class Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default template
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _setDefaultTemplate()
|
|
||||||
{
|
|
||||||
$templates = $this->_conf->getKey('availabletemplates');
|
|
||||||
$template = $this->_conf->getKey('template');
|
|
||||||
TemplateSwitcher::setAvailableTemplates($templates);
|
|
||||||
TemplateSwitcher::setTemplateFallback($template);
|
|
||||||
|
|
||||||
// force default template, if template selection is disabled and a default is set
|
|
||||||
if (!$this->_conf->getKey('templateselection') && !empty($template)) {
|
|
||||||
$_COOKIE['template'] = $template;
|
|
||||||
setcookie('template', $template, array('SameSite' => 'Lax', 'Secure' => true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn off browser caching
|
* Turn off browser caching
|
||||||
*
|
*
|
||||||
|
@ -431,18 +400,11 @@ class Controller
|
||||||
setcookie('lang', $languageselection, array('SameSite' => 'Lax', 'Secure' => true));
|
setcookie('lang', $languageselection, array('SameSite' => 'Lax', 'Secure' => true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set template cookie if that functionality was enabled
|
|
||||||
$templateselection = '';
|
|
||||||
if ($this->_conf->getKey('templateselection')) {
|
|
||||||
$templateselection = TemplateSwitcher::getTemplate();
|
|
||||||
setcookie('template', $templateselection, array('SameSite' => 'Lax', 'Secure' => true));
|
|
||||||
}
|
|
||||||
|
|
||||||
// strip policies that are unsupported in meta tag
|
// strip policies that are unsupported in meta tag
|
||||||
$metacspheader = str_replace(
|
$metacspheader = str_replace(
|
||||||
array(
|
array(
|
||||||
'frame-ancestors \'none\'; ',
|
'frame-ancestors \'none\'; ',
|
||||||
'; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads',
|
'; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
||||||
),
|
),
|
||||||
'',
|
'',
|
||||||
$this->_conf->getKey('cspheader')
|
$this->_conf->getKey('cspheader')
|
||||||
|
@ -476,8 +438,6 @@ class Controller
|
||||||
$page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
|
$page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
|
||||||
$page->assign('LANGUAGESELECTION', $languageselection);
|
$page->assign('LANGUAGESELECTION', $languageselection);
|
||||||
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
||||||
$page->assign('TEMPLATESELECTION', $templateselection);
|
|
||||||
$page->assign('TEMPLATES', TemplateSwitcher::getAvailableTemplates());
|
|
||||||
$page->assign('EXPIRE', $expire);
|
$page->assign('EXPIRE', $expire);
|
||||||
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
|
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
|
||||||
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
||||||
|
@ -487,7 +447,7 @@ class Controller
|
||||||
$page->assign('HTTPSLINK', 'https://' . $this->_request->getHost() . $this->_request->getRequestUri());
|
$page->assign('HTTPSLINK', 'https://' . $this->_request->getHost() . $this->_request->getRequestUri());
|
||||||
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
||||||
$page->assign('SRI', $this->_conf->getSection('sri'));
|
$page->assign('SRI', $this->_conf->getSection('sri'));
|
||||||
$page->draw(TemplateSwitcher::getTemplate());
|
$page->draw($this->_conf->getKey('template'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,7 @@ abstract class AbstractData
|
||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
abstract public function create($pasteid, array &$paste);
|
abstract public function create($pasteid, array $paste);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a paste.
|
* Read a paste.
|
||||||
|
@ -72,7 +72,7 @@ abstract class AbstractData
|
||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
abstract public function createComment($pasteid, $parentid, $commentid, array &$comment);
|
abstract public function createComment($pasteid, $parentid, $commentid, array $comment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all comments of paste.
|
* Read all comments of paste.
|
||||||
|
@ -199,7 +199,7 @@ abstract class AbstractData
|
||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected static function upgradePreV1Format(array &$paste)
|
protected static function upgradePreV1Format(array $paste)
|
||||||
{
|
{
|
||||||
if (array_key_exists('attachment', $paste['meta'])) {
|
if (array_key_exists('attachment', $paste['meta'])) {
|
||||||
$paste['attachment'] = $paste['meta']['attachment'];
|
$paste['attachment'] = $paste['meta']['attachment'];
|
||||||
|
|
|
@ -140,7 +140,7 @@ class Database extends AbstractData
|
||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
$expire_date = 0;
|
$expire_date = 0;
|
||||||
$opendiscussion = $burnafterreading = false;
|
$opendiscussion = $burnafterreading = false;
|
||||||
|
@ -297,18 +297,14 @@ class Database extends AbstractData
|
||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if (array_key_exists('data', $comment)) {
|
if (array_key_exists('data', $comment)) {
|
||||||
$version = 1;
|
$version = 1;
|
||||||
$data = $comment['data'];
|
$data = $comment['data'];
|
||||||
} else {
|
} else {
|
||||||
try {
|
$version = 2;
|
||||||
$version = 2;
|
$data = Json::encode($comment);
|
||||||
$data = Json::encode($comment);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
list($createdKey, $iconKey) = $this->_getVersionedKeys($version);
|
list($createdKey, $iconKey) = $this->_getVersionedKeys($version);
|
||||||
$meta = $comment['meta'];
|
$meta = $comment['meta'];
|
||||||
|
|
|
@ -85,7 +85,7 @@ class Filesystem extends AbstractData
|
||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
$storagedir = $this->_dataid2path($pasteid);
|
$storagedir = $this->_dataid2path($pasteid);
|
||||||
$file = $storagedir . $pasteid . '.php';
|
$file = $storagedir . $pasteid . '.php';
|
||||||
|
@ -188,7 +188,7 @@ class Filesystem extends AbstractData
|
||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
$storagedir = $this->_dataid2discussionpath($pasteid);
|
$storagedir = $this->_dataid2discussionpath($pasteid);
|
||||||
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
|
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
|
||||||
|
@ -276,7 +276,7 @@ class Filesystem extends AbstractData
|
||||||
case 'purge_limiter':
|
case 'purge_limiter':
|
||||||
return $this->_storeString(
|
return $this->_storeString(
|
||||||
$this->_path . DIRECTORY_SEPARATOR . 'purge_limiter.php',
|
$this->_path . DIRECTORY_SEPARATOR . 'purge_limiter.php',
|
||||||
'<?php' . PHP_EOL . '$GLOBALS[\'purge_limiter\'] = ' . var_export($value, true) . ';'
|
'<?php' . PHP_EOL . '$GLOBALS[\'purge_limiter\'] = ' . $value . ';'
|
||||||
);
|
);
|
||||||
case 'salt':
|
case 'salt':
|
||||||
return $this->_storeString(
|
return $this->_storeString(
|
||||||
|
@ -308,9 +308,7 @@ class Filesystem extends AbstractData
|
||||||
$file = $this->_path . DIRECTORY_SEPARATOR . 'purge_limiter.php';
|
$file = $this->_path . DIRECTORY_SEPARATOR . 'purge_limiter.php';
|
||||||
if (is_readable($file)) {
|
if (is_readable($file)) {
|
||||||
require $file;
|
require $file;
|
||||||
if (array_key_exists('purge_limiter', $GLOBALS)) {
|
return $GLOBALS['purge_limiter'];
|
||||||
return $GLOBALS['purge_limiter'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'salt':
|
case 'salt':
|
||||||
|
@ -326,11 +324,9 @@ class Filesystem extends AbstractData
|
||||||
$file = $this->_path . DIRECTORY_SEPARATOR . 'traffic_limiter.php';
|
$file = $this->_path . DIRECTORY_SEPARATOR . 'traffic_limiter.php';
|
||||||
if (is_readable($file)) {
|
if (is_readable($file)) {
|
||||||
require $file;
|
require $file;
|
||||||
if (array_key_exists('traffic_limiter', $GLOBALS)) {
|
$this->_last_cache = $GLOBALS['traffic_limiter'];
|
||||||
$this->_last_cache = $GLOBALS['traffic_limiter'];
|
if (array_key_exists($key, $this->_last_cache)) {
|
||||||
if (array_key_exists($key, $this->_last_cache)) {
|
return $this->_last_cache[$key];
|
||||||
return $this->_last_cache[$key];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -347,11 +343,12 @@ class Filesystem extends AbstractData
|
||||||
*/
|
*/
|
||||||
private function _get($filename)
|
private function _get($filename)
|
||||||
{
|
{
|
||||||
$data = substr(
|
return Json::decode(
|
||||||
file_get_contents($filename),
|
substr(
|
||||||
strlen(self::PROTECTION_LINE . PHP_EOL)
|
file_get_contents($filename),
|
||||||
|
strlen(self::PROTECTION_LINE . PHP_EOL)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
return Json::decode($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -105,7 +105,7 @@ class GoogleCloudStorage extends AbstractData
|
||||||
* @param $payload array to store
|
* @param $payload array to store
|
||||||
* @return bool true if successful, otherwise false.
|
* @return bool true if successful, otherwise false.
|
||||||
*/
|
*/
|
||||||
private function _upload($key, &$payload)
|
private function _upload($key, $payload)
|
||||||
{
|
{
|
||||||
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
||||||
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
||||||
|
@ -136,7 +136,7 @@ class GoogleCloudStorage extends AbstractData
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
if ($this->exists($pasteid)) {
|
if ($this->exists($pasteid)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,7 +201,7 @@ class GoogleCloudStorage extends AbstractData
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -219,8 +219,7 @@ class GoogleCloudStorage extends AbstractData
|
||||||
$prefix = $this->_getKey($pasteid) . '/discussion/';
|
$prefix = $this->_getKey($pasteid) . '/discussion/';
|
||||||
try {
|
try {
|
||||||
foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) {
|
foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) {
|
||||||
$data = $this->_bucket->object($key->name())->downloadAsString();
|
$comment = JSON::decode($this->_bucket->object($key->name())->downloadAsString());
|
||||||
$comment = Json::decode($data);
|
|
||||||
$comment['id'] = basename($key->name());
|
$comment['id'] = basename($key->name());
|
||||||
$slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
|
$slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
|
||||||
$comments[$slot] = $comment;
|
$comments[$slot] = $comment;
|
||||||
|
|
|
@ -165,7 +165,7 @@ class S3Storage extends AbstractData
|
||||||
* @param $payload array to store
|
* @param $payload array to store
|
||||||
* @return bool true if successful, otherwise false.
|
* @return bool true if successful, otherwise false.
|
||||||
*/
|
*/
|
||||||
private function _upload($key, &$payload)
|
private function _upload($key, $payload)
|
||||||
{
|
{
|
||||||
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
||||||
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
||||||
|
@ -191,7 +191,7 @@ class S3Storage extends AbstractData
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
if ($this->exists($pasteid)) {
|
if ($this->exists($pasteid)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -263,7 +263,7 @@ class S3Storage extends AbstractData
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,7 @@ class FormatV2
|
||||||
* @param bool $isComment
|
* @param bool $isComment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isValid(&$message, $isComment = false)
|
public static function isValid($message, $isComment = false)
|
||||||
{
|
{
|
||||||
$required_keys = array('adata', 'v', 'ct');
|
$required_keys = array('adata', 'v', 'ct');
|
||||||
if ($isComment) {
|
if ($isComment) {
|
||||||
|
|
12
lib/I18n.php
|
@ -183,12 +183,9 @@ class I18n
|
||||||
|
|
||||||
// load translations
|
// load translations
|
||||||
self::$_language = $match;
|
self::$_language = $match;
|
||||||
if ($match == 'en') {
|
self::$_translations = ($match == 'en') ? array() : Json::decode(
|
||||||
self::$_translations = array();
|
file_get_contents(self::_getPath($match . '.json'))
|
||||||
} else {
|
);
|
||||||
$data = file_get_contents(self::_getPath($match . '.json'));
|
|
||||||
self::$_translations = Json::decode($data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -276,8 +273,7 @@ class I18n
|
||||||
{
|
{
|
||||||
$file = self::_getPath('languages.json');
|
$file = self::_getPath('languages.json');
|
||||||
if (count(self::$_languageLabels) == 0 && is_readable($file)) {
|
if (count(self::$_languageLabels) == 0 && is_readable($file)) {
|
||||||
$data = file_get_contents($file);
|
self::$_languageLabels = Json::decode(file_get_contents($file));
|
||||||
self::$_languageLabels = Json::decode($data);
|
|
||||||
}
|
}
|
||||||
if (count($languages) == 0) {
|
if (count($languages) == 0) {
|
||||||
return self::$_languageLabels;
|
return self::$_languageLabels;
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Json
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function encode(&$input)
|
public static function encode($input)
|
||||||
{
|
{
|
||||||
$jsonString = json_encode($input);
|
$jsonString = json_encode($input);
|
||||||
self::_detectError();
|
self::_detectError();
|
||||||
|
@ -45,7 +45,7 @@ class Json
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function decode(&$input)
|
public static function decode($input)
|
||||||
{
|
{
|
||||||
$output = json_decode($input, true);
|
$output = json_decode($input, true);
|
||||||
self::_detectError();
|
self::_detectError();
|
||||||
|
|
|
@ -100,9 +100,9 @@ abstract class AbstractModel
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function setData(array &$data)
|
public function setData(array $data)
|
||||||
{
|
{
|
||||||
$this->_sanitize($data);
|
$data = $this->_sanitize($data);
|
||||||
$this->_validate($data);
|
$this->_validate($data);
|
||||||
$this->_data = $data;
|
$this->_data = $data;
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ abstract class AbstractModel
|
||||||
*/
|
*/
|
||||||
public static function isValidId($id)
|
public static function isValidId($id)
|
||||||
{
|
{
|
||||||
return (bool) preg_match('#\A[a-f0-9]{16}\z#', (string) $id);
|
return (bool) preg_match('#\A[a-f\d]{16}\z#', (string) $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,8 +163,9 @@ abstract class AbstractModel
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
abstract protected function _sanitize(array &$data);
|
abstract protected function _sanitize(array $data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate data.
|
* Validate data.
|
||||||
|
@ -173,7 +174,7 @@ abstract class AbstractModel
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function _validate(array &$data)
|
protected function _validate(array $data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ class Comment extends AbstractModel
|
||||||
* @param Paste $paste
|
* @param Paste $paste
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function setPaste(Paste &$paste)
|
public function setPaste(Paste $paste)
|
||||||
{
|
{
|
||||||
$this->_paste = $paste;
|
$this->_paste = $paste;
|
||||||
$this->_data['pasteid'] = $paste->getId();
|
$this->_data['pasteid'] = $paste->getId();
|
||||||
|
@ -155,8 +155,9 @@ class Comment extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function _sanitize(array &$data)
|
protected function _sanitize(array $data)
|
||||||
{
|
{
|
||||||
// we generate an icon based on a SHA512 HMAC of the users IP, if configured
|
// we generate an icon based on a SHA512 HMAC of the users IP, if configured
|
||||||
$icon = $this->_conf->getKey('icon');
|
$icon = $this->_conf->getKey('icon');
|
||||||
|
@ -189,5 +190,6 @@ class Comment extends AbstractModel
|
||||||
$data['meta']['icon'] = $pngdata;
|
$data['meta']['icon'] = $pngdata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,10 +219,11 @@ class Paste extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function _sanitize(array &$data)
|
protected function _sanitize(array $data)
|
||||||
{
|
{
|
||||||
$expiration = $data['meta']['expire'] ?? 0;
|
$expiration = $data['meta']['expire'];
|
||||||
unset($data['meta']['expire']);
|
unset($data['meta']['expire']);
|
||||||
$expire_options = $this->_conf->getSection('expire_options');
|
$expire_options = $this->_conf->getSection('expire_options');
|
||||||
if (array_key_exists($expiration, $expire_options)) {
|
if (array_key_exists($expiration, $expire_options)) {
|
||||||
|
@ -234,6 +235,7 @@ class Paste extends AbstractModel
|
||||||
if ($expire > 0) {
|
if ($expire > 0) {
|
||||||
$data['meta']['expire_date'] = time() + $expire;
|
$data['meta']['expire_date'] = time() + $expire;
|
||||||
}
|
}
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,7 +245,7 @@ class Paste extends AbstractModel
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function _validate(array &$data)
|
protected function _validate(array $data)
|
||||||
{
|
{
|
||||||
// reject invalid or disabled formatters
|
// reject invalid or disabled formatters
|
||||||
if (!array_key_exists($data['adata'][1], $this->_conf->getSection('formatter_options'))) {
|
if (!array_key_exists($data['adata'][1], $this->_conf->getSection('formatter_options'))) {
|
||||||
|
|