Jump to content

Manual/User rights

From Numinix MediaWiki Demo
Revision as of 17:02, 25 July 2026 by Admin (talk | contribs) (Seed from mediawiki.org for Seekmodo connector demo)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

<languages/> <translate> User rights are permissions (such as the ability to edit pages or to block users) that can be assigned to different user groups.</translate> <translate> MediaWiki ships with a default set of user rights and user groups, but these can be customized.</translate> <translate> This page explains the default rights and groups, and how to customize them.</translate>

<translate> For information about how to add and remove individual wiki users from groups, see <tvar name=1></tvar> and <tvar name=2></tvar>.

Changing group permissions[edit]

</translate> <translate> A default MediaWiki installation assigns certain rights to default groups (see table at [[<tvar name=1>#List of permissions</tvar>|#List of permissions]]).</translate> <translate> You can change the default rights by editing the <tvar name=1></tvar> array in <tvar name=2></tvar> with the following syntax:</translate>

<syntaxhighlight lang="php" copy> $wgGroupPermissions['group']['right'] = true /* <translate nowrap> or <tvar name=1>false</tvar></translate> */; </syntaxhighlight> </tvar> will be set in <tvar name=2>includes/DefaultSettings.php</tvar>, but it is not present in <tvar name=3>LocalSettings.php</tvar>.</translate> <translate> You will then need to add it in that file.</translate> }}

<translate> If a member has multiple groups, they get all the permissions from each of the groups they are in.</translate> <translate> All users, including anonymous users, are in the <tvar name=1>*</tvar> group; all registered users are in the <tvar name=2>user</tvar> group.</translate> <translate> In addition to the default groups, you can arbitrarily create new groups using the same array.</translate>

<translate>

Examples[edit]

This example will disable viewing of all pages not listed in <tvar name=1></tvar>, then re-enable for registered users only: </translate>

<syntaxhighlight lang="php" copy> $wgGroupPermissions['*']['read'] = false;

  1. <translate nowrap> The following line is not actually necessary, since it's in the defaults. Setting '*' to false doesn't disable rights for groups that have the right separately set to true!</translate>

$wgGroupPermissions['user']['read'] = true; </syntaxhighlight>

<translate> This example will disable editing of all pages, then re-enable for users with [[<tvar name=1>Special:MyLanguage/Manual:$wgEmailAuthentication</tvar>|confirmed email addresses]] only: </translate> <syntaxhighlight lang="php" copy>

  1. <translate nowrap> Disable for everyone.</translate>

$wgGroupPermissions['*']['edit'] = false;

  1. <translate nowrap> Disable for users, too: by default 'user' is allowed to edit, even if '*' is not.</translate>

$wgGroupPermissions['user']['edit'] = false;

  1. <translate nowrap> Make it so users with confirmed email addresses are in the group.</translate>

$wgAutopromote['emailconfirmed'] = APCOND_EMAILCONFIRMED;

  1. <translate nowrap> Hide group from user list.</translate>

$wgImplicitGroups[] = 'emailconfirmed';

  1. <translate nowrap> Finally, set it to true for the desired group.</translate>

$wgGroupPermissions['emailconfirmed']['edit'] = true; </syntaxhighlight>

<translate>

Creating a new group and assigning permissions to it[edit]

</translate> <translate> A custom group can be created by simply assigning rights to it via [ ]</tvar>|group-name}} where group-name is the actual name of the group.</translate> <translate> From MW 1.12, you can create your own groups into which users are automatically promoted (as with <tvar name=1>autoconfirmed</tvar>) using <tvar name=AutoPromote></tvar>.</translate>

<translate> In addition to assigning permissions, you should create these three wiki pages with suitable content (see also the examples below): </translate>

  • <translate> (content: Name of the group)</translate>
  • <translate> (content: Name of a member of the group)</translate>
  • <translate> (content: Name of the group page)</translate>

<translate> By default, bureaucrats can add users to, or remove them from, any group.</translate> <translate> However, if you are using <tvar name=1></tvar> and <tvar name=2></tvar>, you may need to customize those instead.</translate>

<translate>

