Compare commits

...

144 Commits

Author SHA1 Message Date
Dan Brown
26aadffb20 Updated version and assets for release v24.10 2024-10-09 10:48:34 +01:00
Dan Brown
a5f48e3202 Merge branch 'development' into release 2024-10-09 10:46:07 +01:00
Dan Brown
a58102d6ef Attribution: Updated translator & license files before v24.10 2024-10-09 10:26:07 +01:00
Dan Brown
65453bd94e Updated translations with latest Crowdin changes (#5188) 2024-10-09 10:21:55 +01:00
Dan Brown
d22413b931 JS: Converted/updated translation code to TS, fixed some comment counts
- Migrated translation service to TS, stripping a lot of now unused code
  along the way.
- Added test to cover translation service.
- Fixed some comment count issues, where it was not showing correct
  value. or updating, on comment create or delete.
2024-10-07 22:55:10 +01:00
Dan Brown
8b9bcc1768 Search: Fixed last commented filter when using table prefixes 2024-10-05 15:20:04 +01:00
Dan Brown
51287d545b Searching: Fixed some form search issues
- Form was not retaining certain filters
- Form request handling of entity type set wrong filter name
Added test to cover.
2024-10-05 14:49:30 +01:00
Dan Brown
c314a60a16 WYSIWYG: Code & table fixes
- Fixed new code block insertion to remove selection area instead of
  just adding after.
- Added default table column widths to not be collapsed
- Updated table dom export to not duplicate colgroups.
2024-10-05 12:42:47 +01:00
Dan Brown
9b2520aa0c WYSIWYG: Fixed list indenting selection & display bugs
- Fixed selection breaking on multiple indent changes
- Fixed multi-indent showing numbers on empty child list until the nodes
  are fully re-rendered.
2024-10-04 15:11:09 +01:00
Dan Brown
346b88ae43 JS: Converted a few extra services to TS 2024-10-04 14:36:20 +01:00
Dan Brown
2766c76491 TinyMCE: Updated version from 6.8.3 to 6.8.4 2024-10-04 12:46:22 +01:00
Dan Brown
be6529d0a1 New WYSIWYG: Added mac shortcut support 2024-10-04 12:41:13 +01:00
Dan Brown
b1a3ea1aa4 Languages: Enabled Welsh option 2024-10-04 11:02:17 +01:00
Dan Brown
6646dcc24d Merge pull request #5239 from BookStackApp/search_negation
Search term negation
2024-10-03 19:52:06 +01:00
Dan Brown
966ff91386 Search: Prevented negated terms filling in UI inputs
Added test to cover.
2024-10-03 19:40:11 +01:00
Dan Brown
cd84d08157 Search: Added exact/filter/tag term negation support 2024-10-03 19:27:03 +01:00
Dan Brown
93c677a6a9 Searching: Added negation support to UI and term handling
Updated/added tests to cover.
Support for actual search queries still remains.
2024-10-03 15:59:50 +01:00
Dan Brown
177cfd72bf Search: Added structure for search term inputs
Sets things up to allow more complex terms ready to handle negation.
2024-10-02 17:31:45 +01:00
Dan Brown
34ade50181 Base layout: Changed main app script to be module loaded
Prevents polluting global scope with variables since we're using the
module format bundler in esbuild.
Also cleaned up unused yields.
Fixed bad reference in our tinymce fixes.

For #5232
2024-10-01 10:37:31 +01:00
Dan Brown
e65655594f Merge branch 'feature/opensearch' into development 2024-09-30 17:21:51 +01:00
Dan Brown
514db60617 Tests: Categorised up meta tests
Extracted robots.txt tests into its own file to fit into new folder.
Also tweaked open search tests a tad to specifically check long app
names.
2024-09-30 17:07:53 +01:00
Dan Brown
8bc6e75319 Code Blocks: Added SAS and R language options
For #5206
2024-09-30 16:47:55 +01:00
Maximilian Walter
2f74cfb42c Add test for OpenSearch endpoint 2024-09-30 17:45:20 +02:00
Maximilian Walter
1302e3c959 Add missing XML declaration to OpenSearch endpoint 2024-09-30 17:45:20 +02:00
Maximilian Walter
a5b031f906 Translatable description for OpenSearch XML 2024-09-30 17:45:20 +02:00
Dan Brown
f583354748 Maintenance: Removed stray dd from last commit 2024-09-29 16:50:48 +01:00
Dan Brown
d12e8ec923 Users: Improved user response for failed invite sending
Added specific handling to show relevant error message when user
creation fails due to invite sending errors, while also returning user
to the form with previous input.
Includes test to cover.

For #5195
2024-09-29 16:41:18 +01:00
Dan Brown
89f84c9a95 Pages: Updated editor field to always be set
- Migration for setting on existing pages
- Added test to cover simple new page scenario

For #5117
2024-09-29 14:36:41 +01:00
Dan Brown
6103a22feb Exports: Made pdf command timeout configurable
Added test to cover.
For #5119
2024-09-27 16:33:58 +01:00
Dan Brown
42264f402d CSS: Fixed floating search icon on mobile
Also updated styles to use logical elements instead of conditional rules
for altered search boxes.
Related to #2504
2024-09-27 16:02:13 +01:00
Dan Brown
abda9bc00a PHP Dependancies: Updated packages pending major version changes
Closes #5222
2024-09-27 14:21:12 +01:00
Dan Brown
eec639d84e Maintenance: Fixed js lint and SCSS build warnings 2024-09-27 13:57:39 +01:00
Dan Brown
56b9107c6b Dependancies: Updated php & JS deps, updated license lists
Fixed issue now picked up by newer TS version
2024-09-27 12:29:19 +01:00
Dan Brown
b35b62d59f Merge branch 'lexical' into development 2024-09-27 12:04:01 +01:00
Dan Brown
1b9310e766 Meta: Added lexical licensing info and added TS/JS CI testing 2024-09-27 10:45:48 +01:00
Dan Brown
a62d8381be Lexical: Updated toolbar & text node exporting
- Updated toolbar to match existing editor, including dynamic RTL/LTR
  controls.
- Updated text node handling to not include spans and extra classes when
  not needed. Added & update tests to cover.
2024-09-23 17:36:16 +01:00
Dan Brown
8b32e6c15a Page Editors: Added switching/options for new lexical editor 2024-09-22 20:06:55 +01:00
Dan Brown
c8ccb2bac7 Lexical: Range of fixes
- Prevented ui shortcuts running in editor
- Added form modal closing on submit
- Fixed ability to escape lists via enter on empty last item
2024-09-22 16:15:02 +01:00
Dan Brown
ef3de1050f Lexical: Added UI translation support 2024-09-22 12:29:06 +01:00
Dan Brown
2add15bd72 Lexical: Added direction support to extra blocks
Also removed duplicated dir functionality that remained in core.
2024-09-22 12:07:24 +01:00
Dan Brown
e6edd9340e Lexical: Added alignment detoggle, fixed inital focus area 2024-09-21 17:02:54 +01:00
Dan Brown
654a7a5d03 Lexical: Removed reconciler level direction handling
- Updated tests to consider changes
2024-09-21 13:00:16 +01:00
Dan Brown
dba8ab947f Lexical: Finished conversion/update of test files 2024-09-20 15:31:19 +01:00
Dan Brown
787e06e3d8 Lexical: Adapted a range of further existing tests 2024-09-20 13:05:29 +01:00
Dan Brown
ccd486f2a9 Lexical: Got a range of Editor tests working 2024-09-18 17:31:51 +01:00
Dan Brown
22d078b47f Lexical: Imported core lexical libs
Imported at 0.17.1, Modified to work in-app.
Added & configured test dependancies.
Tests need to be altered to avoid using non-included deps including
react dependancies.
2024-09-18 13:43:39 +01:00
Dan Brown
03490d6597 Lexical: Added RTL/LTR actions
Kinda useless though due to Lexical reconciler :(
2024-09-16 12:29:46 +01:00
Dan Brown
5f46d71af0 Lexical: Fixed a range of issues in RTL mode 2024-09-15 16:10:46 +01:00
Maximilian Walter
4f890c431c Limit short-name for OpenSearch XML to 16 characters
The specification does not allow more than 16 characters.
2024-09-14 15:31:56 +02:00
Maximilian Walter
c110a97d8a Remove unofficial method-attribute from OpenSearch-XML 2024-09-14 15:24:42 +02:00
Dan Brown
6872eb802c Lexical: Altered keyboard handling to indicant handled state 2024-09-13 16:05:55 +01:00
Dan Brown
662110c269 Lexical: Custom list nesting support
Added list nesting support to allow li > ul style nesting which lexical
didn't do by default.
Adds tab handling for inset/outset controls.
Will be a range of edge-case bugs to squash during testing.
2024-09-13 15:50:42 +01:00
Dan Brown
5083188ed8 Lexical: Added block indenting capability
Needed a custom implementation due to hardcoded defaults for Lexical
default indenting.
2024-09-10 15:55:46 +01:00
Dan Brown
2036438203 Lexical: Added single node enter handling
Also updated media to be an inline element to align with old editor
behaviour.
2024-09-10 12:14:26 +01:00
Maximilian Walter
476c2be5a6 Add XML for OpenSearch 2024-09-09 22:54:33 +02:00
Dan Brown
ced66f1671 Lexical: Added single node backspace/delete support 2024-09-09 18:33:54 +01:00
Dan Brown
fb49371c6b Lexical: Refined editor UI
- Cleaned up dropdown lists to look integrated
- Added icons for color picker clear and menu list items
2024-09-09 14:06:41 +01:00
Dan Brown
fd07aa0f05 Lexical: Further fixes
- Improved node resizer positioning to be more accurate
- Fixed drop handling not running within editor margin space
- Made media dom update smarter to reduce reloads
- Fixed media alignment, broken due to added wrapper
2024-09-09 12:28:01 +01:00
Dan Brown
16518a4f89 Lexical: Range of bug fixes, Updated lexical version
- Updated selection change detection to be more accurate
- Added UI refresh for extra actions
- Fixed remove link deleting contents
2024-09-08 15:54:59 +01:00
Dan Brown
bed2c29a33 Lexical: Added media resize support via drag handles 2024-09-08 13:37:13 +01:00
Dan Brown
e5b6d28bca Lexical: Revamped image node resize method
Changed from using a decorator to using a helper that watches for image
selections to then display a resize helper.
Also changes resizer to use a ghost and apply changes on end instead of
continuosly during resize.
2024-09-07 18:39:58 +01:00
Dan Brown
1c9afcb84e Lexical: Added some level of img/media alignment 2024-09-06 14:07:10 +01:00
Dan Brown
1ebb0f8c93 Lexical: Added table column cut/copy/paste support 2024-08-22 13:28:30 +01:00
Dan Brown
8a13a9df80 Lexical: Improved table row copy/paste
Added safeguarding/matching of source/target sizes to prevent broken
tables.
2024-08-22 10:08:08 +01:00
Dan Brown
ddf5f2543c Lexical: Added drop/paste image handling 2024-08-21 12:59:45 +01:00
Dan Brown
dbb2fe3e59 Lexical: Finished off baseline shortcut implementation 2024-08-20 14:54:53 +01:00
Dan Brown
aa1fac62d5 Lexical: Started adding editor shortcuts 2024-08-20 13:07:33 +01:00
Dan Brown
111a313d51 Lexical: Added custom alignment handling for blocks
To align with pre-existing use of alignment classes.
2024-08-18 16:51:08 +01:00
Dan Brown
0039f893cc Lexical: Integrated diagram manager, added menu split button 2024-08-17 10:48:34 +01:00
Dan Brown
ad6b26ba97 Lexical: Added basic URL field header option list
May show bad option label names on chrome/safari.
This was an easy first pass without loads of extra custom UI since we're
using native datalists.
2024-08-16 12:29:40 +01:00
Dan Brown
1ef4044419 Lexical: Connected link selector to link form 2024-08-16 11:22:12 +01:00
Dan Brown
accf2565a0 Lexical: Integrated image manager to image button/form 2024-08-13 19:36:18 +01:00
Dan Brown
ec965f28c0 Lexical: Added id support for all main block types 2024-08-11 16:08:51 +01:00
Dan Brown
ebf95f637a Lexical: Wired table properties, and other buttons 2024-08-10 13:14:55 +01:00
Dan Brown
abbfd42a6c Lexical: Kinda made row copy/paste work 2024-08-09 21:58:45 +01:00
Dan Brown
db4208a7eb Lexical: Linked row properties form up 2024-08-09 12:42:04 +01:00
Dan Brown
da54e1d87c Lexical: Added cell width fetching, Created custom row node 2024-08-09 11:24:25 +01:00
Dan Brown
e8532ef4de Lexical: Added merge cell logic 2024-08-07 20:32:54 +01:00
Dan Brown
fcc1c2968d Lexical: Added table cell node import logic 2024-08-06 09:36:37 +01:00
Dan Brown
b3d3b14f79 Lexical: Finished off core cell properties functionality 2024-08-05 18:49:17 +01:00
Dan Brown
8939f310db Lexical: Started linking up cell properties form 2024-08-05 15:08:52 +01:00
Dan Brown
efec752985 Lexical: Split helpers to utils, refactored files 2024-08-03 18:14:01 +01:00
Dan Brown
e94ad78ea7 Lexical: Completed out table menu elements, logic pending 2024-08-03 18:01:54 +01:00
Dan Brown
a27a325af7 Lexical: Started on table actions
Started building table cell form/actions
2024-08-02 15:28:54 +01:00
Dan Brown
6b06d490c5 Lexical: Started table menu options
Updated UI elements to handle new scenarios needed in more complex table
menu
2024-08-02 11:16:54 +01:00
Dan Brown
13f8f39dd5 Lexical: Updated task list to use/support old format 2024-07-30 14:42:19 +01:00
Dan Brown
fe05cff64f Lexical: Linked up change/draft management 2024-07-29 21:43:20 +01:00
Dan Brown
d86837ac07 Lexical: Got working with attachment insert/drop 2024-07-29 21:14:42 +01:00
Dan Brown
9a7edc6e52 Lexical: Started drop handling, handled templates 2024-07-29 15:27:41 +01:00
Dan Brown
ce8c9dd079 Lexical: Added form complex/tab ui support 2024-07-28 12:48:58 +01:00
Dan Brown
c8f6b7e0d6 Lexical: Got media node core work & form done 2024-07-27 17:25:30 +01:00
Dan Brown
f284d31861 Lexical: Started media node support 2024-07-25 16:25:08 +01:00
Dan Brown
76b0d2d5d8 Lexical: Added common events support 2024-07-23 15:35:18 +01:00
Dan Brown
2cab778f19 Lexical: Improved table resize bars
Added scoll & page resize handling.
Added cropping/limiting to edit area.
2024-07-23 12:45:58 +01:00
Dan Brown
b618287585 Lexical: Added table toolbar, organised button code 2024-07-21 15:11:24 +01:00
Dan Brown
63f4b42453 Lexical: Added toolbar scroll/resize handling
Also added smarter above/below positioning to respond if toolbar would
be off the bottom of the editor, and added hide/show when they'd go
outside editor scroll bounds.
2024-07-19 18:12:51 +01:00
Dan Brown
c7c0df0964 Lexical: Finished up core drawing insert/editing
Added new options that sits on the context, for things needed but not
for the core editor, which are defined out of the editor (drawio URL,
error message text, pageId etc...)
2024-07-19 12:09:41 +01:00
Dan Brown
fb87fb5750 JS: Converted http service to ts 2024-07-18 15:13:14 +01:00
Dan Brown
634b0aaa07 Lexical: Started converting drawio to TS
Converted events service to TS as part of this.
2024-07-18 11:19:11 +01:00
Dan Brown
5002a89754 Lexical: Standardised helper function format 2024-07-17 16:45:57 +01:00
Dan Brown
b367490edc Lexical: Added list support, started todo 2024-07-17 16:38:20 +01:00
Dan Brown
ea4c50c2c2 Lexical: Added code block selection & edit features
Also added extra lifecycle handling for decorators to things can be
properly cleaned up after node destruction.
2024-07-16 16:36:08 +01:00
Dan Brown
51d8044a54 Lexical: Added initial form/modal styles 2024-07-09 20:49:47 +01:00
Dan Brown
2c96af9aea Lexical: Worked on toolbar styling, got format submenu working 2024-07-04 16:16:16 +01:00
Dan Brown
04c7e680fd Lexical: Linked up saving logic of editor via interface 2024-07-04 13:09:53 +01:00
Dan Brown
a8f1160743 JS: Converted come common services to typescript 2024-07-03 11:00:57 +01:00
Dan Brown
feca1f0502 Lexical: Started diagram support 2024-07-03 10:28:04 +01:00
Dan Brown
d0a5a5ef37 Lexical: Linked code block to editor, added button 2024-07-02 17:34:03 +01:00
Dan Brown
97f570a4ee Lexical: Started code block node implementation 2024-07-02 14:46:30 +01:00
Dan Brown
9ebbf7ce94 Lexical: Started loading real content, Improved html loading
Added more styling/layout for buttons and main content area
2024-07-01 15:10:22 +01:00
Dan Brown
c2ecbf071f Lexical: Added tracked container, added fullscreen action
Changed how the editor is loaded in, so it now creates its own DOM, and
content is passed via creation function, to be better self-contained.
2024-07-01 10:44:23 +01:00
Dan Brown
b1c489090e Lexical: Added context toolbar placement, added link toolbar
Also added some basic context toolbar styling
2024-06-30 19:52:09 +01:00
Dan Brown
c9a03c5b01 Lexical: Added base context toolbar logic 2024-06-30 12:13:13 +01:00
Dan Brown
517c578a5f Lexical: Reorganised some logic into manager 2024-06-30 10:31:39 +01:00
Dan Brown
f10ec3271a Lexical: Added overflow container 2024-06-27 16:28:06 +01:00
Dan Brown
4e2820d6e3 Lexical: Added horizontal rule node 2024-06-27 15:48:06 +01:00
Dan Brown
72a0e081ca Lexical: Completed initial table cell resize handle logic 2024-06-26 17:22:00 +01:00
Dan Brown
b1130cb1c3 Lexical: Linked up table resize handler (unfinished) 2024-06-26 13:52:00 +01:00
Dan Brown
59936631ec Lexical: Extracted mouse drag tracking to new helper 2024-06-25 18:33:29 +01:00
Dan Brown
3af22ce754 Lexical: Created custom table node with col width handling 2024-06-24 20:50:17 +01:00
Dan Brown
5546b8ff43 Lexical: Added more icons, made reflective text/bg color buttons 2024-06-23 15:50:41 +01:00
Dan Brown
a07092b7e6 Lexical: Updated lexical, added undo state tracking, format styles 2024-06-23 11:36:48 +01:00
Dan Brown
ac01c62e6e Lexical: Added table creator UI 2024-06-21 16:18:44 +01:00
Dan Brown
f47f7dd9d2 Lexical: Added base table support and started resize handling 2024-06-21 13:47:47 +01:00
Dan Brown
13d970c7ce Lexical: Added button icon system
With a bunch of default icons
2024-06-19 20:00:29 +01:00
Dan Brown
e2409a5fab Lexical: Added basic list button/support 2024-06-19 16:14:20 +01:00
Dan Brown
9e43e03db4 Lexical: Added color picker controls 2024-06-12 19:51:42 +01:00
Dan Brown
a475cf68bf Lexical: Added clear formatting button 2024-06-12 14:24:50 +01:00
Dan Brown
e889bc680b Lexical: Added view/edit source code button/form/action 2024-06-12 14:01:36 +01:00
Dan Brown
5c343638b6 Added base node/button for details/summary 2024-06-06 14:43:50 +01:00
Dan Brown
0722960260 Lexical: Added selection to state for aligned reading
Connected up to work with image form
2024-06-05 18:43:42 +01:00
Dan Brown
e959c468f6 Lexical: Made image resize handles functional 2024-06-05 17:18:58 +01:00
Dan Brown
ba871ec46a Lexical: Started image resize controls, Defined thorough decorator model 2024-06-05 13:04:49 +01:00
Dan Brown
a74e04141c Lexical: Started build of image node and decoration UI 2024-06-03 16:56:31 +01:00
Dan Brown
7c504a10a8 Lexical: Created core modal functionality 2024-06-01 16:49:47 +01:00
Dan Brown
ae98745439 Lexical: Started on form UI 2024-05-30 16:50:55 +01:00
Dan Brown
57259aee00 Lexical: Added format previews to format buttons 2024-05-30 12:25:25 +01:00
Dan Brown
dc1a40ea74 Lexical: Added ui container type
Structured UI logical to be fairly standard and mostly covered via
a base class that handles context and core dom work.
2024-05-29 20:38:31 +01:00
Dan Brown
483d9bf26c Lexical: Added a range of format buttons 2024-05-28 22:56:58 +01:00
Dan Brown
b24d60e98d Lexical: Started UI fundementals with basic button 2024-05-28 18:04:48 +01:00
Dan Brown
0f8bd869d8 Lexical: Added custom id-supporting paragraph blocks 2024-05-28 15:09:50 +01:00
Dan Brown
49546cd627 Lexical: Switched to ts for new editor build 2024-05-27 23:50:28 +01:00
Dan Brown
6e852d2e65 Lexical: Played with commands, extracted & improved callout node 2024-05-27 20:23:45 +01:00
Dan Brown
5a4f595341 Editors: Added lexical editor for testing
Started basic playground for testing lexical as a new WYSIWYG editor.
Moved out tinymce to be under wysiwyg-tinymce instead so lexical is the
default, but TinyMce code remains.
2024-05-27 15:39:41 +01:00
603 changed files with 68859 additions and 2515 deletions

View File

@@ -334,6 +334,11 @@ EXPORT_PAGE_SIZE=a4
# Example: EXPORT_PDF_COMMAND="/scripts/convert.sh {input_html_path} {output_pdf_path}"
EXPORT_PDF_COMMAND=false
# Export PDF Command Timeout
# The number of seconds that the export PDF command will run before a timeout occurs.
# Only applies for the EXPORT_PDF_COMMAND option, not for DomPDF or wkhtmltopdf.
EXPORT_PDF_COMMAND_TIMEOUT=15
# Set path to wkhtmltopdf binary for PDF generation.
# Can be 'false' or a path path like: '/home/bins/wkhtmltopdf'
# When false, BookStack will attempt to find a wkhtmltopdf in the application

View File

@@ -141,7 +141,7 @@ Kauê Sena (kaue.sena.ks) :: Portuguese, Brazilian
MatthieuParis :: French
Douradinho :: Portuguese, Brazilian; Portuguese
Gaku Yaguchi (tama11) :: Japanese
johnroyer :: Chinese Traditional
Zero Huang (johnroyer) :: Chinese Traditional
jackaaa :: Chinese Traditional
Irfan Hukama Arsyad (IrfanArsyad) :: Indonesian
Jeff Huang (s8321414) :: Chinese Traditional
@@ -431,3 +431,21 @@ Michal Melich (michalmelich) :: Czech
David (david-prv) :: German; German Informal
Larry (lahoje) :: Swedish
Marcia dos Santos (marciab80) :: Portuguese
Ricard López Torres (richilpez.torres) :: Catalan
sarahalves7 :: Portuguese, Brazilian
petr.husak :: Czech
javadataherian :: Persian
Ludo-code :: French
hollsten :: Swedish
Ngoc Lan Phung (lanpncz) :: Vietnamese
Worive :: Catalan
Илья Скаба (skabailya) :: Russian
Irjan Olsen (Irch) :: Norwegian Bokmal
Aleksandar Jovanovic (jovanoviczaleksandar) :: Serbian (Cyrillic)
Red (RedVortex) :: Hebrew
xgrug :: Chinese Simplified
HrCalmar :: Danish
Avishay Rapp (AvishayRapp) :: Hebrew
matthias4217 :: French
Berke BOYLU2 (berkeboylu2) :: Turkish
etwas7B :: German

View File

@@ -13,9 +13,9 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Install NPM deps
run: npm ci

29
.github/workflows/test-js.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: test-js
on:
push:
paths:
- '**.js'
- '**.ts'
- '**.json'
pull_request:
paths:
- '**.js'
- '**.ts'
- '**.json'
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Install NPM deps
run: npm ci
- name: Run TypeScript type checking
run: npm run ts:lint
- name: Run JavaScript tests
run: npm run test

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/node_modules
/.vscode
/composer
/coverage
Homestead.yaml
.env
.idea

View File

@@ -0,0 +1,10 @@
<?php
namespace BookStack\Access;
use Exception;
class UserInviteException extends Exception
{
//
}

View File

@@ -13,11 +13,17 @@ class UserInviteService extends UserTokenService
/**
* Send an invitation to a user to sign into BookStack
* Removes existing invitation tokens.
* @throws UserInviteException
*/
public function sendInvitation(User $user)
{
$this->deleteByUser($user);
$token = $this->createTokenForUser($user);
$user->notify(new UserInviteNotification($token));
try {
$user->notify(new UserInviteNotification($token));
} catch (\Exception $exception) {
throw new UserInviteException($exception->getMessage(), $exception->getCode(), $exception);
}
}
}

View File

@@ -64,4 +64,14 @@ class MetaController extends Controller
'jsLibData' => file_get_contents(base_path('dev/licensing/js-library-licenses.txt')),
]);
}
/**
* Show the view for /opensearch.xml.
*/
public function opensearch()
{
return response()
->view('misc.opensearch')
->header('Content-Type', 'application/opensearchdescription+xml');
}
}