Examples[edit]

This example will create an arbitrary <tvar name=1>projectmember</tvar> group that can block users and delete pages, and whose edits are hidden by default in the recent changes log: </translate>

<syntaxhighlight lang="php" copy> $wgGroupPermissions['projectmember']['bot'] = true; $wgGroupPermissions['projectmember']['block'] = true; $wgGroupPermissions['projectmember']['delete'] = true; </syntaxhighlight>

</tvar> or <tvar name=2></tvar> instead of <tvar name=3></tvar>.</translate> <translate> Moreover it is recommended to only use lowercase letters to create a group.</translate>}}

<translate> In this example, you would probably also want to create these pages: </translate>

  • <translate> (content: Project members)</translate>
  • <translate> (content: Project member)</translate>
  • <translate> (content: Project:Project Members)</translate>

<translate> This will ensure that the group will be referred to as "Project members" throughout the interface, a member will be referred to as a "Project member", and overviews will link the group name to . </translate>

<translate> This example disables write access (page editing and creation) by default, creates a group named <tvar name=1>writer</tvar>, and grants it write access.</translate> <translate> Users can be manually added to this group via <tvar name=UserRights>Special:UserRights</tvar>:</translate>

<syntaxhighlight lang="php" copy> $wgGroupPermissions['*']['edit'] = false; $wgGroupPermissions['*']['createpage'] = false; $wgGroupPermissions['user']['edit'] = false; $wgGroupPermissions['user']['createpage'] = false; $wgGroupPermissions['writer']['edit'] = true; $wgGroupPermissions['writer']['createpage'] = true; </syntaxhighlight>

<translate> In this example, you would probably also want to create these pages: </translate>

  • <translate> (content: Writers)</translate>
  • <translate> (content: Writer)</translate>
  • <translate> (content: Project:Write)</translate>

<translate>

List of permissions[edit]

</translate> <translate> The following user rights are available in the latest version of MediaWiki.</translate> <translate> If you are using an older version, look at <tvar name=1>Special:Version</tvar> on your wiki and see if your version is covered in the "Versions" column.</translate>

<translate> Right</translate> <translate> Description</translate> <translate> User groups that have this right by default</translate> <translate> Versions</translate>
'
read – <translate> when set to <tvar name=1></tvar>, override for specific pages with <tvar name=WhitelistRead></tvar></translate>
*, user 1.5+
'
applychangetags – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.25+
autocreateaccount - <translate> a more limited version of <tvar name=1>createaccount</tvar></translate> 1.27+
createaccount – <translate> register / registration</translate> *, sysop 1.5+
createpage – <translate> requires the <tvar name=1>edit</tvar> right</translate> *, user 1.6+
createpreviouslyrenamedaccount – requires the createaccount right sysop 1.47+
createtalk – <translate> requires the <tvar name=1>edit</tvar> right</translate> *, user 1.6+
createwithcontentmodel – requires the createpage right user 1.46+
delete-redirect <translate> (note that this is not needed if the group already has the <tvar name=1>delete</tvar> right)</translate> 1.36+
edit – <translate> requires the <tvar name=1>read</tvar> right</translate> *, user 1.5+
editsemiprotected – <translate> without cascading protection</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> autoconfirmed, bot, sysop 1.22+
editprotected – <translate> without cascading protection</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.13+
minoredit – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.6+
move – <translate> requires the <tvar name=1>edit</tvar> right</translate> user, sysop 1.5+
move-categorypages – <translate> requires the <tvar name=1>move</tvar> right</translate> user, sysop 1.25+
move-rootuserpages – <translate> requires the <tvar name=1>move</tvar> right</translate> user, sysop 1.14+
move-subpages – <translate> requires the <tvar name=1>move</tvar> right</translate> user, sysop 1.13+
movefile – <translate> requires the <tvar name=1>move</tvar> right as well</translate> user, sysop 1.14+
reupload – <translate> requires the <tvar name=1>upload</tvar> right</translate> user, sysop 1.6+
reupload-own – <translate> requires the <tvar name=1>upload</tvar> right (note that this is not needed if the group already has the <tvar name=reupload>reupload</tvar> right)</translate> 1.11+
reupload-shared – <translate> (if one is set up) with local files</translate> <translate> (requires the <tvar name=1>upload</tvar> right)</translate> user, sysop 1.6+
sendemail user 1.16+
upload – <translate> requires the <tvar name=1>edit</tvar> right and <tvar name=2></tvar> to be <tvar name=3></tvar></translate> user, sysop 1.5+
upload_by_url – <translate> requires the <tvar name=1>upload</tvar> right</translate> <translate> (Prior to 1.20 it was given to sysops)</translate> 1.8+
'
autopatrol UseRCPatrol|UseNPPatrol|UseFilePatrol}}</tvar></translate> bot, sysop 1.9+
bigdelete (<translate> as determined by <tvar name=1></tvar></translate>) – <translate> requires the <tvar name=1>delete</tvar> right</translate> sysop 1.12+
block – <translate> Block options include preventing editing and registering new accounts, and autoblocking other users on the same IP address</translate> sysop 1.5+
blockemail – <translate> allows preventing use of the <tvar name=1>Special:Emailuser</tvar> interface when blocking</translate> – <translate> requires the <tvar name=1>block</tvar> right</translate> sysop 1.11+
browsearchive – <translate> through <tvar name=1>Special:Undelete</tvar></translate> – <translate> requires the <tvar name=1>deletedhistory</tvar> right</translate> sysop 1.13+
changetags – <translate> currently unused by extensions</translate> user 1.25+
delete
<translate> allows the deletion or undeletion of pages</translate>
<translate> allows the deletion of pages</translate> <translate> (for undeletions, there is now the <tvar name=1>undelete</tvar> right, see below)</translate>
sysop 1.5+
deletedhistory sysop 1.6+
deletedtext – <translate> requires the <tvar name=1>deletedhistory</tvar> right</translate> sysop 1.16+
deletelogentry – <translate> allows deleting/undeleting information (action text, summary, user who made the action) of specific log entries – requires the <tvar name=1>deleterevision</tvar> right</translate> suppress 1.20+
deleterevision – <translate> allows deleting/undeleting information (revision text, edit summary, user who made the edit) of specific revisions</translate> (<translate> Split into <tvar name=1>deleterevision</tvar> and <tvar name=2>deletelogentry</tvar> in 1.20</translate>) suppress 1.6+
editcontentmodel – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.23.7+
editinterface – <translate> contains [[<tvar name=man>Special:MyLanguage/Manual:Interface</tvar>|interface messages]].</translate> <translate> For editing sitewide CSS/JSON/JS, there are now segregate rights, see below.</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop, interface-admin 1.5+
editmyoptions * 1.22+
editmyprivateinfo – <translate> also hides the "Change Password", but not other ways to change the password</translate> – <translate> requires the <tvar name=1>viewmyprivateinfo</tvar> right</translate> * 1.22+
editmyusercss – <translate> prior to 1.31 it was assigned to everyone (i.e. <tvar name=1>*</tvar>) (note that this is not needed if the group already has the <tvar name=editusercss>editusercss</tvar> right)</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.22+
editmyuserjs – <translate> prior to 1.31 it was assigned to everyone (i.e. <tvar name=1>*</tvar>) (note that this is not needed if the group already has the <tvar name=edituserjs>edituserjs</tvar> right)</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.22+
editmyuserjsredirect <translate> (note that this is not needed if the group already has the <tvar name=edituserjs>edituserjs</tvar> right)</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> 1.34+
editmyuserjson <translate> (note that this is not needed if the group already has the <tvar name=edituserjson>edituserjson</tvar> right)</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> user 1.31+
editmywatchlist – <translate> requires the <tvar name=1>viewmywatchlist</tvar> right</translate> user 1.22+
editsitecss – <translate> requires the <tvar name=1>editinterface</tvar> right</translate> interface-admin 1.32+
editsitejs – <translate> requires the <tvar name=1>editinterface</tvar> right</translate> interface-admin 1.32+
editsitejson – <translate> requires the <tvar name=1>editinterface</tvar> right</translate> sysop, interface-admin 1.32+
editusercss – <translate> requires the <tvar name=1>edit</tvar> right</translate> interface-admin 1.16+
edituserjs – <translate> requires the <tvar name=1>edit</tvar> right</translate> interface-admin 1.16+
edituserjson – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop, interface-admin 1.31+
hideuser – <translate> Only users with 1000 edits or less can be suppressed by default</translate> – <translate> requires the <tvar name=1>block</tvar> right</translate>