View File

@@ -29,6 +29,10 @@ return [
// Example: EXPORT_PDF_COMMAND="/scripts/convert.sh {input_html_path} {output_pdf_path}"
'pdf_command' => env('EXPORT_PDF_COMMAND', false),
// The amount of time allowed for PDF generation command to run
// before the process times out and is stopped.
'pdf_command_timeout' => env('EXPORT_PDF_COMMAND_TIMEOUT', 15),
// 2024-04: Snappy/WKHTMLtoPDF now considered deprecated in regard to BookStack support.
'snappy' => [
'pdf_binary' => env('WKHTMLTOPDF', false),

View File

@@ -3,6 +3,7 @@
namespace BookStack\Entities\Models;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditorType;
use BookStack\Permissions\PermissionApplicator;
use BookStack\Uploads\Attachment;
use Illuminate\Database\Eloquent\Builder;

View File

@@ -11,7 +11,7 @@ use BookStack\Entities\Models\PageRevision;
use BookStack\Entities\Queries\EntityQueries;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditorData;
use BookStack\Entities\Tools\PageEditorType;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Exceptions\MoveOperationException;
use BookStack\Exceptions\PermissionsException;
@@ -43,6 +43,7 @@ class PageRepo
'owned_by' => user()->id,
'updated_by' => user()->id,
'draft' => true,
'editor' => PageEditorType::getSystemDefault()->value,
]);
if ($parent instanceof Chapter) {
@@ -127,7 +128,9 @@ class PageRepo
}
$pageContent = new PageContent($page);
$currentEditor = $page->editor ?: PageEditorData::getSystemDefaultEditor();
$defaultEditor = PageEditorType::getSystemDefault();
$currentEditor = PageEditorType::forPage($page) ?: $defaultEditor;
$inputEditor = PageEditorType::fromRequestValue($input['editor'] ?? '') ?? $currentEditor;
$newEditor = $currentEditor;
$haveInput = isset($input['markdown']) || isset($input['html']);
@@ -136,15 +139,17 @@ class PageRepo
if ($haveInput && $inputEmpty) {
$pageContent->setNewHTML('', user());
} elseif (!empty($input['markdown']) && is_string($input['markdown'])) {
$newEditor = 'markdown';
$newEditor = PageEditorType::Markdown;
$pageContent->setNewMarkdown($input['markdown'], user());
} elseif (isset($input['html'])) {
$newEditor = 'wysiwyg';
$newEditor = ($inputEditor->isHtmlBased() ? $inputEditor : null) ?? ($defaultEditor->isHtmlBased() ? $defaultEditor : null) ?? PageEditorType::WysiwygTinymce;
$pageContent->setNewHTML($input['html'], user());
}
if ($newEditor !== $currentEditor && userCan('editor-change')) {
$page->editor = $newEditor;
if (($newEditor !== $currentEditor || empty($page->editor)) && userCan('editor-change')) {
$page->editor = $newEditor->value;
} elseif (empty($page->editor)) {
$page->editor = $defaultEditor->value;
}
}

View File