<translate> Use <tvar name=HideUserContribLimit></tvar> to disable.</translate>

suppress 1.10+
ignore-restricted-groups – <translate> Only applies to groups the user would be otherwise able to change, based on <tvar name=1>userrights</tvar> right and the contents of <tvar name=2></tvar>.</translate> 1.46+
markbotedits – <translate> see <tvar name=1></tvar></translate> – <translate> requires the <tvar name=1>rollback</tvar> right</translate> sysop 1.12+
mergehistory – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.12+
pagelang – <translate> <tvar name=1></tvar> must be <tvar name=2></tvar></translate> 1.24+
patrol UseRCPatrol|UseNPPatrol|UseFilePatrol}}</tvar></translate> sysop 1.5+
patrolmarks (<translate> note that this is not needed if the group already has the <tvar name=1>patrol</tvar> right</translate>) 1.16+
protect – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.5+
rollback MyLanguage/Manual:Rollback – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.5+
suppressionlog suppress 1.6+
suppressrevision <translate> Prior to <tvar name=1>1.13</tvar> this right was named <tvar name=2>hiderevision</tvar></translate> – <translate> requires the <tvar name=1>deleterevision</tvar> right</translate> suppress 1.6+
unblockself – <translate> Without it, an administrator that has the capability to block cannot unblock themselves if blocked by another administrator</translate> sysop 1.17+
undelete – <translate> requires the <tvar name=1>deletedhistory</tvar> right</translate> sysop 1.12+
userrights – <translate> allows the assignment or removal of all(*) groups to any user.</translate>

<translate> (*)With <tvar name=AddGroups></tvar> and <tvar name=RemoveGroups></tvar> you can set the possibility to add/remove certain groups instead of all</translate>

bureaucrat 1.5+
userrights-interwiki – <translate> requires the <tvar name=1>userrights</tvar> right</translate> 1.12+
viewmyprivateinfo * 1.22+
viewmywatchlist user 1.22+
viewsuppressed – <translate> i.e. a more narrow alternative to <tvar name=1>suppressrevision</tvar> (note that this is not needed if the group already has the <tvar name=2>suppressrevision</tvar> right)</translate> suppress 1.24+
'
deletechangetags – <translate> currently unused by extensions</translate> sysop 1.28+
import – <translate> "transwiki"</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.5+
importupload – <translate> This right was called <tvar name=1>importraw</tvar> in and before version 1.5</translate> – <translate> requires the <tvar name=1>edit</tvar> right</translate> sysop 1.5+
managechangetags – <translate> currently unused by extensions</translate> sysop 1.25+
renameuser (<translate> formerly was part of the Renameuser extension</translate>) bureaucrat 1.40+
siteadmin – <translate> which blocks all interactions with the web site except viewing.</translate> (<translate> not available by default</translate>) 1.5+
unwatchedpages – <translate> lists pages that no user has watchlisted</translate> sysop 1.6+
'
apihighlimits bot, sysop 1.12+
autoconfirmed – <translate> used for the <tvar name=1>autoconfirmed</tvar> group; see the other table below for more information</translate> <translate> (note that this is not needed if the group already has the <tvar name=2>noratelimit</tvar> right)</translate> autoconfirmed, bot, sysop 1.6+
bot – <translate> edits and logged actions are hidden from recent changes, can optionally be viewed</translate> bot 1.5+
ipblock-exempt sysop 1.9+
nominornewtalk – <translate> requires the <tvar name=1>minoredit</tvar> right</translate> bot 1.9+
noratelimit – <translate> not affected by [[<tvar name=1>Special:MyLanguage/Manual:$wgRateLimits</tvar>|rate limits]] (prior to the introduction of this right, the configuration variable <tvar name=RateLimitsExcludedGroups></tvar> was used for this purpose)</translate> sysop, bureaucrat 1.13+
override-export-depth
<translate> With this right, you can define the depth of linked pages at <tvar name=link1>Special:Export</tvar>. Otherwise, the value of <tvar name=link2></tvar>, which is 0 by default, will be used.</translate>
1.15+
suppressredirect – <translate> requires the <tvar name=1>move</tvar> right</translate> bot, sysop 1.12+

Template:Note

<translate>

Predefined groups[edit]

</translate> <translate> The following groups are available in the latest version of MediaWiki.</translate> <translate> If you are using an older version then some of these may not be implemented.</translate>

<translate> Group</translate> <translate> Description</translate> <translate> Default rights</translate> <translate> Versions</translate>
* <translate> All users (including anonymous).</translate> createaccount, createpage, createtalk, edit, editmyoptions, editmyprivateinfo, read, viewmyprivateinfo 1.5+
temp <translate> Temporary user accounts (<tvar name=1>T330816</tvar>)</translate> <translate> Similar to <tvar name=1>*</tvar> group</translate> 1.41+
user <translate> Registered accounts.</translate> <translate> Does not include temporary accounts.</translate> applychangetags, changetags, createpage, createtalk, createwithcontentmodel, edit, editcontentmodel, editmyusercss, editmyuserjs, editmyuserjson, editmywatchlist, minoredit, move, move-categorypages, move-rootuserpages, move-subpages, movefile, purge, read, reupload, reupload-shared, sendemail, upload, viewmywatchlist 1.13+
autoconfirmed <translate> Registered accounts at least as old as <tvar name=AutoConfirmAge></tvar> and having at least as many edits as <tvar name=AutoConfirmCount></tvar>.</translate> autoconfirmed, editsemiprotected 1.6+
bot <translate> Accounts with the bot right (intended for automated scripts).</translate> autoconfirmed, autopatrol, apihighlimits, bot, editsemiprotected, nominornewtalk, suppressredirect 1.5+
sysop <translate> Users who by default can delete and restore pages, block and unblock users, etc.</translate> apihighlimits, autoconfirmed, autopatrol, bigdelete, block, blockemail, browsearchive, createaccount, createpreviouslyrenamedaccount, delete, deletedhistory, deletedtext, editinterface, editprotected, editsemiprotected, editsitejson, edituserjson, import, importupload, ipblock-exempt, managechangetags, markbotedits, mergehistory, move, move-categorypages, move-rootuserpages, move-subpages, movefile, noratelimit, patrol, protect, reupload, reupload-shared, rollback, suppressredirect, unblockself, undelete, unwatchedpages, upload 1.5+
interface-admin <translate> Users who can edit sitewide CSS and JavaScript.</translate> editinterface, editsitecss, editsitejs, editsitejson, editusercss, edituserjs, edituserjson 1.32+
bureaucrat <translate> Users who can change the rights of other users by default and therefore have full access of the entire wiki.</translate> noratelimit, renameuser, userrights 1.5+
suppress deletelogentry, deleterevision, hideuser, suppressionlog, suppressrevision, viewsuppressed 1.13+

<translate>

Removing predefined groups[edit]

</translate> <translate> MediaWiki out of the box comes with a number of predefined groups.</translate> <translate> Most of these groups can be removed by unsetting the according array keys, among them [ ]</tvar>|group-name}}.</translate> <translate> For details, see below.</translate>

<translate>

Example[edit]

</translate> <translate> This example will eliminate the <tvar name=1>bureaucrat</tvar> group entirely.</translate> <translate> It is necessary to ensure that all six of these variables are unset for any group that one wishes to remove from being listed at <tvar name=List>Special:ListGroupRights</tvar>; however, merely unsetting <tvar name=1>$wgGroupPermissions</tvar> will suffice to remove it from <tvar name=UserRights>Special:UserRights</tvar>.</translate>