@@ -74,17 +74,17 @@ class PageEditorData
];
}
protected function updateContentForEditor(Page $page, string $editorType): void
protected function updateContentForEditor(Page $page, PageEditorType $editorType): void
{
$isHtml = !empty($page->html) && empty($page->markdown);
// HTML to markdown-clean conversion
if ($editorType === 'markdown' && $isHtml && $this->requestedEditor === 'markdown-clean') {
if ($editorType === PageEditorType::Markdown && $isHtml && $this->requestedEditor === 'markdown-clean') {
$page->markdown = (new HtmlToMarkdown($page->html))->convert();
}
// Markdown to HTML conversion if we don't have HTML
if ($editorType === 'wysiwyg' && !$isHtml) {
if ($editorType->isHtmlBased() && !$isHtml) {
$page->html = (new MarkdownToHtml($page->markdown))->convert();
}
}
@@ -94,24 +94,16 @@ class PageEditorData
* Defaults based upon the current content of the page otherwise will fall back
* to system default but will take a requested type (if provided) if permissions allow.
*/
protected function getEditorType(Page $page): string
protected function getEditorType(Page $page): PageEditorType
{
$editorType = $page->editor ?: self::getSystemDefaultEditor();
$editorType = PageEditorType::forPage($page) ?: PageEditorType::getSystemDefault();
// Use requested editor if valid and if we have permission
$requestedType = explode('-', $this->requestedEditor)[0];
if (($requestedType === 'markdown' || $requestedType === 'wysiwyg') && userCan('editor-change')) {
$requestedType = PageEditorType::fromRequestValue($this->requestedEditor);
if ($requestedType && userCan('editor-change')) {
$editorType = $requestedType;
}
return $editorType;
}
/**
* Get the configured system default editor.
*/
public static function getSystemDefaultEditor(): string
{
return setting('app-editor') === 'markdown' ? 'markdown' : 'wysiwyg';
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace BookStack\Entities\Tools;
use BookStack\Entities\Models\Page;
enum PageEditorType: string
{
case WysiwygTinymce = 'wysiwyg';
case WysiwygLexical = 'wysiwyg2024';
case Markdown = 'markdown';
public function isHtmlBased(): bool
{
return match ($this) {
self::WysiwygTinymce, self::WysiwygLexical => true,
self::Markdown => false,
};
}
public static function fromRequestValue(string $value): static|null
{
$editor = explode('-', $value)[0];
return static::tryFrom($editor);
}
public static function forPage(Page $page): static|null
{
return static::tryFrom($page->editor);
}
public static function getSystemDefault(): static
{
$setting = setting('app-editor');
return static::tryFrom($setting) ?? static::WysiwygTinymce;
}
}

View File

@@ -5,6 +5,7 @@ namespace BookStack\Entities\Tools;
use BookStack\Exceptions\PdfExportException;
use Knp\Snappy\Pdf as SnappyPdf;
use Dompdf\Dompdf;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Process;
class PdfGenerator
@@ -85,9 +86,15 @@ class PdfGenerator
file_put_contents($inputHtml, $html);
$timeout = intval(config('exports.pdf_command_timeout'));
$process = Process::fromShellCommandline($command);
$process->setTimeout(15);
$process->run();
$process->setTimeout($timeout);
try {
$process->run();
} catch (ProcessTimedOutException $e) {
throw new PdfExportException("PDF Export via command failed due to timeout at {$timeout} second(s)");
}
if (!$process->isSuccessful()) {
throw new PdfExportException("PDF Export via command failed with exit code {$process->getExitCode()}, stdout: {$process->getOutput()}, stderr: {$process->getErrorOutput()}");

View File

@@ -0,0 +1,13 @@
<?php
namespace BookStack\Search\Options;
class ExactSearchOption extends SearchOption
{
public function toString(): string
{
$escaped = str_replace('\\', '\\\\', $this->value);
$escaped = str_replace('"', '\"', $escaped);
return ($this->negated ? '-' : '') . '"' . $escaped . '"';
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace BookStack\Search\Options;
class FilterSearchOption extends SearchOption
{
protected string $name;
public function __construct(
string $value,
string $name,
bool $negated = false,
) {
parent::__construct($value, $negated);
$this->name = $name;
}
public function toString(): string
{
$valueText = ($this->value ? ':' . $this->value : '');
$filterBrace = '{' . $this->name . $valueText . '}';
return ($this->negated ? '-' : '') . $filterBrace;
}
public function getKey(): string
{
return $this->name;
}
public static function fromContentString(string $value, bool $negated = false): self
{
$explodedFilter = explode(':', $value, 2);
$filterValue = (count($explodedFilter) > 1) ? $explodedFilter[1] : '';
$filterName = $explodedFilter[0];
return new self($filterValue, $filterName, $negated);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace BookStack\Search\Options;
abstract class SearchOption
{
public function __construct(
public string $value,
public bool $negated = false,
) {
}
/**
* Get the key used for this option when used in a map.
* Null indicates to use the index of the containing array.
*/
public function getKey(): string|null
{
return null;
}
/**
* Get the search string representation for this search option.
*/
abstract public function toString(): string;
}

View File

@@ -0,0 +1,37 @@
<?php
namespace BookStack\Search\Options;
class TagSearchOption extends SearchOption
{
/**
* Acceptable operators to be used within a tag search option.
*
* @var string[]
*/
protected array $queryOperators = ['<=', '>=', '=', '<', '>', 'like', '!='];
public function toString(): string
{
return ($this->negated ? '-' : '') . "[{$this->value}]";
}
/**
* @return array{name: string, operator: string, value: string}
*/
public function getParts(): array
{
$operatorRegex = implode('|', array_map(fn($op) => preg_quote($op), $this->queryOperators));
preg_match('/^(.*?)((' . $operatorRegex . ')(.*?))?$/', $this->value, $tagSplit);
$extractedOperator = count($tagSplit) > 2 ? $tagSplit[3] : '';
$tagOperator = in_array($extractedOperator, $this->queryOperators) ? $extractedOperator : '=';
$tagValue = count($tagSplit) > 3 ? $tagSplit[4] : '';
return [
'name' => $tagSplit[1],
'operator' => $tagOperator,
'value' => $tagValue,
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace BookStack\Search\Options;
class TermSearchOption extends SearchOption
{
public function toString(): string
{
return $this->value;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace BookStack\Search;
use BookStack\Search\Options\SearchOption;
/**
* @template T of SearchOption
*/
class SearchOptionSet
{
/**
* @var T[]
*/
protected array $options = [];
public function __construct(array $options = [])
{
$this->options = $options;
}
public function toValueArray(): array
{
return array_map(fn(SearchOption $option) => $option->value, $this->options);
}
public function toValueMap(): array
{
$map = [];
foreach ($this->options as $index => $option) {
$key = $option->getKey() ?? $index;
$map[$key] = $option->value;
}
return $map;
}
public function merge(SearchOptionSet $set): self
{
return new self(array_merge($this->options, $set->options));
}
public function filterEmpty(): self
{
$filteredOptions = array_values(array_filter($this->options, fn (SearchOption $option) => !empty($option->value)));
return new self($filteredOptions);
}
/**
* @param class-string<SearchOption> $class
*/
public static function fromValueArray(array $values, string $class): self
{
$options = array_map(fn($val) => new $class($val), $values);
return new self($options);
}
/**
* @return T[]
*/
public function all(): array
{
return $this->options;
}
/**
* @return self<T>
*/
public function negated(): self
{
$values = array_values(array_filter($this->options, fn (SearchOption $option) => $option->negated));
return new self($values);
}
/**
* @return self<T>
*/
public function nonNegated(): self
{
$values = array_values(array_filter($this->options, fn (SearchOption $option) => !$option->negated));
return new self($values);
}
}

View File

@@ -2,26 +2,39 @@
namespace BookStack\Search;
use BookStack\Search\Options\ExactSearchOption;
use BookStack\Search\Options\FilterSearchOption;
use BookStack\Search\Options\SearchOption;
use BookStack\Search\Options\TagSearchOption;
use BookStack\Search\Options\TermSearchOption;
use Illuminate\Http\Request;
class SearchOptions
{
public array $searches = [];
public array $exacts = [];
public array $tags = [];
public array $filters = [];
/** @var SearchOptionSet<TermSearchOption> */
public SearchOptionSet $searches;
/** @var SearchOptionSet<ExactSearchOption> */
public SearchOptionSet $exacts;
/** @var SearchOptionSet<TagSearchOption> */
public SearchOptionSet $tags;
/** @var SearchOptionSet<FilterSearchOption> */
public SearchOptionSet $filters;
public function __construct()
{
$this->searches = new SearchOptionSet();
$this->exacts = new SearchOptionSet();
$this->tags = new SearchOptionSet();
$this->filters = new SearchOptionSet();
}
/**
* Create a new instance from a search string.
*/
public static function fromString(string $search): self
{
$decoded = static::decode($search);
$instance = new SearchOptions();
foreach ($decoded as $type => $value) {
$instance->$type = $value;
}
$instance = new self();
$instance->addOptionsFromString($search);
return $instance;
}
@@ -41,46 +54,64 @@ class SearchOptions
}
$instance = new SearchOptions();
$inputs = $request->only(['search', 'types', 'filters', 'exact', 'tags']);
$inputs = $request->only(['search', 'types', 'filters', 'exact', 'tags', 'extras']);
$parsedStandardTerms = static::parseStandardTermString($inputs['search'] ?? '');
$instance->searches = array_filter($parsedStandardTerms['terms']);
$instance->exacts = array_filter($parsedStandardTerms['exacts']);
array_push($instance->exacts, ...array_filter($inputs['exact'] ?? []));
$instance->tags = array_filter($inputs['tags'] ?? []);
$inputExacts = array_filter($inputs['exact'] ?? []);
$instance->searches = SearchOptionSet::fromValueArray(array_filter($parsedStandardTerms['terms']), TermSearchOption::class);
$instance->exacts = SearchOptionSet::fromValueArray(array_filter($parsedStandardTerms['exacts']), ExactSearchOption::class);
$instance->exacts = $instance->exacts->merge(SearchOptionSet::fromValueArray($inputExacts, ExactSearchOption::class));
$instance->tags = SearchOptionSet::fromValueArray(array_filter($inputs['tags'] ?? []), TagSearchOption::class);
$cleanedFilters = [];
foreach (($inputs['filters'] ?? []) as $filterKey => $filterVal) {
if (empty($filterVal)) {
continue;
}
$instance->filters[$filterKey] = $filterVal === 'true' ? '' : $filterVal;
$cleanedFilterVal = $filterVal === 'true' ? '' : $filterVal;
$cleanedFilters[] = new FilterSearchOption($cleanedFilterVal, $filterKey);
}
if (isset($inputs['types']) && count($inputs['types']) < 4) {
$instance->filters['type'] = implode('|', $inputs['types']);
$cleanedFilters[] = new FilterSearchOption(implode('|', $inputs['types']), 'type');
}
$instance->filters = new SearchOptionSet($cleanedFilters);
// Parse and merge in extras if provided
if (!empty($inputs['extras'])) {
$extras = static::fromString($inputs['extras']);
$instance->searches = $instance->searches->merge($extras->searches);
$instance->exacts = $instance->exacts->merge($extras->exacts);
$instance->tags = $instance->tags->merge($extras->tags);
$instance->filters = $instance->filters->merge($extras->filters);
}
return $instance;
}
/**
* Decode a search string into an array of terms.
* Decode a search string and add its contents to this instance.
*/
protected static function decode(string $searchString): array
protected function addOptionsFromString(string $searchString): void
{
/** @var array<string, SearchOption[]> $terms */
$terms = [
'searches' => [],
'exacts' => [],
'tags' => [],
'filters' => [],
];
$patterns = [
'exacts' => '/"((?:\\\\.|[^"\\\\])*)"/',
'tags' => '/\[(.*?)\]/',
'filters' => '/\{(.*?)\}/',
'exacts' => '/-?"((?:\\\\.|[^"\\\\])*)"/',
'tags' => '/-?\[(.*?)\]/',
'filters' => '/-?\{(.*?)\}/',
];
$constructors = [
'exacts' => fn(string $value, bool $negated) => new ExactSearchOption($value, $negated),
'tags' => fn(string $value, bool $negated) => new TagSearchOption($value, $negated),
'filters' => fn(string $value, bool $negated) => FilterSearchOption::fromContentString($value, $negated),
];
// Parse special terms
@@ -88,34 +119,32 @@ class SearchOptions
$matches = [];
preg_match_all($pattern, $searchString, $matches);
if (count($matches) > 0) {
$terms[$termType] = $matches[1];
foreach ($matches[1] as $index => $value) {
$negated = str_starts_with($matches[0][$index], '-');
$terms[$termType][] = $constructors[$termType]($value, $negated);
}
$searchString = preg_replace($pattern, '', $searchString);
}
}
// Unescape exacts and backslash escapes
foreach ($terms['exacts'] as $index => $exact) {
$terms['exacts'][$index] = static::decodeEscapes($exact);
foreach ($terms['exacts'] as $exact) {
$exact->value = static::decodeEscapes($exact->value);
}
// Parse standard terms
$parsedStandardTerms = static::parseStandardTermString($searchString);
array_push($terms['searches'], ...$parsedStandardTerms['terms']);
array_push($terms['exacts'], ...$parsedStandardTerms['exacts']);
$this->searches = $this->searches
->merge(SearchOptionSet::fromValueArray($parsedStandardTerms['terms'], TermSearchOption::class))
->filterEmpty();
$this->exacts = $this->exacts
->merge(new SearchOptionSet($terms['exacts']))
->merge(SearchOptionSet::fromValueArray($parsedStandardTerms['exacts'], ExactSearchOption::class))
->filterEmpty();
// Split filter values out
$splitFilters = [];
foreach ($terms['filters'] as $filter) {
$explodedFilter = explode(':', $filter, 2);
$splitFilters[$explodedFilter[0]] = (count($explodedFilter) > 1) ? $explodedFilter[1] : '';
}
$terms['filters'] = $splitFilters;
// Filter down terms where required
$terms['exacts'] = array_filter($terms['exacts']);
$terms['searches'] = array_filter($terms['searches']);
return $terms;
// Add tags & filters
$this->tags = $this->tags->merge(new SearchOptionSet($terms['tags']));
$this->filters = $this->filters->merge(new SearchOptionSet($terms['filters']));
}
/**
@@ -175,7 +204,9 @@ class SearchOptions
*/
public function setFilter(string $filterName, string $filterValue = ''): void
{
$this->filters[$filterName] = $filterValue;
$this->filters = $this->filters->merge(
new SearchOptionSet([new FilterSearchOption($filterValue, $filterName)])
);
}
/**
@@ -183,22 +214,43 @@ class SearchOptions
*/
public function toString(): string
{
$parts = $this->searches;
$options = [
...$this->searches->all(),
...$this->exacts->all(),
...$this->tags->all(),
...$this->filters->all(),
];
foreach ($this->exacts as $term) {
$escaped = str_replace('\\', '\\\\', $term);
$escaped = str_replace('"', '\"', $escaped);
$parts[] = '"' . $escaped . '"';
}
foreach ($this->tags as $term) {
$parts[] = "[{$term}]";
}
foreach ($this->filters as $filterName => $filterVal) {
$parts[] = '{' . $filterName . ($filterVal ? ':' . $filterVal : '') . '}';
}
$parts = array_map(fn(SearchOption $o) => $o->toString(), $options);
return implode(' ', $parts);
}
/**
* Get the search options that don't have UI controls provided for.
* Provided back as a key => value array with the keys being expected
* input names for a search form, and values being the option value.
*/
public function getAdditionalOptionsString(): string
{
$options = [];
// Handle filters without UI support
$userFilters = ['updated_by', 'created_by', 'owned_by'];
$unsupportedFilters = ['is_template', 'sort_by'];
foreach ($this->filters->all() as $filter) {
if (in_array($filter->getKey(), $userFilters, true) && $filter->value !== null && $filter->value !== 'me') {
$options[] = $filter;
} else if (in_array($filter->getKey(), $unsupportedFilters, true)) {
$options[] = $filter;
}
}
// Negated items
array_push($options, ...$this->exacts->negated()->all());
array_push($options, ...$this->tags->negated()->all());
array_push($options, ...$this->filters->negated()->all());
return implode(' ', array_map(fn(SearchOption $o) => $o->toString(), $options));
}
}

View File

@@ -25,11 +25,12 @@ class SearchResultsFormatter
* Update the given entity model to set attributes used for previews of the item
* primarily within search result lists.
*/
protected function setSearchPreview(Entity $entity, SearchOptions $options)
protected function setSearchPreview(Entity $entity, SearchOptions $options): void
{
$textProperty = $entity->textField;
$textContent = $entity->$textProperty;
$terms = array_merge($options->exacts, $options->searches);
$relevantSearchOptions = $options->exacts->merge($options->searches);
$terms = $relevantSearchOptions->toValueArray();
$originalContentByNewAttribute = [
'preview_name' => $entity->name,

View File

@@ -7,6 +7,7 @@ use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Queries\EntityQueries;
use BookStack\Permissions\PermissionApplicator;
use BookStack\Search\Options\TagSearchOption;
use BookStack\Users\Models\User;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
@@ -16,31 +17,21 @@ use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use SplObjectStorage;
use WeakMap;
class SearchRunner
{
/**
* Acceptable operators to be used in a query.
*
* @var string[]
*/
protected array $queryOperators = ['<=', '>=', '=', '<', '>', 'like', '!='];
/**
* Retain a cache of score adjusted terms for specific search options.
* From PHP>=8 this can be made into a WeakMap instead.
*
* @var SplObjectStorage
*/
protected $termAdjustmentCache;
protected WeakMap $termAdjustmentCache;
public function __construct(
protected EntityProvider $entityProvider,
protected PermissionApplicator $permissions,
protected EntityQueries $entityQueries,
) {
$this->termAdjustmentCache = new SplObjectStorage();
$this->termAdjustmentCache = new WeakMap();
}
/**
@@ -55,10 +46,11 @@ class SearchRunner
$entityTypes = array_keys($this->entityProvider->all());
$entityTypesToSearch = $entityTypes;
$filterMap = $searchOpts->filters->toValueMap();
if ($entityType !== 'all') {
$entityTypesToSearch = [$entityType];
} elseif (isset($searchOpts->filters['type'])) {
$entityTypesToSearch = explode('|', $searchOpts->filters['type']);
} elseif (isset($filterMap['type'])) {
$entityTypesToSearch = explode('|', $filterMap['type']);
}
$results = collect();
@@ -97,7 +89,8 @@ class SearchRunner
{
$opts = SearchOptions::fromString($searchString);
$entityTypes = ['page', 'chapter'];
$entityTypesToSearch = isset($opts->filters['type']) ? explode('|', $opts->filters['type']) : $entityTypes;
$filterMap = $opts->filters->toValueMap();
$entityTypesToSearch = isset($filterMap['type']) ? explode('|', $filterMap['type']) : $entityTypes;
$results = collect();
foreach ($entityTypesToSearch as $entityType) {
@@ -161,24 +154,26 @@ class SearchRunner
$this->applyTermSearch($entityQuery, $searchOpts, $entityType);
// Handle exact term matching
foreach ($searchOpts->exacts as $inputTerm) {
$entityQuery->where(function (EloquentBuilder $query) use ($inputTerm, $entityModelInstance) {
$inputTerm = str_replace('\\', '\\\\', $inputTerm);
foreach ($searchOpts->exacts->all() as $exact) {
$filter = function (EloquentBuilder $query) use ($exact, $entityModelInstance) {
$inputTerm = str_replace('\\', '\\\\', $exact->value);
$query->where('name', 'like', '%' . $inputTerm . '%')
->orWhere($entityModelInstance->textField, 'like', '%' . $inputTerm . '%');
});
};
$exact->negated ? $entityQuery->whereNot($filter) : $entityQuery->where($filter);
}
// Handle tag searches
foreach ($searchOpts->tags as $inputTerm) {
$this->applyTagSearch($entityQuery, $inputTerm);
foreach ($searchOpts->tags->all() as $tagOption) {
$this->applyTagSearch($entityQuery, $tagOption);
}
// Handle filters
foreach ($searchOpts->filters as $filterTerm => $filterValue) {
$functionName = Str::camel('filter_' . $filterTerm);
foreach ($searchOpts->filters->all() as $filterOption) {
$functionName = Str::camel('filter_' . $filterOption->getKey());
if (method_exists($this, $functionName)) {
$this->$functionName($entityQuery, $entityModelInstance, $filterValue);
$this->$functionName($entityQuery, $entityModelInstance, $filterOption->value, $filterOption->negated);
}
}
@@ -190,7 +185,7 @@ class SearchRunner
*/
protected function applyTermSearch(EloquentBuilder $entityQuery, SearchOptions $options, string $entityType): void
{
$terms = $options->searches;
$terms = $options->searches->toValueArray();
if (count($terms) === 0) {
return;
}
@@ -209,8 +204,8 @@ class SearchRunner
$subQuery->where('entity_type', '=', $entityType);
$subQuery->where(function (Builder $query) use ($terms) {
foreach ($terms as $inputTerm) {
$inputTerm = str_replace('\\', '\\\\', $inputTerm);
$query->orWhere('term', 'like', $inputTerm . '%');
$escapedTerm = str_replace('\\', '\\\\', $inputTerm);
$query->orWhere('term', 'like', $escapedTerm . '%');
}
});
$subQuery->groupBy('entity_type', 'entity_id');
@@ -264,7 +259,7 @@ class SearchRunner
$whenStatements = [];
$whenBindings = [];
foreach ($options->searches as $term) {
foreach ($options->searches->toValueArray() as $term) {
$whenStatements[] = 'WHEN term LIKE ? THEN ?';
$whenBindings[] = $term . '%';
$whenBindings[] = $term;
@@ -310,179 +305,165 @@ class SearchRunner
}
/**
* Get the available query operators as a regex escaped list.
* Apply a tag search term onto an entity query.
*/
protected function getRegexEscapedOperators(): string
protected function applyTagSearch(EloquentBuilder $query, TagSearchOption $option): void
{
$escapedOperators = [];
foreach ($this->queryOperators as $operator) {
$escapedOperators[] = preg_quote($operator);
}
$filter = function (EloquentBuilder $query) use ($option): void {
$tagParts = $option->getParts();
if (empty($tagParts['operator']) || empty($tagParts['value'])) {
$query->where('name', '=', $tagParts['name']);
return;
}
return implode('|', $escapedOperators);
if (!empty($tagParts['name'])) {
$query->where('name', '=', $tagParts['name']);
}
if (is_numeric($tagParts['value']) && $tagParts['operator'] !== 'like') {
// We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will
// search the value as a string which prevents being able to do number-based operations
// on the tag values. We ensure it has a numeric value and then cast it just to be sure.
/** @var Connection $connection */
$connection = $query->getConnection();
$quotedValue = (float) trim($connection->getPdo()->quote($tagParts['value']), "'");
$query->whereRaw("value {$tagParts['operator']} {$quotedValue}");
} else if ($tagParts['operator'] === 'like') {
$query->where('value', $tagParts['operator'], str_replace('\\', '\\\\', $tagParts['value']));
} else {
$query->where('value', $tagParts['operator'], $tagParts['value']);
}
};
$option->negated ? $query->whereDoesntHave('tags', $filter) : $query->whereHas('tags', $filter);
}
/**
* Apply a tag search term onto a entity query.
*/
protected function applyTagSearch(EloquentBuilder $query, string $tagTerm): EloquentBuilder
protected function applyNegatableWhere(EloquentBuilder $query, bool $negated, string $column, string $operator, mixed $value): void
{
preg_match('/^(.*?)((' . $this->getRegexEscapedOperators() . ')(.*?))?$/', $tagTerm, $tagSplit);
$query->whereHas('tags', function (EloquentBuilder $query) use ($tagSplit) {
$tagName = $tagSplit[1];
$tagOperator = count($tagSplit) > 2 ? $tagSplit[3] : '';
$tagValue = count($tagSplit) > 3 ? $tagSplit[4] : '';
$validOperator = in_array($tagOperator, $this->queryOperators);
if (!empty($tagOperator) && !empty($tagValue) && $validOperator) {
if (!empty($tagName)) {
$query->where('name', '=', $tagName);
}
if (is_numeric($tagValue) && $tagOperator !== 'like') {
// We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will
// search the value as a string which prevents being able to do number-based operations
// on the tag values. We ensure it has a numeric value and then cast it just to be sure.
/** @var Connection $connection */
$connection = $query->getConnection();
$tagValue = (float) trim($connection->getPdo()->quote($tagValue), "'");
$query->whereRaw("value {$tagOperator} {$tagValue}");
} else {
if ($tagOperator === 'like') {
$tagValue = str_replace('\\', '\\\\', $tagValue);
}
$query->where('value', $tagOperator, $tagValue);
}
} else {
$query->where('name', '=', $tagName);
}
});
return $query;
if ($negated) {
$query->whereNot($column, $operator, $value);
} else {
$query->where($column, $operator, $value);
}
}
/**
* Custom entity search filters.
*/
protected function filterUpdatedAfter(EloquentBuilder $query, Entity $model, $input): void
protected function filterUpdatedAfter(EloquentBuilder $query, Entity $model, string $input, bool $negated): void
{
try {
$date = date_create($input);
$query->where('updated_at', '>=', $date);
} catch (\Exception $e) {
}
$date = date_create($input);
$this->applyNegatableWhere($query, $negated, 'updated_at', '>=', $date);
}
protected function filterUpdatedBefore(EloquentBuilder $query, Entity $model, $input): void
protected function filterUpdatedBefore(EloquentBuilder $query, Entity $model, string $input, bool $negated): void
{
try {
$date = date_create($input);
$query->where('updated_at', '<', $date);
} catch (\Exception $e) {
}
$date = date_create($input);
$this->applyNegatableWhere($query, $negated, 'updated_at', '<', $date);
}
protected function filterCreatedAfter(EloquentBuilder $query, Entity $model, $input): void
protected function filterCreatedAfter(EloquentBuilder $query, Entity $model, string $input, bool $negated): void
{
try {
$date = date_create($input);
$query->where('created_at', '>=', $date);
} catch (\Exception $e) {
}
$date = date_create($input);
$this->applyNegatableWhere($query, $negated, 'created_at', '>=', $date);
}
protected function filterCreatedBefore(EloquentBuilder $query, Entity $model, $input)
protected function filterCreatedBefore(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
try {
$date = date_create($input);
$query->where('created_at', '<', $date);
} catch (\Exception $e) {
}
$date = date_create($input);
$this->applyNegatableWhere($query, $negated, 'created_at', '<', $date);
}
protected function filterCreatedBy(EloquentBuilder $query, Entity $model, $input)
protected function filterCreatedBy(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$userSlug = $input === 'me' ? user()->slug : trim($input);
$user = User::query()->where('slug', '=', $userSlug)->first(['id']);
if ($user) {
$query->where('created_by', '=', $user->id);
$this->applyNegatableWhere($query, $negated, 'created_by', '=', $user->id);
}
}
protected function filterUpdatedBy(EloquentBuilder $query, Entity $model, $input)
protected function filterUpdatedBy(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$userSlug = $input === 'me' ? user()->slug : trim($input);
$user = User::query()->where('slug', '=', $userSlug)->first(['id']);
if ($user) {
$query->where('updated_by', '=', $user->id);
$this->applyNegatableWhere($query, $negated, 'updated_by', '=', $user->id);
}
}
protected function filterOwnedBy(EloquentBuilder $query, Entity $model, $input)
protected function filterOwnedBy(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$userSlug = $input === 'me' ? user()->slug : trim($input);
$user = User::query()->where('slug', '=', $userSlug)->first(['id']);
if ($user) {
$query->where('owned_by', '=', $user->id);
$this->applyNegatableWhere($query, $negated, 'owned_by', '=', $user->id);
}
}
protected function filterInName(EloquentBuilder $query, Entity $model, $input)
protected function filterInName(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$query->where('name', 'like', '%' . $input . '%');
$this->applyNegatableWhere($query, $negated, 'name', 'like', '%' . $input . '%');
}
protected function filterInTitle(EloquentBuilder $query, Entity $model, $input)
protected function filterInTitle(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$this->filterInName($query, $model, $input);
$this->filterInName($query, $model, $input, $negated);
}
protected function filterInBody(EloquentBuilder $query, Entity $model, $input)
protected function filterInBody(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$query->where($model->textField, 'like', '%' . $input . '%');
$this->applyNegatableWhere($query, $negated, $model->textField, 'like', '%' . $input . '%');
}
protected function filterIsRestricted(EloquentBuilder $query, Entity $model, $input)
protected function filterIsRestricted(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$query->whereHas('permissions');
$negated ? $query->whereDoesntHave('permissions') : $query->whereHas('permissions');
}
protected function filterViewedByMe(EloquentBuilder $query, Entity $model, $input)
protected function filterViewedByMe(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$query->whereHas('views', function ($query) {
$filter = function ($query) {
$query->where('user_id', '=', user()->id);
});
};
$negated ? $query->whereDoesntHave('views', $filter) : $query->whereHas('views', $filter);
}
protected function filterNotViewedByMe(EloquentBuilder $query, Entity $model, $input)
protected function filterNotViewedByMe(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$query->whereDoesntHave('views', function ($query) {
$filter = function ($query) {
$query->where('user_id', '=', user()->id);
});
};
$negated ? $query->whereHas('views', $filter) : $query->whereDoesntHave('views', $filter);
}
protected function filterIsTemplate(EloquentBuilder $query, Entity $model, $input)
protected function filterIsTemplate(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
if ($model instanceof Page) {
$query->where('template', '=', true);
$this->applyNegatableWhere($query, $negated, 'template', '=', true);
}
}
protected function filterSortBy(EloquentBuilder $query, Entity $model, $input)
protected function filterSortBy(EloquentBuilder $query, Entity $model, string $input, bool $negated)
{
$functionName = Str::camel('sort_by_' . $input);
if (method_exists($this, $functionName)) {
$this->$functionName($query, $model);
$this->$functionName($query, $model, $negated);
}
}
/**
* Sorting filter options.
*/
protected function sortByLastCommented(EloquentBuilder $query, Entity $model)
protected function sortByLastCommented(EloquentBuilder $query, Entity $model, bool $negated)
{
$commentsTable = DB::getTablePrefix() . 'comments';
$morphClass = str_replace('\\', '\\\\', $model->getMorphClass());
$commentQuery = DB::raw('(SELECT c1.entity_id, c1.entity_type, c1.created_at as last_commented FROM ' . $commentsTable . ' c1 LEFT JOIN ' . $commentsTable . ' c2 ON (c1.entity_id = c2.entity_id AND c1.entity_type = c2.entity_type AND c1.created_at < c2.created_at) WHERE c1.entity_type = \'' . $morphClass . '\' AND c2.created_at IS NULL) as comments');
$query->join($commentQuery, $model->getTable() . '.id', '=', 'comments.entity_id')->orderBy('last_commented', 'desc');
$query->join($commentQuery, $model->getTable() . '.id', '=', DB::raw('comments.entity_id'))
->orderBy('last_commented', $negated ? 'asc' : 'desc');
}
}

View File

@@ -3,6 +3,7 @@
namespace BookStack\Users\Controllers;
use BookStack\Access\SocialDriverManager;
use BookStack\Access\UserInviteException;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\UserUpdateException;
use BookStack\Http\Controller;
@@ -14,6 +15,7 @@ use BookStack\Util\SimpleListOptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\ValidationException;
@@ -91,9 +93,15 @@ class UserController extends Controller
$validated = $this->validate($request, array_filter($validationRules));
DB::transaction(function () use ($validated, $sendInvite) {
$this->userRepo->create($validated, $sendInvite);
});
try {
DB::transaction(function () use ($validated, $sendInvite) {
$this->userRepo->create($validated, $sendInvite);
});
} catch (UserInviteException $e) {
Log::error("Failed to send user invite with error: {$e->getMessage()}");
$this->showErrorNotification(trans('errors.users_could_not_send_invite'));
return redirect('/settings/users/create')->withInput();
}
return redirect('/settings/users');
}

View File

@@ -2,6 +2,7 @@
namespace BookStack\Users;
use BookStack\Access\UserInviteException;
use BookStack\Access\UserInviteService;
use BookStack\Activity\ActivityType;
use BookStack\Entities\EntityProvider;
@@ -83,6 +84,7 @@ class UserRepo
* As per "createWithoutActivity" but records a "create" activity.
*
* @param array{name: string, email: string, password: ?string, external_auth_id: ?string, language: ?string, roles: ?array} $data
* @throws UserInviteException
*/
public function create(array $data, bool $sendInvite = false): User
{

View File

@@ -16,9 +16,9 @@
"ext-json": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"bacon/bacon-qr-code": "^2.0",
"bacon/bacon-qr-code": "^3.0",
"doctrine/dbal": "^3.5",
"dompdf/dompdf": "^2.0",
"dompdf/dompdf": "^3.0",
"guzzlehttp/guzzle": "^7.4",
"intervention/image": "^3.5",
"knplabs/knp-snappy": "^1.5",

801
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Ensure we have an "editor" value set for pages
// Get default
$default = DB::table('settings')
->where('setting_key', '=', 'app-editor')
->first()
->value ?? 'wysiwyg';
$default = ($default === 'markdown') ? 'markdown' : 'wysiwyg';
// We set it to 'markdown' for pages currently with markdown content
DB::table('pages')
->where('editor', '=', '')
->where('markdown', '!=', '')
->update(['editor' => 'markdown']);
// We set it to 'wysiwyg' where we have HTML but no markdown
DB::table('pages')
->where('editor', '=', '')
->where('markdown', '=', '')
->where('html', '!=', '')
->update(['editor' => 'wysiwyg']);
// Otherwise, where still empty, set to the current default
DB::table('pages')
->where('editor', '=', '')
->update(['editor' => $default]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Can't reverse due to not knowing what would have been empty before
}
};

View File

@@ -14,6 +14,7 @@ const entryPoints = {
code: path.join(__dirname, '../../resources/js/code/index.mjs'),
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
markdown: path.join(__dirname, '../../resources/js/markdown/index.mjs'),
wysiwyg: path.join(__dirname, '../../resources/js/wysiwyg/index.ts'),
};
// Locate our output directory
@@ -31,6 +32,15 @@ esbuild.build({
format: 'esm',
minify: isProd,
logLevel: 'info',
loader: {
'.svg': 'text',
},
absWorkingDir: path.join(__dirname, '../..'),
alias: {
'@icons': './resources/icons',
lexical: './resources/js/wysiwyg/lexical/core',
'@lexical': './resources/js/wysiwyg/lexical',
},
banner: {
js: '// See the "/licenses" URI for full package license details',
css: '/* See the "/licenses" URI for full package license details */',

View File

@@ -137,8 +137,8 @@ window.$events.showValidationErrors(error);
// Translator
// Take the given plural text and count to decide on what plural option
// to use, Similar to laravel's trans_choice function but instead
// takes the direction directly instead of a translation key.
window.trans_plural(translationString, count, replacements);
// takes the translation text directly instead of a translation key.
window.$trans.choice(translationString, count, replacements);
// Component System
// Parse and initialise any components from the given root el down.

File diff suppressed because it is too large Load Diff

View File

@@ -96,6 +96,22 @@ Copyright: Copyright (C) 1991, 1999 Free Software Foundation, Inc.
Source: https://github.com/dompdf/dompdf.git
Link: https://github.com/dompdf/dompdf
-----------
dompdf/php-font-lib
License: LGPL-2.1-or-later
License File: vendor/dompdf/php-font-lib/LICENSE
Copyright: Copyright (C) 1991, 1999 Free Software Foundation, Inc.
Source: https://github.com/dompdf/php-font-lib.git
Link: https://github.com/dompdf/php-font-lib
-----------
dompdf/php-svg-lib
License: LGPL-3.0-or-later
License File: vendor/dompdf/php-svg-lib/LICENSE
Copyright: Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Source: https://github.com/dompdf/php-svg-lib.git
Link: https://github.com/dompdf/php-svg-lib
-----------
dragonmantank/cron-expression
License: MIT
License File: vendor/dragonmantank/cron-expression/LICENSE
@@ -128,7 +144,7 @@ Link: https://github.com/fruitcake/php-cors
graham-campbell/result-type
License: MIT
License File: vendor/graham-campbell/result-type/LICENSE
Copyright: Copyright (c) 2020-2023 Graham Campbell <*****@**********.**.**>
Copyright: Copyright (c) 2020-2024 Graham Campbell <*****@**********.**.**>
Source: https://github.com/GrahamCampbell/Result-Type.git
Link: https://github.com/GrahamCampbell/Result-Type.git
-----------
@@ -375,22 +391,6 @@ Copyright: Copyright (c) 2015 Paragon Initiative Enterprises
Source: https://github.com/paragonie/random_compat.git
Link: https://github.com/paragonie/random_compat.git
-----------
phenx/php-font-lib
License: LGPL-2.1-or-later
License File: vendor/phenx/php-font-lib/LICENSE
Copyright: Copyright (C) 1991, 1999 Free Software Foundation, Inc.
Source: https://github.com/dompdf/php-font-lib.git
Link: https://github.com/PhenX/php-font-lib
-----------
phenx/php-svg-lib
License: LGPL-3.0-or-later
License File: vendor/phenx/php-svg-lib/LICENSE
Copyright: Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Source: https://github.com/dompdf/php-svg-lib.git
Link: https://github.com/PhenX/php-svg-lib
-----------
phpoption/phpoption
License: Apache-2.0
License File: vendor/phpoption/phpoption/LICENSE
@@ -676,13 +676,6 @@ Copyright: Copyright (c) 2015-present Fabien Potencier
Source: https://github.com/symfony/polyfill-mbstring.git
Link: https://symfony.com
-----------
symfony/polyfill-php72
License: MIT
License File: vendor/symfony/polyfill-php72/LICENSE
Copyright: Copyright (c) 2015-present Fabien Potencier
Source: https://github.com/symfony/polyfill-php72.git
Link: https://symfony.com
-----------
symfony/polyfill-php80
License: MIT
License File: vendor/symfony/polyfill-php80/LICENSE

209
jest.config.ts Normal file
View File

@@ -0,0 +1,209 @@
/**
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/configuration
*/
import type {Config} from 'jest';
import {pathsToModuleNameMapper} from "ts-jest";
import { compilerOptions } from './tsconfig.json';
const config: Config = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: undefined,
// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// The default configuration for fake timers
// fakeTimers: {
// "enableGlobally": false
// },
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
globals: {
__DEV__: true,
},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "mjs",
// "cjs",
// "jsx",
// "ts",
// "tsx",
// "json",
// "node"
// ],
modulePaths: ['./'],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
'lexical/shared/invariant': 'resources/js/wysiwyg/lexical/core/shared/__mocks__/invariant',
...pathsToModuleNameMapper(compilerOptions.paths),
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: undefined,
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state before every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state and implementation before every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
roots: [
"./resources/js"
],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
testEnvironment: "jsdom",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
testMatch: [
"**/__tests__/**/*.test.[jt]s",
],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
// testRunner: "jest-circus/runner",
// A map from regular expressions to paths to transformers
transform: {
"^.+.tsx?$": ["ts-jest",{}],
},
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/",
// "\\.pnp\\.[^\\/]+$"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};
export default config;

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'سياسة الخصوصية',
'terms_of_service' => 'اتفاقية شروط الخدمة',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'تثبيت سجل التعديل',
'pages_edit_enter_changelog_desc' => 'ضع وصف مختصر للتعديلات التي تمت',
'pages_edit_enter_changelog' => 'أدخل سجل التعديل',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'لا يمكن حذف المشرف الوحيد',
'users_cannot_delete_guest' => 'لا يمكن حذف المستخدم الضيف',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'لا يمكن تعديل هذا الدور',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Политика за поверителност',
'terms_of_service' => 'Условия на услугата',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Задайте регистър на промените',
'pages_edit_enter_changelog_desc' => 'Въведете кратко резюме на промените, които сте създали',
'pages_edit_enter_changelog' => 'Въведи регистър на промените',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Не можеш да изтриеш единствения администратор',
'users_cannot_delete_guest' => 'Не можеш да изтриеш потребителя на госта',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Ролята не може да бъде редактирана',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Pravila o privatnosti',
'terms_of_service' => 'Uslovi korištenja',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Set Changelog',
'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made',
'pages_edit_enter_changelog' => 'Enter Changelog',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Ne možete izbrisati jedinog administratora',
'users_cannot_delete_guest' => 'Ne možete izbrisati gost korisnika',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Ova uloga ne može biti mijenjana',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Política de privadesa',
'terms_of_service' => 'Condicions del servei',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Contingut net)',
'pages_edit_switch_to_markdown_stable' => '(Contingut estable)',
'pages_edit_switch_to_wysiwyg' => 'Canvia a leditor WYSIWYG',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Registre de canvis',
'pages_edit_enter_changelog_desc' => 'Introduïu una descripció breu dels canvis que heu fet',
'pages_edit_enter_changelog' => 'Registra un canvi',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'No podeu suprimir ladministrador únic.',
'users_cannot_delete_guest' => 'No podeu suprimir lusuari convidat.',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'No es pot editar aquest rol.',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Zásady ochrany osobních údajů',
'terms_of_service' => 'Podmínky služby',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Vytvořený obsah)',
'pages_edit_switch_to_markdown_stable' => '(Stabilní obsah)',
'pages_edit_switch_to_wysiwyg' => 'Přepnout na WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Nastavit protokol změn',
'pages_edit_enter_changelog_desc' => 'Zadejte stručný popis změn, které jste provedli',
'pages_edit_enter_changelog' => 'Zadejte protokol změn',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Nemůžete odstranit posledního administrátora',
'users_cannot_delete_guest' => 'Uživatele Host není možno odstranit',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Tuto roli nelze editovat',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -59,22 +59,22 @@ return [
'favourite_remove_notification' => 'Mae ":name" wedi\'i tynnu o\'ch ffefrynnau',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Dewisiadau gwylio wediu diweddaru\'n llwyddiannus',
// Auth
'auth_login' => 'wedi\'u mewngofnodi',
'auth_register' => 'wedi\'i cofrestru\'n ddefnyddiwr newydd',
'auth_password_reset_request' => 'wedi ceisio ailosod gair pass defnyddiwr',
'auth_password_reset_update' => 'ailosododd air pass defnyddiwr',
'mfa_setup_method' => 'configured MFA method',
'mfa_setup_method' => 'Dull Dilysu Aml-ffactor wedii ffurfweddu',
'mfa_setup_method_notification' => 'Dull aml-ffactor wedi\'i ffurfweddu\'n llwyddiannus',
'mfa_remove_method' => 'removed MFA method',
'mfa_remove_method' => 'Dull Dilysu Aml-ffactor wedi\'i ddileu',
'mfa_remove_method_notification' => 'Llwyddwyd i ddileu dull aml-ffactor',
// Settings
'settings_update' => 'diweddarodd osodiadau',
'settings_update_notification' => 'Gosodiadau wedi\'i diweddaru\'n llwyddiannus',
'maintenance_action_run' => 'ran maintenance action',
'maintenance_action_run' => 'rhedeg gweithred cynnal a chadw',
// Webhooks
'webhook_create' => 'webhook wedi creu',
@@ -111,7 +111,7 @@ return [
// Recycle Bin
'recycle_bin_empty' => 'gwagodd fin ailgylchu',
'recycle_bin_restore' => 'wedi\'i adfer o\'r bin ailgylchu',
'recycle_bin_destroy' => 'removed from recycle bin',
'recycle_bin_destroy' => 'symudwyd or bin ailgylchu',
// Comments
'commented_on' => 'gwnaeth sylwadau ar',

View File

@@ -40,17 +40,17 @@ return [
// Login auto-initiation
'auto_init_starting' => 'Wrthi\'n ceisio mewngofnodi',
'auto_init_starting_desc' => 'We\'re contacting your authentication system to start the login process. If there\'s no progress after 5 seconds you can try clicking the link below.',
'auto_init_starting_desc' => 'Rydym yn cysylltu â\'ch system ddilysu i ddechrau\'r broses fewngofnodi. Os nad oes cynnydd ar ôl 5 eiliad, gallwch geisio clicio ar y ddolen isod.',
'auto_init_start_link' => 'Parhau gyda dilysu',
// Password Reset
'reset_password' => 'Ailosod cyfrinair',
'reset_password_send_instructions' => 'Rhowch eich e-bost isod ac anfonir e-bost atoch gyda dolen ailosod cyfrinair.',
'reset_password_send_button' => 'Anfon Dolen Ailosod',
'reset_password_sent' => 'A password reset link will be sent to :email if that email address is found in the system.',
'reset_password_success' => 'Your password has been successfully reset.',
'reset_password_sent' => 'Bydd dolen ailosod cyfrinair yn cael ei hanfon at :email os ceir hyd ir cyfeiriad e-bost hwn yn y system.',
'reset_password_success' => 'Mae eich cyfrinair wedi\'i ailosod yn llwyddiannus.',
'email_reset_subject' => 'Ailosod eich gair pass :appName',
'email_reset_text' => 'You are receiving this email because we received a password reset request for your account.',
'email_reset_text' => 'Anfonwyd yr e-bost hwn atoch oherwydd ein bod wedi cael cais ailosod cyfrinair ar gyfer eich cyfrif.',
'email_reset_not_requested' => 'Os nad oeddwch chi\'n ceisio ailosod eich gair pass, does dim byd arall i wneud.',
// Email Confirmation
@@ -58,60 +58,60 @@ return [
'email_confirm_greeting' => 'Diolch am ymuno â :appName!',
'email_confirm_text' => 'Os gwelwch yn dda cadarnhewch eich e-bost chi gan clicio ar y botwm isod:',
'email_confirm_action' => 'Cadarnhau E-bost',
'email_confirm_send_error' => 'Email confirmation required but the system could not send the email. Contact the admin to ensure email is set up correctly.',
'email_confirm_success' => 'Your email has been confirmed! You should now be able to login using this email address.',
'email_confirm_resent' => 'Confirmation email resent, Please check your inbox.',
'email_confirm_send_error' => 'Mae angen cadarnhad e-bost ond ni allai\'r system anfon yr e-bost. Cysylltwch â\'r gweinyddwr i sicrhau bod yr e-bost wedi\'i osod yn gywir.',
'email_confirm_success' => 'Mae eich e-bost wedi\'i gadarnhau! Dylech nawr allu mewngofnodi gan ddefnyddio\'r cyfeiriad e-bost hwn.',
'email_confirm_resent' => 'Ail-anfonwyd cadarnhad e-bost, gwiriwch eich mewnflwch.',
'email_confirm_thanks' => 'Diolch am gadarnhau!',
'email_confirm_thanks_desc' => 'Please wait a moment while your confirmation is handled. If you are not redirected after 3 seconds press the "Continue" link below to proceed.',
'email_confirm_thanks_desc' => 'Arhoswch eiliad wrth ich cadarnhad gael ei drin. Os na chewch eich ailgyfeirio ar ôl 3 eiliad, pwyswch y ddolen "Parhau" isod i symud ymlaen.',
'email_not_confirmed' => 'Cyfeiriad E-bost heb ei Gadarnhau',
'email_not_confirmed_text' => 'Dyw eich cyfeiriad e-bost chi ddim wedi cael ei gadarnhau eto.',
'email_not_confirmed_click_link' => 'Please click the link in the email that was sent shortly after you registered.',
'email_not_confirmed_resend' => 'If you cannot find the email you can re-send the confirmation email by submitting the form below.',
'email_not_confirmed_resend_button' => 'Resend Confirmation Email',
'email_not_confirmed_click_link' => 'Cliciwch ar y ddolen yn yr e-bost a anfonwyd yn fuan ar ôl i chi gofrestru.',
'email_not_confirmed_resend' => 'Os na allwch ddod o hyd i\'r e-bost, gallwch ail-anfon yr e-bost cadarnhad trwy gyflwyno\'r ffurflen isod.',
'email_not_confirmed_resend_button' => 'Ail-anfon E-bost Cadarnhad',
// User Invite
'user_invite_email_subject' => 'You have been invited to join :appName!',
'user_invite_email_subject' => 'Rydych chi wedi cael gwahoddiad i ymuno :appName!',
'user_invite_email_greeting' => 'Mae cyfrif wedi cae ei greu i chi ar :appName.',
'user_invite_email_text' => 'Click the button below to set an account password and gain access:',
'user_invite_email_action' => 'Set Account Password',
'user_invite_email_text' => 'Cliciwch ar y botwm isod i osod cyfrinair cyfrif a chael mynediad:',
'user_invite_email_action' => 'Gosod Cyfrinair Cyfrif',
'user_invite_page_welcome' => 'Croeso i :appName!',
'user_invite_page_text' => 'To finalise your account and gain access you need to set a password which will be used to log-in to :appName on future visits.',
'user_invite_page_text' => 'I gwblhau eich cyfrif a chael mynediad mae angen i chi osod cyfrinair a fydd yn cael ei ddefnyddio i fewngofnodi i :appName ar ymweliadau yn y dyfodol.',
'user_invite_page_confirm_button' => 'Cadarnhau cyfrinair',
'user_invite_success_login' => 'Password set, you should now be able to login using your set password to access :appName!',
'user_invite_success_login' => 'Cyfrinair wedii osod, dylech nawr allu mewngofnodi gan ddefnyddio\'r cyfrinair a osodwyd i gael mynediad i :appName!',
// Multi-factor Authentication
'mfa_setup' => 'Setup Multi-Factor Authentication',
'mfa_setup_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'mfa_setup' => 'Gosod Dilysu Aml-Ffactor',
'mfa_setup_desc' => 'Gosod dilysu aml-ffactor fel haen ychwanegol o ddiogelwch ar gyfer eich cyfrif defnyddiwr.',
'mfa_setup_configured' => 'Wedi\'i ail-ffurfweddu\'n barod',
'mfa_setup_reconfigure' => 'Ail-ffurfweddu',
'mfa_setup_remove_confirmation' => 'Are you sure you want to remove this multi-factor authentication method?',
'mfa_setup_remove_confirmation' => 'Ydych chi\'n siŵr eich bod am gael gwared ar y dull dilysu aml-ffactor hwn?',
'mfa_setup_action' => 'Gosodiad',
'mfa_backup_codes_usage_limit_warning' => 'You have less than 5 backup codes remaining, Please generate and store a new set before you run out of codes to prevent being locked out of your account.',
'mfa_backup_codes_usage_limit_warning' => 'Mae gennych lai na 5 cod wrth gefn yn weddill, crëwch a storio cyfres newydd cyn i chi redeg allan o godau i osgoi cael eich cloi allan o\'ch cyfrif.',
'mfa_option_totp_title' => 'Ap Ffôn Symudol',
'mfa_option_totp_desc' => 'To use multi-factor authentication you\'ll need a mobile application that supports TOTP such as Google Authenticator, Authy or Microsoft Authenticator.',
'mfa_option_totp_desc' => 'I ddefnyddio dilysu aml-ffactor bydd angen dyfais symudol arnoch sy\'n cefnogi TOTP megis Google Authenticator, Authy neu Microsoft Authenticator.',
'mfa_option_backup_codes_title' => 'Codau wrth Gefn',
'mfa_option_backup_codes_desc' => 'Generates a set of one-time-use backup codes which you\'ll enter on login to verify your identity. Make sure to store these in a safe & secure place.',
'mfa_gen_confirm_and_enable' => 'Confirm and Enable',
'mfa_option_backup_codes_desc' => 'Maen cynhyrchu cyfres o godau wrth gefn un-amser y byddwch chi\'n eu defnyddio i fewngofnodi i wirio pwy ydych chi. Gwnewch yn siŵr eich bod yn storio\'r rhain mewn lle saff a diogel.',
'mfa_gen_confirm_and_enable' => 'Cadarnhau a Galluogi',
'mfa_gen_backup_codes_title' => 'Gosodiad Codau wrth Gefn',
'mfa_gen_backup_codes_desc' => 'Store the below list of codes in a safe place. When accessing the system you\'ll be able to use one of the codes as a second authentication mechanism.',
'mfa_gen_backup_codes_desc' => 'Storiwch y rhestr isod o godau mewn lle diogel. Wrth ddefnyddior system bydd modd i chi ddefnyddio un o\'r codau fel ail fecanwaith dilysu.',
'mfa_gen_backup_codes_download' => 'Llwytho Codau i Lawr',
'mfa_gen_backup_codes_usage_warning' => 'Each code can only be used once',
'mfa_gen_totp_title' => 'Mobile App Setup',
'mfa_gen_totp_desc' => 'To use multi-factor authentication you\'ll need a mobile application that supports TOTP such as Google Authenticator, Authy or Microsoft Authenticator.',
'mfa_gen_totp_scan' => 'Scan the QR code below using your preferred authentication app to get started.',
'mfa_gen_totp_verify_setup' => 'Verify Setup',
'mfa_gen_totp_verify_setup_desc' => 'Verify that all is working by entering a code, generated within your authentication app, in the input box below:',
'mfa_gen_totp_provide_code_here' => 'Provide your app generated code here',
'mfa_gen_backup_codes_usage_warning' => 'Gellir defnyddio pob cod unwaith yn unig',
'mfa_gen_totp_title' => 'Gosod Ap Symudol',
'mfa_gen_totp_desc' => 'I ddefnyddio dilysu aml-ffactor bydd angen dyfais symudol arnoch sy\'n cefnogi TOTP megis Google Authenticator, Authy neu Microsoft Authenticator.',
'mfa_gen_totp_scan' => 'Sganiwch y cod QR isod gan ddefnyddio\'ch ap dilysu dewisol i ddechrau.',
'mfa_gen_totp_verify_setup' => 'Gwirio Gosodiad',
'mfa_gen_totp_verify_setup_desc' => 'Gwiriwch fod popeth yn gweithio trwy roi cod, a gynhyrchwyd gan eich ap dilysu, yn y blwch mewnbwn isod:',
'mfa_gen_totp_provide_code_here' => 'Rhowch y cod a gynhyrchwyd gan eich ap yma',
'mfa_verify_access' => 'Gwirio Mynediad',
'mfa_verify_access_desc' => 'Your user account requires you to confirm your identity via an additional level of verification before you\'re granted access. Verify using one of your configured methods to continue.',
'mfa_verify_no_methods' => 'No Methods Configured',
'mfa_verify_no_methods_desc' => 'No multi-factor authentication methods could be found for your account. You\'ll need to set up at least one method before you gain access.',
'mfa_verify_access_desc' => 'Mae eich cyfrif defnyddiwr yn gofyn i chi gadarnhau pwy ydych chi trwy lefel ychwanegol o ddilysu cyn i chi gael mynediad. Gwiriwch gan ddefnyddio un o\'ch dulliau ffurfweddu i barhau.',
'mfa_verify_no_methods' => 'Dim Dulliau wedi\'u Ffurfweddu',
'mfa_verify_no_methods_desc' => 'Ni ellid dod o hyd i unrhyw ddulliau dilysu aml-ffactor ar gyfer eich cyfrif. Bydd angen i chi osod o leiaf un dull cyn i chi gael mynediad.',
'mfa_verify_use_totp' => 'Gwirio gan ap ffôn',
'mfa_verify_use_backup_codes' => 'Gwirio gan god wrth gefn',
'mfa_verify_backup_code' => 'Cod wrth Gefn',
'mfa_verify_backup_code_desc' => 'Enter one of your remaining backup codes below:',
'mfa_verify_backup_code_desc' => 'Rhowch un o\'ch codau wrth gefn sy\'n weddill isod:',
'mfa_verify_backup_code_enter_here' => 'Cofnodi cod wrth gefn yma',
'mfa_verify_totp_desc' => 'Enter the code, generated using your mobile app, below:',
'mfa_setup_login_notification' => 'Multi-factor method configured, Please now login again using the configured method.',
'mfa_verify_totp_desc' => 'Rhowch y cod, a gynhyrchwyd gan ddefnyddio\'ch ap symudol, isod:',
'mfa_setup_login_notification' => 'Dull aml-ffactor wedi\'i ffurfweddu, nawr mewngofnodwch eto gan ddefnyddio\'r dull wedi\'i ffurfweddu.',
];

View File

@@ -19,8 +19,8 @@ return [
'name' => 'Enw',
'description' => 'Disgrifiad',
'role' => 'Rôl',
'cover_image' => 'Cover image',
'cover_image_description' => 'This image should be approximately 440x250px although it will be flexibly scaled & cropped to fit the user interface in different scenarios as required, so actual dimensions for display will differ.',
'cover_image' => 'Delwedd y clawr',
'cover_image_description' => 'Dylai\'r ddelwedd hon fod oddeutu 440x250px er y bydd wedi\'i graddio ai thocio i ffitio rhyngwyneb y defnyddiwr mewn gwahanol senarios yn ôl yr angen, felly bydd y dimensiynau arddangos gwirioneddol yn amrywio.',
// Actions
'actions' => 'Gweithredoedd',
@@ -56,7 +56,7 @@ return [
// Sort Options
'sort_options' => 'Trefnu\'r opsiynau',
'sort_direction_toggle' => 'Sort Direction Toggle',
'sort_direction_toggle' => 'Trefnu Cyfeiriad Togl',
'sort_ascending' => 'Trefnu\'n esgynnol',
'sort_descending' => 'Trefnu\'n ddisgynnol',
'sort_name' => 'Enw',
@@ -76,7 +76,7 @@ return [
'grid_view' => 'Golwg Grid',
'list_view' => 'Golwg Rhestr',
'default' => 'Diofyn',
'breadcrumb' => 'Breadcrumb',
'breadcrumb' => 'Briwsion bara',
'status' => 'Statws',
'status_active' => 'Gweithredol',
'status_inactive' => 'Anweithredol',
@@ -85,26 +85,29 @@ return [
// Header
'homepage' => 'Tudalen cartref',
'header_menu_expand' => 'Expand Header Menu',
'header_menu_expand' => 'Ehangu Dewislen Pennawd',
'profile_menu' => 'Dewislen Proffil',
'view_profile' => 'Gweld proffil',
'edit_profile' => 'Golygu Proffil',
'dark_mode' => 'Modd Tywyll',
'light_mode' => 'Modd Golau',
'global_search' => 'Global Search',
'global_search' => 'Chwilio Byd-eang',
// Layout tabs
'tab_info' => 'Gwybodaeth',
'tab_info_label' => 'Tab: Show Secondary Information',
'tab_info_label' => 'Tab: Dangos Gwybodaeth Eilaidd',
'tab_content' => 'Cynnwys',
'tab_content_label' => 'Tab: Show Primary Content',
'tab_content_label' => 'Tab: Dangos Prif Gynnwys',
// Email Content
'email_action_help' => 'If youre having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:',
'email_rights' => 'All rights reserved',
'email_action_help' => 'Os ydych chi\'n cael trafferth clicio ar y botwm ":actionText", copïwch a gludwch yr URL isod i\'ch porwr gwe:',
'email_rights' => 'Cedwir pob hawl',
// Footer Link Options
// Not directly used but available for convenience to users.
'privacy_policy' => 'Polisi Preifatrwydd',
'terms_of_service' => 'Terms of Service',
'terms_of_service' => 'Telerau Gwasanaeth',
// OpenSearch
'opensearch_description' => 'Chwilio :appName',
];

View File

@@ -5,42 +5,42 @@
return [
// Image Manager
'image_select' => 'Image Select',
'image_select' => 'Dewis Llun',
'image_list' => 'Rhestr o Ddelweddau',
'image_details' => 'Manylion Delwedd',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_upload' => 'Uwchlwytho Llun',
'image_intro' => 'Yma gallwch ddewis a rheoli lluniau sydd wedi\'u huwchlwytho ir system or blaen.',
'image_intro_upload' => 'Uwchlwythwch lun newydd drwy lusgo ffeil llun i\'r ffenestr hon, neu drwy ddefnyddio\'r botwm "Uwchlwytho Llun" uchod.',
'image_all' => 'Popeth',
'image_all_title' => 'Gweld holl ddelweddau',
'image_book_title' => 'View images uploaded to this book',
'image_page_title' => 'View images uploaded to this page',
'image_book_title' => 'Gweld lluniau a uwchlwythwyd ir llyfr hwn',
'image_page_title' => 'Gweld lluniau a uwchlwythwyd ir dudalen hon',
'image_search_hint' => 'Cwilio gan enw delwedd',
'image_uploaded' => 'Uploaded :uploadedDate',
'image_uploaded_by' => 'Uploaded by :userName',
'image_uploaded_to' => 'Uploaded to :pageLink',
'image_updated' => 'Updated :updateDate',
'image_load_more' => 'Load More',
'image_uploaded' => 'Uwchlwythwyd am :uploadedDate',
'image_uploaded_by' => 'Uwchlwythwyd gan :userName',
'image_uploaded_to' => 'Uwchlwythwyd i :pageLink',
'image_updated' => 'Diweddarwyd am :updateDate',
'image_load_more' => 'Llwytho Mwy',
'image_image_name' => 'Enw Delwedd',
'image_delete_used' => 'This image is used in the pages below.',
'image_delete_used' => 'Mae\'r llun hwn yn cael ei ddefnyddio ar y tudalennau isod.',
'image_delete_confirm_text' => 'Wyt ti\'n bendant eisiau dileu\'r ddelwedd hwn?',
'image_select_image' => 'Select Image',
'image_dropzone' => 'Drop images or click here to upload',
'image_dropzone_drop' => 'Drop images here to upload',
'image_select_image' => 'Dewis Llun',
'image_dropzone' => 'Gollyngwch luniau neu cliciwch yma i uwchlwytho',
'image_dropzone_drop' => 'Gollyngwch luniau yma i uwchlwytho',
'images_deleted' => 'Delweddau wedi\'u Dileu',
'image_preview' => 'Image Preview',
'image_upload_success' => 'Image uploaded successfully',
'image_update_success' => 'Image details successfully updated',
'image_delete_success' => 'Image successfully deleted',
'image_replace' => 'Replace Image',
'image_replace_success' => 'Image file successfully updated',
'image_rebuild_thumbs' => 'Regenerate Size Variations',
'image_rebuild_thumbs_success' => 'Image size variations successfully rebuilt!',
'image_preview' => 'Rhagolwg or Llun',
'image_upload_success' => 'Uwchlwythwyd y llun yn llwyddiannus',
'image_update_success' => 'Diweddarwyd manylion y llun yn llwyddiannus',
'image_delete_success' => 'Dilëwyd y llun yn llwyddiannus',
'image_replace' => 'Newid y llun',
'image_replace_success' => 'Ffeil llun wedi\'i diweddarun llwyddiannus',
'image_rebuild_thumbs' => 'Atgynhyrchu Amrywiadau Maint',
'image_rebuild_thumbs_success' => 'Ailadeiladwyd amrywiadau maint y llun yn llwyddiannus!',
// Code Editor
'code_editor' => 'Edit Code',
'code_language' => 'Code Language',
'code_content' => 'Code Content',
'code_session_history' => 'Session History',
'code_save' => 'Save Code',
'code_editor' => 'Golygu Cod',
'code_language' => 'Iaith y Cod',
'code_content' => 'Cynnwys y Cod',
'code_session_history' => 'Hanes y Sesiwn',
'code_save' => 'Cadw Cod',
];

View File

@@ -8,7 +8,7 @@
return [
// General editor terms
'general' => 'Cyffredin',
'advanced' => 'Advanced',
'advanced' => 'Datblygedig',
'none' => 'Dim un',
'cancel' => 'Canslo',
'save' => 'Cadw',
@@ -33,144 +33,144 @@ return [
'header_small' => 'Pennyn Bach',
'header_tiny' => 'Pennyn Mân',
'paragraph' => 'Paragraff',
'blockquote' => 'Blockquote',
'inline_code' => 'Inline code',
'callouts' => 'Callouts',
'blockquote' => 'Dyfyniad bloc',
'inline_code' => 'Cod mewnol',
'callouts' => 'Galwadau',
'callout_information' => 'Gwybodaeth',
'callout_success' => 'Llwyddiant',
'callout_warning' => 'Rhybudd',
'callout_danger' => 'Perygl',
'bold' => 'Trwm',
'italic' => 'Italig',
'underline' => 'Underline',
'strikethrough' => 'Strikethrough',
'superscript' => 'Superscript',
'subscript' => 'Subscript',
'underline' => 'Tanlinellu',
'strikethrough' => 'Llinell Drwodd',
'superscript' => 'Uwchysgrif',
'subscript' => 'Isysgrif',
'text_color' => 'Lliw testun',
'custom_color' => 'Lliw addasu',
'remove_color' => 'Remove color',
'remove_color' => 'Dileu lliw',
'background_color' => 'Lliw cefnder',
'align_left' => 'Align left',
'align_center' => 'Align center',
'align_right' => 'Align right',
'align_justify' => 'Justify',
'list_bullet' => 'Bullet list',
'list_numbered' => 'Numbered list',
'list_task' => 'Task list',
'indent_increase' => 'Increase indent',
'indent_decrease' => 'Decrease indent',
'align_left' => 'Alinio i\'r chwith',
'align_center' => 'Alinio ir canol',
'align_right' => 'Alinio i\'r dde',
'align_justify' => 'Unioni',
'list_bullet' => 'Rhestr o Bwyntiau Bwled',
'list_numbered' => 'Rhestr wedi\'i rhifo',
'list_task' => 'Rhestr dasgau',
'indent_increase' => 'Cynyddu mewnoliad',
'indent_decrease' => 'Lleihau mewnoliad',
'table' => 'Bwrdd',
'insert_image' => 'Insert image',
'insert_image_title' => 'Insert/Edit Image',
'insert_link' => 'Insert/edit link',
'insert_link_title' => 'Insert/Edit Link',
'insert_horizontal_line' => 'Insert horizontal line',
'insert_code_block' => 'Insert code block',
'edit_code_block' => 'Edit code block',
'insert_drawing' => 'Insert/edit drawing',
'drawing_manager' => 'Drawing manager',
'insert_media' => 'Insert/edit media',
'insert_media_title' => 'Insert/Edit Media',
'clear_formatting' => 'Clear formatting',
'source_code' => 'Source code',
'source_code_title' => 'Source Code',
'fullscreen' => 'Fullscreen',
'image_options' => 'Image options',
'insert_image' => 'Mewnosod llun',
'insert_image_title' => 'Mewnosod/Golygu Llun',
'insert_link' => 'Mewnosod/golygu dolen',
'insert_link_title' => 'Mewnosod/Golygu Dolen',
'insert_horizontal_line' => 'Mewnosod llinell lorweddol',
'insert_code_block' => 'Mewnosod bloc cod',
'edit_code_block' => 'Golygu bloc cod',
'insert_drawing' => 'Mewnosod/golygu dyluniad',
'drawing_manager' => 'Rheolwr dylunio',
'insert_media' => 'Mewnosod/golygu cyfryngau',
'insert_media_title' => 'Mewnosod/Golygu Cyfryngau',
'clear_formatting' => 'Clirio fformatio',
'source_code' => 'Cod ffynhonnell',
'source_code_title' => 'Cod Ffynhonnell',
'fullscreen' => 'Sgrin lawn',
'image_options' => 'Opsiynau llun',
// Tables
'table_properties' => 'Table properties',
'table_properties_title' => 'Table Properties',
'delete_table' => 'Delete table',
'table_clear_formatting' => 'Clear table formatting',
'resize_to_contents' => 'Resize to contents',
'row_header' => 'Row header',
'insert_row_before' => 'Insert row before',
'insert_row_after' => 'Insert row after',
'delete_row' => 'Delete row',
'insert_column_before' => 'Insert column before',
'insert_column_after' => 'Insert column after',
'delete_column' => 'Delete column',
'table_properties' => 'Priodweddau tabl',
'table_properties_title' => 'Priodweddau Tabl',
'delete_table' => 'Dileu tabl',
'table_clear_formatting' => 'Clirio fformatio tabl',
'resize_to_contents' => 'Newid maint i\'r cynnwys',
'row_header' => 'Pennyn rhes',
'insert_row_before' => 'Mewnosod rhes cyn',
'insert_row_after' => 'Mewnosod rhes ar ôl',
'delete_row' => 'Dileu rhes',
'insert_column_before' => 'Mewnosod colofn cyn',
'insert_column_after' => 'Mewnosod colofn ar ôl',
'delete_column' => 'Dileu colofn',
'table_cell' => 'Cell',
'table_row' => 'Row',
'table_column' => 'Column',
'cell_properties' => 'Cell properties',
'cell_properties_title' => 'Cell Properties',
'cell_type' => 'Cell type',
'table_row' => 'Rhes',
'table_column' => 'Colofn',
'cell_properties' => 'Priodweddau cell',
'cell_properties_title' => 'Priodweddau Cell',
'cell_type' => 'Math o gell',
'cell_type_cell' => 'Cell',
'cell_scope' => 'Scope',
'cell_type_header' => 'Header cell',
'merge_cells' => 'Merge cells',
'split_cell' => 'Split cell',
'table_row_group' => 'Row Group',
'table_column_group' => 'Column Group',
'horizontal_align' => 'Horizontal align',
'vertical_align' => 'Vertical align',
'border_width' => 'Border width',
'border_style' => 'Border style',
'border_color' => 'Border color',
'row_properties' => 'Row properties',
'row_properties_title' => 'Row Properties',
'cut_row' => 'Cut row',
'copy_row' => 'Copy row',
'paste_row_before' => 'Paste row before',
'paste_row_after' => 'Paste row after',
'row_type' => 'Row type',
'cell_scope' => 'Cwmpas',
'cell_type_header' => 'Pennyn cell',
'merge_cells' => 'Uno celloedd',
'split_cell' => 'Hollti cell',
'table_row_group' => 'Grŵp Rhes',
'table_column_group' => 'Grŵp Colofn',
'horizontal_align' => 'Alinio llorweddol',
'vertical_align' => 'Alinio fertigol',
'border_width' => 'Lled y border',
'border_style' => 'Arddull y border',
'border_color' => 'Lliw y border',
'row_properties' => 'Priodweddaur rhes',
'row_properties_title' => 'Priodweddaur Rhes',
'cut_row' => 'Torri rhes',
'copy_row' => 'Copïo rhes',
'paste_row_before' => 'Gludo rhes cyn',
'paste_row_after' => 'Gludo rhes ar ôl',
'row_type' => 'Math o res',
'row_type_header' => 'Pennyn',
'row_type_body' => 'Body',
'row_type_body' => 'Corff',
'row_type_footer' => 'Troedyn',
'alignment' => 'Aliniad',
'cut_column' => 'Cut column',
'copy_column' => 'Copy column',
'paste_column_before' => 'Paste column before',
'paste_column_after' => 'Paste column after',
'cell_padding' => 'Cell padding',
'cell_spacing' => 'Cell spacing',
'cut_column' => 'Torri colofn',
'copy_column' => 'Copïo colofn',
'paste_column_before' => 'Gludo colofn cyn',
'paste_column_after' => 'Gludo colofn ar ôl',
'cell_padding' => 'Padio cell',
'cell_spacing' => 'Bylchau rhwng celloedd',
'caption' => 'Pennawd',
'show_caption' => 'Dangos pennawd',
'constrain' => 'Constrain proportions',
'constrain' => 'Cyfyngu cyfrannau',
'cell_border_solid' => 'Solid',
'cell_border_dotted' => 'Dotted',
'cell_border_dashed' => 'Dashed',
'cell_border_double' => 'Double',
'cell_border_groove' => 'Groove',
'cell_border_ridge' => 'Ridge',
'cell_border_inset' => 'Inset',
'cell_border_outset' => 'Outset',
'cell_border_dotted' => 'Dotiog',
'cell_border_dashed' => 'Llinell Doredig',
'cell_border_double' => 'Dwbl',
'cell_border_groove' => 'Rhigol',
'cell_border_ridge' => 'Crib',
'cell_border_inset' => 'Mewnosodiad',
'cell_border_outset' => 'Cychwyniad',
'cell_border_none' => 'Dim un',
'cell_border_hidden' => 'Hidden',
'cell_border_hidden' => 'Cuddiedig',
// Images, links, details/summary & embed
'source' => 'Source',
'alt_desc' => 'Alternative description',
'embed' => 'Embed',
'paste_embed' => 'Paste your embed code below:',
'source' => 'Ffynhonnell',
'alt_desc' => 'Disgrifiad amgen',
'embed' => 'Ymgorffori',
'paste_embed' => 'Gludwch eich cod ymgorffori isod:',
'url' => 'URL',
'text_to_display' => 'Text to display',
'text_to_display' => 'Testun i\'w arddangos',
'title' => 'Teitl',
'open_link' => 'Open link',
'open_link_in' => 'Open link in...',
'open_link_current' => 'Current window',
'open_link_new' => 'New window',
'remove_link' => 'Remove link',
'insert_collapsible' => 'Insert collapsible block',
'collapsible_unwrap' => 'Unwrap',
'edit_label' => 'Edit label',
'toggle_open_closed' => 'Toggle open/closed',
'collapsible_edit' => 'Edit collapsible block',
'toggle_label' => 'Toggle label',
'open_link' => 'Agor dolen',
'open_link_in' => 'Agor dolen yn...',
'open_link_current' => 'Ffenestr bresennol',
'open_link_new' => 'Ffenestr newydd',
'remove_link' => 'Dileu dolen',
'insert_collapsible' => 'Mewnosod bloc cwympadwy',
'collapsible_unwrap' => 'Datod',
'edit_label' => 'Golygu label',
'toggle_open_closed' => 'Agor/cau Togl',
'collapsible_edit' => 'Golygu bloc cwympadwy',
'toggle_label' => 'Toglo label',
// About view
'about' => 'About the editor',
'about_title' => 'About the WYSIWYG Editor',
'editor_license' => 'Editor License & Copyright',
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
'save_continue' => 'Save Page & Continue',
'callouts_cycle' => '(Keep pressing to toggle through types)',
'link_selector' => 'Link to content',
'shortcuts' => 'Shortcuts',
'shortcut' => 'Shortcut',
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
'about' => 'Ynglŷn â\'r golygydd',
'about_title' => 'Ynglŷn â\'r Golygydd WYSIWYG',
'editor_license' => 'Trwydded a Hawlfraint Golygydd',
'editor_tiny_license' => 'Mae\'r golygydd hwn wedi\'i adeiladu gan ddefnyddio :tinyLink sy\'n cael ei ddarparu o dan y drwydded MIT.',
'editor_tiny_license_link' => 'Gellir dod o hyd i fanylion hawlfraint a thrwydded TinyMCE yma.',
'save_continue' => 'Cadw Tudalen a Pharhau',
'callouts_cycle' => '(Pwyswch i doglo drwyr mathau)',
'link_selector' => 'Dolen i\'r cynnwys',
'shortcuts' => 'Llwybrau Byr',
'shortcut' => 'Llwybr Byr',
'shortcuts_intro' => 'Mae\'r llwybrau byr canlynol ar gael yn y golygydd:',
'windows_linux' => '(Windows/Linux)',
'mac' => '(Mac)',
'description' => 'Disgrifiad',

View File

@@ -6,165 +6,165 @@
return [
// Shared
'recently_created' => 'Recently Created',
'recently_created_pages' => 'Recently Created Pages',
'recently_updated_pages' => 'Recently Updated Pages',
'recently_created_chapters' => 'Recently Created Chapters',
'recently_created_books' => 'Recently Created Books',
'recently_created_shelves' => 'Recently Created Shelves',
'recently_update' => 'Recently Updated',
'recently_viewed' => 'Recently Viewed',
'recent_activity' => 'Recent Activity',
'create_now' => 'Create one now',
'revisions' => 'Revisions',
'recently_created' => 'Crëwyd yn Ddiweddar',
'recently_created_pages' => 'Tudalennau a Grëwyd yn Ddiweddar',
'recently_updated_pages' => 'Tudalennau a Ddiweddarwyd yn Ddiweddar',
'recently_created_chapters' => 'Penodau a Grëwyd yn Ddiweddar',
'recently_created_books' => 'Llyfrau a Grëwyd yn Ddiweddar',
'recently_created_shelves' => 'Silffoedd a Grëwyd yn Ddiweddar',
'recently_update' => 'Diweddarwyd yn Ddiweddar',
'recently_viewed' => 'Gwelwyd yn Ddiweddar',
'recent_activity' => 'Gweithgaredd Diweddar',
'create_now' => 'Creu un nawr',
'revisions' => 'Diwygiadau',
'meta_revision' => 'Diwygiad #:revisionCount',
'meta_created' => 'Created :timeLength',
'meta_created_name' => 'Created :timeLength by :user',
'meta_updated' => 'Updated :timeLength',
'meta_updated_name' => 'Updated :timeLength by :user',
'meta_owned_name' => 'Owned by :user',
'meta_reference_count' => 'Referenced by :count item|Referenced by :count items',
'entity_select' => 'Entity Select',
'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item',
'meta_created' => 'Crëwyd',
'meta_created_name' => 'Crëwyd :timeLength gan :user',
'meta_updated' => 'Diweddarwyd :timeLength',
'meta_updated_name' => 'Diweddarwyd :timeLength gan :user',
'meta_owned_name' => 'Mae\'n eiddo i :user',
'meta_reference_count' => 'Cyfeirir ato gan :count eitem|Cyfeirir ato gan :count o eitemau',
'entity_select' => 'Dewis Endid',
'entity_select_lack_permission' => 'Nid oes gennych y caniatâd angenrheidiol i ddewis yr eitem hon',
'images' => 'Delweddau',
'my_recent_drafts' => 'My Recent Drafts',
'my_recently_viewed' => 'My Recently Viewed',
'my_most_viewed_favourites' => 'My Most Viewed Favourites',
'my_favourites' => 'My Favourites',
'no_pages_viewed' => 'You have not viewed any pages',
'no_pages_recently_created' => 'No pages have been recently created',
'no_pages_recently_updated' => 'No pages have been recently updated',
'export' => 'Export',
'export_html' => 'Contained Web File',
'my_recent_drafts' => 'Fy Nrafftiau Diweddar',
'my_recently_viewed' => 'Edrych yn Ddiweddar',
'my_most_viewed_favourites' => 'Fy Ffefrynnau Mwyaf Poblogaidd',
'my_favourites' => 'Fy Ffefrynnau',
'no_pages_viewed' => 'Nid ydych wedi edrych ar unrhyw dudalennau',
'no_pages_recently_created' => 'Nid oes unrhyw dudalennau wedi\'u creu\'n ddiweddar',
'no_pages_recently_updated' => 'Nid oes unrhyw dudalennau wedi\'u diweddaru\'n ddiweddar',
'export' => 'Allforio',
'export_html' => 'Ffeil Gwe wedi\'i Chynnwys',
'export_pdf' => 'Ffeil PDF',
'export_text' => 'Plain Text File',
'export_md' => 'Markdown File',
'default_template' => 'Default Page Template',
'default_template_explain' => 'Assign a page template that will be used as the default content for all pages created within this item. Keep in mind this will only be used if the page creator has view access to the chosen template page.',
'default_template_select' => 'Select a template page',
'export_text' => 'Ffeil Testun Plaen',
'export_md' => 'Ffeil Markdown',
'default_template' => 'Templed Tudalen Diofyn',
'default_template_explain' => 'Clustnodwch dempled tudalen a fydd yn cael ei ddefnyddio fel y cynnwys diofyn ar gyfer pob tudalen a grëwyd yn yr eitem hon. Cofiwch y bydd hwn ond yn cael ei ddefnyddio os ywr sawl a grëodd y dudalen â mynediad gweld ir dudalen dempled a ddewiswyd.',
'default_template_select' => 'Dewiswch dudalen templed',
// Permissions and restrictions
'permissions' => 'Permissions',
'permissions_desc' => 'Set permissions here to override the default permissions provided by user roles.',
'permissions_book_cascade' => 'Permissions set on books will automatically cascade to child chapters and pages, unless they have their own permissions defined.',
'permissions_chapter_cascade' => 'Permissions set on chapters will automatically cascade to child pages, unless they have their own permissions defined.',
'permissions_save' => 'Save Permissions',
'permissions_owner' => 'Owner',
'permissions_role_everyone_else' => 'Everyone Else',
'permissions_role_everyone_else_desc' => 'Set permissions for all roles not specifically overridden.',
'permissions_role_override' => 'Override permissions for role',
'permissions_inherit_defaults' => 'Inherit defaults',
'permissions' => 'Caniatâd',
'permissions_desc' => 'Gosodwch ganiatâd yma i ddiystyru\'r caniatâd diofyn a ddarperir gan rolau defnyddwyr.',
'permissions_book_cascade' => 'Bydd caniatâd a osodir ar lyfrau yn rhaeadrun awtomatig i benodau a thudalennau plant, oni bai bod ganddynt eu caniatâd diffiniedig eu hunain.',
'permissions_chapter_cascade' => 'Bydd caniatâd a osodir ar benodau yn rhaeadrun awtomatig i dudalennau plant, oni bai bod ganddynt eu caniatâd diffiniedig eu hunain.',
'permissions_save' => 'Cadw Caniatâd',
'permissions_owner' => 'Perchennog',
'permissions_role_everyone_else' => 'Pawb arall',
'permissions_role_everyone_else_desc' => 'Gosod caniatâd ar gyfer pob rôl nad ydynt yn cael eu diystyru\'n benodol.',
'permissions_role_override' => 'Diystyru caniatâd ar gyfer rôl',
'permissions_inherit_defaults' => 'Etifeddu rhagosodiadau',
// Search
'search_results' => 'Search Results',
'search_total_results_found' => ':count result found|:count total results found',
'search_results' => 'Canlyniadau Chwilio',
'search_total_results_found' => 'Cafwyd :count canlyniad|Cafwyd cyfanswm o :count canlyniad',
'search_clear' => 'Clirio\'r Chwiliad',
'search_no_pages' => 'No pages matched this search',
'search_for_term' => 'Search for :term',
'search_more' => 'More Results',
'search_advanced' => 'Advanced Search',
'search_terms' => 'Search Terms',
'search_content_type' => 'Content Type',
'search_exact_matches' => 'Exact Matches',
'search_tags' => 'Tag Searches',
'search_no_pages' => 'Nid oedd unrhyw dudalennau yn cyfateb â\'r chwiliad hwn',
'search_for_term' => 'Chwilio am :term',
'search_more' => 'Mwy o Ganlyniadau',
'search_advanced' => 'Math o Gynnwys',
'search_terms' => 'Termau Chwilio',
'search_content_type' => 'Math o Gynnwys',
'search_exact_matches' => 'Union Gyfatebiaethau',
'search_tags' => 'Tagio Chwiliadau',
'search_options' => 'Opsiynau',
'search_viewed_by_me' => 'Viewed by me',
'search_not_viewed_by_me' => 'Not viewed by me',
'search_permissions_set' => 'Permissions set',
'search_created_by_me' => 'Created by me',
'search_updated_by_me' => 'Updated by me',
'search_owned_by_me' => 'Owned by me',
'search_date_options' => 'Date Options',
'search_updated_before' => 'Updated before',
'search_updated_after' => 'Updated after',
'search_created_before' => 'Created before',
'search_created_after' => 'Created after',
'search_set_date' => 'Set Date',
'search_update' => 'Update Search',
'search_viewed_by_me' => 'Gwelwyd gennyf fi',
'search_not_viewed_by_me' => 'Nas gwelwyd gennyf fi',
'search_permissions_set' => 'Gosod Caniatâd',
'search_created_by_me' => 'Crëwyd gennyf fi',
'search_updated_by_me' => 'Diweddarwyd gennyf fi',
'search_owned_by_me' => 'Yn eiddo i mi',
'search_date_options' => 'Opsiynau Dyddiad',
'search_updated_before' => 'Diweddarwyd cyn',
'search_updated_after' => 'Diweddarwyd ar ôl',
'search_created_before' => 'Crëwyd cyn',
'search_created_after' => 'Crëwyd ar ôl',
'search_set_date' => 'Gosod Dyddiad',
'search_update' => 'Diweddaru Chwiliad',
// Shelves
'shelf' => 'Silff',
'shelves' => 'Silffau',
'x_shelves' => ':count Silff|:count Shelves',
'shelves_empty' => 'No shelves have been created',
'shelves_create' => 'Create New Shelf',
'shelves_popular' => 'Popular Shelves',
'shelves_empty' => 'Ni chrëwyd unrhyw silffoedd',
'shelves_create' => 'Creu Silff Newydd',
'shelves_popular' => 'Silffoedd Poblogaidd',
'shelves_new' => 'Silffau Newydd',
'shelves_new_action' => 'Silff Newydd',
'shelves_popular_empty' => 'The most popular shelves will appear here.',
'shelves_new_empty' => 'The most recently created shelves will appear here.',
'shelves_save' => 'Save Shelf',
'shelves_books' => 'Books on this shelf',
'shelves_add_books' => 'Add books to this shelf',
'shelves_drag_books' => 'Drag books below to add them to this shelf',
'shelves_empty_contents' => 'This shelf has no books assigned to it',
'shelves_edit_and_assign' => 'Edit shelf to assign books',
'shelves_edit_named' => 'Edit Shelf :name',
'shelves_edit' => 'Edit Shelf',
'shelves_delete' => 'Delete Shelf',
'shelves_delete_named' => 'Delete Shelf :name',
'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.",
'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?',
'shelves_permissions' => 'Shelf Permissions',
'shelves_permissions_updated' => 'Shelf Permissions Updated',
'shelves_permissions_active' => 'Shelf Permissions Active',
'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.',
'shelves_permissions_create' => 'Shelf create permissions are only used for copying permissions to child books using the action below. They do not control the ability to create books.',
'shelves_copy_permissions_to_books' => 'Copy Permissions to Books',
'shelves_copy_permissions' => 'Copy Permissions',
'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.',
'shelves_copy_permission_success' => 'Shelf permissions copied to :count books',
'shelves_popular_empty' => 'Bydd y silffoedd mwyaf poblogaidd yn ymddangos yma.',
'shelves_new_empty' => 'Bydd y silffoedd a grëwyd fwyaf diweddar yn ymddangos yma.',
'shelves_save' => 'Cadw Silff',
'shelves_books' => 'Llyfrau ar y silff hon',
'shelves_add_books' => 'Ychwanegu llyfrau i\'r silff hon',
'shelves_drag_books' => 'Llusgwch lyfrau isod i\'w hychwanegu at y silff hon',
'shelves_empty_contents' => 'Nid oes gan y silff hon unrhyw lyfrau wediu clustnodi iddi',
'shelves_edit_and_assign' => 'Golygu silff i glustnodi llyfrau',
'shelves_edit_named' => 'Golygu Silff :name',
'shelves_edit' => 'Golygu Silff',
'shelves_delete' => 'Dileu Silff',
'shelves_delete_named' => 'Dileu Silff :name',
'shelves_delete_explain' => "Bydd hyn yn dileu'r silff gyda'r enw ':name'. Ni fydd llyfrau wedi'u cynnwys yn cael eu dileu.",
'shelves_delete_confirmation' => 'Ydych chi\'n siŵr eich bod chi eisiau dileu\'r silff hon?',
'shelves_permissions' => 'Caniatâd Silffoedd',
'shelves_permissions_updated' => 'Diweddarwyd Caniatâd Silffoedd',
'shelves_permissions_active' => 'Caniatâd Silffoedd yn Weithredol',
'shelves_permissions_cascade_warning' => 'Nid yw caniatâd ar silffoedd yn rhaeadrun awtomatig i lyfrau sydd wedi\'u cynnwys. Mae hyn oherwydd y gall llyfr fodoli ar silffoedd lluosog. Fodd bynnag, gellir copïo caniatâd i lawr i lyfrau plant gan ddefnyddio\'r opsiwn a geir isod.',
'shelves_permissions_create' => 'Dim ond ar gyfer copïo caniatâd i lyfrau plant y defnyddir caniatâd creu silff gan ddefnyddio\'r camau isod. Nid ydynt yn rheoli\'r gallu i greu llyfrau.',
'shelves_copy_permissions_to_books' => 'Copïo Caniatâd i Lyfrau',
'shelves_copy_permissions' => 'Copïo Caniatâd',
'shelves_copy_permissions_explain' => 'Bydd hyn yn cymhwyso gosodiadau caniatâd presennol y silff hon i bob llyfr sydd wedi\'u cynnwys ynddi. Cyn ysgogi, gwnewch yn siŵr bod unrhyw newidiadau i ganiatâd y silff hon wedi\'u cadw.',
'shelves_copy_permission_success' => 'Caniatâd silff wedi\'i gopïo i :count o lyfrau',
// Books
'book' => 'Llyfr',
'books' => 'Llyfrau',
'x_books' => ':count Book|:count Books',
'books_empty' => 'No books have been created',
'books_popular' => 'Popular Books',
'books_recent' => 'Recent Books',
'books_new' => 'New Books',
'books_new_action' => 'New Book',
'books_popular_empty' => 'The most popular books will appear here.',
'books_new_empty' => 'The most recently created books will appear here.',
'x_books' => ':count Llyfr|:count o Lyfrau',
'books_empty' => 'Ni chrëwyd unrhyw llyfrau',
'books_popular' => 'Llyfrau Poblogaidd',
'books_recent' => 'Llyfrau Diweddar',
'books_new' => 'Llyfrau Newydd',
'books_new_action' => 'Llyfr Newydd',
'books_popular_empty' => 'Bydd y llyfrau mwyaf poblogaidd yn ymddangos yma.',
'books_new_empty' => 'Bydd y llyfrau a grëwyd fwyaf diweddar yn ymddangos yma.',
'books_create' => 'Creu Llyfr Newydd',
'books_delete' => 'Dileu Llyfr',
'books_delete_named' => 'Dileu :bookName Llyfr',
'books_delete_explain' => 'This will delete the book with the name \':bookName\'. All pages and chapters will be removed.',
'books_delete_confirmation' => 'Are you sure you want to delete this book?',
'books_delete_explain' => 'Bydd hyn yn dileu\'r llyfr gyda\'r enw :bookName. Bydd yr holl dudalennau a phenodau yn cael eu dileu.',
'books_delete_confirmation' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r llyfr hwn?',
'books_edit' => 'Golygu\'r Llyfr',
'books_edit_named' => 'Golygu :bookName Llyfr',
'books_form_book_name' => 'Enw\'r Llyfr',
'books_save' => 'Save Book',
'books_permissions' => 'Book Permissions',
'books_permissions_updated' => 'Book Permissions Updated',
'books_empty_contents' => 'No pages or chapters have been created for this book.',
'books_save' => 'Cadw Llyfr',
'books_permissions' => 'Caniatâd Llyfr',
'books_permissions_updated' => 'Diweddarwyd Caniatâd Llyfr',
'books_empty_contents' => 'Ni chrëwyd unrhyw dudalennau neu benodau ar gyfer y llyfr hwn.',
'books_empty_create_page' => 'Creu tudalen newydd',
'books_empty_sort_current_book' => 'Sort the current book',
'books_empty_add_chapter' => 'Add a chapter',
'books_permissions_active' => 'Book Permissions Active',
'books_search_this' => 'Search this book',
'books_navigation' => 'Book Navigation',
'books_sort' => 'Sort Book Contents',
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
'books_sort_updated' => 'Sort by Updated Date',
'books_sort_chapters_first' => 'Chapters First',
'books_sort_chapters_last' => 'Chapters Last',
'books_sort_show_other' => 'Show Other Books',
'books_sort_save' => 'Save New Order',
'books_sort_show_other_desc' => 'Add other books here to include them in the sort operation, and allow easy cross-book reorganisation.',
'books_sort_move_up' => 'Move Up',
'books_sort_move_down' => 'Move Down',
'books_sort_move_prev_book' => 'Move to Previous Book',
'books_sort_move_next_book' => 'Move to Next Book',
'books_sort_move_prev_chapter' => 'Move Into Previous Chapter',
'books_sort_move_next_chapter' => 'Move Into Next Chapter',
'books_sort_move_book_start' => 'Move to Start of Book',
'books_sort_move_book_end' => 'Move to End of Book',
'books_sort_move_before_chapter' => 'Move to Before Chapter',
'books_sort_move_after_chapter' => 'Move to After Chapter',
'books_empty_sort_current_book' => 'Trefnur llyfr presennol',
'books_empty_add_chapter' => 'Ychwanegu pennod',
'books_permissions_active' => 'Caniatâd Llyfr yn Weithredol',
'books_search_this' => 'Chwilio\'r llyfr hwn',
'books_navigation' => 'Llywio Llyfr',
'books_sort' => 'Trefnu Cynnwys Llyfr',
'books_sort_desc' => 'Symudwch benodau a thudalennau o fewn llyfr i ad-drefnu ei gynnwys. Gellir ychwanegu llyfrau eraill sy\'n caniatáu symud penodau a thudalennau yn hawdd rhwng llyfrau.',
'books_sort_named' => 'Trefnu Llyfr :bookName',
'books_sort_name' => 'Trefnu yn ôl Enw',
'books_sort_created' => 'Trefnu yn ôl Dyddiad Creu',
'books_sort_updated' => 'Trefnu yn ôl Dyddiad Diweddaru',
'books_sort_chapters_first' => 'Penodau yn Gyntaf',
'books_sort_chapters_last' => 'Penodau yn Olaf',
'books_sort_show_other' => 'Dangos Llyfrau Eraill',
'books_sort_save' => 'Cadwr Drefn Newydd',
'books_sort_show_other_desc' => 'Ychwanegwch lyfrau eraill yma i\'w cynnwys yn y gwaith didoli, a chaniatáu ad-drefnu hawdd rhwng llyfrau.',
'books_sort_move_up' => 'Symud i Fyny',
'books_sort_move_down' => 'Symud i Lawr',
'books_sort_move_prev_book' => 'Symud i\'r Llyfr Blaenorol',
'books_sort_move_next_book' => 'Symud i\'r Llyfr Nesaf',
'books_sort_move_prev_chapter' => 'Symud i\'r Bennod Flaenorol',
'books_sort_move_next_chapter' => 'Symud i\'r Bennod Nesaf',
'books_sort_move_book_start' => 'Symud i Ddechrau\'r Llyfr',
'books_sort_move_book_end' => 'Symud i Ddiwedd y Llyfr',
'books_sort_move_before_chapter' => 'Symud ir Bennod Cynt',
'books_sort_move_after_chapter' => 'Symud ir Bennod Ddilynol',
'books_copy' => 'Copio Llyfr',
'books_copy_success' => 'Llyfr wedi\'i copio\'n llwyddiannus',
@@ -172,266 +172,268 @@ return [
'chapter' => 'Pennod',
'chapters' => 'Penodau',
'x_chapters' => ':count Pennod|:count Penodau',
'chapters_popular' => 'Popular Chapters',
'chapters_popular' => 'Penodau Poblogaidd',
'chapters_new' => 'Pennod Newydd',
'chapters_create' => 'Creu Pennod Newydd',
'chapters_delete' => 'Dileu Pennod',
'chapters_delete_named' => 'Dileu :chapterName Pennod',
'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\'. All pages that exist within this chapter will also be deleted.',
'chapters_delete_confirm' => 'Are you sure you want to delete this chapter?',
'chapters_edit' => 'Edit Chapter',
'chapters_edit_named' => 'Edit Chapter :chapterName',
'chapters_save' => 'Save Chapter',
'chapters_move' => 'Move Chapter',
'chapters_move_named' => 'Move Chapter :chapterName',
'chapters_copy' => 'Copy Chapter',
'chapters_copy_success' => 'Chapter successfully copied',
'chapters_permissions' => 'Chapter Permissions',
'chapters_empty' => 'No pages are currently in this chapter.',
'chapters_permissions_active' => 'Chapter Permissions Active',
'chapters_permissions_success' => 'Chapter Permissions Updated',
'chapters_search_this' => 'Search this chapter',
'chapter_sort_book' => 'Sort Book',
'chapters_delete_explain' => 'Bydd hyn yn dileu\'r bennod gyda\'r enw \':chapterName\'. Bydd yr holl dudalennau sy\'n bodoli yn y bennod hon hefyd yn cael eu dileu.',
'chapters_delete_confirm' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r bennod hon?',
'chapters_edit' => 'Ychwanegu Pennod',
'chapters_edit_named' => 'Ychwanegu Pennod :chapterName',
'chapters_save' => 'Cadw Pennod',
'chapters_move' => 'Symud Pennod',
'chapters_move_named' => 'Symud Pennod :chapterName',
'chapters_copy' => 'Copïo Pennod',
'chapters_copy_success' => 'Pennod wedi\'i chopïo\'n llwyddiannus',
'chapters_permissions' => 'Pennau Taith Pennod',
'chapters_empty' => 'Does dim tudalennau yn y bennod hon ar hyn o bryd.',
'chapters_permissions_active' => 'Caniatâd Pennod yn Weithredol',
'chapters_permissions_success' => 'Diweddarwyd Caniatâd Pennod',
'chapters_search_this' => 'Chwilio yn y bennod hon',
'chapter_sort_book' => 'Trefnu Llyfr',
// Pages
'page' => 'Page',
'pages' => 'Pages',
'page' => 'Tudalen',
'pages' => 'Tudalennau',
'x_pages' => ':count Tudalen|:count Tudalennau',
'pages_popular' => 'Popular Pages',
'pages_popular' => 'Tudalennau Poblogaidd',
'pages_new' => 'Tudalen Newydd',
'pages_attachments' => 'Attachments',
'pages_navigation' => 'Page Navigation',
'pages_attachments' => 'Atodiadau',
'pages_navigation' => 'Llywio Tudalen',
'pages_delete' => 'Dileu Tudalen',
'pages_delete_named' => 'Dileu :pageName Tudalen',
'pages_delete_draft_named' => 'Delete Draft Page :pageName',
'pages_delete_draft' => 'Delete Draft Page',
'pages_delete_success' => 'Page deleted',
'pages_delete_draft_success' => 'Draft page deleted',
'pages_delete_warning_template' => 'This page is in active use as a book or chapter default page template. These books or chapters will no longer have a default page template assigned after this page is deleted.',
'pages_delete_confirm' => 'Are you sure you want to delete this page?',
'pages_delete_draft_confirm' => 'Are you sure you want to delete this draft page?',
'pages_editing_named' => 'Editing Page :pageName',
'pages_edit_draft_options' => 'Draft Options',
'pages_edit_save_draft' => 'Save Draft',
'pages_edit_draft' => 'Edit Page Draft',
'pages_editing_draft' => 'Editing Draft',
'pages_editing_page' => 'Editing Page',
'pages_edit_draft_save_at' => 'Draft saved at ',
'pages_edit_delete_draft' => 'Delete Draft',
'pages_edit_delete_draft_confirm' => 'Are you sure you want to delete your draft page changes? All of your changes, since the last full save, will be lost and the editor will be updated with the latest page non-draft save state.',
'pages_edit_discard_draft' => 'Discard Draft',
'pages_edit_switch_to_markdown' => 'Switch to Markdown Editor',
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_set_changelog' => 'Set Changelog',
'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made',
'pages_edit_enter_changelog' => 'Enter Changelog',
'pages_editor_switch_title' => 'Switch Editor',
'pages_editor_switch_are_you_sure' => 'Are you sure you want to change the editor for this page?',
'pages_editor_switch_consider_following' => 'Consider the following when changing editors:',
'pages_editor_switch_consideration_a' => 'Once saved, the new editor option will be used by any future editors, including those that may not be able to change editor type themselves.',
'pages_editor_switch_consideration_b' => 'This can potentially lead to a loss of detail and syntax in certain circumstances.',
'pages_editor_switch_consideration_c' => 'Tag or changelog changes, made since last save, won\'t persist across this change.',
'pages_save' => 'Save Page',
'pages_delete_draft_named' => 'Dileu Tudalen Ddrafft :pageName',
'pages_delete_draft' => 'Dileu Tudalen Ddrafft',
'pages_delete_success' => 'Tudalen wedi\'i dileu',
'pages_delete_draft_success' => 'Tudalen ddrafft wedii dileu',
'pages_delete_warning_template' => 'Mae\'r dudalen hon yn cael ei defnyddio\'n weithredol fel templed tudalen diofyn llyfr neu bennod. Ni fydd gan y llyfrau neu\'r penodau hyn dempled tudalen diofyn wedi\'i glustnodi ar ôl dileu\'r dudalen hon.',
'pages_delete_confirm' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r dudalen hon?',
'pages_delete_draft_confirm' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r dudalen ddrafft hon?',
'pages_editing_named' => 'Golygu Tudalen :pageName',
'pages_edit_draft_options' => 'Opsiynau Drafft',
'pages_edit_save_draft' => 'Cadw Drafft',
'pages_edit_draft' => 'Golygu Tudalen Ddrafft',
'pages_editing_draft' => 'Golygu Drafft',
'pages_editing_page' => 'Golygu Tudalen',
'pages_edit_draft_save_at' => 'Cadwyd drafft ar ',
'pages_edit_delete_draft' => 'Dileu Drafft',
'pages_edit_delete_draft_confirm' => 'Ydych chi\'n siŵr eich bod am ddileu eich newidiadau ir dudalen ddrafft? Bydd eich holl newidiadau, ers eu cadw ddiwethaf, yn cael eu colli a bydd y golygydd yn cael ei ddiweddaru gyda\'r dudalen ddiweddaraf nad yw\'n ddrafft.',
'pages_edit_discard_draft' => 'Gwaredu Drafft',
'pages_edit_switch_to_markdown' => 'Newid ir Golygydd Markdown',
'pages_edit_switch_to_markdown_clean' => '(Cynnwys Glân)',
'pages_edit_switch_to_markdown_stable' => '(Cynnwys Glân)',
'pages_edit_switch_to_wysiwyg' => 'Newid i Olygydd WYSIWYG',
'pages_edit_switch_to_new_wysiwyg' => 'Newid i WYSIWYG newydd',
'pages_edit_switch_to_new_wysiwyg_desc' => '(Mewn Profi Alpha)',
'pages_edit_set_changelog' => 'Gosod Changelog',
'pages_edit_enter_changelog_desc' => 'Rhowch ddisgrifiad byr o\'r newidiadau rydych wedi\'u gwneud',
'pages_edit_enter_changelog' => 'Cofnodwch Changelog',
'pages_editor_switch_title' => 'Newid Golygydd',
'pages_editor_switch_are_you_sure' => 'Ydych chi\'n siŵr eich bod eisiau newid y golygydd ar gyfer y dudalen hon?',
'pages_editor_switch_consider_following' => 'Ystyriwch y canlynol wrth newid golygyddion:',
'pages_editor_switch_consideration_a' => 'Ar ôl ei gadw, bydd yr opsiwn golygydd newydd yn cael ei ddefnyddio gan unrhyw olygydd yn y dyfodol, gan gynnwys y rhai na fyddant efallai\'n gallu newid y math o olygydd eu hunain.',
'pages_editor_switch_consideration_b' => 'Gall hyn arwain at golli manylion a Syntax mewn rhai amgylchiadau.',
'pages_editor_switch_consideration_c' => 'Ni fydd newidiadau tag neu changelog, a wnaed ers eu cadw ddiwethaf, yn parhau ar draws y newid hwn.',
'pages_save' => 'Cadw Tudalen',
'pages_title' => 'Teitl y Dudalen',
'pages_name' => 'Enw\'r Dudalen',
'pages_md_editor' => 'Golygydd',
'pages_md_preview' => 'Preview',
'pages_md_insert_image' => 'Insert Image',
'pages_md_insert_link' => 'Insert Entity Link',
'pages_md_insert_drawing' => 'Insert Drawing',
'pages_md_show_preview' => 'Show preview',
'pages_md_sync_scroll' => 'Sync preview scroll',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_not_in_chapter' => 'Page is not in a chapter',
'pages_move' => 'Move Page',
'pages_copy' => 'Copy Page',
'pages_copy_desination' => 'Copy Destination',
'pages_copy_success' => 'Page successfully copied',
'pages_permissions' => 'Page Permissions',
'pages_permissions_success' => 'Page permissions updated',
'pages_revision' => 'Revision',
'pages_revisions' => 'Page Revisions',
'pages_revisions_desc' => 'Listed below are all the past revisions of this page. You can look back upon, compare, and restore old page versions if permissions allow. The full history of the page may not be fully reflected here since, depending on system configuration, old revisions could be auto-deleted.',
'pages_revisions_named' => 'Page Revisions for :pageName',
'pages_revision_named' => 'Page Revision for :pageName',
'pages_revision_restored_from' => 'Restored from #:id; :summary',
'pages_revisions_created_by' => 'Created By',
'pages_revisions_date' => 'Revision Date',
'pages_md_preview' => 'Rhagolwg',
'pages_md_insert_image' => 'Mewnosod Delwedd',
'pages_md_insert_link' => 'Mewnosod Dolen Endid',
'pages_md_insert_drawing' => 'Mewnosod Llun',
'pages_md_show_preview' => 'Dangos rhagolwg',
'pages_md_sync_scroll' => 'Cydamseru sgrôl ragolwg',
'pages_drawing_unsaved' => 'Canfuwyd Llun heb ei Gadw',
'pages_drawing_unsaved_confirm' => 'Canfuwyd data llun heb ei gadw o ymgais aflwyddiannus blaenorol i gadw llun. Hoffech chi adfer a pharhau i olygu\'r llun heb ei gadw?',
'pages_not_in_chapter' => 'Nid yw\'r dudalen mewn pennod',
'pages_move' => 'Symud Tudalen',
'pages_copy' => 'Copïo Tudalen',
'pages_copy_desination' => 'Copïo Cyrchfan',
'pages_copy_success' => 'Tudalen wedi\'i chreu\'n llwyddiannus',
'pages_permissions' => 'Pennau Taith Tudalen',
'pages_permissions_success' => 'Pennau taith tudalen wedi\'u diweddaru',
'pages_revision' => 'Diwygiad',
'pages_revisions' => 'Diwygiadau\'r Dudalen',
'pages_revisions_desc' => 'Isod ceir holl ddiwygiadau blaenorol y dudalen hon. Gallwch edrych yn ôl ar, cymharu, ac adfer hen fersiynau or dudalen os oes gennych y caniatâd priodol. Efallai na fydd hanes llawn y dudalen yn cael ei adlewyrchu\'n llawn yma oherwydd, gan ddibynnu ar ffurfweddiad y system, gallai hen fersiynau fod wediu dileun awtomatig.',
'pages_revisions_named' => 'Diwygiadau Tudalen ar gyfer :pageName',
'pages_revision_named' => 'Diwygiad Tudalen ar gyfer :pageName',
'pages_revision_restored_from' => 'Adferwyd o #:id; :summary',
'pages_revisions_created_by' => 'Crëwyd gan',
'pages_revisions_date' => 'Dyddiad Adolygu',
'pages_revisions_number' => '#',
'pages_revisions_sort_number' => 'Revision Number',
'pages_revisions_numbered' => 'Revision #:id',
'pages_revisions_numbered_changes' => 'Revision #:id Changes',
'pages_revisions_editor' => 'Editor Type',
'pages_revisions_sort_number' => 'Rhif Diwygiad',
'pages_revisions_numbered' => 'Diwygiad #:id',
'pages_revisions_numbered_changes' => 'Diwygiad #:id Newidiadau',
'pages_revisions_editor' => 'Math o Olygydd',
'pages_revisions_changelog' => 'Changelog',
'pages_revisions_changes' => 'Changes',
'pages_revisions_current' => 'Current Version',
'pages_revisions_preview' => 'Preview',
'pages_revisions_restore' => 'Restore',
'pages_revisions_none' => 'This page has no revisions',
'pages_copy_link' => 'Copy Link',
'pages_edit_content_link' => 'Jump to section in editor',
'pages_pointer_enter_mode' => 'Enter section select mode',
'pages_pointer_label' => 'Page Section Options',
'pages_pointer_permalink' => 'Page Section Permalink',
'pages_pointer_include_tag' => 'Page Section Include Tag',
'pages_pointer_toggle_link' => 'Permalink mode, Press to show include tag',
'pages_pointer_toggle_include' => 'Include tag mode, Press to show permalink',
'pages_permissions_active' => 'Page Permissions Active',
'pages_initial_revision' => 'Initial publish',
'pages_references_update_revision' => 'System auto-update of internal links',
'pages_revisions_changes' => 'Newidiadau',
'pages_revisions_current' => 'Fersiwn Bresennol',
'pages_revisions_preview' => 'Rhagolwg',
'pages_revisions_restore' => 'Adfer',
'pages_revisions_none' => 'Nid oes gan y dudalen hon unrhyw ddiwygiadau',
'pages_copy_link' => 'Copïo Dolen',
'pages_edit_content_link' => 'Neidio i\'r adran yn y golygydd',
'pages_pointer_enter_mode' => 'Rhowch y modd dethol adran',
'pages_pointer_label' => 'Dewisiadau Adran Tudalen',
'pages_pointer_permalink' => 'Dolen Barhaol Adran Tudalen',
'pages_pointer_include_tag' => 'Adran Tudalen Cynnwys Tag',
'pages_pointer_toggle_link' => 'Modd dolen barhaol, Pwyswch i ddangos cynnwys tag',
'pages_pointer_toggle_include' => 'Modd cynnwys tag, Pwyswch i ddangos dolen barhaol',
'pages_permissions_active' => 'Caniatâd Tudalen yn Weithredol',
'pages_initial_revision' => 'Cyhoeddi cychwynnol',
'pages_references_update_revision' => 'Diweddariad awtomatig y system o ddolenni mewnol',
'pages_initial_name' => 'Tudalen Newydd',
'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.',
'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.',
'pages_draft_page_changed_since_creation' => 'This page has been updated since this draft was created. It is recommended that you discard this draft or take care not to overwrite any page changes.',
'pages_editing_draft_notification' => 'Rydych chi wrthin golygu drafft a gafodd ei gadw ddiwethaf ar :timeDiff.',
'pages_draft_edited_notification' => 'Mae\'r dudalen hon wedi\'i diweddaru ers hynny. Argymhellir eich bod yn dileu\'r drafft hwn.',
'pages_draft_page_changed_since_creation' => 'Mae\'r dudalen hon wedi\'i diweddaru ers i\'r drafft hwn gael ei greu. Argymhellir eich bod yn dileu\'r drafft hwn neu\'n sicrhau nad ydych yn ysgrifennu unrhyw newidiadau ir dudalen.',
'pages_draft_edit_active' => [
'start_a' => ':count users have started editing this page',
'start_b' => ':userName has started editing this page',
'time_a' => 'since the page was last updated',
'time_b' => 'in the last :minCount minutes',
'message' => ':start :time. Take care not to overwrite each other\'s updates!',
'start_a' => 'Mae :count defnyddiwr wedi dechrau golygu\'r dudalen hon',
'start_b' => 'Mae :userName wedi dechrau golygu\'r dudalen hon',
'time_a' => 'ers i\'r dudalen gael ei diweddaru ddiwethaf',
'time_b' => 'yn y :minCount munud diwethaf',
'message' => ':start :time. Gofalwch beidio ag ysgrifennu dros ddiweddariadau eich gilydd!',
],
'pages_draft_discarded' => 'Draft discarded! The editor has been updated with the current page content',
'pages_draft_deleted' => 'Draft deleted! The editor has been updated with the current page content',
'pages_specific' => 'Specific Page',
'pages_is_template' => 'Page Template',
'pages_draft_discarded' => 'Drafft wedi\'i waredu! Mae\'r golygydd wedi\'i ddiweddaru gyda chynnwys presennol y dudalen',
'pages_draft_deleted' => 'Drafft wedi\'i ddileu! Mae\'r golygydd wedi\'i ddiweddaru gyda chynnwys presennol y dudalen',
'pages_specific' => 'Tudalen Benodol',
'pages_is_template' => 'Templed Tudalen',
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
'shelf_tags' => 'Shelf Tags',
'toggle_sidebar' => 'Toglo Bar ochr',
'page_tags' => 'Tagiau Tudalennau',
'chapter_tags' => 'Tagiau Penodau',
'book_tags' => 'Tagiau Llyfrau',
'shelf_tags' => 'Tagiau Silffoedd',
'tag' => 'Tag',
'tags' => 'Tags',
'tags_index_desc' => 'Tags can be applied to content within the system to apply a flexible form of categorization. Tags can have both a key and value, with the value being optional. Once applied, content can then be queried using the tag name and value.',
'tag_name' => 'Tag Name',
'tag_value' => 'Tag Value (Optional)',
'tags_explain' => "Add some tags to better categorise your content. \n You can assign a value to a tag for more in-depth organisation.",
'tags_add' => 'Add another tag',
'tags_remove' => 'Remove this tag',
'tags_usages' => 'Total tag usages',
'tags_assigned_pages' => 'Assigned to Pages',
'tags_assigned_chapters' => 'Assigned to Chapters',
'tags_assigned_books' => 'Assigned to Books',
'tags_assigned_shelves' => 'Assigned to Shelves',
'tags_x_unique_values' => ':count unique values',
'tags_all_values' => 'All values',
'tags_view_tags' => 'View Tags',
'tags_view_existing_tags' => 'View existing tags',
'tags_list_empty_hint' => 'Tags can be assigned via the page editor sidebar or while editing the details of a book, chapter or shelf.',
'attachments' => 'Attachments',
'attachments_explain' => 'Upload some files or attach some links to display on your page. These are visible in the page sidebar.',
'attachments_explain_instant_save' => 'Changes here are saved instantly.',
'attachments_upload' => 'Upload File',
'attachments_link' => 'Attach Link',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Set Link',
'attachments_delete' => 'Are you sure you want to delete this attachment?',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'No files have been uploaded',
'attachments_explain_link' => 'You can attach a link if you\'d prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.',
'attachments_link_name' => 'Link Name',
'attachment_link' => 'Attachment link',
'attachments_link_url' => 'Link to file',
'attachments_link_url_hint' => 'Url of site or file',
'attach' => 'Attach',
'attachments_insert_link' => 'Add Attachment Link to Page',
'attachments_edit_file' => 'Edit File',
'tags' => 'Tagiau',
'tags_index_desc' => 'Gellir cymhwyso tagiau i gynnwys o fewn y system i sicrhau categoreiddio hyblyg. Gall tagiau fod ag allwedd a gwerth, gyda\'r gwerth yn ddewisol. Ar ôl ei gymhwyso, gellir cwestiynur cynnwys gan ddefnyddio enw a gwerth y tag.',
'tag_name' => 'Enwr Tag',
'tag_value' => 'Gwerth y Tag (Dewisol)',
'tags_explain' => "Ychwanegwch rai tagiau i gategoreiddio'ch cynnwys yn well. Gallwch glustnodi gwerth i dag i gael trefn fanylach.",
'tags_add' => 'Ychwanegu tag arall',
'tags_remove' => 'Tynnur tag hwn',
'tags_usages' => 'Cyfanswm y defnydd or tag',
'tags_assigned_pages' => 'Clustnodwyd i Dudalennau',
'tags_assigned_chapters' => 'Clustnodwyd i Benodau',
'tags_assigned_books' => 'Clustnodwyd i Lyfrau',
'tags_assigned_shelves' => 'Clustnodwyd i Silffoedd',
'tags_x_unique_values' => ':count gwerthoedd unigryw',
'tags_all_values' => 'Pob gwerth',
'tags_view_tags' => 'Gweld Tagiau',
'tags_view_existing_tags' => 'Gweld tagiau presennol',
'tags_list_empty_hint' => 'Gellir clustnodi tagiau trwy far ochr golygydd y dudalen neu wrth olygu manylion llyfr, pennod neu silff.',
'attachments' => 'Atodiadau',
'attachments_explain' => 'Uwchlwytho rhai ffeiliau neu atodi rhai dolenni i\'w harddangos ar eich tudalen. Mae\'r rhain i\'w gweld ym mar ochr y dudalen.',
'attachments_explain_instant_save' => 'Caiff y newidiadau yma eu cadw ar unwaith.',
'attachments_upload' => 'Uwchlwytho Ffeil',
'attachments_link' => 'Atodi Dolen',
'attachments_upload_drop' => 'Neu gallwch lusgo a gollwng ffeil yma i\'w huwchlwytho fel atodiad.',
'attachments_set_link' => 'Gosod Dolen',
'attachments_delete' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r atodiad hwn?',
'attachments_dropzone' => 'Gollyngwch ffeiliau yma i\'w huwchlwytho',
'attachments_no_files' => 'Nid oes unrhyw ffeiliau wedi\'u huwchlwytho',
'attachments_explain_link' => 'Gallwch atodi dolen pe bain well gennych beidio ag uwchlwytho ffeil. Gall hyn fod yn ddolen i dudalen arall neu\'n ddolen i ffeil yn y cwmwl.',
'attachments_link_name' => 'Enwr Ddolen',
'attachment_link' => 'Dolen atodiad',
'attachments_link_url' => 'Dolen i ffeil',
'attachments_link_url_hint' => 'Url y safle neu ffeil',
'attach' => 'Atodi',
'attachments_insert_link' => 'Ychwanegu Dolen Atodiad i Dudalen',
'attachments_edit_file' => 'Golygu Ffeil',
'attachments_edit_file_name' => 'Enw\'r Ffeil',
'attachments_edit_drop_upload' => 'Drop files or click here to upload and overwrite',
'attachments_order_updated' => 'Attachment order updated',
'attachments_updated_success' => 'Attachment details updated',
'attachments_deleted' => 'Attachment deleted',
'attachments_file_uploaded' => 'File successfully uploaded',
'attachments_file_updated' => 'File successfully updated',
'attachments_link_attached' => 'Link successfully attached to page',
'templates' => 'Templates',
'templates_set_as_template' => 'Page is a template',
'templates_explain_set_as_template' => 'You can set this page as a template so its contents be utilized when creating other pages. Other users will be able to use this template if they have view permissions for this page.',
'templates_replace_content' => 'Replace page content',
'templates_append_content' => 'Append to page content',
'templates_prepend_content' => 'Prepend to page content',
'attachments_edit_drop_upload' => 'Gollwng ffeiliau neu glicio yma i uwchlwytho ac arysgrifennu',
'attachments_order_updated' => 'Trefn atodiad wedii diweddaru',
'attachments_updated_success' => 'Manylion yr atodiad wedi\'u diweddaru',
'attachments_deleted' => 'Atodiad wedii ddileu',
'attachments_file_uploaded' => 'Ffeil wedi\'i huwchwytho\'n llwyddiannus',
'attachments_file_updated' => 'Ffeil wedi\'i diweddarun llwyddiannus',
'attachments_link_attached' => 'Dolen wedi\'i atodin llwyddiannus i\'r dudalen',
'templates' => 'Templedi',
'templates_set_as_template' => 'Mae\'r dudalen yn dempled',
'templates_explain_set_as_template' => 'Gallwch osod y dudalen hon fel templed er mwyn gallu defnyddio ei chynnwys wrth greu tudalennau eraill. Bydd modd i ddefnyddwyr eraill ddefnyddio\'r templed hwn os oes ganddynt ganiatâd gweld ar gyfer y dudalen hon.',
'templates_replace_content' => 'Disodli cynnwys tudalen',
'templates_append_content' => 'Atodi i gynnwys tudalen',
'templates_prepend_content' => 'Rhagarweiniad i gynnwys tudalen',
// Profile View
'profile_user_for_x' => 'User for :time',
'profile_created_content' => 'Created Content',
'profile_not_created_pages' => ':userName has not created any pages',
'profile_not_created_chapters' => ':userName has not created any chapters',
'profile_not_created_books' => ':userName has not created any books',
'profile_not_created_shelves' => ':userName has not created any shelves',
'profile_user_for_x' => 'Defnyddiwr am :time',
'profile_created_content' => 'Cynnwys a Grëwyd',
'profile_not_created_pages' => 'Nid yw :userName wedi creu unrhyw dudalennau',
'profile_not_created_chapters' => 'Nid yw :userName wedi creu unrhyw benodau',
'profile_not_created_books' => 'Nid yw :userName wedi creu unrhyw lyfrau',
'profile_not_created_shelves' => 'Nid yw :userName wedi creu unrhyw silffoedd',
// Comments
'comment' => 'Comment',
'comments' => 'Comments',
'comment_add' => 'Add Comment',
'comment_placeholder' => 'Leave a comment here',
'comment_count' => '{0} No Comments|{1} 1 Comment|[2,*] :count Comments',
'comment_save' => 'Save Comment',
'comment_new' => 'New Comment',
'comment_created' => 'commented :createDiff',
'comment_updated' => 'Updated :updateDiff by :username',
'comment_updated_indicator' => 'Updated',
'comment_deleted_success' => 'Comment deleted',
'comment_created_success' => 'Comment added',
'comment_updated_success' => 'Comment updated',
'comment_delete_confirm' => 'Are you sure you want to delete this comment?',
'comment_in_reply_to' => 'In reply to :commentId',
'comment_editor_explain' => 'Here are the comments that have been left on this page. Comments can be added & managed when viewing the saved page.',
'comment' => 'Sylw',
'comments' => 'Sylwadau',
'comment_add' => 'Ychwanegu Sylw',
'comment_placeholder' => 'Gadewch sylw yma',
'comment_count' => '{0} Dim sylwadau|{1} 1 Sylw| [2,*] :count Sylwadau',
'comment_save' => 'Cadw Sylw',
'comment_new' => 'Sylw Newydd',
'comment_created' => 'sylwodd :createDiff',
'comment_updated' => 'Diweddarwyd :update gan :username',
'comment_updated_indicator' => 'Diweddarwyd',
'comment_deleted_success' => 'Dilëwyd sylw',
'comment_created_success' => 'Ychwanegwyd sylw',
'comment_updated_success' => 'Diweddarwyd sylw',
'comment_delete_confirm' => 'Ydych chi\'n siwr eich bod eisiau dileu\'r sylw hwn?',
'comment_in_reply_to' => 'Mewn ymateb i :commentId',
'comment_editor_explain' => 'Dyma\'r sylwadau sydd wedi eu gadael ar y dudalen hon. Gellir ychwanegu a rheoli sylwadau wrth edrych ar y dudalen a gadwyd.',
// Revision
'revision_delete_confirm' => 'Are you sure you want to delete this revision?',
'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.',
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.',
'revision_delete_confirm' => 'Ydych chi\'n siŵr eich bod eisiau dileu\'r adolygiad hwn?',
'revision_restore_confirm' => 'Ydych chi\'n siŵr eich bod eisiau adfer yr adolygiad hwn? Bydd cynnwys presennol y dudalen yn cael ei newid.',
'revision_cannot_delete_latest' => 'Ni ellir dileu\'r adolygiad diweddaraf.',
// Copy view
'copy_consider' => 'Please consider the below when copying content.',
'copy_consider_permissions' => 'Custom permission settings will not be copied.',
'copy_consider_owner' => 'You will become the owner of all copied content.',
'copy_consider_images' => 'Page image files will not be duplicated & the original images will retain their relation to the page they were originally uploaded to.',
'copy_consider_attachments' => 'Page attachments will not be copied.',
'copy_consider_access' => 'A change of location, owner or permissions may result in this content being accessible to those previously without access.',
'copy_consider' => 'Ystyriwch yr isod wrth gopïo cynnwys.',
'copy_consider_permissions' => 'Ni fydd gosodiadau caniatâd personol yn cael eu copïo.',
'copy_consider_owner' => 'Byddwch yn dod yn berchennog yr holl gynnwys sydd wedii gopïo.',
'copy_consider_images' => 'Ni fydd ffeiliau delwedd tudalen yn cael eu dyblygu a bydd y delweddau gwreiddiol yn cadw eu perthynas â\'r dudalen y cawsant eu huwchlwytho yn wreiddiol iddi.',
'copy_consider_attachments' => 'Ni fydd atodiadau tudalen yn cael eu copïo.',
'copy_consider_access' => 'Gall newid lleoliad, perchennog neu ganiatâd olygu bod y cynnwys hwn yn hygyrch i\'r rhai nad oedd ganddynt fynediad o\'r blaen.',
// Conversions
'convert_to_shelf' => 'Convert to Shelf',
'convert_to_shelf_contents_desc' => 'You can convert this book to a new shelf with the same contents. Chapters contained within this book will be converted to new books. If this book contains any pages, that are not in a chapter, this book will be renamed and contain such pages, and this book will become part of the new shelf.',
'convert_to_shelf_permissions_desc' => 'Any permissions set on this book will be copied to the new shelf and to all new child books that don\'t have their own permissions enforced. Note that permissions on shelves do not auto-cascade to content within, as they do for books.',
'convert_book' => 'Convert Book',
'convert_book_confirm' => 'Are you sure you want to convert this book?',
'convert_undo_warning' => 'This cannot be as easily undone.',
'convert_to_book' => 'Convert to Book',
'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.',
'convert_chapter' => 'Convert Chapter',
'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?',
'convert_to_shelf' => 'Trosi i Silff',
'convert_to_shelf_contents_desc' => 'Gallwch drosi\'r llyfr hwn i silff newydd gyda\'r un cynnwys. Bydd penodau yn y llyfr hwn yn cael eu trosi i lyfrau newydd. Os yw\'r llyfr hwn yn cynnwys unrhyw dudalennau, nad ydynt mewn pennod, bydd y llyfr hwn yn cael ei ailenwi ac yn cynnwys tudalennau o\'r fath, a bydd y llyfr hwn yn dod yn rhan o\'r silff newydd.',
'convert_to_shelf_permissions_desc' => 'Bydd unrhyw ganiatâd a osodir ar y llyfr hwn yn cael ei gopïo i\'r silff newydd ac i bob llyfr plentyn newydd nad oes ganddynt eu caniatâd eu hunain. Noder nad yw caniatâd ar silffoedd yn rhaeadrun awtomatig ir cynnwys oddi mewn, fel y maent ar gyfer llyfrau.',
'convert_book' => 'Trosi Llyfr',
'convert_book_confirm' => 'Ydych chi\'n siwr eich bod eisiau trosir llyfr hwn?',
'convert_undo_warning' => 'Ni ellir dad-wneud hyn mor hawdd.',
'convert_to_book' => 'Trosi i Lyfr',
'convert_to_book_desc' => 'Gallwch drosi\'r bennod hon i lyfr newydd gyda\'r un cynnwys. Bydd unrhyw ganiatâd a osodir ar y bennod hon yn cael ei gopïo i\'r llyfr newydd ond ni fydd unrhyw ganiatâd a etifeddir o\'r llyfr rhiant yn cael ei gopïo, a allai arwain at newid rheolaeth mynediad.',
'convert_chapter' => 'Trosi Pennod',
'convert_chapter_confirm' => 'Ydych chi\'n siŵr eich bod eisiau trosir bennod hon?',
// References
'references' => 'References',
'references_none' => 'There are no tracked references to this item.',
'references_to_desc' => 'Listed below is all the known content in the system that links to this item.',
'references' => 'Cyfeirnodau',
'references_none' => 'Nid oes unrhyw gyfeirnodau wedi\'u holrhain ar gyfer yr eitem hon.',
'references_to_desc' => 'Isod ceir yr holl gynnwys hysbys yn y system sy\'n cysylltu â\'r eitem hon.',
// Watch Options
'watch' => 'Gwylio',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_default' => 'Dewisiadau Diofyn',
'watch_desc_default' => 'Newid i weld eich dewisiadau hysbysu diofyn yn unig.',
'watch_title_ignore' => 'Anwybyddu',
'watch_desc_ignore' => 'Anwybyddu pob hysbysiad, gan gynnwys y rhai o ddewisiadau lefel defnyddiwr.',
'watch_title_new' => 'Tudalennau Newydd',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch_desc_new' => 'Rhoi gwybod pan fydd unrhyw dudalen newydd yn cael ei chreu yn yr eitem hon.',
'watch_title_updates' => 'Diweddariadau Pob Tudalen',
'watch_desc_updates' => 'Hysbysu am bob tudalen newydd a newid i dudalennau.',
'watch_desc_updates_page' => 'Hysbysu am bob newid i dudalennau.',
'watch_title_comments' => 'Pob Diweddariad i Dualennau a Sylwadau',
'watch_desc_comments' => 'Hysbysu am bob tudalen newydd, newidiadau i dudalennau a sylwadau newydd.',
'watch_desc_comments_page' => 'Hysbysu am newidiadau i dudalennau a sylwadau newydd.',
'watch_change_default' => 'Newid dewisiadau hysbysu diofyn',
'watch_detail_ignore' => 'Anwybyddu hysbysiadau',
'watch_detail_new' => 'Gwylio am dudalennau newydd',
'watch_detail_updates' => 'Gwylio tudalennau a diweddariadau newydd',
'watch_detail_comments' => 'Gwylio tudalennau newydd, diweddariadau a sylwadau',
'watch_detail_parent_book' => 'Gwylio trwy lyfr rhiant',
'watch_detail_parent_book_ignore' => 'Anwybyddu trwy lyfr rhiant',
'watch_detail_parent_chapter' => 'Gwylio trwy bennod rhiant',
'watch_detail_parent_chapter_ignore' => 'Anwybyddu trwy bennod rhiant',
];

View File

@@ -10,7 +10,7 @@ return [
// Auth
'error_user_exists_different_creds' => 'Mae defnyddiwr gyda\'r e-bost :email eisoes yn bodoli ond gyda nodweddion gwahanol.',
'auth_pre_register_theme_prevention' => 'User account could not be registered for the provided details',
'auth_pre_register_theme_prevention' => 'Nid oedd modd cofrestru cyfrif defnyddiwr ar gyfer y manylion a ddarparwyd',
'email_already_confirmed' => 'E-bost eisoes wedi\'i gadarnhau, Ceisiwch fewngofnodi.',
'email_confirmation_invalid' => 'Nid yw\'r tocyn cadarnhau hwn yn ddilys neu mae eisoes wedi\'i ddefnyddio. Ceisiwch gofrestru eto.',
'email_confirmation_expired' => 'Mae\'r tocyn cadarnhad wedi dod i ben, Mae e-bost cadarnhau newydd wedi\'i anfon.',
@@ -37,37 +37,37 @@ return [
'social_driver_not_found' => 'Gyrrwr cymdeithasol heb ei ganfod',
'social_driver_not_configured' => 'Nid yw eich gosodiadau cymdeithasol :socialAccount wedi\'u ffurfweddu\'n gywir.',
'invite_token_expired' => 'Mae\'r ddolen wahoddiad hon wedi dod i ben. Yn lle hynny, gallwch chi geisio ailosod cyfrinair eich cyfrif.',
'login_user_not_found' => 'A user for this action could not be found.',
'login_user_not_found' => 'Nid oedd modd dod o hyd i ddefnyddiwr ar gyfer y weithred hon.',
// System
'path_not_writable' => 'Nid oedd modd uwchlwytho llwybr ffeil :filePath. Sicrhewch ei fod yn ysgrifenadwy i\'r gweinydd.',
'cannot_get_image_from_url' => 'Methu cael delwedd o :url',
'cannot_create_thumbs' => 'Ni all y gweinydd greu mân-luniau. Gwiriwch fod gennych yr estyniad GD PHP wedi\'i osod.',
'server_upload_limit' => 'Nid yw\'r gweinydd yn caniatáu uwchlwythiadau o\'r maint hwn. Rhowch gynnig ar faint ffeil llai.',
'server_post_limit' => 'The server cannot receive the provided amount of data. Try again with less data or a smaller file.',
'server_post_limit' => 'Ni all y gweinydd dderbyn y swm o ddata a ddarparwyd. Rhowch gynnig arall arni eto gyda llai o ddata neu ffeil lai.',
'uploaded' => 'Nid yw\'r gweinydd yn caniatáu uwchlwythiadau o\'r maint hwn. Rhowch gynnig ar faint ffeil llai.',
// Drawing & Images
'image_upload_error' => 'Bu gwall wrth uwchlwytho\'r ddelwedd',
'image_upload_type_error' => 'Mae\'r math o ddelwedd sy\'n cael ei huwchlwytho yn annilys',
'image_upload_replace_type' => 'Image file replacements must be of the same type',
'image_upload_memory_limit' => 'Failed to handle image upload and/or create thumbnails due to system resource limits.',
'image_thumbnail_memory_limit' => 'Failed to create image size variations due to system resource limits.',
'image_gallery_thumbnail_memory_limit' => 'Failed to create gallery thumbnails due to system resource limits.',
'drawing_data_not_found' => 'Drawing data could not be loaded. The drawing file might no longer exist or you may not have permission to access it.',
'image_upload_replace_type' => 'Rhaid i ffeiliau delwedd a newidir fod o\'r un math',
'image_upload_memory_limit' => 'Methwyd â thrin y llun a uwchlwythwyd a/neu greu mân-luniau oherwydd cyfyngiadau i adnoddaur system.',
'image_thumbnail_memory_limit' => 'Methwyd â chreu amrywiadau i faint y llun oherwydd cyfyngiadau i adnoddaur system.',
'image_gallery_thumbnail_memory_limit' => 'Methwyd â chreu oriel o fân-luniau oherwydd cyfyngiadau i adnoddaur system.',
'drawing_data_not_found' => 'Nid oedd modd llwytho\'r data dylunio. Efallai nad ywr ffeil ddylunio yn bodoli mwyach neu efallai nad oes gennych ganiatâd i\'w defnyddio.',
// Attachments
'attachment_not_found' => 'Ni chanfuwyd yr atodiad',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
'attachment_upload_error' => 'Digwyddodd gwall wrth uwchlwythor ffeil atodiad',
// Pages
'page_draft_autosave_fail' => 'Wedi methu cadw\'r drafft. Sicrhewch fod gennych gysylltiad rhyngrwyd cyn cadw\'r dudalen hon',
'page_draft_delete_fail' => 'Failed to delete page draft and fetch current page saved content',
'page_draft_delete_fail' => 'Methwyd â dileur dudalen ddrafft a chyrchu cynnwys y dudalen gyfredol',
'page_custom_home_deletion' => 'Methu dileu tudalen tra ei bod wedi\'i gosod fel hafan',
// Entities
'entity_not_found' => 'Endid heb ei ganfod',
'bookshelf_not_found' => 'Shelf not found',
'bookshelf_not_found' => 'Ni chanfuwyd y silff',
'book_not_found' => 'Ni chanfuwyd y llyfr',
'page_not_found' => 'Heb ganfod y dudalen',
'chapter_not_found' => 'Pennod heb ei chanfod',
@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Ni allwch ddileu\'r unig weinyddwr',
'users_cannot_delete_guest' => 'Ni allwch ddileu\'r defnyddiwr gwadd',
'users_could_not_send_invite' => 'Methu creu defnyddiwr oherwydd ni fu modd anfon e-bost gwahodd',
// Roles
'role_cannot_be_edited' => 'Nid oes modd golygu\'r rôl hon',
@@ -116,5 +117,5 @@ return [
'maintenance_test_email_failure' => 'Gwall a daflwyd wrth anfon e-bost prawf:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'Nid yw\'r URL yn cyd-fynd â\'r gwesteion SSR ffurfweddu a ganiateir',
];

View File

@@ -10,18 +10,18 @@ return [
'new_page_intro' => 'Mae tudalen newydd wedi cael ei chreu yn :appName:',
'updated_page_subject' => 'Tudalen wedi\'i diweddaru :pageName',
'updated_page_intro' => 'Mae tudalen newydd wedi cael ei diweddaru yn :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'updated_page_debounce' => 'Er mwyn atal llu o hysbysiadau, am gyfnod ni fyddwch yn cael hysbysiadau am ragor o olygiadau i\'r dudalen hon gan yr un golygydd.',
'detail_page_name' => 'Enw\'r dudalen:',
'detail_page_path' => 'Page Path:',
'detail_commenter' => 'Commenter:',
'detail_page_path' => 'Llwybr Tudalen:',
'detail_commenter' => 'Sylwebydd:',
'detail_comment' => 'Sylw:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_created_by' => 'Crëwyd gan:',
'detail_updated_by' => 'Diweddarwyd Gan:',
'action_view_comment' => 'Gweld y sylw',
'action_view_page' => 'Gweld y dudalen',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => 'Anfonwyd yr hysbysiad hwn atoch oherwydd bod y :ddolen yn ymdrin âr math hwn o weithgaredd ar gyfer yr eitem hon.',
'footer_reason_link' => 'eich dewisiadau hysbysu',
];

View File

@@ -6,10 +6,10 @@
*/
return [
'password' => 'Passwords must be at least eight characters and match the confirmation.',
'user' => "We can't find a user with that e-mail address.",
'token' => 'The password reset token is invalid for this email address.',
'sent' => 'We have e-mailed your password reset link!',
'reset' => 'Your password has been reset!',
'password' => 'Rhaid i gyfrineiriau fod yn 8 nod o leiaf ac yn cyd-fynd â\'r cadarnhad.',
'user' => "Ni allwn ddod o hyd i ddefnyddiwr gyda'r cyfeiriad e-bost hwn.",
'token' => 'Mae\'r tocyn ailosod cyfrinair yn annilys ar gyfer y cyfeiriad e-bost hwn.',
'sent' => 'Rydym wedi e-bostio eich dolen ailosod cyfrinair!',
'reset' => 'Mae eich cyfrinair wedi\'i ailosod!',
];

View File

@@ -7,45 +7,45 @@
return [
'my_account' => 'Fy Nghyfrif',
'shortcuts' => 'Shortcuts',
'shortcuts_interface' => 'UI Shortcut Preferences',
'shortcuts_toggle_desc' => 'Here you can enable or disable keyboard system interface shortcuts, used for navigation and actions.',
'shortcuts_customize_desc' => 'You can customize each of the shortcuts below. Just press your desired key combination after selecting the input for a shortcut.',
'shortcuts_toggle_label' => 'Keyboard shortcuts enabled',
'shortcuts_section_navigation' => 'Navigation',
'shortcuts_section_actions' => 'Common Actions',
'shortcuts_save' => 'Save Shortcuts',
'shortcuts_overlay_desc' => 'Note: When shortcuts are enabled a helper overlay is available via pressing "?" which will highlight the available shortcuts for actions currently visible on the screen.',
'shortcuts_update_success' => 'Shortcut preferences have been updated!',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts' => 'Llwybrau Byr',
'shortcuts_interface' => 'Dewisiadau Llwybr Byr UI',
'shortcuts_toggle_desc' => 'Yma gallwch alluogi neu analluogi llwybrau byr rhyngwyneb system ar y bysellfwrdd, a ddefnyddir ar gyfer llywio a gweithredoedd.',
'shortcuts_customize_desc' => 'Gallwch addasu pob un o\'r llwybrau byr isod. Pwyswch eich cyfuniad o fysellau ar ôl dewis y mewnbwn ar gyfer llwybr byr.',
'shortcuts_toggle_label' => 'Llwybrau byr bysellfwrdd wedi\'u galluogi',
'shortcuts_section_navigation' => 'Llywio',
'shortcuts_section_actions' => 'Gweithredoedd Cyffredin',
'shortcuts_save' => 'Cadw Llwybrau Byr',
'shortcuts_overlay_desc' => 'Noder: Pan fydd llwybrau byr yn cael eu galluogi, mae troshaen helpwr ar gael trwy bwyso "?" a fydd yn tynnu sylw at y llwybrau byr sydd ar gael ar gyfer camau gweithredu sydd i\'w gweld ar y sgrin ar hyn o bryd.',
'shortcuts_update_success' => 'Maer dewisiadau llwybr byr wedi\'u diweddaru!',
'shortcuts_overview_desc' => 'Rheoli llwybrau byr bysellfwrdd a gellir eu defnyddio i lywio trwy ryngwyneb defnyddiwr y system.',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => 'Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => 'Dewisiadau Hysbysu',
'notifications_desc' => 'Rheolir hysbysiadau e-bost a gewch pan fydd gweithgaredd penodol yn cael ei gyflawni o fewn y system.',
'notifications_opt_own_page_changes' => 'Hysbysu am newidiadau i dudalennau yr wyf yn berchen arnynt',
'notifications_opt_own_page_comments' => 'Hysbysu am sylwadau ar dudalennau yr wyf yn berchen arnynt',
'notifications_opt_comment_replies' => 'Hysbysu am atebion i\'m sylwadau',
'notifications_save' => 'Dewisiadau Cadw',
'notifications_update_success' => 'Maer dewisiadau hysbysu wedi\'u diweddaru!',
'notifications_watched' => 'Eitemau Gwylio ac Anwybyddu',
'notifications_watched_desc' => 'Isod ceir yr eitemau sydd â dewisiadau gwylio penodol wedi\'u cymhwyso. I ddiweddaru eich dewisiadau ar gyfer y rhain, edrychwch ar yr eitem yna dewch o hyd i\'r opsiynau gwylio yn y bar ochr.',
'auth' => 'Access & Security',
'auth_change_password' => 'Change Password',
'auth_change_password_desc' => 'Change the password you use to log-in to the application. This must be at least 8 characters long.',
'auth_change_password_success' => 'Password has been updated!',
'auth' => 'Mynediad a Diogelwch',
'auth_change_password' => 'Newid Cyfrinair',
'auth_change_password_desc' => 'Newidiwch y cyfrinair rydych chin ei ddefnyddio i fewngofnodi ir rhaglen. Rhaid i gyfrineiriau fod yn 8 nod o leiaf.',
'auth_change_password_success' => 'Mae\'r cyfrinair wedi\'i ddiweddaru!',
'profile' => 'Profile Details',
'profile_desc' => 'Manage the details of your account which represents you to other users, in addition to details that are used for communication and system personalisation.',
'profile_view_public' => 'View Public Profile',
'profile_name_desc' => 'Configure your display name which will be visible to other users in the system through the activity you perform, and content you own.',
'profile_email_desc' => 'This email will be used for notifications and, depending on active system authentication, system access.',
'profile_email_no_permission' => 'Unfortunately you don\'t have permission to change your email address. If you want to change this, you\'d need to ask an administrator to change this for you.',
'profile_avatar_desc' => 'Select an image which will be used to represent yourself to others in the system. Ideally this image should be square and about 256px in width and height.',
'profile_admin_options' => 'Administrator Options',
'profile_admin_options_desc' => 'Additional administrator-level options, like those to manage role assignments, can be found for your user account in the "Settings > Users" area of the application.',
'profile' => 'Manylion Proffil',
'profile_desc' => 'Rheoli manylion eich cyfrif sy\'n eich cynrychioli chi i ddefnyddwyr eraill, yn ogystal â manylion a ddefnyddir ar gyfer cyfathrebu a phersonoli systemau.',
'profile_view_public' => 'Gweld Proffil Cyhoeddus',
'profile_name_desc' => 'Ffurfweddwch eich enw arddangos a fydd yn weladwy i ddefnyddwyr eraill yn y system trwy\'r hyn yr ydych yn ei wneud, a\'r cynnwys rydych chi\'n berchen arno.',
'profile_email_desc' => 'Bydd yr e-bost hwn yn cael ei ddefnyddio ar gyfer hysbysiadau a, gan ddibynnu ar ddilysiad system gweithredol, mynediad ir system.',
'profile_email_no_permission' => 'Yn anffodus, nid oes gennych ganiatâd i newid eich cyfeiriad e-bost. Os hoffech newid hwn, byddai angen i chi ofyn i weinyddwr newid hyn ar eich rhan.',
'profile_avatar_desc' => 'Dewiswch lun a fydd yn cael ei ddefnyddio ich cynrychioli chi i eraill yn y system. Yn ddelfrydol, dylai\'r llun hwn fod yn sgwâr a thua 256px o led ac uchder.',
'profile_admin_options' => 'Dewisiadau Gweinyddwr',
'profile_admin_options_desc' => 'Gellir dod o hyd i ddewisiadau lefel gweinyddwyr ychwanegol, fel y rhai i reoli aseiniadau rôl, ar gyfer eich cyfrif defnyddiwr yn yr ardal "Gosodiadau > Defnyddiwr” or rhaglen.',
'delete_account' => 'Delete Account',
'delete_my_account' => 'Delete My Account',
'delete_my_account_desc' => 'This will fully delete your user account from the system. You will not be able to recover this account or revert this action. Content you\'ve created, such as created pages and uploaded images, will remain.',
'delete_my_account_warning' => 'Are you sure you want to delete your account?',
'delete_account' => 'Dileu Cyfrif',
'delete_my_account' => 'Dileu fy Nghyfrif',
'delete_my_account_desc' => 'Bydd hyn yn dileu eich cyfrif defnyddiwr o\'r system yn llwyr. Ni fydd modd i chi adfer y cyfrif hwn na gwrthdroi\'r weithred hon. Bydd cynnwys rydych chi wedi\'i greu, megis tudalennau wedi\'u creu a delweddau wedi\'u huwchlwytho, yn parhau.',
'delete_my_account_warning' => 'Ydych chi\'n siŵr eich bod eisiau dileu eich cyfrif?',
];

View File

@@ -64,15 +64,15 @@ return [
'reg_settings' => 'Cofrestriad',
'reg_enable' => 'Galluogi Cofrestru',
'reg_enable_toggle' => 'Galluogi cofrestru',
'reg_enable_desc' => 'When registration is enabled user will be able to sign themselves up as an application user. Upon registration they are given a single, default user role.',
'reg_default_role' => 'Default user role after registration',
'reg_enable_external_warning' => 'The option above is ignored while external LDAP or SAML authentication is active. User accounts for non-existing members will be auto-created if authentication, against the external system in use, is successful.',
'reg_email_confirmation' => 'Email Confirmation',
'reg_email_confirmation_toggle' => 'Require email confirmation',
'reg_confirm_email_desc' => 'If domain restriction is used then email confirmation will be required and this option will be ignored.',
'reg_confirm_restrict_domain' => 'Domain Restriction',
'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.',
'reg_confirm_restrict_domain_placeholder' => 'No restriction set',
'reg_enable_desc' => 'Pan fydd cofrestru wedi\'i alluogi bydd modd i ddefnyddwyr gofrestru fel defnyddwyr y rhaglen. Wrth gofrestru maent yn cael un rôl defnyddiwr diofyn.',
'reg_default_role' => 'Rôl defnyddiwr diofyn ar ôl cofrestru',
'reg_enable_external_warning' => 'Anwybyddir y dewis uchod tra bod dilysu LDAP neu SAML allanol yn weithredol. Bydd cyfrifon defnyddwyr ar gyfer aelodau nad ydynt yn bodoli yn cael eu creu\'n awtomatig os bydd dilysiad, yn erbyn y system allanol sy\'n cael ei defnyddio, yn llwyddiannus.',
'reg_email_confirmation' => 'Cadarnhad E-bost',
'reg_email_confirmation_toggle' => 'Angen cadarnhad e-bost',
'reg_confirm_email_desc' => 'Os defnyddir cyfyngiad parth, bydd angen cadarnhad e-bost a bydd yr opsiwn hwn yn cael ei anwybyddu.',
'reg_confirm_restrict_domain' => 'Cyfyngiad Parth',
'reg_confirm_restrict_domain_desc' => 'Rhowch restr wedi\'i gwahanu gan goma o barthau e-bost yr hoffech gyfyngu cofrestriad iddynt. Bydd defnyddwyr yn cael e-bost i gadarnhau eu cyfeiriad cyn cael caniatâd i ryngweithio â\'r rhaglen. <br> Noder y bydd modd i ddefnyddwyr newid eu cyfeiriadau e-bost ar ôl cofrestru\'n llwyddiannus.',
'reg_confirm_restrict_domain_placeholder' => 'Ni osodwyd cyfyngiad',
// Maintenance settings
'maint' => 'Cynnal',
@@ -130,17 +130,17 @@ return [
'audit_table_related' => 'Eitem neu Fanylion Cysylltiedig',
'audit_table_ip' => 'Cyfeiriad IP',
'audit_table_date' => 'Dyddiad Gweithgaredd',
'audit_date_from' => 'Date Range From',
'audit_date_to' => 'Date Range To',
'audit_date_from' => 'Amrediad Dyddiad O',
'audit_date_to' => 'Amrediad Dyddiad Tan',
// Role Settings
'roles' => 'Rolau',
'role_user_roles' => 'Rolau Defnyddiwr',
'roles_index_desc' => 'Roles are used to group users & provide system permission to their members. When a user is a member of multiple roles the privileges granted will stack and the user will inherit all abilities.',
'roles_x_users_assigned' => ':count user assigned|:count users assigned',
'roles_index_desc' => 'Defnyddir rolau i grwpio defnyddwyr a rhoi caniatâd system i\'w haelodau. Pan fydd defnyddiwr yn aelod o sawl rôl, bydd y breintiau a roddir yn pentyrru a bydd y defnyddiwr yn etifeddu pob gallu.',
'roles_x_users_assigned' => ':count defnyddiwr wedi\'u clustnodi|:count o ddefnyddwyr wedi\'u clustnodi',
'roles_x_permissions_provided' => ':count caniatâd|:count caniatâd',
'roles_assigned_users' => 'Assigned Users',
'roles_permissions_provided' => 'Provided Permissions',
'roles_assigned_users' => 'Clustnodi Defnyddwyr',
'roles_permissions_provided' => 'Darparu Caniatâd',
'role_create' => 'Creu Rôl Newydd',
'role_delete' => 'Dileu Rôl',
'role_delete_confirm' => 'Bydd hyn yn dileu\'r rôl gyda\'r enw \':roleName\'.',
@@ -200,7 +200,7 @@ return [
'users_delete_named' => 'Dileu defnyddiwr :userName',
'users_delete_warning' => 'Bydd hyn yn dileu\'r defnyddiwr hwn yn llawn gyda\'r enw \':userName\' o\'r system.',
'users_delete_confirm' => 'Ydych chi\'n siŵr eich bod eisiau dileur defnyddiwr hwn?',
'users_migrate_ownership' => 'Migrate Ownership',
'users_migrate_ownership' => 'Mudo Perchnogaeth',
'users_migrate_ownership_desc' => 'Dewiswch ddefnyddiwr yma os ydych chi am i ddefnyddiwr arall ddod yn berchennog ar yr holl eitemau sy\'n eiddo i\'r defnyddiwr hwn ar hyn o bryd.',
'users_none_selected' => 'Ni ddewiswyd defnyddiwr',
'users_edit' => 'Golygu Defnyddiwr',
@@ -256,7 +256,7 @@ return [
'webhooks_edit' => 'Golygu Gwe-fachyn',
'webhooks_save' => 'Cadw Gwe-fachyn',
'webhooks_details' => 'Manylion Gwe-fachyn',
'webhooks_details_desc' => 'Provide a user friendly name and a POST endpoint as a location for the webhook data to be sent to.',
'webhooks_details_desc' => 'Darparu enw defnyddiwr cyfeillgar a chyfeiriad POST fel lleoliad ar gyfer anfon y data gwe-fachyn iddo.',
'webhooks_events' => 'Digwyddiadau Gwe-fachyn',
'webhooks_events_desc' => 'Dewiswch yr holl ddigwyddiadau a ddylai sbarduno\'r gwe-fachyn hwn i gael ei alw.',
'webhooks_events_warning' => 'Cadwch mewn cof y bydd y digwyddiadau hyn yn cael eu sbarduno ar gyfer yr holl ddigwyddiadau a ddewiswyd, hyd yn oed os rhoddir caniatâd arferol ar waith. Gwnewch yn siŵr na fydd defnyddio\'r gwe-fachyn hwn yn datgelu cynnwys cyfrinachol.',
@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -65,7 +65,7 @@ return [
'auth_login' => 'loggede ind',
'auth_register' => 'registered as new user',
'auth_password_reset_request' => 'requested user password reset',
'auth_password_reset_update' => 'reset user password',
'auth_password_reset_update' => 'nulstil adgangskode',
'mfa_setup_method' => 'configured MFA method',
'mfa_setup_method_notification' => 'Multi-faktor metode konfigureret',
'mfa_remove_method' => 'removed MFA method',
@@ -85,8 +85,8 @@ return [
'webhook_delete_notification' => 'Webhooken blev slettet',
// Users
'user_create' => 'created user',
'user_create_notification' => 'User successfully created',
'user_create' => 'opret bruger',
'user_create_notification' => 'Bruger oprettet korrekt',
'user_update' => 'updated user',
'user_update_notification' => 'Brugeren blev opdateret',
'user_delete' => 'deleted user',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Privatlivspolitik',
'terms_of_service' => 'Tjenestevilkår',
// OpenSearch
'opensearch_description' => 'Søg :appName',
];

View File

@@ -50,7 +50,7 @@ return [
'permissions_chapter_cascade' => 'Permissions set on chapters will automatically cascade to child pages, unless they have their own permissions defined.',
'permissions_save' => 'Gem tilladelser',
'permissions_owner' => 'Ejer',
'permissions_role_everyone_else' => 'Everyone Else',
'permissions_role_everyone_else' => 'Alle andre',
'permissions_role_everyone_else_desc' => 'Set permissions for all roles not specifically overridden.',
'permissions_role_override' => 'Override permissions for role',
'permissions_inherit_defaults' => 'Inherit defaults',
@@ -100,8 +100,8 @@ return [
'shelves_empty_contents' => 'Denne reol har ingen bøger tilknyttet til den',
'shelves_edit_and_assign' => 'Rediger reol for at tilføje bøger',
'shelves_edit_named' => 'Edit Shelf :name',
'shelves_edit' => 'Edit Shelf',
'shelves_delete' => 'Delete Shelf',
'shelves_edit' => 'Rediger Reol',
'shelves_delete' => 'Slettede reoler',
'shelves_delete_named' => 'Delete Shelf :name',
'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.",
'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?',
@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Skift til WYSIWYG redigering',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Sæt ændringsoversigt',
'pages_edit_enter_changelog_desc' => 'Indtast en kort beskrivelse af ændringer du har lavet',
'pages_edit_enter_changelog' => 'Indtast ændringsoversigt',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Du kan ikke slette den eneste admin',
'users_cannot_delete_guest' => 'Du kan ikke slette gæstebrugeren',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Denne rolle kan ikke redigeres',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Catalansk',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Datenschutzbestimmungen',
'terms_of_service' => 'Allgemeine Geschäftsbedingungen',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(gesäuberter Output)',
'pages_edit_switch_to_markdown_stable' => '(html beibehalten)',
'pages_edit_switch_to_wysiwyg' => 'Wechseln Sie zum WYSIWYG-Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Änderungsprotokoll hinzufügen',
'pages_edit_enter_changelog_desc' => 'Bitte geben Sie eine kurze Zusammenfassung Ihrer Änderungen ein',
'pages_edit_enter_changelog' => 'Änderungsprotokoll eingeben',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Sie können den einzigen Administrator nicht löschen',
'users_cannot_delete_guest' => 'Sie können den Gast-Benutzer nicht löschen',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Diese Rolle kann nicht bearbeitet werden',

View File

@@ -296,6 +296,7 @@ Hinweis: Benutzer können ihre E-Mail-Adresse nach erfolgreicher Registrierung
'bs' => 'Bosnisch',
'ca' => 'Katalanisch',
'cs' => 'Tschechisch',
'cy' => 'Cymraeg',
'da' => 'Dänisch',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Datenschutzerklärung',
'terms_of_service' => 'Allgemeine Geschäftsbedingungen',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Sauberer Inhalt)',
'pages_edit_switch_to_markdown_stable' => '(Stabiler Inhalt)',
'pages_edit_switch_to_wysiwyg' => 'Zum WYSIWYG Editor wechseln',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Änderungsprotokoll hinzufügen',
'pages_edit_enter_changelog_desc' => 'Bitte gib eine kurze Zusammenfassung deiner Änderungen ein',
'pages_edit_enter_changelog' => 'Änderungsprotokoll eingeben',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Du kannst den einzigen Administrator nicht löschen.',
'users_cannot_delete_guest' => 'Du kannst den Gast-Benutzer nicht löschen',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Diese Rolle kann nicht bearbeitet werden.',

View File

@@ -296,6 +296,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
'bs' => 'Bosnisch',
'ca' => 'Katalanisch',
'cs' => 'Tschechisch',
'cy' => 'Cymraeg',
'da' => 'Dänisch',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Πολιτική Απορρήτου',
'terms_of_service' => 'Όροι χρήσης',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Καθαρισμός Περιεχομένου)',
'pages_edit_switch_to_markdown_stable' => '(Σταθερό Περιεχόμενο)',
'pages_edit_switch_to_wysiwyg' => 'Εναλλαγή στον επεξεργαστή WYSIWYG',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Ορισμός καταγραφής αλλαγών',
'pages_edit_enter_changelog_desc' => 'Εισάγετε μια σύντομη περιγραφή των αλλαγών που κάνατε',
'pages_edit_enter_changelog' => 'Εισαγωγή Αρχείου Καταγραφής Αλλαγών',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Δεν μπορείτε να διαγράψετε τον μοναδικό διαχειριστή',
'users_cannot_delete_guest' => 'Δεν μπορείτε να διαγράψετε τον επισκέπτη',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Αυτός ο ρόλος δεν μπορεί να επεξεργαστεί',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Privacy Policy',
'terms_of_service' => 'Terms of Service',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Set Changelog',
'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made',
'pages_edit_enter_changelog' => 'Enter Changelog',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'You cannot delete the only admin',
'users_cannot_delete_guest' => 'You cannot delete the guest user',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'This role cannot be edited',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski',
'ca' => 'Català',
'cs' => 'Česky',
'cy' => 'Cymraeg',
'da' => 'Dansk',
'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Política de privacidad',
'terms_of_service' => 'Términos de Servicio',
// OpenSearch
'opensearch_description' => 'Buscar :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Limpiar Contenido)',
'pages_edit_switch_to_markdown_stable' => '(Contenido Estable)',
'pages_edit_switch_to_wysiwyg' => 'Cambiar a Editor WYSIWYG',
'pages_edit_switch_to_new_wysiwyg' => 'Cambiar a nuevo editor WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(En alfa)',
'pages_edit_set_changelog' => 'Ajustar Log de cambios',
'pages_edit_enter_changelog_desc' => 'Introduzca una breve descripción de los cambios que ha realizado',
'pages_edit_enter_changelog' => 'Entrar al Log de cambios',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'No se puede borrar el único administrador',
'users_cannot_delete_guest' => 'No se puede borrar el usuario invitado',
'users_could_not_send_invite' => 'No se pudo crear el usuario porque no se pudo enviar el correo de invitación',
// Roles
'role_cannot_be_edited' => 'Este rol no puede ser editado',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosnio',
'ca' => 'Català',
'cs' => 'Checo',
'cy' => 'Cymraeg',
'da' => 'Danés',
'de' => 'Alemán (informal)',
'de_informal' => 'Alemán (formal)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Política de privacidad',
'terms_of_service' => 'Términos de Servicio',
// OpenSearch
'opensearch_description' => 'Buscar :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Limpiar Contenido)',
'pages_edit_switch_to_markdown_stable' => '(Contenido Estable)',
'pages_edit_switch_to_wysiwyg' => 'Cambiar a Editor WYSIWYG',
'pages_edit_switch_to_new_wysiwyg' => 'Cambiar a nuevo editor WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(En alfa)',
'pages_edit_set_changelog' => 'Establecer cambios de registro',
'pages_edit_enter_changelog_desc' => 'Introduzca una breve descripción de los cambios que ha realizado',
'pages_edit_enter_changelog' => 'Entrar en cambio de registro',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'No se puede borrar el único administrador',
'users_cannot_delete_guest' => 'No se puede borrar el usuario invitado',
'users_could_not_send_invite' => 'No se pudo crear el usuario porque no se pudo enviar el correo de invitación',
// Roles
'role_cannot_be_edited' => 'Este rol no puede ser editado',

View File

@@ -296,6 +296,7 @@ return [
'bs' => 'Bosnio',
'ca' => 'Català',
'cs' => 'Checo',
'cy' => 'Cymraeg',
'da' => 'Danés',
'de' => 'Alemán (informal)',
'de_informal' => 'Alemán (formal)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Privaatsus',
'terms_of_service' => 'Kasutustingimused',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Puhas sisu)',
'pages_edit_switch_to_markdown_stable' => '(Stabiilne sisu)',
'pages_edit_switch_to_wysiwyg' => 'Kasuta WYSIWYG redaktorit',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Muudatuste logi',
'pages_edit_enter_changelog_desc' => 'Sisesta tehtud muudatuste lühikirjeldus',
'pages_edit_enter_changelog' => 'Salvesta muudatuste logi',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'Ainsat administraatorit ei saa kustutada',
'users_cannot_delete_guest' => 'Külaliskasutajat ei saa kustutada',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'Seda rolli ei saa muuta',

View File

@@ -295,6 +295,7 @@ return [
'bs' => 'Bosanski (bosnia keel)',
'ca' => 'Català (katalaani keel)',
'cs' => 'Česky (tšehhi keel)',
'cy' => 'Cymraeg',
'da' => 'Dansk (taani keel)',
'de' => 'Deutsch (saksa keel)',
'de_informal' => 'Deutsch (Du) (mitteformaalne saksa keel)',

View File

@@ -107,4 +107,7 @@ return [
// Not directly used but available for convenience to users.
'privacy_policy' => 'Pribatutasun politika',
'terms_of_service' => 'Zerbitzu-baldintzak',
// OpenSearch
'opensearch_description' => 'Search :appName',
];

View File

@@ -224,6 +224,8 @@ return [
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(In Alpha Testing)',
'pages_edit_set_changelog' => 'Set Changelog',
'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made',
'pages_edit_enter_changelog' => 'Enter Changelog',

View File

@@ -78,6 +78,7 @@ return [
// Users
'users_cannot_delete_only_admin' => 'You cannot delete the only admin',
'users_cannot_delete_guest' => 'You cannot delete the guest user',
'users_could_not_send_invite' => 'Could not create user since invite email failed to send',
// Roles
'role_cannot_be_edited' => 'This role cannot be edited',

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