<syntaxhighlight lang="php" copy> unset( $wgGroupPermissions['bureaucrat'] ); unset( $wgRevokePermissions['bureaucrat'] ); unset( $wgAddGroups['bureaucrat'] ); unset( $wgRemoveGroups['bureaucrat'] ); unset( $wgGroupsAddToSelf['bureaucrat'] ); unset( $wgGroupsRemoveFromSelf['bureaucrat'] ); </syntaxhighlight>

<translate> This code will not work if any extension that modifies the default rights for the <tvar name=2>bureaucrat</tvar> group, such as <tvar name=1></tvar>, is installed.</translate>


<translate> More broadly, to disable a user group created by an extension, the above code needs to run after all extensions have been registered.</translate> <translate> This used to be possible by registering an extension function in <tvar name=1>LocalSettings.php</tvar>:</translate>

<syntaxhighlight lang="php" copy> $wgExtensionFunctions[] = function() use ( &$wgGroupPermissions ) {

   unset( $wgGroupPermissions['oversight'] );
   unset( $wgGroupPermissions['flow-bot'] );

}; </syntaxhighlight>

<translate> However, this no longer works reliably due to <tvar name=1>T275334</tvar>.</translate>

Template:Note

<translate>

Default rights[edit]

The default rights are defined in <tvar name=1></tvar>. </translate>

  • Template:Git file
  • |file=includes/MainConfigSchema.php|text=<translate> Default values in the latest stable version (branch <tvar name=1></tvar>, version <tvar name=2></tvar>)</translate>}}

<translate>

  • Additional rights: you should be able to list all the permissions available on your wiki by running <tvar name=1></tvar>.

Adding new rights[edit]

</translate> <translate> Information for coders only follows.</translate>

<translate> If you're adding a new right in core, for instance to [[<tvar name=2>Special:MyLanguage/Manual:Special pages</tvar>|control a new special page]], you are required to add it to the list of available rights in <tvar name=User></tvar>, <tvar name=1></tvar> ([<tvar name=url>https://gerrit.wikimedia.org/r/c/mediawiki/core/+/559622/9/includes/Permissions/PermissionManager.php</tvar> example]).</translate> <translate> If you're , you instead need to use <tvar name=2></tvar>, or preferably define the right in <tvar name=3></tvar>.</translate>

<translate> You probably also want to assign it to some user group by editing <tvar name=GroupPermissions></tvar> described above.

If you want this right to be accessible to external applications by <tvar name=OAuth></tvar> or by [[<tvar name=1>Special:MyLanguage/Manual:Bot passwords</tvar>|bot passwords]], then you will need to add it to a grant by editing <tvar name=GrantPermissions></tvar>. </translate>

<syntaxhighlight lang="php" copy> // <translate nowrap> create projectmember-powers right</translate> $wgAvailableRights[] = 'projectmember-powers';

// <translate nowrap> add projectmember-powers to the projectmember-group</translate> $wgGroupPermissions['projectmember']['projectmember-powers'] = true;

// <translate nowrap> add projectmember-powers to the 'basic' grant so we can use our projectmember powers over an API request</translate> $wgGrantPermissions['basic']['projectmember-powers'] = true; </syntaxhighlight>

<translate> You also need to add and interface messages to <tvar name=3>languages/i18n/en.json</tvar> (with documentation in <tvar name=4>qqq.json</tvar>).</translate> <translate> The <tvar name=1>right-*</tvar> messages can be seen on <tvar name=2>Special:ListGroupRights</tvar> and the <tvar name=3>action-*</tvar> messages are used in a sentence like "You do not have permission to ...".</translate>

<translate>

See also[edit]

</translate>

  • Special:ListGroupRights – <translate> Links to this help page and might contain not yet documented rights</translate>
  • – <translate> Help page describing use of the <tvar name=1>Special:Userrights</tvar> interface (for bureaucrats)</translate>
  • – <translate> Information about managing and the assignment of user groups.</translate>
  • |AddGroups|RemoveGroups}}
  • – <translate> Examples</translate>
  • – <translate> Many extensions relating to user rights</translate>

Sample content adapted from mediawikiwiki:Manual:User_rights on mediawiki.org, licensed under CC BY-SA 4.0.