Merge "Remove uncalled Skin::getNamespaceNotice"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 14 Dec 2015 00:34:54 +0000 (00:34 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 14 Dec 2015 00:34:54 +0000 (00:34 +0000)
368 files changed:
HISTORY
RELEASE-NOTES-1.26 [deleted file]
RELEASE-NOTES-1.27
autoload.php
composer.json
docs/extension.schema.json
docs/hooks.txt
docs/memcached.txt
includes/AjaxResponse.php
includes/DefaultSettings.php
includes/EditPage.php
includes/ForkController.php
includes/GlobalFunctions.php
includes/Hooks.php
includes/HttpFunctions.php
includes/Linker.php
includes/MediaWiki.php
includes/MovePage.php
includes/OutputHandler.php
includes/OutputPage.php
includes/Preferences.php
includes/PrefixSearch.php
includes/Sanitizer.php
includes/Setup.php
includes/Title.php
includes/User.php [deleted file]
includes/UserArray.php [deleted file]
includes/UserArrayFromResult.php [deleted file]
includes/UserRightsProxy.php [deleted file]
includes/actions/HistoryAction.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFormatRaw.php
includes/api/ApiParse.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiQueryUsers.php
includes/api/ApiResult.php
includes/api/ApiStashEdit.php
includes/api/i18n/de.json
includes/api/i18n/diq.json
includes/api/i18n/en.json
includes/api/i18n/eu.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ko.json
includes/api/i18n/ksh.json
includes/api/i18n/lki.json [new file with mode: 0644]
includes/api/i18n/mr.json
includes/api/i18n/pl.json
includes/api/i18n/ps.json
includes/api/i18n/qqq.json
includes/api/i18n/sv.json
includes/api/i18n/tl.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/cache/HTMLFileCache.php
includes/cache/MessageBlobStore.php
includes/cache/MessageCache.php
includes/changes/CategoryMembershipChange.php
includes/changes/EnhancedChangesList.php
includes/clientpool/RedisConnectionPool.php
includes/clientpool/SquidPurgeClient.php
includes/context/RequestContext.php
includes/db/Database.php
includes/db/DatabaseError.php
includes/db/DatabaseUtility.php
includes/debug/logger/monolog/AvroFormatter.php
includes/deferred/CdnCacheUpdate.php [new file with mode: 0644]
includes/deferred/DeferrableUpdate.php [new file with mode: 0644]
includes/deferred/DeferredUpdates.php
includes/deferred/HTMLCacheUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/MergeableUpdate.php [new file with mode: 0644]
includes/deferred/SearchUpdate.php
includes/deferred/SquidUpdate.php [deleted file]
includes/diff/DairikiDiff.php
includes/exception/MWExceptionHandler.php
includes/filerepo/FileRepo.php
includes/filerepo/file/LocalFile.php
includes/gallery/ImageGalleryBase.php
includes/installer/i18n/ca.json
includes/installer/i18n/el.json
includes/installer/i18n/eu.json
includes/installer/i18n/is.json
includes/installer/i18n/it.json
includes/installer/i18n/lki.json [new file with mode: 0644]
includes/installer/i18n/mk.json
includes/installer/i18n/mr.json
includes/installer/i18n/ru.json
includes/jobqueue/JobQueue.php
includes/jobqueue/JobQueueFederated.php
includes/jobqueue/JobQueueRedis.php
includes/jobqueue/README
includes/jobqueue/jobs/CategoryMembershipChangeJob.php [new file with mode: 0644]
includes/jobqueue/jobs/CdnPurgeJob.php [new file with mode: 0644]
includes/jobqueue/jobs/HTMLCacheUpdateJob.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/jobqueue/utils/BacklinkJobUtils.php
includes/libs/SamplingStatsdClient.php
includes/libs/StatusValue.php
includes/libs/Timing.php
includes/libs/objectcache/WANObjectCache.php
includes/logging/LogEventsList.php
includes/media/FormatMetadata.php
includes/objectcache/ObjectCache.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/CoreParserFunctions.php
includes/password/PasswordPolicyChecks.php
includes/profiler/output/ProfilerOutputDb.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/revisiondelete/RevDelFileList.php
includes/revisiondelete/RevisionDeleter.php
includes/search/SearchExactMatchRescorer.php [new file with mode: 0644]
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/QueryPage.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialAllPages.php
includes/specials/SpecialCategories.php
includes/specials/SpecialChangeContentModel.php
includes/specials/SpecialContributions.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialExport.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialListfiles.php
includes/specials/SpecialListusers.php
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialNewimages.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialTags.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialWantedpages.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/tidy/TidyDriverBase.php
includes/user/CentralIdLookup.php [new file with mode: 0644]
includes/user/LocalIdLookup.php [new file with mode: 0644]
includes/user/User.php [new file with mode: 0644]
includes/user/UserArray.php [new file with mode: 0644]
includes/user/UserArrayFromResult.php [new file with mode: 0644]
includes/user/UserRightsProxy.php [new file with mode: 0644]
includes/utils/IP.php
includes/utils/UIDGenerator.php
languages/i18n/ady-cyrl.json
languages/i18n/af.json
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/cv.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frc.json
languages/i18n/fy.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/he.json
languages/i18n/hif-latn.json
languages/i18n/hr.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/ilo.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/khw.json
languages/i18n/kiu.json
languages/i18n/kk-cyrl.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/la.json
languages/i18n/lb.json
languages/i18n/lij.json
languages/i18n/lki.json [new file with mode: 0644]
languages/i18n/lmo.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/or.json
languages/i18n/pam.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/th.json
languages/i18n/tl.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/uz.json
languages/i18n/vec.json
languages/i18n/vep.json
languages/i18n/vi.json
languages/i18n/vmf.json
languages/i18n/wuu.json
languages/i18n/yi.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesEn.php
languages/messages/MessagesKo.php
maintenance/README
maintenance/benchmarks/benchmarkPurge.php
maintenance/cleanupImages.php
maintenance/cleanupRemovedModules.php
maintenance/cleanupTable.inc
maintenance/cleanupTitles.php
maintenance/clearCacheStats.php [deleted file]
maintenance/createCommonPasswordCdb.php [new file with mode: 0644]
maintenance/makeTestEdits.php [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/purgeChangedPages.php
maintenance/purgeList.php
maintenance/showCacheStats.php [deleted file]
package.json
resources/Resources.php
resources/ResourcesOOUI.php
resources/lib/oojs-ui/i18n/bn.json
resources/lib/oojs-ui/i18n/lki.json [new file with mode: 0644]
resources/lib/oojs-ui/i18n/pt.json
resources/lib/oojs-ui/i18n/sd.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-apex-noimages.css
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/themes/apex/images/icons/search.png
resources/lib/oojs-ui/themes/apex/images/icons/search.svg
resources/lib/oojs-ui/themes/apex/images/indicators/search-ltr.svg
resources/lib/oojs-ui/themes/apex/images/indicators/search-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl.svg
resources/src/jquery/jquery.suggestions.js
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.special/mediawiki.special.watchlist.js [new file with mode: 0644]
resources/src/mediawiki/api.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js
resources/src/mediawiki/mediawiki.feedback.js
resources/src/mediawiki/mediawiki.toc.css [new file with mode: 0644]
resources/src/mediawiki/mediawiki.toc.print.css [new file with mode: 0644]
resources/src/mediawiki/page/image-pagination.js
resources/src/mediawiki/page/startup.js
resources/src/oojs-ui-local.js [new file with mode: 0644]
serialized/commonpasswords.cdb [new file with mode: 0644]
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/TemplateParserTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/UserArrayFromResultTest.php [deleted file]
tests/phpunit/includes/UserTest.php [deleted file]
tests/phpunit/includes/api/ApiErrorFormatterTest.php
tests/phpunit/includes/api/ApiResultTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/content/CssContentHandlerTest.php
tests/phpunit/includes/content/JavaScriptContentHandlerTest.php
tests/phpunit/includes/db/DatabaseTest.php
tests/phpunit/includes/deferred/CdnCacheUpdateTest.php [new file with mode: 0644]
tests/phpunit/includes/deferred/DeferredUpdatesTest.php
tests/phpunit/includes/deferred/LinksUpdateTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php
tests/phpunit/includes/jobqueue/JobQueueTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/parser/MediaWikiParserTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/user/CentralIdLookupTest.php [new file with mode: 0644]
tests/phpunit/includes/user/LocalIdLookupTest.php [new file with mode: 0644]
tests/phpunit/includes/user/UserArrayFromResultTest.php [new file with mode: 0644]
tests/phpunit/includes/user/UserTest.php [new file with mode: 0644]
tests/phpunit/includes/utils/UIDGeneratorTest.php
tests/phpunit/languages/LanguageConverterTest.php
tests/phpunit/suite.xml
tests/phpunit/suites/UploadFromUrlTestSuite.php
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js

diff --git a/HISTORY b/HISTORY
index 0c2b8ac..9cb5399 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,7 +1,304 @@
 Change notes from older releases. For current info see RELEASE-NOTES-1.27.
 
+== MediaWiki 1.26 ==
+
+=== Configuration changes in 1.26 ===
+* $wgPasswordResetRoutes['email'] = true by default.
+* $wgEnableParserCache was deprecated, set $wgParserCacheType to CACHE_NONE
+  instead if you want to disable the parser cache.
+* New-style continuation is now the default for API action=continue. Clients may
+  use the 'rawcontinue' parameter to receive raw query-continue data, but the
+  new style is encouraged as it's harder to implement incorrectly.
+* Deprecated API formats dump and wddx have been completely removed.
+* (T7645) The "Signature" button on the edit toolbar is now hidden by default
+  in non-talk namespaces. A new configuration variable,
+  $wgExtraSignatureNamespaces, controls in which subject (non-talk) namespaces
+  the "Signature" button on the edit toolbar will be displayed.
+* $wgResourceLoaderUseESI was deprecated and removed. This was an experimental
+  feature that was never enabled by default.
+* $wgResourceLoaderExperimentalAsyncLoading was deprecated and removed.
+  This experimental feature was never enabled by default and is obsolete as of
+  MediaWiki 1.26, in where ResourceLoader became fully asynchronous.
+* $wgMasterWaitTimeout was removed (deprecated in 1.24).
+* Fields in ParserOptions are now private. Use the accessors instead.
+* Custom LESS functions (defined via $wgResourceLoaderLESSFunctions or
+  in extension.json) have been removed, after being deprecated in 1.24.
+* $wgAlwaysUseTidy has been removed.
+* ResetSessionID hook has been removed. Nothing seems to use it.
+* Certain AuthPlugin methods are deprecated in favor of new hooks:
+** AuthPlugin::initUser() is replaced by LocalUserCreated.
+** AuthPlugin::updateUser() is replaced by UserLoggedIn.
+** AuthPlugin::updateExternalDB() is replaced by the existing UserSaveSettings.
+** AuthPlugin::updateExternalDBGroups() is replaced by UserGroupsChanged.
+** AuthPluginUser::isHidden() is replaced by UserIsHidden.
+** AuthPluginUser::isLocked() is replaced by UserIsLocked.
+* The UserRights hook is deprecated in favor of the new UserGroupsChanged hook.
+* AuthPlugin::initUser() and AuthPlugin::updateUser() should no longer replace
+  the passed User object.
+* $wgBlockAllowsUTEdit is now set to true by default. This allows
+  blocked users to edit their talk pages unless explicitly disabled
+  when they are being blocked.
+
+=== New features in 1.26 ===
+* (T51506) Now action=info gives estimates of actual watchers for a page.
+  See $wgRCMaxAge, $wgWatchersMaxAge and $wgUnwatchedPageSecret
+  to learn how to configure if needed.
+* Change tags can now be hidden in the interface by disabling the associated
+  "tag-<id>" interface message.
+* ':' (colon) is now invalid in usernames for new accounts. Existing accounts
+  are not affected.
+* Added a new hook, 'LogException', to log exceptions in nonstandard ways.
+* Revive the 'SpecialSearchResultsAppend' hook which occurs after the list of
+  search results are rendered. The initial use case is to append a "give us
+  feedback" link beneath the search results.
+* Added a new hook, 'RejectParserCacheValue', which allows extensions to
+  reject an otherwise-successful parser cache lookup. The intent is to allow
+  extensions to manage the eviction of archaic HTML output from the cache.
+* (T68699) The expiration of the UserID and Token login cookies
+  ($wgExtendedLoginCookieExpiration) can be configured independently of the
+  expiration of all other cookies ($wgCookieExpiration).
+* (T50519) Support for generating JPEG/PNG thumbnails from WebP images added
+  if ImageMagick is used as image scaler ($wgUseImageMagick = true). Uploading
+  of WebP images still disabled by default. Add $wgFileExtensions[] =
+  'webp'; to LocalSettings.php to enable uploading of WebP images.
+* Added new hooks 'EnhancedChangesListModifyLineData' &
+  'EnhancedChangesListModifyBlockLineData', to modify the data used to build
+  lines in enhanced recentchanges and watchlist.
+* Caches that need purging ability now use the WANObjectCache interface.
+  This corresponds to a new $wgMainWANCache setting, which defaults to using
+  the $wgMainCacheType settings.
+* Callers needing fast light-weight data stores use $wgMainStash to select
+  the store type from $wgObjectCaches. The default is the local database.
+* Interface message overrides in the MediaWiki namespace will now be cached in
+  memcached and APC (if available), rather than memcached and local files.
+* Added a new hook, 'RandomPageQuery', to allow modification of the query used
+  by Special:Random to select random pages.
+* $wgTransactionalTimeLimit was added, which controls the request time limit
+  for potentially slow POST requests that need to be as atomic as possible.
+* ResourceLoader now loads all scripts asynchronously. The top-queue and
+  startup modules are no longer synchronously loaded.
+* 'mediawiki.ui.button' styles are no longer unconditionally loaded on every
+  page. During the deprecation period, the styles will only be loaded on pages
+  which contain 'mw-ui-button' in their HTML. Starting in 1.28, the styles will
+  only be loaded if explicitly required.
+* If search returns zero results and current search engine has a "did you mean"
+  suggestion, results for suggestion will be shown. Can be disabled by setting
+  $wgSearchRunSuggestedQuery to false.
+* Added several JavaScript libraries for uploading files to MediaWiki
+  from the client-side. See documentation for mw.Upload and its
+  subclasses for more information.
+* Added OOUI dialogs and layout for file upload interfaces. See
+  documentation for mw.Upload.Dialog, mw.Upload.BookletLayout and its
+  subclasses for more information.
+
+== extension.json changes in 1.26 ==
+* (T99344) The extension.json schema is now versioned. All extensions
+  and skins should set a "manifest_version" property corresponding to
+  the schema version they were written for. The only supported version
+  currently is "1".
+* (T102523) The error message if a non-array attribute is set was improved.
+* (T107646) Configuration settings can now specify how they should be merged,
+  which is necessary for arrays using integer keys.
+* (T110389) Adding namespaces through extension.json now actually works
+* $wgNamespaceProtection can now be set in extension.json.
+* $wgCapitalLinkOverrides can now be set in extension.json.
+* (T97186) Extensions using a custom prefix for their configuration settings
+  can now set a "_prefix" key to override the default of "wg".
+* (T99084) Extensions can now specify what MediaWiki core versions they
+  depend upon.
+* (T105236) The extension.json schema now validates custom classes in
+  the "ResourceModules" property properly.
+
+=== External library changes in 1.26 ===
+==== Upgraded external libraries ====
+* Updated es5-shim from v4.0.0 to v4.1.5.
+* Updated json2 from revision 2014-02-04 to 2015-05-03.
+* Updated Sinon.JS from 1.10.3 to 1.15.4.
+* Updated jQuery Client from v1.0.0 to v2.0.0.
+* Updated QUnit from v1.17.1 to v1.18.0.
+* Updated liuggio/statsd-php-client from v1.0.12 to v1.0.16.
+* Updated oojs/oojs-ui from v0.11.3 to v0.12.12.
+* Updated wikimedia/cdb from v1.0.1 to v1.3.0.
+* Updated wikimedia/utfnormal from v1.0.2 to v1.0.3.
+* Updated wikimedia/composer-merge-plugin from v1.0.0 to v1.3.0.
+* Updated zordius/lightncandy from v0.18 to v0.21.
+
+==== New external libraries ====
+* Added composer/semver v1.0.0.
+* Added mediawiki/at-ease v1.1.0.
+* Added wikimedia/assert v0.2.2.
+* Added wikimedia/ip-set v1.0.1.
+* Added wikimedia/wrappedstring v2.0.0.
+
+==== Removed and replaced external libraries ====
+* Replaced leafo/lessphp v0.5.0 with oyejorge/less.php v1.7.0.9.
+
+=== Bug fixes in 1.26 ===
+* (T53283) load.php sometimes sends 304 response without full headers
+* (T65198) Talk page tabs now have a "rel=discussion" attribute
+* (T98841) {{msgnw:}} now preserves comments even when subst: is not used.
+* (T104142) $wgEmergencyContact and $wgPasswordSender now use their default
+  value if set to an empty string.
+
+=== Action API changes in 1.26 ===
+* New-style continuation is now the default for action=continue. Clients may
+  use the 'rawcontinue' parameter to receive raw query-continue data, but the
+  new style is encouraged as it's harder to implement incorrectly.
+* Deprecated API formats dump and wddx have been completely removed.
+* API action=query&list=tags: The displayname can now be boolean false if the
+  tag is meant to be hidden from user interfaces.
+* action=import no longer allows both the namespace= and rootpage= parameters
+  to be set. If they are both set, the value of rootpage= will be ignored.
+* prop=revision output in enum mode is now sorted by timestamp rather than
+  revision ID. This usually won't make any difference.
+* (T102645) Namespace list from meta=siteinfo&siprop=namespaces is now an array
+  with formatversion=2.
+* Various other output from meta=siteinfo will now always be arrays instead of
+  sometimes being numerically-indexed objects with formatversion=2.
+* When errors about users being blocked are returned, they now include
+  information about the relevant block.
+* (T99926) list=random has higher limits, in line with other API modules.
+* list=random's rnredirect parameter is deprecated in favor of a new
+  rnfilterredir parameter that also allows for listing both redirects and
+  non-redirects.
+* list=random now supports continuation.
+* API responses to GET requests may now include ETag and Last-Modified headers,
+  and will honor corresponding If-None-Match and If-Modified-Since on such
+  requests.
+
+=== Action API internal changes in 1.26 ===
+* New metadata item ApiResult::META_KVP_MERGE to allow for merging the KVP key
+  into the value when the value is an assoc.
+* API action modules may now provide values for the RFC 7232 ETag and
+  Last-Modified headers. The API will check these against If-None-Match and
+  If-Modified-Since request headers on GET requests and avoid executing the
+  module when appropriate.
+
+=== Languages updated in 1.26 ===
+
+MediaWiki supports over 350 languages. Many localisations are updated
+regularly. Below only new and removed languages are listed, as well as
+changes to languages because of Phabricator reports.
+
+* Languages added:
+** ase (American sign language), thanks to translator Icemandeaf
+** dty (डोटेली/Doteli), thanks to translators जनक राज भट्ट, बिप्लब आनन्द,
+   मेश सिंह बोहरा, and राम प्रसाद जोशी
+** luz (لئری دوٙمینی / Southern Luri)
+** olo (Livvinкarjala / Livvi-Karelian), thanks to translators Denö, Hiloin Natoi,
+   Ilja.mos, and Mashoi7
+
+=== Other changes in 1.26 ===
+* ChangeTags::tagDescription() will return false if the interface message
+  for the tag is disabled.
+* Added PageHistoryPager::doBatchLookups hook.
+* Added $wikiId parameter to FormatAutocomments hook.
+* Added ParserCacheSaveComplete to ParserCache
+* supportsDirectEditing and supportsDirectApiEditing methods added to
+  ContentHandler, to provide a way for ApiEditPage and EditPage to check
+  if direct editing of content is allowed. These methods return false,
+  by default for the ContentHandler base class and true for TextContentHandler
+  and it's derivative classes (everything in core). For Content types that
+  do not support direct editing, an alternative mechanism should be provided
+  for editing, such as action overrides or specific api modules.
+* mediaWiki.confirmCloseWindow now returns an object of functions, instead of
+  one function. The callback can't be called directly any more. The callback
+  function is replaced with confirmCloseWindow.release().
+* BREAKING CHANGE: Added an optional ResouceLoaderContext parameter to
+  ResourceLoaderModule::getDependencies(). Extension classes that override that
+  method should be updated. If they aren't updated, PHP Strict standards
+  warnings will appear when E_STRICT error reporting is enabled. Note: in the
+  near future, this parameter will probably become non-optional.
+* Removed maintenance script deleteImageMemcached.php.
+* MWFunction::newObj() was removed (deprecated in 1.25).
+  ObjectFactory::getObjectFromSpec() should be used instead.
+* The parser will no longer randomize the string it uses to mark the place of
+  items that were stripped during parsing. It will use a fixed string instead.
+  This causes the parser to re-use the regular expressions it uses to search
+  and replace markers rather than generate novel expressions on each parse.
+  Re-using regular expressions will improve performance on HHVM and the
+  forthcoming PHP 7. The interfaces changes accompanying this change are:
+  - Parser::getRandomString() and Parser::uniqPrefix() have been deprecated.
+  - The $uniq_prefix argument for Parser::extractTagsAndParams() and the
+    $prefix argument for StripState::_construct() are deprecated and their
+    value is ignored.
+* wfSuppressWarnings() and wfRestoreWarnings() were split into a separate library,
+  mediawiki/at-ease, and are now deprecated. Callers should use
+  MediaWiki\suppressWarnings() and MediaWiki\restoreWarnings() directly.
+* The Block class constructor now takes an associative array of parameters
+  instead of many optional positional arguments. Calling the constructor the old
+  way will issue a deprecation warning.
+* The jquery.mwExtension module was deprecated.
+* $wgSpecialPageGroups was removed (deprecated in 1.21).
+* SpecialPageFactory::setGroup was removed (deprecated in 1.21).
+* SpecialPageFactory::getGroup was removed (deprecated in 1.21).
+* DatabaseBase::ignoreErrors() is now protected.
+* BREAKING CHANGE: mediawiki.legacy.ajax has been removed, following
+  a lengthy deprecation period.
+* The ScopedPHPTimeout class was removed.
+* Removed maintenance script fixSlaveDesync.php.
+* Watchlist tokens, SpecialResetTokens, and User::getTokenFromOption()
+  are deprecated. Applications using those can work via the OAuth
+  extension instead. New tokens types should not be added.
+* DatabaseBase::errorCount() was removed (unused).
+* $wgDeferredUpdateList was removed.
+* DeferredUpdates::addHTMLCacheUpdate() was removed.
+
 == MediaWiki 1.25 ==
 
+== MediaWiki 1.25.3 ==
+
+This is a security and maintenance release of the MediaWiki 1.25 branch.
+
+=== Changes since 1.25.2 ===
+
+* (T98975) Fix having multiple callbacks for a single hook.
+* (T107632) maintenance/refreshLinks.php did not always remove all links
+  pointing to nonexistent pages.
+* (T104142) $wgEmergencyContact and $wgPasswordSender now use their default
+  value if set to an empty string.
+* (T62174) Provide fallbacks for use of mb_convert_encoding() in
+  HtmlFormatter. It was causing an error when accessing the api help page
+  if the mbstring PHP extension was not installed.
+* (T105896) Confirmation emails would sometimes contain invalid codes.
+* (T105597) Fixed edit stash inclusion queries.
+* (T91850) SECURITY: Add throttle check in ApiUpload and SpecialUpload
+* (T91203, T91205) SECURITY: API: Improve validation in chunked uploading
+* (T95589) SECURITY: RevDel: Check all revisions for suppression, not just the
+  first
+* (T108616) SECURITY: Avoid exposure of local path in PNG thumbnails
+
+== MediaWiki 1.25.2 ==
+
+This is a security and maintenance release of the MediaWiki 1.25 branch.
+
+=== Changes since 1.25.1 ===
+
+* (T94116) SECURITY: Compare API watchlist token in constant time
+* (T97391) SECURITY: Escape error message strings in thumb.php
+* (T106893) SECURITY: Don't leak autoblocked IP addresses on
+  Special:DeletedContributions
+* (T102562) Fix InstantCommons parameters to handle the new HTTPS-only
+  policy of Wikimedia Commons.
+* (T100767) Setting a configuration setting for skin or extension to
+  false in LocalSettings.php was not working.
+* (T100635) API action=opensearch json output no longer breaks when
+  $wgDebugToolbar is enabled.
+* (T102522) Using an extension.json or skin.json file which has
+  a "manifest_version" property for 1.26 compatability will no longer
+  trigger warnings.
+* (T86156) Running updateSearchIndex.php will not throw an error as
+  page_restrictions has been added to the locked table list.
+* Special:Version would throw notices if using SVN due to an incorrectly
+  named variable. Add an additional check that an index is defined.
+
+== MediaWiki 1.25.1 ==
+
+This is a bug fix release of the MediaWiki 1.25 branch.
+
+=== Changes since 1.25 ===
+* (T100351) Fix syntax errors in extension.json of ConfirmEdit extension
+
 === Configuration changes in 1.25 ===
 * $wgPageShowWatchingUsers was removed.
 * $wgLocalVirtualHosts has been added to replace $wgConf->localVHosts.
@@ -548,6 +845,76 @@ For notes on 1.24.x and older releases, see HISTORY.
 
 == MediaWiki 1.24 ==
 
+== MediaWiki 1.24.4 ==
+
+This is a security and maintenance release of the MediaWiki 1.24 branch.
+
+== Changes since 1.24.3 ==
+
+* (T91653) Minimal PSR-3 debug logger to support backports from 1.25+.
+* (T68650) Fix indexing of moved pages with PostgreSQL. Requires running
+  update.php to fix.
+* (T91850) SECURITY: Add throttle check in ApiUpload and SpecialUpload
+* (T91203, T91205) SECURITY: API: Improve validation in chunked uploading
+* (T95589) SECURITY: RevDel: Check all revisions for suppression, not just the
+  first
+* (T108616) SECURITY: Avoid exposure of local path in PNG thumbnails
+
+== MediaWiki 1.24.3 ==
+
+This is a security and maintenance release of the MediaWiki 1.24 branch.
+
+== Changes since 1.24.2 ==
+
+* (T94116) SECURITY: Compare API watchlist token in constant time
+* (T97391) SECURITY: Escape error message strings in thumb.php
+* (T106893) SECURITY: Don't leak autoblocked IP addresses on
+  Special:DeletedContributions
+* Update jQuery from v1.11.2 to v1.11.3.
+* (T102562) Fix InstantCommons parameters to handle the new HTTPS-only
+  policy of Wikimedia Commons.
+
+== MediaWiki 1.24.2 ==
+
+This is a security and maintenance release of the MediaWiki 1.24 branch.
+
+== Changes since 1.24.1 ==
+
+* (T85848, T71210) SECURITY: Don't parse XMP blocks that contain XML entities,
+  to prevent various DoS attacks.
+* (T85848) SECURITY: Don't allow directly calling Xml::isWellFormed, to reduce
+  likelihood of DoS.
+* (T88310) SECURITY: Always expand xml entities when checking SVG's.
+* (T73394) SECURITY: Escape > in Html::expandAttributes to prevent XSS.
+* (T85855) SECURITY: Don't execute another user's CSS or JS on preview.
+* (T64685) SECURITY: Allow setting maximal password length to prevent DoS when
+  using PBKDF2.
+* (T85349, T85850, T86711) SECURITY: Multiple issues fixed in SVG filtering to
+  prevent XSS and protect viewer's privacy.
+* Fix case of SpecialAllPages/SpecialAllMessages in SpecialPageFactory to fix
+  loading these special pages when $wgAutoloadAttemptLowercase is false.
+* (bug T70087) Fix Special:ActiveUsers page for installations using
+  PostgreSQL.
+* (bug T76254) Fix deleting of pages with PostgreSQL. Requires a schema change
+  and running update.php to fix.
+
+== MediaWiki 1.24.1 ==
+
+This is a security and maintenance release of the MediaWiki 1.24 branch.
+
+== Changes since 1.24.0 ==
+
+* (bug T76686) [SECURITY] thumb.php outputs wikitext message as raw HTML, which
+  could lead to xss. Permission to edit MediaWiki namespace is required to
+  exploit this.
+* (bug T77028) [SECURITY] Malicious site can bypass CORS restrictions in
+  $wgCrossSiteAJAXdomains in API calls if it only included an allowed domain as
+  part of its name.
+* (bug T74222) The original patch for T74222 was reverted as unnecessary.
+* Fixed a couple of entries in RELEASE-NOTES-1.24.
+* (bug T76168) OutputPage: Add accessors for some protected properties.
+* (bug T74834) Make 1.24 branch directly installable under PostgreSQL.
+
 === Configuration changes in 1.24 ===
 * MediaWiki will no longer run if register_globals is enabled. It has been
   deprecated for 5 years now, and was removed in PHP 5.4. For more information
@@ -1243,6 +1610,174 @@ of files that are no longer available follows.
 
 == MediaWiki 1.23 ==
 
+== MediaWiki 1.23.11 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+== Changes since 1.23.10 ==
+
+* (T91850) SECURITY: Add throttle check in ApiUpload and SpecialUpload
+* (T91203, T91205) SECURITY: API: Improve validation in chunked uploading
+* (T108616) SECURITY: Avoid exposure of local path in PNG thumbnails
+
+== MediaWiki 1.23.10 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+== Changes since 1.23.9 ==
+
+* (T94116) SECURITY: Compare API watchlist token in constant time
+* (T97391) SECURITY: Escape error message strings in thumb.php
+* (T106893) SECURITY: Don't leak autoblocked IP addresses on
+  Special:DeletedContributions
+* (bug 67644) Make AutoLoaderTest handle namespaces
+* (T91653) Minimal PSR-3 debug logger to support backports from 1.25+.
+* (T102562) Fix InstantCommons parameters to handle the new HTTPS-only
+  policy of Wikimedia Commons.
+
+== MediaWiki 1.23.9 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+== Changes since 1.23.8 ==
+
+* (T85848, T71210) SECURITY: Don't parse XMP blocks that contain XML entities,
+  to prevent various DoS attacks.
+* (T85848) SECURITY: Don't allow directly calling Xml::isWellFormed, to reduce
+  likelihood of DoS.
+* (T88310) SECURITY: Always expand xml entities when checking SVG's.
+* (T73394) SECURITY: Escape > in Html::expandAttributes to prevent XSS.
+* (T85855) SECURITY: Don't execute another user's CSS or JS on preview.
+* (T85349, T85850, T86711) SECURITY: Multiple issues fixed in SVG filtering to
+  prevent XSS and protect viewer's privacy.
+* (bug T68650) Fix indexing of moved pages with PostgreSQL. Requires running
+  update.php to fix.
+* (bug T70087) Fix Special:ActiveUsers page for installations using 
+  PostgreSQL.
+
+== MediaWiki 1.23.8 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+== Changes since 1.23.7 ==
+
+* (bug T76686) [SECURITY] thumb.php outputs wikitext message as raw HTML, which
+  could lead to xss. Permission to edit MediaWiki namespace is required to
+  exploit this.
+* (bug T77028) [SECURITY] Malicious site can bypass CORS restrictions in
+  $wgCrossSiteAJAXdomains in API calls if it only included an allowed domain as
+  part of its name.
+* (bug T74222) The original patch for T74222 was reverted as unnecessary.
+
+== MediaWiki 1.23.7 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+== Changes since 1.23.6 ==
+
+* (bugs 66776, 71478) SECURITY:  User PleaseStand reported a way to inject code
+  into API clients that used format=php to process pages that underwent flash
+  policy mangling. This was fixed along with improving how the mangling was done
+  for format=json, and allowing sites to disable the mangling using
+  $wgMangleFlashPolicy.
+* (bug 70901) SECURITY: User Jackmcbarn reported that the ability to update
+  the content model for a page could allow an unprivileged attacker to edit
+  another user's common.js under certain circumstances. The user right
+  "editcontentmodel" was added, and is needed to change a revision's content
+  model.
+* (bug 71111) SECURITY: User PleaseStand reported that on wikis that allow raw
+  HTML, it is not safe to preview wikitext coming from an untrusted source such
+  as a cross-site request. Thus add an edit token to the form, and when raw HTML
+  is allowed, ensure the token is provided before showing the preview. This
+  check is not performed on wikis that both allow raw HTML and anonymous
+  editing, since there are easier ways to exploit that scenario.
+* (bug 72222) SECURITY: Do not show log action when the entry is revdeleted with
+  DELETED_ACTION. NOTICE: this may be reverted in a future release pending a
+  public RFC about the desired functionality. This issue was reported by user
+  Bawolff.
+* (bug 71621) Make allowing site-wide styles on restricted special pages a
+  config option.
+* (bug 42723) Added updated version history from 1.19.2 to 1.22.13
+* $wgMangleFlashPolicy was added to make MediaWiki's mangling of anything that
+  might be a flash policy directive configurable.
+
+== MediaWiki 1.23.6 ==
+
+This is a maintenance release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.5 ===
+* (Bug 72274) Job queue not running (HTTP 411) due to missing
+  Content-Length: header
+* (Bug 67440) Allow classes to be registered properly from installer
+
+== MediaWiki 1.23.5 ==
+
+This is a security release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.4 ===
+* (bug 70672) SECURITY: OutputPage: Remove separation of css and js module
+  allowance.
+
+== MediaWiki 1.23.4 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.3 ===
+
+* (bug 69008) SECURITY: Enhance CSS filtering in SVG files. Filter <style>
+  elements; normalize style elements and attributes before filtering; add
+  checks for attributes that contain css; add unit tests for html5sec and
+  reported bugs.
+* (bug 65998) Make MySQLi work with non-standard socket.
+* (bug 66986) GlobalVarConfig shouldn't throw exceptions for null-valued config
+  settings.
+
+== MediaWiki 1.23.3 ==
+
+This is a maintenance release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.2 ===
+
+* (bug 68501) Correctly handle incorrect namespace in cleanupTitles.php.
+* (bug 64970) Fix support for blobs on DatabaseOracle::update.
+* (bug 66574) Display MediaWiki:Loginprompt on the login page.
+* (bug 67870) wfShellExec() cuts off stdout at multiples of 8192 bytes.
+* (bug 60629) Handle invalid language code gracefully in
+  Language::fetchLanguageNames.
+* (bug 62017) Restore the number of rows shown on Special:Watchlist.
+* Check for boolean false result from database query in SqlBagOStuff.
+
+== MediaWiki 1.23.2 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.1 ===
+
+* (bug 68187) SECURITY: Prepend jsonp callback with comment.
+* (bug 66608) SECURITY: Fix for XSS issue in bug 66608: Generate the URL used
+  for loading a new page in Javascript,instead of relying on the URL in the link
+  that has been clicked.
+* (bug 65778) SECURITY: Copy prevent-clickjacking between OutputPage and
+  ParserOutput.
+* (bug 68313) Preferences: Turn stubthreshold back into a combo box.
+* (bug 65214) Fix initSiteStats.php maintenance script.
+* (bug 67594) Special:ActiveUsers: Fix to work with PostgreSQL.
+
+== MediaWiki 1.23.1 ==
+
+This is a security and maintenance release of the MediaWiki 1.23 branch.
+
+=== Changes since 1.23.0 ===
+
+* (bug 65839) SECURITY: Prevent external resources in SVG files.
+* (bug 67025) Special:Watchlist: Don't try to render empty row.
+* (bug 66922) Don't allow some E_NOTICE messages to end up in the LocalSettings.php.
+* (bug 66467) FileBackend: Avoid using popen() when "parallelize" is disabled.
+* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects
+  like only extracting the tail of the file partially or not at all.
+* (bug 66182) Removed -x flag on some php files.
+
+
 === Configuration changes in 1.23 ===
 * (bug 13250) Restored method for clearing a watchlist in web UI
   so that users with large watchlists don't have to perform
@@ -1712,6 +2247,44 @@ changes to languages because of Bugzilla reports.
 
 == MediaWiki 1.22 ==
 
+== MediaWiki 1.22.15 ==
+
+This is a security and maintenance release of the MediaWiki 1.22 branch.
+
+=== Changes since 1.22.14 ===
+
+* (bug T76686) [SECURITY] thumb.php outputs wikitext message as raw HTML, which
+  could lead to xss. Permission to edit MediaWiki namespace is required to
+  exploit this.
+* (bug T77028) [SECURITY] Malicious site can bypass CORS restrictions in
+  $wgCrossSiteAJAXdomains in API calls if it only included an allowed domain as
+  part of its name.
+* (bug T74222) The original patch for T74222 was reverted as unnecessary.
+
+== MediaWiki 1.22.14 ==
+
+This is a security and maintenance release of the MediaWiki 1.22 branch.
+
+=== Changes since 1.22.13 ===
+
+* (bugs 66776, 71478) SECURITY:  User PleaseStand reported a way to inject code
+  into API clients that used format=php to process pages that underwent flash
+  policy mangling. This was fixed along with improving how the mangling was done
+  for format=json, and allowing sites to disable the mangling using
+  $wgMangleFlashPolicy.
+* (bug 70901) SECURITY: User Jackmcbarn reported that the ability to update
+  the content model for a page could allow an unprivileged attacker to edit
+  another user's common.js under certain circumstances. The user right
+  "editcontentmodel" was added, and is needed to change a revision's content
+  model.
+* (bug 72222) SECURITY: Do not show log action when the entry is revdeleted with
+  DELETED_ACTION. NOTICE: this may be reverted in a future release pending a
+  public RFC about the desired functionality. This issue was reported by user
+  Bawolff.
+* (bug 71621) Make allowing site-wide styles on restricted special pages a
+  config option.
+* $wgMangleFlashPolicy was added to make MediaWiki's mangling of anything that
+  might be a flash policy directive configurable.
 
 == MediaWiki 1.22.13 ==
 This is a maintenance release of the MediaWiki 1.22 branch.
diff --git a/RELEASE-NOTES-1.26 b/RELEASE-NOTES-1.26
deleted file mode 100644 (file)
index ac2f947..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-Security reminder: If you have PHP's register_globals option set, you must
-turn it off. MediaWiki will not work with it enabled.
-
-== MediaWiki 1.26 ==
-
-THIS IS NOT A RELEASE YET
-
-MediaWiki 1.26 is an alpha-quality branch and is not recommended for use in
-production.
-
-=== Configuration changes in 1.26 ===
-* $wgPasswordResetRoutes['email'] = true by default.
-* $wgEnableParserCache was deprecated, set $wgParserCacheType to CACHE_NONE
-  instead if you want to disable the parser cache.
-* New-style continuation is now the default for API action=continue. Clients may
-  use the 'rawcontinue' parameter to receive raw query-continue data, but the
-  new style is encouraged as it's harder to implement incorrectly.
-* Deprecated API formats dump and wddx have been completely removed.
-* (T7645) The "Signature" button on the edit toolbar is now hidden by default
-  in non-talk namespaces. A new configuration variable,
-  $wgExtraSignatureNamespaces, controls in which subject (non-talk) namespaces
-  the "Signature" button on the edit toolbar will be displayed.
-* $wgResourceLoaderUseESI was deprecated and removed. This was an experimental
-  feature that was never enabled by default.
-* $wgResourceLoaderExperimentalAsyncLoading was deprecated and removed.
-  This experimental feature was never enabled by default and is obsolete as of
-  MediaWiki 1.26, in where ResourceLoader became fully asynchronous.
-* $wgMasterWaitTimeout was removed (deprecated in 1.24).
-* Fields in ParserOptions are now private. Use the accessors instead.
-* Custom LESS functions (defined via $wgResourceLoaderLESSFunctions or
-  in extension.json) have been removed, after being deprecated in 1.24.
-* $wgAlwaysUseTidy has been removed.
-* ResetSessionID hook has been removed. Nothing seems to use it.
-* Certain AuthPlugin methods are deprecated in favor of new hooks:
-** AuthPlugin::initUser() is replaced by LocalUserCreated.
-** AuthPlugin::updateUser() is replaced by UserLoggedIn.
-** AuthPlugin::updateExternalDB() is replaced by the existing UserSaveSettings.
-** AuthPlugin::updateExternalDBGroups() is replaced by UserGroupsChanged.
-** AuthPluginUser::isHidden() is replaced by UserIsHidden.
-** AuthPluginUser::isLocked() is replaced by UserIsLocked.
-* The UserRights hook is deprecated in favor of the new UserGroupsChanged hook.
-* AuthPlugin::initUser() and AuthPlugin::updateUser() should no longer replace
-  the passed User object.
-* $wgBlockAllowsUTEdit is now set to true by default. This allows
-  blocked users to edit their talk pages unless explicitly disabled
-  when they are being blocked.
-
-=== New features in 1.26 ===
-* (T51506) Now action=info gives estimates of actual watchers for a page.
-  See $wgRCMaxAge, $wgWatchersMaxAge and $wgUnwatchedPageSecret
-  to learn how to configure if needed.
-* Change tags can now be hidden in the interface by disabling the associated
-  "tag-<id>" interface message.
-* ':' (colon) is now invalid in usernames for new accounts. Existing accounts
-  are not affected.
-* Added a new hook, 'LogException', to log exceptions in nonstandard ways.
-* Revive the 'SpecialSearchResultsAppend' hook which occurs after the list of
-  search results are rendered. The initial use case is to append a "give us
-  feedback" link beneath the search results.
-* Added a new hook, 'RejectParserCacheValue', which allows extensions to
-  reject an otherwise-successful parser cache lookup. The intent is to allow
-  extensions to manage the eviction of archaic HTML output from the cache.
-* (T68699) The expiration of the UserID and Token login cookies
-  ($wgExtendedLoginCookieExpiration) can be configured independently of the
-  expiration of all other cookies ($wgCookieExpiration).
-* (T50519) Support for generating JPEG/PNG thumbnails from WebP images added
-  if ImageMagick is used as image scaler ($wgUseImageMagick = true). Uploading
-  of WebP images still disabled by default. Add $wgFileExtensions[] =
-  'webp'; to LocalSettings.php to enable uploading of WebP images.
-* Added new hooks 'EnhancedChangesListModifyLineData' &
-  'EnhancedChangesListModifyBlockLineData', to modify the data used to build
-  lines in enhanced recentchanges and watchlist.
-* Caches that need purging ability now use the WANObjectCache interface.
-  This corresponds to a new $wgMainWANCache setting, which defaults to using
-  the $wgMainCacheType settings.
-* Callers needing fast light-weight data stores use $wgMainStash to select
-  the store type from $wgObjectCaches. The default is the local database.
-* Interface message overrides in the MediaWiki namespace will now be cached in
-  memcached and APC (if available), rather than memcached and local files.
-* Added a new hook, 'RandomPageQuery', to allow modification of the query used
-  by Special:Random to select random pages.
-* $wgTransactionalTimeLimit was added, which controls the request time limit
-  for potentially slow POST requests that need to be as atomic as possible.
-* ResourceLoader now loads all scripts asynchronously. The top-queue and
-  startup modules are no longer synchronously loaded.
-* 'mediawiki.ui.button' styles are no longer unconditionally loaded on every
-  page. During the deprecation period, the styles will only be loaded on pages
-  which contain 'mw-ui-button' in their HTML. Starting in 1.28, the styles will
-  only be loaded if explicitly required.
-* If search returns zero results and current search engine has a "did you mean"
-  suggestion, results for suggestion will be shown. Can be disabled by setting
-  $wgSearchRunSuggestedQuery to false.
-* Added several JavaScript libraries for uploading files to MediaWiki
-  from the client-side. See documentation for mw.Upload and its
-  subclasses for more information.
-* Added OOUI dialogs and layout for file upload interfaces. See
-  documentation for mw.Upload.Dialog, mw.Upload.BookletLayout and its
-  subclasses for more information.
-
-== extension.json changes in 1.26 ==
-* (T99344) The extension.json schema is now versioned. All extensions
-  and skins should set a "manifest_version" property corresponding to
-  the schema version they were written for. The only supported version
-  currently is "1".
-* (T102523) The error message if a non-array attribute is set was improved.
-* (T107646) Configuration settings can now specify how they should be merged,
-  which is necessary for arrays using integer keys.
-* (T110389) Adding namespaces through extension.json now actually works
-* $wgNamespaceProtection can now be set in extension.json.
-* $wgCapitalLinkOverrides can now be set in extension.json.
-* (T97186) Extensions using a custom prefix for their configuration settings
-  can now set a "_prefix" key to override the default of "wg".
-* (T99084) Extensions can now specify what MediaWiki core versions they
-  depend upon.
-* (T105236) The extension.json schema now validates custom classes in
-  the "ResourceModules" property properly.
-
-=== External library changes in 1.26 ===
-==== Upgraded external libraries ====
-* Updated es5-shim from v4.0.0 to v4.1.5.
-* Updated json2 from revision 2014-02-04 to 2015-05-03.
-* Updated Sinon.JS from 1.10.3 to 1.15.4.
-* Updated jQuery Client from v1.0.0 to v2.0.0.
-* Updated QUnit from v1.17.1 to v1.18.0.
-* Updated liuggio/statsd-php-client from v1.0.12 to v1.0.16.
-* Updated oojs/oojs-ui from v0.11.3 to v0.12.12.
-* Updated wikimedia/cdb from v1.0.1 to v1.3.0.
-* Updated wikimedia/utfnormal from v1.0.2 to v1.0.3.
-* Updated wikimedia/composer-merge-plugin from v1.0.0 to v1.3.0.
-* Updated zordius/lightncandy from v0.18 to v0.21.
-
-==== New external libraries ====
-* Added composer/semver v1.0.0.
-* Added mediawiki/at-ease v1.1.0.
-* Added wikimedia/assert v0.2.2.
-* Added wikimedia/ip-set v1.0.1.
-* Added wikimedia/wrappedstring v2.0.0.
-
-==== Removed and replaced external libraries ====
-* Replaced leafo/lessphp v0.5.0 with oyejorge/less.php v1.7.0.9.
-
-=== Bug fixes in 1.26 ===
-* (T53283) load.php sometimes sends 304 response without full headers
-* (T65198) Talk page tabs now have a "rel=discussion" attribute
-* (T98841) {{msgnw:}} now preserves comments even when subst: is not used.
-* (T104142) $wgEmergencyContact and $wgPasswordSender now use their default
-  value if set to an empty string.
-
-=== Action API changes in 1.26 ===
-* New-style continuation is now the default for action=continue. Clients may
-  use the 'rawcontinue' parameter to receive raw query-continue data, but the
-  new style is encouraged as it's harder to implement incorrectly.
-* Deprecated API formats dump and wddx have been completely removed.
-* API action=query&list=tags: The displayname can now be boolean false if the
-  tag is meant to be hidden from user interfaces.
-* action=import no longer allows both the namespace= and rootpage= parameters
-  to be set. If they are both set, the value of rootpage= will be ignored.
-* prop=revision output in enum mode is now sorted by timestamp rather than
-  revision ID. This usually won't make any difference.
-* (T102645) Namespace list from meta=siteinfo&siprop=namespaces is now an array
-  with formatversion=2.
-* Various other output from meta=siteinfo will now always be arrays instead of
-  sometimes being numerically-indexed objects with formatversion=2.
-* When errors about users being blocked are returned, they now include
-  information about the relevant block.
-* (T99926) list=random has higher limits, in line with other API modules.
-* list=random's rnredirect parameter is deprecated in favor of a new
-  rnfilterredir parameter that also allows for listing both redirects and
-  non-redirects.
-* list=random now supports continuation.
-* API responses to GET requests may now include ETag and Last-Modified headers,
-  and will honor corresponding If-None-Match and If-Modified-Since on such
-  requests.
-
-=== Action API internal changes in 1.26 ===
-* New metadata item ApiResult::META_KVP_MERGE to allow for merging the KVP key
-  into the value when the value is an assoc.
-* API action modules may now provide values for the RFC 7232 ETag and
-  Last-Modified headers. The API will check these against If-None-Match and
-  If-Modified-Since request headers on GET requests and avoid executing the
-  module when appropriate.
-
-=== Languages updated in 1.26 ===
-
-MediaWiki supports over 350 languages. Many localisations are updated
-regularly. Below only new and removed languages are listed, as well as
-changes to languages because of Phabricator reports.
-
-* Languages added:
-** ase (American sign language), thanks to translator Icemandeaf
-** dty (डोटेली/Doteli), thanks to translators जनक राज भट्ट, बिप्लब आनन्द,
-   मेश सिंह बोहरा, and राम प्रसाद जोशी
-** luz (لئری دوٙمینی / Southern Luri)
-** olo (Livvinкarjala / Livvi-Karelian), thanks to translators Denö, Hiloin Natoi,
-   Ilja.mos, and Mashoi7
-
-=== Other changes in 1.26 ===
-* ChangeTags::tagDescription() will return false if the interface message
-  for the tag is disabled.
-* Added PageHistoryPager::doBatchLookups hook.
-* Added $wikiId parameter to FormatAutocomments hook.
-* Added ParserCacheSaveComplete to ParserCache
-* supportsDirectEditing and supportsDirectApiEditing methods added to
-  ContentHandler, to provide a way for ApiEditPage and EditPage to check
-  if direct editing of content is allowed. These methods return false,
-  by default for the ContentHandler base class and true for TextContentHandler
-  and it's derivative classes (everything in core). For Content types that
-  do not support direct editing, an alternative mechanism should be provided
-  for editing, such as action overrides or specific api modules.
-* mediaWiki.confirmCloseWindow now returns an object of functions, instead of
-  one function. The callback can't be called directly any more. The callback
-  function is replaced with confirmCloseWindow.release().
-* BREAKING CHANGE: Added an optional ResouceLoaderContext parameter to
-  ResourceLoaderModule::getDependencies(). Extension classes that override that
-  method should be updated. If they aren't updated, PHP Strict standards
-  warnings will appear when E_STRICT error reporting is enabled. Note: in the
-  near future, this parameter will probably become non-optional.
-* Removed maintenance script deleteImageMemcached.php.
-* MWFunction::newObj() was removed (deprecated in 1.25).
-  ObjectFactory::getObjectFromSpec() should be used instead.
-* The parser will no longer randomize the string it uses to mark the place of
-  items that were stripped during parsing. It will use a fixed string instead.
-  This causes the parser to re-use the regular expressions it uses to search
-  and replace markers rather than generate novel expressions on each parse.
-  Re-using regular expressions will improve performance on HHVM and the
-  forthcoming PHP 7. The interfaces changes accompanying this change are:
-  - Parser::getRandomString() and Parser::uniqPrefix() have been deprecated.
-  - The $uniq_prefix argument for Parser::extractTagsAndParams() and the
-    $prefix argument for StripState::_construct() are deprecated and their
-    value is ignored.
-* wfSuppressWarnings() and wfRestoreWarnings() were split into a separate library,
-  mediawiki/at-ease, and are now deprecated. Callers should use
-  MediaWiki\suppressWarnings() and MediaWiki\restoreWarnings() directly.
-* The Block class constructor now takes an associative array of parameters
-  instead of many optional positional arguments. Calling the constructor the old
-  way will issue a deprecation warning.
-* The jquery.mwExtension module was deprecated.
-* $wgSpecialPageGroups was removed (deprecated in 1.21).
-* SpecialPageFactory::setGroup was removed (deprecated in 1.21).
-* SpecialPageFactory::getGroup was removed (deprecated in 1.21).
-* DatabaseBase::ignoreErrors() is now protected.
-* BREAKING CHANGE: mediawiki.legacy.ajax has been removed, following
-  a lengthy deprecation period.
-* The ScopedPHPTimeout class was removed.
-* Removed maintenance script fixSlaveDesync.php.
-* Watchlist tokens, SpecialResetTokens, and User::getTokenFromOption()
-  are deprecated. Applications using those can work via the OAuth
-  extension instead. New tokens types should not be added.
-* DatabaseBase::errorCount() was removed (unused).
-* $wgDeferredUpdateList was removed.
-* DeferredUpdates::addHTMLCacheUpdate() was removed.
-
-== Compatibility ==
-
-MediaWiki 1.26 requires PHP 5.3.3 or later. There is experimental support for
-HHVM 3.3.0.
-
-MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
-support for them is somewhat less mature. There is experimental support for
-Oracle and Microsoft SQL Server.
-
-The supported versions are:
-
-* MySQL 5.0.3 or later
-* PostgreSQL 8.3 or later
-* SQLite 3.3.7 or later
-* Oracle 9.0.1 or later
-* Microsoft SQL Server 2005 (9.00.1399)
-
-== Upgrading ==
-
-1.26 has several database changes since 1.25, and will not work without schema
-updates. Note that due to changes to some very large tables like the revision
-table, the schema update may take quite long (minutes on a medium sized site,
-many hours on a large site).
-
-If upgrading from before 1.11, and you are using a wiki as a commons
-repository, make sure that it is updated as well. Otherwise, errors may arise
-due to database schema changes.
-
-If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
-new database fields are filled with data.
-
-If you are upgrading from MediaWiki 1.4.x or earlier, you should upgrade to
-1.5 first. The upgrade script maintenance/upgrade1_5.php has been removed
-with MediaWiki 1.21.
-
-Don't forget to always back up your database before upgrading!
-
-See the file UPGRADE for more detailed upgrade instructions.
-
-For notes on 1.25.x and older releases, see HISTORY.
-
-== Online documentation ==
-
-Documentation for both end-users and site administrators is available on
-MediaWiki.org, and is covered under the GNU Free Documentation License (except
-for pages that explicitly state that their contents are in the public domain):
-
-       https://www.mediawiki.org/wiki/Documentation
-
-== Mailing list ==
-
-A mailing list is available for MediaWiki user support and discussion:
-
-       https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
-
-A low-traffic announcements-only list is also available:
-
-       https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
-
-It's highly recommended that you sign up for one of these lists if you're
-going to run a public MediaWiki, so you can be notified of security fixes.
-
-== IRC help ==
-
-There's usually someone online in #mediawiki on irc.freenode.net.
index 262bbbc..ab136b1 100644 (file)
@@ -54,6 +54,13 @@ production.
 * $wgRateLimitLog was removed; use $wgDebugLogGroups['ratelimit'] instead.
 * Deprecated API formats dbg, txt, and yaml have been removed.
 * CLDRPluralRule* classes have been replaced with wikimedia/cldr-plural-rule-parser.
+* Removed $wgProfilePerHost, $wgUDPProfilerHost, $wgUDPProfilerPort,
+  $wgUDPProfilerFormatString, $wgStatsMethod, $wgAggregateStatsID, $wgStatsFormatString,
+  and $wgProfileCallTree (deprecated since 1.20).
+* For proper operation of LocalIdLookup with shared user tables, ensure that
+  $wgSharedDB and $wgSharedTables are properly set even on the "central" wiki
+  that all others are sharing from and that $wgLocalDatabases is set to the
+  full list of sharing wikis on all those wikis.
 
 === New features in 1.27 ===
 * $wgDataCenterId and $wgDataCenterRoles where added, which will serve as
@@ -84,6 +91,14 @@ production.
 * Added MWTimestamp::getTimezoneString() which returns the localized timezone
   string, if available. To localize this string, see the comments of
   $wgLocaltimezone in includes/DefaultSettings.php.
+* Added CentralIdLookup, a service that allows extensions needing a concept of
+  "central" users to get that without having to know about specific central
+  authentication extensions.
+* $wgMaxUserDBWriteDuration added to limit huge user-generated transactions.
+  Regular web request transactions that takes longer than this are aborted.
+* Added a new hook, 'TitleMoveCompleting', which runs before a page move is committed.
+* $wgCdnReboundPurgeDelay was added to provide secondary delayed purges of URLs
+  from CDN to mitigate DB replication lag and WAN cache purge lag.
 
 === External library changes in 1.27 ===
 ==== Upgraded external libraries ====
@@ -157,6 +172,8 @@ changes to languages because of Phabricator reports.
 * ResourceLoader::getLessCompiler() now takes an optional parameter of
   additional LESS variables to set for the compiler.
 * wfBaseConvert() marked as deprecated, use Wikimedia\base_convert() directly instead.
+* Obsolete maintenance scripts clearCacheStats.php and showCacheStats.php
+  were removed. The underlying data is sent to StatsD (see $wgStatsdServer).
 
 == Compatibility ==
 
index 2844dc7..dea31ab 100644 (file)
@@ -164,8 +164,8 @@ $wgAutoloadLocalClasses = array(
        'BenchIfSwitch' => __DIR__ . '/maintenance/benchmarks/bench_if_switch.php',
        'BenchStrtrStrReplace' => __DIR__ . '/maintenance/benchmarks/bench_strtr_str_replace.php',
        'BenchUtf8TitleCheck' => __DIR__ . '/maintenance/benchmarks/bench_utf8_title_check.php',
-       'BenchWikimediaBaseConvert' => __DIR__ . '/maintenance/benchmarks/bench_Wikimedia_base_convert.php',
        'BenchWfIsWindows' => __DIR__ . '/maintenance/benchmarks/bench_wfIsWindows.php',
+       'BenchWikimediaBaseConvert' => __DIR__ . '/maintenance/benchmarks/bench_Wikimedia_base_convert.php',
        'BenchmarkDeleteTruncate' => __DIR__ . '/maintenance/benchmarks/bench_delete_truncate.php',
        'BenchmarkHooks' => __DIR__ . '/maintenance/benchmarks/benchmarkHooks.php',
        'BenchmarkParse' => __DIR__ . '/maintenance/benchmarks/benchmarkParse.php',
@@ -192,12 +192,16 @@ $wgAutoloadLocalClasses = array(
        'Category' => __DIR__ . '/includes/Category.php',
        'CategoryFinder' => __DIR__ . '/includes/CategoryFinder.php',
        'CategoryMembershipChange' => __DIR__ . '/includes/changes/CategoryMembershipChange.php',
+       'CategoryMembershipChangeJob' => __DIR__ . '/includes/jobqueue/jobs/CategoryMembershipChangeJob.php',
        'CategoryPage' => __DIR__ . '/includes/page/CategoryPage.php',
        'CategoryPager' => __DIR__ . '/includes/specials/SpecialCategories.php',
        'CategoryViewer' => __DIR__ . '/includes/CategoryViewer.php',
        'CdbException' => __DIR__ . '/includes/compat/CdbCompat.php',
        'CdbReader' => __DIR__ . '/includes/compat/CdbCompat.php',
        'CdbWriter' => __DIR__ . '/includes/compat/CdbCompat.php',
+       'CdnCacheUpdate' => __DIR__ . '/includes/deferred/CdnCacheUpdate.php',
+       'CdnPurgeJob' => __DIR__ . '/includes/jobqueue/jobs/CdnPurgeJob.php',
+       'CentralIdLookup' => __DIR__ . '/includes/user/CentralIdLookup.php',
        'CgzCopyTransaction' => __DIR__ . '/maintenance/storage/recompressTracked.php',
        'ChangePassword' => __DIR__ . '/maintenance/changePassword.php',
        'ChangeTags' => __DIR__ . '/includes/changetags/ChangeTags.php',
@@ -226,7 +230,6 @@ $wgAutoloadLocalClasses = array(
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
        'CleanupRemovedModules' => __DIR__ . '/maintenance/cleanupRemovedModules.php',
        'CleanupSpam' => __DIR__ . '/maintenance/cleanupSpam.php',
-       'ClearCacheStats' => __DIR__ . '/maintenance/clearCacheStats.php',
        'ClearInterwikiCache' => __DIR__ . '/maintenance/clearInterwikiCache.php',
        'CliInstaller' => __DIR__ . '/includes/installer/CliInstaller.php',
        'CloneDatabase' => __DIR__ . '/includes/db/CloneDatabase.php',
@@ -287,6 +290,7 @@ $wgAutoloadLocalClasses = array(
        'DBQueryError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBReadOnlyError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBSiteStore' => __DIR__ . '/includes/site/DBSiteStore.php',
+       'DBTransactionError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBUnexpectedError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DataUpdate' => __DIR__ . '/includes/deferred/DataUpdate.php',
        'Database' => __DIR__ . '/includes/db/Database.php',
@@ -305,7 +309,7 @@ $wgAutoloadLocalClasses = array(
        'DateFormats' => __DIR__ . '/maintenance/language/date-formats.php',
        'DateFormatter' => __DIR__ . '/includes/parser/DateFormatter.php',
        'DeadendPagesPage' => __DIR__ . '/includes/specials/SpecialDeadendpages.php',
-       'DeferrableUpdate' => __DIR__ . '/includes/deferred/DeferredUpdates.php',
+       'DeferrableUpdate' => __DIR__ . '/includes/deferred/DeferrableUpdate.php',
        'DeferredStringifier' => __DIR__ . '/includes/libs/DeferredStringifier.php',
        'DeferredUpdates' => __DIR__ . '/includes/deferred/DeferredUpdates.php',
        'DeleteAction' => __DIR__ . '/includes/actions/DeleteAction.php',
@@ -469,6 +473,7 @@ $wgAutoloadLocalClasses = array(
        'GanConverter' => __DIR__ . '/languages/classes/LanguageGan.php',
        'GenderCache' => __DIR__ . '/includes/cache/GenderCache.php',
        'GenerateCollationData' => __DIR__ . '/maintenance/language/generateCollationData.php',
+       'GenerateCommonPassword' => __DIR__ . '/maintenance/createCommonPasswordCdb.php',
        'GenerateJsonI18n' => __DIR__ . '/maintenance/generateJsonI18n.php',
        'GenerateNormalizerDataAr' => __DIR__ . '/maintenance/language/generateNormalizerDataAr.php',
        'GenerateNormalizerDataMl' => __DIR__ . '/maintenance/language/generateNormalizerDataMl.php',
@@ -693,6 +698,7 @@ $wgAutoloadLocalClasses = array(
        'LocalFileDeleteBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
        'LocalFileMoveBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
        'LocalFileRestoreBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
+       'LocalIdLookup' => __DIR__ . '/includes/user/LocalIdLookup.php',
        'LocalRepo' => __DIR__ . '/includes/filerepo/LocalRepo.php',
        'LocalSettingsGenerator' => __DIR__ . '/includes/installer/LocalSettingsGenerator.php',
        'LocalisationCache' => __DIR__ . '/includes/cache/LocalisationCache.php',
@@ -719,7 +725,6 @@ $wgAutoloadLocalClasses = array(
        'MWDocGen' => __DIR__ . '/maintenance/mwdocgen.php',
        'MWException' => __DIR__ . '/includes/exception/MWException.php',
        'MWExceptionHandler' => __DIR__ . '/includes/exception/MWExceptionHandler.php',
-       'MWHookException' => __DIR__ . '/includes/Hooks.php',
        'MWHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
        'MWMemcached' => __DIR__ . '/includes/compat/MemcachedClientCompat.php',
        'MWMessagePack' => __DIR__ . '/includes/libs/MWMessagePack.php',
@@ -790,6 +795,7 @@ $wgAutoloadLocalClasses = array(
        'MergeHistoryPager' => __DIR__ . '/includes/specials/SpecialMergeHistory.php',
        'MergeLogFormatter' => __DIR__ . '/includes/logging/MergeLogFormatter.php',
        'MergeMessageFileList' => __DIR__ . '/maintenance/mergeMessageFileList.php',
+       'MergeableUpdate' => __DIR__ . '/includes/deferred/MergeableUpdate.php',
        'Message' => __DIR__ . '/includes/Message.php',
        'MessageBlobStore' => __DIR__ . '/includes/cache/MessageBlobStore.php',
        'MessageCache' => __DIR__ . '/includes/cache/MessageCache.php',
@@ -1086,6 +1092,7 @@ $wgAutoloadLocalClasses = array(
        'SearchDump' => __DIR__ . '/maintenance/dumpIterator.php',
        'SearchEngine' => __DIR__ . '/includes/search/SearchEngine.php',
        'SearchEngineDummy' => __DIR__ . '/includes/search/SearchEngine.php',
+       'SearchExactMatchRescorer' => __DIR__ . '/includes/search/SearchExactMatchRescorer.php',
        'SearchHighlighter' => __DIR__ . '/includes/search/SearchHighlighter.php',
        'SearchMssql' => __DIR__ . '/includes/search/SearchMssql.php',
        'SearchMySQL' => __DIR__ . '/includes/search/SearchMySQL.php',
@@ -1101,7 +1108,6 @@ $wgAutoloadLocalClasses = array(
        'SevenZipStream' => __DIR__ . '/maintenance/7zip.inc',
        'ShiConverter' => __DIR__ . '/languages/classes/LanguageShi.php',
        'ShortPagesPage' => __DIR__ . '/includes/specials/SpecialShortpages.php',
-       'ShowCacheStats' => __DIR__ . '/maintenance/showCacheStats.php',
        'ShowJobs' => __DIR__ . '/maintenance/showJobs.php',
        'ShowSiteStats' => __DIR__ . '/maintenance/showSiteStats.php',
        'Site' => __DIR__ . '/includes/site/Site.php',
@@ -1209,7 +1215,7 @@ $wgAutoloadLocalClasses = array(
        'SqliteUpdater' => __DIR__ . '/includes/installer/SqliteUpdater.php',
        'SquidPurgeClient' => __DIR__ . '/includes/clientpool/SquidPurgeClient.php',
        'SquidPurgeClientPool' => __DIR__ . '/includes/clientpool/SquidPurgeClientPool.php',
-       'SquidUpdate' => __DIR__ . '/includes/deferred/SquidUpdate.php',
+       'SquidUpdate' => __DIR__ . '/includes/deferred/CdnCacheUpdate.php',
        'SrConverter' => __DIR__ . '/languages/classes/LanguageSr.php',
        'StatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'Status' => __DIR__ . '/includes/Status.php',
@@ -1233,7 +1239,6 @@ $wgAutoloadLocalClasses = array(
        'SwiftVirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/SwiftVirtualRESTService.php',
        'SyncFileBackend' => __DIR__ . '/maintenance/syncFileBackend.php',
        'TableCleanup' => __DIR__ . '/maintenance/cleanupTable.inc',
-       'TableCleanupTest' => __DIR__ . '/maintenance/cleanupTable.inc',
        'TableDiffFormatter' => __DIR__ . '/includes/diff/TableDiffFormatter.php',
        'TablePager' => __DIR__ . '/includes/pager/TablePager.php',
        'TagLogFormatter' => __DIR__ . '/includes/logging/TagLogFormatter.php',
@@ -1320,9 +1325,9 @@ $wgAutoloadLocalClasses = array(
        'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UppercaseCollation' => __DIR__ . '/includes/Collation.php',
        'UsageException' => __DIR__ . '/includes/api/ApiMain.php',
-       'User' => __DIR__ . '/includes/User.php',
-       'UserArray' => __DIR__ . '/includes/UserArray.php',
-       'UserArrayFromResult' => __DIR__ . '/includes/UserArrayFromResult.php',
+       'User' => __DIR__ . '/includes/user/User.php',
+       'UserArray' => __DIR__ . '/includes/user/UserArray.php',
+       'UserArrayFromResult' => __DIR__ . '/includes/user/UserArrayFromResult.php',
        'UserBlockedError' => __DIR__ . '/includes/exception/UserBlockedError.php',
        'UserCache' => __DIR__ . '/includes/cache/UserCache.php',
        'UserDupes' => __DIR__ . '/maintenance/userDupes.inc',
@@ -1330,7 +1335,7 @@ $wgAutoloadLocalClasses = array(
        'UserNotLoggedIn' => __DIR__ . '/includes/exception/UserNotLoggedIn.php',
        'UserOptions' => __DIR__ . '/maintenance/userOptions.inc',
        'UserPasswordPolicy' => __DIR__ . '/includes/password/UserPasswordPolicy.php',
-       'UserRightsProxy' => __DIR__ . '/includes/UserRightsProxy.php',
+       'UserRightsProxy' => __DIR__ . '/includes/user/UserRightsProxy.php',
        'UsercreateTemplate' => __DIR__ . '/includes/templates/Usercreate.php',
        'UserloginTemplate' => __DIR__ . '/includes/templates/Userlogin.php',
        'UserrightsPage' => __DIR__ . '/includes/specials/SpecialUserrights.php',
index 0f8da12..e0cece5 100644 (file)
@@ -21,7 +21,7 @@
                "ext-iconv": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.14.0",
+               "oojs/oojs-ui": "0.14.1",
                "oyejorge/less.php": "1.7.0.9",
                "php": ">=5.3.3",
                "psr/log": "1.0.0",
index dde4fa1..b635467 100644 (file)
                        },
                        "patternProperties": {
                                "^[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*$": {
-                                       "type": ["object", "array", "string", "integer", "null", "boolean"],
                                        "properties": {
                                                "_merge_strategy": {
                                                        "type": "string",
index 7c79e72..c65cdb6 100644 (file)
@@ -1686,9 +1686,9 @@ $rc: RecentChange object that triggered url generation
 'IsFileCacheable': Override the result of Article::isFileCacheable() (if true)
 &$article: article (object) being checked
 
-'IsTrustedProxy': Override the result of wfIsTrustedProxy()
+'IsTrustedProxy': Override the result of IP::isTrustedProxy()
 &$ip: IP being check
-&$result: Change this value to override the result of wfIsTrustedProxy()
+&$result: Change this value to override the result of IP::isTrustedProxy()
 
 'IsUploadAllowedFromUrl': Override the result of UploadFromUrl::isAllowedUrl()
 $url: URL used to upload from
@@ -3030,7 +3030,7 @@ $old: old title
 $nt: new title
 $user: user who does the move
 
-'TitleMoveComplete': After moving an article (title).
+'TitleMoveComplete': After moving an article (title), post-commit.
 &$old: old title
 &$nt: new title
 &$user: user who did the move
@@ -3038,6 +3038,14 @@ $pageid: database ID of the page that's been moved
 $redirid: database ID of the created redirect
 $reason: reason for the move
 
+'TitleMoveCompleting': After moving an article (title), pre-commit.
+$old: old title
+$nt: new title
+$user: user who did the move
+$pageid: database ID of the page that's been moved
+$redirid: database ID of the created redirect
+$reason: reason for the move
+
 'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to
 or override the quick permissions check.
 $title: The Title object being accessed
index ad2307f..55fa725 100644 (file)
@@ -232,14 +232,6 @@ Special:Recentchanges (feed):
        Special:Recentchanges?action=purge&feed=atom,
        but note need $wgGroupPermissions[...]['purge'] permission.
 
-Statistics:
-       controlled by: $wgStatsMethod
-       key: $wgDBname:stats:$key
-       ex: wikibd:stats:request_with_session
-       stores: counter for statistics (see maintenance/showCacheStats.php script)
-       expiry: none (?)
-       cleared by: maintenance/clearCacheStats.php script
-
 User:
        key: $wgDBname:user:id:$sId
        ex: wikidb:user:id:51
index 34bb65f..db989a4 100644 (file)
@@ -175,14 +175,14 @@ class AjaxResponse {
                }
 
                if ( $this->mCacheDuration ) {
-                       # If squid caches are configured, tell them to cache the response,
-                       # and tell the client to always check with the squid. Otherwise,
+                       # If CDN caches are configured, tell them to cache the response,
+                       # and tell the client to always check with the CDN. Otherwise,
                        # tell the client to use a cached copy, without a way to purge it.
 
                        if ( $this->mConfig->get( 'UseSquid' ) ) {
                                # Expect explicit purge of the proxy cache, but require end user agents
                                # to revalidate against the proxy on each visit.
-                               # Surrogate-Control controls our Squid, Cache-Control downstream caches
+                               # Surrogate-Control controls our CDN, Cache-Control downstream caches
 
                                if ( $this->mConfig->get( 'UseESI' ) ) {
                                        header( 'Surrogate-Control: max-age=' . $this->mCacheDuration . ', content="ESI/1.0"' );
index fa6f13a..f68c0ef 100644 (file)
@@ -2440,10 +2440,8 @@ $wgStyleVersion = '303';
 
 /**
  * This will cache static pages for non-logged-in users to reduce
- * database traffic on public sites.
- * Automatically sets $wgShowIPinHeader = false
- * ResourceLoader requests to default language and skins are cached
- * as well as single module requests.
+ * database traffic on public sites. ResourceLoader requests to default
+ * language and skins are cached as well as single module requests.
  */
 $wgUseFileCache = false;
 
@@ -2536,7 +2534,7 @@ $wgExtensionInfoMTime = false;
 /** @} */ # end of cache settings
 
 /************************************************************************//**
- * @name   HTTP proxy (Squid) settings
+ * @name   HTTP proxy (CDN) settings
  *
  * Many of these settings apply to any HTTP proxy used in front of MediaWiki,
  * although they are referred to as Squid settings for historical reasons.
@@ -2549,7 +2547,7 @@ $wgExtensionInfoMTime = false;
  */
 
 /**
- * Enable/disable Squid.
+ * Enable/disable CDN.
  * See https://www.mediawiki.org/wiki/Manual:Squid_caching
  */
 $wgUseSquid = false;
@@ -2577,7 +2575,7 @@ $wgUseKeyHeader = false;
 $wgVaryOnXFP = false;
 
 /**
- * Internal server name as known to Squid, if different.
+ * Internal server name as known to CDN, if different.
  *
  * @par Example:
  * @code
@@ -2589,7 +2587,7 @@ $wgInternalServer = false;
 /**
  * Cache TTL for the CDN sent as s-maxage (without ESI) or
  * Surrogate-Control (with ESI). Without ESI, you should strip
- * out s-maxage in the Squid config.
+ * out s-maxage in the CDN config.
  *
  * 18000 seconds = 5 hours, more cache hits with 2678400 = 31 days.
  */
@@ -2602,6 +2600,15 @@ $wgSquidMaxage = 18000;
  */
 $wgCdnMaxageLagged = 30;
 
+/**
+ * If set, any SquidPurge call on a URL or URLs will send a second purge no less than
+ * this many seconds later via the job queue. This requires delayed job support.
+ * This should be safely higher than the 'max lag' value in $wgLBFactoryConf.
+ *
+ * @since 1.27
+ */
+$wgCdnReboundPurgeDelay = 0;
+
 /**
  * Default maximum age for raw CSS/JS accesses
  *
@@ -3162,13 +3169,6 @@ $wgWellFormedXml = true;
  */
 $wgXhtmlNamespaces = array();
 
-/**
- * Show IP address, for non-logged in users. It's necessary to switch this off
- * for some forms of caching.
- * @warning Will disable file cache.
- */
-$wgShowIPinHeader = true;
-
 /**
  * Site notice shown at the top of each page
  *
@@ -4342,6 +4342,21 @@ $wgActiveUserDays = 30;
  * @{
  */
 
+/**
+ * Central ID lookup providers
+ * Key is the provider ID, value is a specification for ObjectFactory
+ * @since 1.27
+ */
+$wgCentralIdLookupProviders = array(
+       'local' => array( 'class' => 'LocalIdLookup' ),
+);
+
+/**
+ * Central ID lookup provider to use by default
+ * @var string
+ */
+$wgCentralIdLookupProvider = 'local';
+
 /**
  * Password policy for local wiki users. A user's effective policy
  * is the superset of all policy statements from the policies for the
@@ -4359,6 +4374,10 @@ $wgActiveUserDays = 30;
  *     - PasswordCannotMatchUsername - Password cannot match username to
  *     - PasswordCannotMatchBlacklist - Username/password combination cannot
  *             match a specific, hardcoded blacklist.
+ *     - PasswordCannotBePopular - Blacklist passwords which are known to be
+ *             commonly chosen. Set to integer n to ban the top n passwords.
+ *             If you want to ban all common passwords on file, use the
+ *             PHP_INT_MAX constant.
  * @since 1.26
  */
 $wgPasswordPolicy = array(
@@ -4367,11 +4386,13 @@ $wgPasswordPolicy = array(
                        'MinimalPasswordLength' => 8,
                        'MinimumPasswordLengthToLogin' => 1,
                        'PasswordCannotMatchUsername' => true,
+                       'PasswordCannotBePopular' => 25,
                ),
                'sysop' => array(
                        'MinimalPasswordLength' => 8,
                        'MinimumPasswordLengthToLogin' => 1,
                        'PasswordCannotMatchUsername' => true,
+                       'PasswordCannotBePopular' => 25,
                ),
                'bot' => array(
                        'MinimalPasswordLength' => 8,
@@ -4391,6 +4412,7 @@ $wgPasswordPolicy = array(
                'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
                'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
                'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
+               'PasswordCannotBePopular' => 'PasswordPolicyChecks::checkPopularPasswordBlacklist'
        ),
 );
 
@@ -4584,6 +4606,7 @@ $wgDefaultUserOptions = array(
        'watchlisthideown' => 0,
        'watchlisthidepatrolled' => 0,
        'watchlisthidecategorization' => 1,
+       'watchlistreloadautomatically' => 0,
        'watchmoves' => 0,
        'watchrollback' => 0,
        'wllimit' => 250,
@@ -5671,79 +5694,6 @@ $wgProfileLimit = 0.0;
  */
 $wgProfileOnly = false;
 
-/**
- * If true, print a raw call tree instead of per-function report
- */
-$wgProfileCallTree = false;
-
-/**
- * Should application server host be put into profiling table
- *
- * @deprecated set $wgProfiler['perhost'] = true instead
- */
-$wgProfilePerHost = null;
-
-/**
- * Host for UDP profiler.
- *
- * The host should be running a daemon which can be obtained from MediaWiki
- * Git at:
- * https://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile
- *
- * @deprecated set $wgProfiler['udphost'] instead
- */
-$wgUDPProfilerHost = null;
-
-/**
- * Port for UDP profiler.
- * @see $wgUDPProfilerHost
- *
- * @deprecated set $wgProfiler['udpport'] instead
- */
-$wgUDPProfilerPort = null;
-
-/**
- * Format string for the UDP profiler. The UDP profiler invokes sprintf() with
- * (profile id, count, cpu, cpu_sq, real, real_sq, entry name, memory) as
- * arguments. You can use sprintf's argument numbering/swapping capability to
- * repeat, re-order or omit fields.
- *
- * @see $wgStatsFormatString
- * @since 1.22
- *
- * @deprecated set $wgProfiler['udpformat'] instead
- */
-$wgUDPProfilerFormatString = null;
-
-/**
- * Destination for wfIncrStats() data...
- * 'cache' to go into the system cache, if enabled (memcached)
- * 'udp' to be sent to the UDP profiler (see $wgUDPProfilerHost)
- * false to disable
- */
-$wgStatsMethod = 'cache';
-
-/**
- * When $wgStatsMethod is 'udp', setting this to a string allows statistics to
- * be aggregated over more than one wiki. The string will be used in place of
- * the DB name in outgoing UDP packets. If this is set to false, the DB name
- * will be used.
- */
-$wgAggregateStatsID = false;
-
-/**
- * When $wgStatsMethod is 'udp', this variable specifies how stats should be
- * formatted. Its value should be a format string suitable for a sprintf()
- * invocation with (id, count, key) arguments, where 'id' is either
- * $wgAggregateStatsID or the DB name, 'count' is the value by which the metric
- * is being incremented, and 'key' is the metric name.
- *
- * @see $wgUDPProfilerFormatString
- * @see $wgAggregateStatsID
- * @since 1.22
- */
-$wgStatsFormatString = "stats/%s - %s 1 1 1 1 %s\n";
-
 /**
  * Destination of statsd metrics.
  *
@@ -5757,15 +5707,13 @@ $wgStatsFormatString = "stats/%s - %s 1 1 1 1 %s\n";
 $wgStatsdServer = false;
 
 /**
- * Prefix for metric names sent to wgStatsdServer.
- *
- * Defaults to "MediaWiki".
+ * Prefix for metric names sent to $wgStatsdServer.
  *
  * @see RequestContext::getStats
  * @see BufferingStatsdDataFactory
  * @since 1.25
  */
-$wgStatsdMetricPrefix = false;
+$wgStatsdMetricPrefix = 'MediaWiki';
 
 /**
  * InfoAction retrieves a list of transclusion links (both to and from).
@@ -6188,7 +6136,14 @@ $wgRCEngines = array(
 );
 
 /**
- * Treat category membership changes as a RecentChange
+ * Treat category membership changes as a RecentChange.
+ * Changes are mentioned in RC for page actions as follows:
+ *   - creation: pages created with categories are mentioned
+ *   - edit: category additions/removals to existing pages are mentioned
+ *   - move: nothing is mentioned (unless templates used depend on the title)
+ *   - deletion: nothing is mentioned
+ *   - undeletion: nothing is mentioned
+ *
  * @since 1.27
  */
 $wgRCWatchCategoryMembership = false;
@@ -6741,9 +6696,11 @@ $wgJobClasses = array(
        'PublishStashedFile' => 'PublishStashedFileJob',
        'ThumbnailRender' => 'ThumbnailRenderJob',
        'recentChangesUpdate' => 'RecentChangesUpdateJob',
-       'refreshLinksPrioritized' => 'RefreshLinksJob', // for cascading protection
-       'refreshLinksDynamic' => 'RefreshLinksJob', // for pages with dynamic content
+       'refreshLinksPrioritized' => 'RefreshLinksJob',
+       'refreshLinksDynamic' => 'RefreshLinksJob',
        'activityUpdateJob' => 'ActivityUpdateJob',
+       'categoryMembershipChange' => 'CategoryMembershipChangeJob',
+       'cdnPurge' => 'CdnPurgeJob',
        'enqueue' => 'EnqueueJob', // local queue for multi-DC setups
        'null' => 'NullJob'
 );
@@ -7776,6 +7733,28 @@ $wgVirtualRestConfig = array(
  */
 $wgSearchRunSuggestedQuery = true;
 
+/**
+ * Where popular password file is located.
+ *
+ * Default in core contains 50,000 most popular. This config
+ * allows you to change which file, in case you want to generate
+ * a password file with > 50000 entries in it.
+ *
+ * @see maintenance/createCommonPasswordCdb.php
+ * @since 1.27
+ * @var string path to file
+ */
+$wgPopularPasswordFile = __DIR__ . '/../serialized/commonpasswords.cdb';
+
+/*
+ * Max time (in seconds) a user-generated transaction can spend in writes.
+ * If exceeded, the transaction is rolled back with an error instead of being committed.
+ *
+ * @var int|bool Disabled if false
+ * @since 1.27
+ */
+$wgMaxUserDBWriteDuration = false;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 58936e0..47912cb 100644 (file)
@@ -1211,7 +1211,7 @@ class EditPage {
         * across a recoverable edit conflict, the ID of the newer revision to
         * which we have rebased this page.
         *
-        * @since 1.25
+        * @since 1.27
         * @return int Revision ID
         */
        public function getParentRevId() {
@@ -1849,7 +1849,7 @@ class EditPage {
                                                $this->page->getComment() == $this->newSectionSummary()
                                        ) {
                                                // Probably a duplicate submission of a new comment.
-                                               // This can happen when squid resends a request after
+                                               // This can happen when CDN resends a request after
                                                // a timeout but the first one actually went through.
                                                wfDebug( __METHOD__
                                                        . ": duplicate new section submission; trigger edit conflict!\n" );
index c1765e2..4a021ee 100644 (file)
@@ -153,7 +153,9 @@ class ForkController {
                wfGetLBFactory()->destroyInstance();
                FileBackendGroup::destroySingleton();
                LockManagerGroup::destroySingletons();
+               JobQueueGroup::destroySingletons();
                ObjectCache::clear();
+               RedisConnectionPool::destroySingletons();
                $wgMemc = null;
        }
 
index 43b936b..e30b371 100644 (file)
@@ -374,20 +374,22 @@ function wfObjectToArray( $objOrArray, $recursive = true ) {
  * not likely to give duplicate values for any realistic
  * number of articles.
  *
+ * @note This is designed for use in relation to Special:RandomPage
+ *       and the page_random database field.
+ *
  * @return string
  */
 function wfRandom() {
-       # The maximum random value is "only" 2^31-1, so get two random
-       # values to reduce the chance of dupes
+       // The maximum random value is "only" 2^31-1, so get two random
+       // values to reduce the chance of dupes
        $max = mt_getrandmax() + 1;
        $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12, '.', '' );
-
        return $rand;
 }
 
 /**
- * Get a random string containing a number of pseudo-random hex
- * characters.
+ * Get a random string containing a number of pseudo-random hex characters.
+ *
  * @note This is not secure, if you are trying to generate some sort
  *       of token please use MWCryptRand instead.
  *
@@ -458,12 +460,12 @@ function wfUrlencode( $s ) {
 }
 
 /**
- * This function takes two arrays as input, and returns a CGI-style string, e.g.
+ * This function takes one or two arrays as input, and returns a CGI-style string, e.g.
  * "days=7&limit=100". Options in the first array override options in the second.
  * Options set to null or false will not be output.
  *
  * @param array $array1 ( String|Array )
- * @param array $array2 ( String|Array )
+ * @param array|null $array2 ( String|Array )
  * @param string $prefix
  * @return string
  */
@@ -1049,7 +1051,6 @@ function wfDebug( $text, $dest = 'all', array $context = array() ) {
 
        $text = trim( $text );
 
-       // Inline logic from deprecated wfDebugTimer()
        if ( $wgDebugTimestamps ) {
                $context['seconds_elapsed'] = sprintf(
                        '%6.4f',
@@ -1092,26 +1093,6 @@ function wfIsDebugRawPage() {
        return $cache;
 }
 
-/**
- * Get microsecond timestamps for debug logs
- *
- * @deprecated since 1.25
- * @return string
- */
-function wfDebugTimer() {
-       global $wgDebugTimestamps, $wgRequestTime;
-
-       wfDeprecated( __METHOD__, '1.25' );
-
-       if ( !$wgDebugTimestamps ) {
-               return '';
-       }
-
-       $prefix = sprintf( "%6.4f", microtime( true ) - $wgRequestTime );
-       $mem = sprintf( "%5.1fM", ( memory_get_usage( true ) / ( 1024 * 1024 ) ) );
-       return "$prefix $mem  ";
-}
-
 /**
  * Send a line giving PHP memory usage.
  *
@@ -4091,46 +4072,6 @@ function wfIsInfinity( $str ) {
        return in_array( $str, $infinityValues );
 }
 
-/**
- * Work out the IP address based on various globals
- * For trusted proxies, use the XFF client IP (first of the chain)
- *
- * @deprecated since 1.19; call $wgRequest->getIP() directly.
- * @return string
- */
-function wfGetIP() {
-       wfDeprecated( __METHOD__, '1.19' );
-       global $wgRequest;
-       return $wgRequest->getIP();
-}
-
-/**
- * Checks if an IP is a trusted proxy provider.
- * Useful to tell if X-Forwarded-For data is possibly bogus.
- * Squid cache servers for the site are whitelisted.
- * @deprecated Since 1.24, use IP::isTrustedProxy()
- *
- * @param string $ip
- * @return bool
- */
-function wfIsTrustedProxy( $ip ) {
-       wfDeprecated( __METHOD__, '1.24' );
-       return IP::isTrustedProxy( $ip );
-}
-
-/**
- * Checks if an IP matches a proxy we've configured.
- * @deprecated Since 1.24, use IP::isConfiguredProxy()
- *
- * @param string $ip
- * @return bool
- * @since 1.23 Supports CIDR ranges in $wgSquidServersNoPurge
- */
-function wfIsConfiguredProxy( $ip ) {
-       wfDeprecated( __METHOD__, '1.24' );
-       return IP::isConfiguredProxy( $ip );
-}
-
 /**
  * Returns true if these thumbnail parameters match one that MediaWiki
  * requests from file description pages and/or parser output.
index 980d350..cd38a7d 100644 (file)
  * @file
  */
 
-/**
- * @since 1.18
- */
-class MWHookException extends MWException {
-}
-
 /**
  * Hooks class.
  *
@@ -193,34 +187,17 @@ class Hooks {
                        $badhookmsg = null;
                        $hook_args = array_merge( $hook, $args );
 
-                       set_error_handler( 'Hooks::hookErrorHandler' );
-
                        // mark hook as deprecated, if deprecation version is specified
                        if ( $deprecatedVersion !== null ) {
                                wfDeprecated( "$event hook (used in $func)", $deprecatedVersion );
                        }
 
-                       try {
-                               $retval = call_user_func_array( $callback, $hook_args );
-                       } catch ( MWHookException $e ) {
-                               $badhookmsg = $e->getMessage();
-                       } catch ( Exception $e ) {
-                               restore_error_handler();
-                               throw $e;
-                       }
-
-                       restore_error_handler();
+                       $retval = call_user_func_array( $callback, $hook_args );
 
                        // Process the return value.
                        if ( is_string( $retval ) ) {
                                // String returned means error.
                                throw new FatalError( $retval );
-                       } elseif ( $badhookmsg !== null ) {
-                               // Exception was thrown from Hooks::hookErrorHandler.
-                               throw new MWException(
-                                       'Detected bug in an extension! ' .
-                                       "Hook $func has invalid call signature; " . $badhookmsg
-                               );
                        } elseif ( $retval === false ) {
                                // False was returned. Stop processing, but no error.
                                return false;
@@ -229,31 +206,4 @@ class Hooks {
 
                return true;
        }
-
-       /**
-        * Handle PHP errors issued inside a hook. Catch errors that have to do
-        * with a function expecting a reference, missing arguments, or wrong argument
-        * types. Pass all others through to to the default error handler.
-        *
-        * This is useful for throwing errors for major callback invocation errors
-        * (with regard to parameter signature) which PHP just gives warnings for.
-        *
-        * @since 1.18
-        *
-        * @param int $errno Error number (unused)
-        * @param string $errstr Error message
-        * @throws MWHookException If the error has to do with the function signature
-        * @return bool
-        */
-       public static function hookErrorHandler( $errno, $errstr ) {
-               if ( strpos( $errstr, 'expected to be a reference, value given' ) !== false
-                       || strpos( $errstr, 'Missing argument ' ) !== false
-                       || strpos( $errstr, ' expects parameter ' ) !== false
-               ) {
-                       throw new MWHookException( $errstr, $errno );
-               }
-
-               // Delegate unhandled errors to the default handlers
-               return false;
-       }
 }
index 60196ab..e6801e3 100644 (file)
@@ -80,7 +80,8 @@ class Http {
                } else {
                        $errors = $status->getErrorsByType( 'error' );
                        $logger = LoggerFactory::getInstance( 'http' );
-                       $logger->warning( $status->getWikiText(), array( 'caller' => $caller ) );
+                       $logger->warning( $status->getWikiText(),
+                               array( 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ) );
                        return false;
                }
        }
index 842d276..5255b9a 100644 (file)
@@ -1393,7 +1393,10 @@ class Linker {
         * is ignored
         *
         * @todo FIXME: Doesn't handle sub-links as in image thumb texts like the main parser
-        * @param string $comment Text to format links in
+        * @param string $comment Text to format links in. WARNING! Since the output of this
+        *      function is html, $comment must be sanitized for use as html. You probably want
+        *      to pass $comment through Sanitizer::escapeHtmlAllowEntities() before calling
+        *      this function.
         * @param Title|null $title An optional title object used to links to sections
         * @param bool $local Whether section links should refer to local page
         * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
index 38d9e47..bb0f1e4 100644 (file)
@@ -308,7 +308,7 @@ class MediaWiki {
                $targetUrl = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
 
                if ( $targetUrl != $request->getFullRequestURL() ) {
-                       $output->setSquidMaxage( 1200 );
+                       $output->setCdnMaxage( 1200 );
                        $output->redirect( $targetUrl, '301' );
                        return true;
                }
@@ -443,15 +443,15 @@ class MediaWiki {
                $action = Action::factory( $act, $page, $this->context );
 
                if ( $action instanceof Action ) {
-                       # Let Squid cache things if we can purge them.
+                       # Let CDN cache things if we can purge them.
                        if ( $this->config->get( 'UseSquid' ) &&
                                in_array(
-                                       // Use PROTO_INTERNAL because that's what getSquidURLs() uses
+                                       // Use PROTO_INTERNAL because that's what getCdnUrls() uses
                                        wfExpandUrl( $request->getRequestURL(), PROTO_INTERNAL ),
-                                       $requestTitle->getSquidURLs()
+                                       $requestTitle->getCdnUrls()
                                )
                        ) {
-                               $output->setSquidMaxage( $this->config->get( 'SquidMaxage' ) );
+                               $output->setCdnMaxage( $this->config->get( 'SquidMaxage' ) );
                        }
 
                        $action->show();
@@ -505,17 +505,34 @@ class MediaWiki {
                // Either all DBs should commit or none
                ignore_user_abort( true );
 
-               // Commit all changes and record ChronologyProtector positions
+               $config = $context->getConfig();
+
                $factory = wfGetLBFactory();
+               // Check if any transaction was too big
+               $limit = $config->get( 'MaxUserDBWriteDuration' );
+               $factory->forEachLB( function ( LoadBalancer $lb ) use ( $limit ) {
+                       $lb->forEachOpenConnection( function ( IDatabase $db ) use ( $limit ) {
+                               $time = $db->pendingWriteQueryDuration();
+                               if ( $limit > 0 && $time > $limit ) {
+                                       throw new DBTransactionError(
+                                               $db,
+                                               wfMessage( 'transaction-duration-limit-exceeded', $time, $limit )->plain()
+                                       );
+                               }
+                       } );
+               } );
+               // Commit all changes
                $factory->commitMasterChanges();
+               // Record ChronologyProtector positions
                $factory->shutdown();
+               wfDebug( __METHOD__ . ': all transactions committed' );
 
-               wfDebug( __METHOD__ . ' completed; all transactions committed' );
+               DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND );
+               wfDebug( __METHOD__ . ': pre-send deferred updates completed' );
 
                // Set a cookie to tell all CDN edge nodes to "stick" the user to the
                // DC that handles this POST request (e.g. the "master" data center)
                $request = $context->getRequest();
-               $config = $context->getConfig();
                if ( $request->wasPosted() && $factory->hasOrMadeRecentMasterChanges() ) {
                        $expires = time() + $config->get( 'DataCenterUpdateStickTTL' );
                        $request->response()->setCookie( 'UseDC', 'master', $expires, array( 'prefix' => '' ) );
index 736cd8d..b918955 100644 (file)
@@ -369,10 +369,17 @@ class MovePage {
                        WatchedItem::duplicateEntries( $this->oldTitle, $this->newTitle );
                }
 
+               Hooks::run(
+                       'TitleMoveCompleting',
+                       array( $this->oldTitle, $this->newTitle, $user, $pageid, $redirid, $reason )
+               );
+
                $dbw->endAtomic( __METHOD__ );
 
                $params = array( &$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason );
-               $dbw->onTransactionIdle( function () use ( $params ) {
+               $dbw->onTransactionIdle( function () use ( $params, $dbw ) {
+                       // Keep each single hook handler atomic
+                       $dbw->setFlag( DBO_TRX ); // flag is automatically reset by DB layer
                        Hooks::run( 'TitleMoveComplete', $params );
                } );
 
index 39716ca..30f193c 100644 (file)
@@ -162,7 +162,7 @@ function wfMangleFlashPolicy( $s ) {
 }
 
 /**
- * Add a Content-Length header if possible. This makes it cooperate with squid better.
+ * Add a Content-Length header if possible. This makes it cooperate with CDN better.
  *
  * @param int $length
  */
index c35204d..fea667e 100644 (file)
@@ -233,8 +233,8 @@ class OutputPage extends ContextSource {
        private $mParseWarnings = array();
 
        /** @var int Cache stuff. Looks like mEnableClientCache */
-       protected $mSquidMaxage = 0;
-       /** @var int Upper limit on mSquidMaxage */
+       protected $mCdnMaxage = 0;
+       /** @var int Upper limit on mCdnMaxage */
        protected $mCdnMaxageLimit = INF;
 
        /**
@@ -1354,6 +1354,8 @@ class OutputPage extends ContextSource {
                        array( &$this, $categories, &$this->mCategoryLinks ) )
                ) {
                        foreach ( $categories as $category => $type ) {
+                               // array keys will cast numeric category names to ints, so cast back to string
+                               $category = (string)$category;
                                $origcategory = $category;
                                $title = Title::makeTitleSafe( NS_CATEGORY, $category );
                                if ( !$title ) {
@@ -1941,24 +1943,32 @@ class OutputPage extends ContextSource {
                return Parser::stripOuterParagraph( $parsed );
        }
 
+       /**
+        * @param $maxage
+        * @deprecated since 1.27 Use setCdnMaxage() instead
+        */
+       public function setSquidMaxage( $maxage ) {
+               $this->setCdnMaxage( $maxage );
+       }
+
        /**
         * Set the value of the "s-maxage" part of the "Cache-control" HTTP header
         *
-        * @param int $maxage Maximum cache time on the Squid, in seconds.
+        * @param int $maxage Maximum cache time on the CDN, in seconds.
         */
-       public function setSquidMaxage( $maxage ) {
-               $this->mSquidMaxage = min( $maxage, $this->mCdnMaxageLimit );
+       public function setCdnMaxage( $maxage ) {
+               $this->mCdnMaxage = min( $maxage, $this->mCdnMaxageLimit );
        }
 
        /**
         * Lower the value of the "s-maxage" part of the "Cache-control" HTTP header
         *
-        * @param int $maxage Maximum cache time on the Squid, in seconds
+        * @param int $maxage Maximum cache time on the CDN, in seconds
         * @since 1.27
         */
        public function lowerCdnMaxage( $maxage ) {
                $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
-               $this->setSquidMaxage( $this->mSquidMaxage );
+               $this->setCdnMaxage( $this->mCdnMaxage );
        }
 
        /**
@@ -2179,27 +2189,27 @@ class OutputPage extends ContextSource {
                if ( $this->mEnableClientCache ) {
                        if (
                                $config->get( 'UseSquid' ) && session_id() == '' && !$this->isPrintable() &&
-                               $this->mSquidMaxage != 0 && !$this->haveCacheVaryCookies()
+                               $this->mCdnMaxage != 0 && !$this->haveCacheVaryCookies()
                        ) {
                                if ( $config->get( 'UseESI' ) ) {
                                        # We'll purge the proxy cache explicitly, but require end user agents
                                        # to revalidate against the proxy on each visit.
-                                       # Surrogate-Control controls our Squid, Cache-Control downstream caches
+                                       # Surrogate-Control controls our CDN, Cache-Control downstream caches
                                        wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", 'log' );
                                        # start with a shorter timeout for initial testing
                                        # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
                                        $response->header( 'Surrogate-Control: max-age=' . $config->get( 'SquidMaxage' )
-                                               . '+' . $this->mSquidMaxage . ', content="ESI/1.0"' );
+                                               . '+' . $this->mCdnMaxage . ', content="ESI/1.0"' );
                                        $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
                                } else {
                                        # We'll purge the proxy cache for anons explicitly, but require end user agents
                                        # to revalidate against the proxy on each visit.
-                                       # IMPORTANT! The Squid needs to replace the Cache-Control header with
+                                       # IMPORTANT! The CDN needs to replace the Cache-Control header with
                                        # Cache-Control: s-maxage=0, must-revalidate, max-age=0
                                        wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", 'log' );
                                        # start with a shorter timeout for initial testing
                                        # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
-                                       $response->header( 'Cache-Control: s-maxage=' . $this->mSquidMaxage
+                                       $response->header( 'Cache-Control: s-maxage=' . $this->mCdnMaxage
                                                . ', must-revalidate, max-age=0' );
                                }
                        } else {
@@ -2429,7 +2439,7 @@ class OutputPage extends ContextSource {
                        # not especially useful as a returnto parameter. Use the title
                        # from the request instead, if there was one.
                        $request = $this->getRequest();
-                       $returnto = Title::newFromURL( $request->getVal( 'title', '' ) );
+                       $returnto = Title::newFromText( $request->getVal( 'title', '' ) );
                        if ( $action == 'edit' ) {
                                $msg = 'whitelistedittext';
                                $displayReturnto = $returnto;
@@ -2901,7 +2911,7 @@ class OutputPage extends ContextSource {
                                // on-wiki like user pages, or user preferences; we need to find the highest
                                // timestamp of these user-changeable modules so we can ensure cache misses on change
                                // This should NOT be done for the site group (bug 27564) because anons get that too
-                               // and we shouldn't be putting timestamps in Squid-cached HTML
+                               // and we shouldn't be putting timestamps in CDN-cached HTML
                                $version = null;
                                if ( $group === 'user' ) {
                                        $query['version'] = $resourceLoader->getCombinedVersion( $context, array_keys( $grpModules ) );
index 096f8e3..c7ab9cd 100644 (file)
@@ -1006,6 +1006,11 @@ class Preferences {
                        'section' => 'watchlist/advancedwatchlist',
                        'label-message' => 'tog-watchlisthideliu',
                );
+               $defaultPreferences['watchlistreloadautomatically'] = array(
+                       'type' => 'toggle',
+                       'section' => 'watchlist/advancedwatchlist',
+                       'label-message' => 'tog-watchlistreloadautomatically',
+               );
 
                if ( $config->get( 'RCWatchCategoryMembership' ) ) {
                        $defaultPreferences['watchlisthidecategorization'] = array(
index e328e9f..c6f187d 100644 (file)
@@ -164,112 +164,9 @@ abstract class PrefixSearch {
                return $this->strings( $this->handleResultFromHook( $srchres, $namespaces, $search, $limit ) );
        }
 
-       /**
-        * Default search backend does proper prefix searching, but custom backends
-        * may sort based on other algorythms that may cause the exact title match
-        * to not be in the results or be lower down the list.
-        * @param array $srchres results from the hook
-        * @return array munged results from the hook
-        */
        private function handleResultFromHook( $srchres, $namespaces, $search, $limit ) {
-               // Pick namespace (based on PrefixSearch::defaultSearchBackend)
-               $ns = in_array( NS_MAIN, $namespaces ) ? NS_MAIN : $namespaces[0];
-               $t = Title::newFromText( $search, $ns );
-               if ( !$t || !$t->exists() ) {
-                       // No exact match so just return the search results
-                       return $srchres;
-               }
-               $string = $t->getPrefixedText();
-               $key = array_search( $string, $srchres );
-               if ( $key !== false ) {
-                       // Exact match was in the results so just move it to the front
-                       return $this->pullFront( $key, $srchres );
-               }
-               // Exact match not in the search results so check for some redirect handling cases
-               if ( $t->isRedirect() ) {
-                       $target = $this->getRedirectTarget( $t );
-                       $key = array_search( $target, $srchres );
-                       if ( $key !== false ) {
-                               // Exact match is a redirect to one of the returned matches so pull the
-                               // returned match to the front.  This might look odd but the alternative
-                               // is to put the redirect in front and drop the match.  The name of the
-                               // found match is often more descriptive/better formed than the name of
-                               // the redirect AND by definition they share a prefix.  Hopefully this
-                               // choice is less confusing and more helpful.  But it might not be.  But
-                               // it is the choice we're going with for now.
-                               return $this->pullFront( $key, $srchres );
-                       }
-                       $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
-                       if ( isset( $redirectTargetsToRedirect[$target] ) ) {
-                               // The exact match and something in the results list are both redirects
-                               // to the same thing!  In this case we'll pull the returned match to the
-                               // top following the same logic above.  Again, it might not be a perfect
-                               // choice but it'll do.
-                               return $this->pullFront( $redirectTargetsToRedirect[$target], $srchres );
-                       }
-               } else {
-                       $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
-                       if ( isset( $redirectTargetsToRedirect[$string] ) ) {
-                               // The exact match is the target of a redirect already in the results list so remove
-                               // the redirect from the results list and push the exact match to the front
-                               array_splice( $srchres, $redirectTargetsToRedirect[$string], 1 );
-                               array_unshift( $srchres, $string );
-                               return $srchres;
-                       }
-               }
-
-               // Exact match is totally unique from the other results so just add it to the front
-               array_unshift( $srchres, $string );
-               // And roll one off the end if the results are too long
-               if ( count( $srchres ) > $limit ) {
-                       array_pop( $srchres );
-               }
-               return $srchres;
-       }
-
-       /**
-        * @param Array(string) $titles as strings
-        * @return Array(string => int) redirect target prefixedText to index of title in titles
-        *   that is a redirect to it.
-        */
-       private function redirectTargetsToRedirect( $titles ) {
-               $result = array();
-               foreach ( $titles as $key => $titleText ) {
-                       $title = Title::newFromText( $titleText );
-                       if ( !$title || !$title->isRedirect() ) {
-                               continue;
-                       }
-                       $target = $this->getRedirectTarget( $title );
-                       if ( !$target ) {
-                               continue;
-                       }
-                       $result[$target] = $key;
-               }
-               return $result;
-       }
-
-       /**
-        * @param int $key key to pull to the front
-        * @return array $array with the item at $key pulled to the front
-        */
-       private function pullFront( $key, $array ) {
-               $cut = array_splice( $array, $key, 1 );
-               array_unshift( $array, $cut[0] );
-               return $array;
-       }
-
-       /**
-        * Get a redirect's destination from a title
-        * @param Title $title A title to redirect. It may not redirect or even exist
-        * @return null|string If title exists and redirects, get the destination's prefixed name
-        */
-       private function getRedirectTarget( $title ) {
-               $page = WikiPage::factory( $title );
-               if ( !$page->exists() ) {
-                       return null;
-               }
-               $redir = $page->getRedirectTarget();
-               return $redir ? $redir->getPrefixedText() : null;
+               $rescorer = new SearchExactMatchRescorer();
+               return $rescorer->rescore( $search, $namespaces, $srchres, $limit );
        }
 
        /**
index 4fc3209..b1b5da2 100644 (file)
@@ -750,7 +750,15 @@ class Sanitizer {
                        }
 
                        # Allow any attribute beginning with "data-"
-                       if ( !preg_match( '/^data-(?!ooui)/i', $attribute ) && !isset( $whitelist[$attribute] ) ) {
+                       # However:
+                       # * data-ooui is reserved for ooui
+                       # * data-mw and data-parsoid are reserved for parsoid
+                       # * data-mw-<ext name here> is reserved for extensions (or core) if
+                       #   they need to communicate some data to the client and want to be
+                       #   sure that it isn't coming from an untrusted user.
+                       if ( !preg_match( '/^data-(?!ooui|mw|parsoid)/i', $attribute )
+                               && !isset( $whitelist[$attribute] )
+                       ) {
                                continue;
                        }
 
index 44c1f71..e22184f 100644 (file)
@@ -421,11 +421,9 @@ if ( is_array( $wgExtraNamespaces ) ) {
 // To determine the user language, use $wgLang->getCode()
 $wgContLanguageCode = $wgLanguageCode;
 
-// Easy to forget to falsify $wgShowIPinHeader for static caches.
-// If file cache or squid cache is on, just disable this (DWIMD).
-// Do the same for $wgDebugToolbar.
+// Easy to forget to falsify $wgDebugToolbar for static caches.
+// If file cache or CDN cache is on, just disable this (DWIMD).
 if ( $wgUseFileCache || $wgUseSquid ) {
-       $wgShowIPinHeader = false;
        $wgDebugToolbar = false;
 }
 
index 4b39efd..5d8b072 100644 (file)
@@ -1824,7 +1824,7 @@ class Title {
 
        /**
         * Get the URL form for an internal link.
-        * - Used in various Squid-related code, in case we have a different
+        * - Used in various CDN-related code, in case we have a different
         * internal hostname for the server from the exposed one.
         *
         * This uses $wgInternalServer to qualify the path, or $wgServer
@@ -3557,12 +3557,12 @@ class Title {
        }
 
        /**
-        * Get a list of URLs to purge from the Squid cache when this
+        * Get a list of URLs to purge from the CDN cache when this
         * page changes
         *
         * @return string[] Array of String the URLs
         */
-       public function getSquidURLs() {
+       public function getCdnUrls() {
                $urls = array(
                        $this->getInternalURL(),
                        $this->getInternalURL( 'action=history' )
@@ -3588,15 +3588,20 @@ class Title {
        }
 
        /**
-        * Purge all applicable Squid URLs
+        * @deprecated since 1.27 use getCdnUrls()
+        */
+       public function getSquidURLs() {
+               return $this->getCdnUrls();
+       }
+
+       /**
+        * Purge all applicable CDN URLs
         */
        public function purgeSquid() {
-               global $wgUseSquid;
-               if ( $wgUseSquid ) {
-                       $urls = $this->getSquidURLs();
-                       $u = new SquidUpdate( $urls );
-                       $u->doUpdate();
-               }
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( $this->getCdnUrls() ),
+                       DeferredUpdates::PRESEND
+               );
        }
 
        /**
@@ -4417,7 +4422,7 @@ class Title {
        }
 
        /**
-        * Update page_touched timestamps and send squid purge messages for
+        * Update page_touched timestamps and send CDN purge messages for
         * pages linking to this title. May be sent to the job queue depending
         * on the number of links. Typically called on create and delete.
         */
diff --git a/includes/User.php b/includes/User.php
deleted file mode 100644 (file)
index 3d1aa7e..0000000
+++ /dev/null
@@ -1,5334 +0,0 @@
-<?php
-/**
- * Implements the User class for the %MediaWiki software.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * String Some punctuation to prevent editing from broken text-mangling proxies.
- * @ingroup Constants
- */
-define( 'EDIT_TOKEN_SUFFIX', '+\\' );
-
-/**
- * The User object encapsulates all of the user-specific settings (user_id,
- * name, rights, email address, options, last login time). Client
- * classes use the getXXX() functions to access these fields. These functions
- * do all the work of determining whether the user is logged in,
- * whether the requested option can be satisfied from cookies or
- * whether a database query is needed. Most of the settings needed
- * for rendering normal pages are set in the cookie to minimize use
- * of the database.
- */
-class User implements IDBAccessObject {
-       /**
-        * @const int Number of characters in user_token field.
-        */
-       const TOKEN_LENGTH = 32;
-
-       /**
-        * Global constant made accessible as class constants so that autoloader
-        * magic can be used.
-        */
-       const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
-
-       /**
-        * @const int Serialized record version.
-        */
-       const VERSION = 10;
-
-       /**
-        * Maximum items in $mWatchedItems
-        */
-       const MAX_WATCHED_ITEMS_CACHE = 100;
-
-       /**
-        * Exclude user options that are set to their default value.
-        * @since 1.25
-        */
-       const GETOPTIONS_EXCLUDE_DEFAULTS = 1;
-
-       /**
-        * Array of Strings List of member variables which are saved to the
-        * shared cache (memcached). Any operation which changes the
-        * corresponding database fields must call a cache-clearing function.
-        * @showinitializer
-        */
-       protected static $mCacheVars = array(
-               // user table
-               'mId',
-               'mName',
-               'mRealName',
-               'mEmail',
-               'mTouched',
-               'mToken',
-               'mEmailAuthenticated',
-               'mEmailToken',
-               'mEmailTokenExpires',
-               'mRegistration',
-               'mEditCount',
-               // user_groups table
-               'mGroups',
-               // user_properties table
-               'mOptionOverrides',
-       );
-
-       /**
-        * Array of Strings Core rights.
-        * Each of these should have a corresponding message of the form
-        * "right-$right".
-        * @showinitializer
-        */
-       protected static $mCoreRights = array(
-               'apihighlimits',
-               'applychangetags',
-               'autoconfirmed',
-               'autopatrol',
-               'bigdelete',
-               'block',
-               'blockemail',
-               'bot',
-               'browsearchive',
-               'changetags',
-               'createaccount',
-               'createpage',
-               'createtalk',
-               'delete',
-               'deletedhistory',
-               'deletedtext',
-               'deletelogentry',
-               'deleterevision',
-               'edit',
-               'editcontentmodel',
-               'editinterface',
-               'editprotected',
-               'editmyoptions',
-               'editmyprivateinfo',
-               'editmyusercss',
-               'editmyuserjs',
-               'editmywatchlist',
-               'editsemiprotected',
-               'editusercssjs', # deprecated
-               'editusercss',
-               'edituserjs',
-               'hideuser',
-               'import',
-               'importupload',
-               'ipblock-exempt',
-               'managechangetags',
-               'markbotedits',
-               'mergehistory',
-               'minoredit',
-               'move',
-               'movefile',
-               'move-categorypages',
-               'move-rootuserpages',
-               'move-subpages',
-               'nominornewtalk',
-               'noratelimit',
-               'override-export-depth',
-               'pagelang',
-               'passwordreset',
-               'patrol',
-               'patrolmarks',
-               'protect',
-               'proxyunbannable',
-               'purge',
-               'read',
-               'reupload',
-               'reupload-own',
-               'reupload-shared',
-               'rollback',
-               'sendemail',
-               'siteadmin',
-               'suppressionlog',
-               'suppressredirect',
-               'suppressrevision',
-               'unblockself',
-               'undelete',
-               'unwatchedpages',
-               'upload',
-               'upload_by_url',
-               'userrights',
-               'userrights-interwiki',
-               'viewmyprivateinfo',
-               'viewmywatchlist',
-               'viewsuppressed',
-               'writeapi',
-       );
-
-       /**
-        * String Cached results of getAllRights()
-        */
-       protected static $mAllRights = false;
-
-       /** Cache variables */
-       // @{
-       public $mId;
-       /** @var string */
-       public $mName;
-       /** @var string */
-       public $mRealName;
-
-       /** @var string */
-       public $mEmail;
-       /** @var string TS_MW timestamp from the DB */
-       public $mTouched;
-       /** @var string TS_MW timestamp from cache */
-       protected $mQuickTouched;
-       /** @var string */
-       protected $mToken;
-       /** @var string */
-       public $mEmailAuthenticated;
-       /** @var string */
-       protected $mEmailToken;
-       /** @var string */
-       protected $mEmailTokenExpires;
-       /** @var string */
-       protected $mRegistration;
-       /** @var int */
-       protected $mEditCount;
-       /** @var array */
-       public $mGroups;
-       /** @var array */
-       protected $mOptionOverrides;
-       // @}
-
-       /**
-        * Bool Whether the cache variables have been loaded.
-        */
-       // @{
-       public $mOptionsLoaded;
-
-       /**
-        * Array with already loaded items or true if all items have been loaded.
-        */
-       protected $mLoadedItems = array();
-       // @}
-
-       /**
-        * String Initialization data source if mLoadedItems!==true. May be one of:
-        *  - 'defaults'   anonymous user initialised from class defaults
-        *  - 'name'       initialise from mName
-        *  - 'id'         initialise from mId
-        *  - 'session'    log in from cookies or session if possible
-        *
-        * Use the User::newFrom*() family of functions to set this.
-        */
-       public $mFrom;
-
-       /**
-        * Lazy-initialized variables, invalidated with clearInstanceCache
-        */
-       protected $mNewtalk;
-       /** @var string */
-       protected $mDatePreference;
-       /** @var string */
-       public $mBlockedby;
-       /** @var string */
-       protected $mHash;
-       /** @var array */
-       public $mRights;
-       /** @var string */
-       protected $mBlockreason;
-       /** @var array */
-       protected $mEffectiveGroups;
-       /** @var array */
-       protected $mImplicitGroups;
-       /** @var array */
-       protected $mFormerGroups;
-       /** @var bool */
-       protected $mBlockedGlobally;
-       /** @var bool */
-       protected $mLocked;
-       /** @var bool */
-       public $mHideName;
-       /** @var array */
-       public $mOptions;
-
-       /**
-        * @var WebRequest
-        */
-       private $mRequest;
-
-       /** @var Block */
-       public $mBlock;
-
-       /** @var bool */
-       protected $mAllowUsertalk;
-
-       /** @var Block */
-       private $mBlockedFromCreateAccount = false;
-
-       /** @var array */
-       private $mWatchedItems = array();
-
-       /** @var integer User::READ_* constant bitfield used to load data */
-       protected $queryFlagsUsed = self::READ_NORMAL;
-
-       public static $idCacheByName = array();
-
-       /**
-        * Lightweight constructor for an anonymous user.
-        * Use the User::newFrom* factory functions for other kinds of users.
-        *
-        * @see newFromName()
-        * @see newFromId()
-        * @see newFromConfirmationCode()
-        * @see newFromSession()
-        * @see newFromRow()
-        */
-       public function __construct() {
-               $this->clearInstanceCache( 'defaults' );
-       }
-
-       /**
-        * @return string
-        */
-       public function __toString() {
-               return $this->getName();
-       }
-
-       /**
-        * Load the user table data for this object from the source given by mFrom.
-        *
-        * @param integer $flags User::READ_* constant bitfield
-        */
-       public function load( $flags = self::READ_NORMAL ) {
-               if ( $this->mLoadedItems === true ) {
-                       return;
-               }
-
-               // Set it now to avoid infinite recursion in accessors
-               $this->mLoadedItems = true;
-               $this->queryFlagsUsed = $flags;
-
-               switch ( $this->mFrom ) {
-                       case 'defaults':
-                               $this->loadDefaults();
-                               break;
-                       case 'name':
-                               // Make sure this thread sees its own changes
-                               if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) {
-                                       $flags |= self::READ_LATEST;
-                                       $this->queryFlagsUsed = $flags;
-                               }
-
-                               $this->mId = self::idFromName( $this->mName, $flags );
-                               if ( !$this->mId ) {
-                                       // Nonexistent user placeholder object
-                                       $this->loadDefaults( $this->mName );
-                               } else {
-                                       $this->loadFromId( $flags );
-                               }
-                               break;
-                       case 'id':
-                               $this->loadFromId( $flags );
-                               break;
-                       case 'session':
-                               if ( !$this->loadFromSession() ) {
-                                       // Loading from session failed. Load defaults.
-                                       $this->loadDefaults();
-                               }
-                               Hooks::run( 'UserLoadAfterLoadFromSession', array( $this ) );
-                               break;
-                       default:
-                               throw new UnexpectedValueException(
-                                       "Unrecognised value for User->mFrom: \"{$this->mFrom}\"" );
-               }
-       }
-
-       /**
-        * Load user table data, given mId has already been set.
-        * @param integer $flags User::READ_* constant bitfield
-        * @return bool False if the ID does not exist, true otherwise
-        */
-       public function loadFromId( $flags = self::READ_NORMAL ) {
-               if ( $this->mId == 0 ) {
-                       $this->loadDefaults();
-                       return false;
-               }
-
-               // Try cache (unless this needs data from the master DB).
-               // NOTE: if this thread called saveSettings(), the cache was cleared.
-               $latest = DBAccessObjectUtils::hasFlags( $flags, self::READ_LATEST );
-               if ( $latest || !$this->loadFromCache() ) {
-                       wfDebug( "User: cache miss for user {$this->mId}\n" );
-                       // Load from DB (make sure this thread sees its own changes)
-                       if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) {
-                               $flags |= self::READ_LATEST;
-                       }
-                       if ( !$this->loadFromDatabase( $flags ) ) {
-                               // Can't load from ID, user is anonymous
-                               return false;
-                       }
-                       $this->saveToCache();
-               }
-
-               $this->mLoadedItems = true;
-               $this->queryFlagsUsed = $flags;
-
-               return true;
-       }
-
-       /**
-        * @since 1.27
-        * @param string $wikiId
-        * @param integer $userId
-        */
-       public static function purge( $wikiId, $userId ) {
-               $cache = ObjectCache::getMainWANInstance();
-               $cache->delete( $cache->makeGlobalKey( 'user', 'id', $wikiId, $userId ) );
-       }
-
-       /**
-        * @since 1.27
-        * @param WANObjectCache $cache
-        * @return string
-        */
-       protected function getCacheKey( WANObjectCache $cache ) {
-               return $cache->makeGlobalKey( 'user', 'id', wfWikiID(), $this->mId );
-       }
-
-       /**
-        * Load user data from shared cache, given mId has already been set.
-        *
-        * @return bool false if the ID does not exist or data is invalid, true otherwise
-        * @since 1.25
-        */
-       protected function loadFromCache() {
-               if ( $this->mId == 0 ) {
-                       $this->loadDefaults();
-                       return false;
-               }
-
-               $cache = ObjectCache::getMainWANInstance();
-               $data = $cache->get( $this->getCacheKey( $cache ) );
-               if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
-                       // Object is expired
-                       return false;
-               }
-
-               wfDebug( "User: got user {$this->mId} from cache\n" );
-
-               // Restore from cache
-               foreach ( self::$mCacheVars as $name ) {
-                       $this->$name = $data[$name];
-               }
-
-               return true;
-       }
-
-       /**
-        * Save user data to the shared cache
-        *
-        * This method should not be called outside the User class
-        */
-       public function saveToCache() {
-               $this->load();
-               $this->loadGroups();
-               $this->loadOptions();
-
-               if ( $this->isAnon() ) {
-                       // Anonymous users are uncached
-                       return;
-               }
-
-               $data = array();
-               foreach ( self::$mCacheVars as $name ) {
-                       $data[$name] = $this->$name;
-               }
-               $data['mVersion'] = self::VERSION;
-               $opts = Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
-
-               $cache = ObjectCache::getMainWANInstance();
-               $key = $this->getCacheKey( $cache );
-               $cache->set( $key, $data, $cache::TTL_HOUR, $opts );
-       }
-
-       /** @name newFrom*() static factory methods */
-       // @{
-
-       /**
-        * Static factory method for creation from username.
-        *
-        * This is slightly less efficient than newFromId(), so use newFromId() if
-        * you have both an ID and a name handy.
-        *
-        * @param string $name Username, validated by Title::newFromText()
-        * @param string|bool $validate Validate username. Takes the same parameters as
-        *  User::getCanonicalName(), except that true is accepted as an alias
-        *  for 'valid', for BC.
-        *
-        * @return User|bool User object, or false if the username is invalid
-        *  (e.g. if it contains illegal characters or is an IP address). If the
-        *  username is not present in the database, the result will be a user object
-        *  with a name, zero user ID and default settings.
-        */
-       public static function newFromName( $name, $validate = 'valid' ) {
-               if ( $validate === true ) {
-                       $validate = 'valid';
-               }
-               $name = self::getCanonicalName( $name, $validate );
-               if ( $name === false ) {
-                       return false;
-               } else {
-                       // Create unloaded user object
-                       $u = new User;
-                       $u->mName = $name;
-                       $u->mFrom = 'name';
-                       $u->setItemLoaded( 'name' );
-                       return $u;
-               }
-       }
-
-       /**
-        * Static factory method for creation from a given user ID.
-        *
-        * @param int $id Valid user ID
-        * @return User The corresponding User object
-        */
-       public static function newFromId( $id ) {
-               $u = new User;
-               $u->mId = $id;
-               $u->mFrom = 'id';
-               $u->setItemLoaded( 'id' );
-               return $u;
-       }
-
-       /**
-        * Factory method to fetch whichever user has a given email confirmation code.
-        * This code is generated when an account is created or its e-mail address
-        * has changed.
-        *
-        * If the code is invalid or has expired, returns NULL.
-        *
-        * @param string $code Confirmation code
-        * @param int $flags User::READ_* bitfield
-        * @return User|null
-        */
-       public static function newFromConfirmationCode( $code, $flags = 0 ) {
-               $db = ( $flags & self::READ_LATEST ) == self::READ_LATEST
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-
-               $id = $db->selectField(
-                       'user',
-                       'user_id',
-                       array(
-                               'user_email_token' => md5( $code ),
-                               'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ),
-                       )
-               );
-
-               return $id ? User::newFromId( $id ) : null;
-       }
-
-       /**
-        * Create a new user object using data from session or cookies. If the
-        * login credentials are invalid, the result is an anonymous user.
-        *
-        * @param WebRequest|null $request Object to use; $wgRequest will be used if omitted.
-        * @return User
-        */
-       public static function newFromSession( WebRequest $request = null ) {
-               $user = new User;
-               $user->mFrom = 'session';
-               $user->mRequest = $request;
-               return $user;
-       }
-
-       /**
-        * Create a new user object from a user row.
-        * The row should have the following fields from the user table in it:
-        * - either user_name or user_id to load further data if needed (or both)
-        * - user_real_name
-        * - all other fields (email, etc.)
-        * It is useless to provide the remaining fields if either user_id,
-        * user_name and user_real_name are not provided because the whole row
-        * will be loaded once more from the database when accessing them.
-        *
-        * @param stdClass $row A row from the user table
-        * @param array $data Further data to load into the object (see User::loadFromRow for valid keys)
-        * @return User
-        */
-       public static function newFromRow( $row, $data = null ) {
-               $user = new User;
-               $user->loadFromRow( $row, $data );
-               return $user;
-       }
-
-       /**
-        * Static factory method for creation of a "system" user from username.
-        *
-        * A "system" user is an account that's used to attribute logged actions
-        * taken by MediaWiki itself, as opposed to a bot or human user. Examples
-        * might include the 'Maintenance script' or 'Conversion script' accounts
-        * used by various scripts in the maintenance/ directory or accounts such
-        * as 'MediaWiki message delivery' used by the MassMessage extension.
-        *
-        * This can optionally create the user if it doesn't exist, and "steal" the
-        * account if it does exist.
-        *
-        * @param string $name Username
-        * @param array $options Options are:
-        *  - validate: As for User::getCanonicalName(), default 'valid'
-        *  - create: Whether to create the user if it doesn't already exist, default true
-        *  - steal: Whether to reset the account's password and email if it
-        *    already exists, default false
-        * @return User|null
-        */
-       public static function newSystemUser( $name, $options = array() ) {
-               $options += array(
-                       'validate' => 'valid',
-                       'create' => true,
-                       'steal' => false,
-               );
-
-               $name = self::getCanonicalName( $name, $options['validate'] );
-               if ( $name === false ) {
-                       return null;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow(
-                       'user',
-                       array_merge(
-                               self::selectFields(),
-                               array( 'user_password', 'user_newpassword' )
-                       ),
-                       array( 'user_name' => $name ),
-                       __METHOD__
-               );
-               if ( !$row ) {
-                       // No user. Create it?
-                       return $options['create'] ? self::createNew( $name ) : null;
-               }
-               $user = self::newFromRow( $row );
-
-               // A user is considered to exist as a non-system user if it has a
-               // password set, or a temporary password set, or an email set.
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               try {
-                       $password = $passwordFactory->newFromCiphertext( $row->user_password );
-               } catch ( PasswordError $e ) {
-                       wfDebug( 'Invalid password hash found in database.' );
-                       $password = PasswordFactory::newInvalidPassword();
-               }
-               try {
-                       $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
-               } catch ( PasswordError $e ) {
-                       wfDebug( 'Invalid password hash found in database.' );
-                       $newpassword = PasswordFactory::newInvalidPassword();
-               }
-               if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
-                       || $user->mEmail
-               ) {
-                       // User exists. Steal it?
-                       if ( !$options['steal'] ) {
-                               return null;
-                       }
-
-                       $nopass = PasswordFactory::newInvalidPassword()->toString();
-
-                       $dbw->update(
-                               'user',
-                               array(
-                                       'user_password' => $nopass,
-                                       'user_newpassword' => $nopass,
-                                       'user_newpass_time' => null,
-                               ),
-                               array( 'user_id' => $user->getId() ),
-                               __METHOD__
-                       );
-                       $user->invalidateEmail();
-                       $user->saveSettings();
-               }
-
-               return $user;
-       }
-
-       // @}
-
-       /**
-        * Get the username corresponding to a given user ID
-        * @param int $id User ID
-        * @return string|bool The corresponding username
-        */
-       public static function whoIs( $id ) {
-               return UserCache::singleton()->getProp( $id, 'name' );
-       }
-
-       /**
-        * Get the real name of a user given their user ID
-        *
-        * @param int $id User ID
-        * @return string|bool The corresponding user's real name
-        */
-       public static function whoIsReal( $id ) {
-               return UserCache::singleton()->getProp( $id, 'real_name' );
-       }
-
-       /**
-        * Get database id given a user name
-        * @param string $name Username
-        * @param integer $flags User::READ_* constant bitfield
-        * @return int|null The corresponding user's ID, or null if user is nonexistent
-        */
-       public static function idFromName( $name, $flags = self::READ_NORMAL ) {
-               $nt = Title::makeTitleSafe( NS_USER, $name );
-               if ( is_null( $nt ) ) {
-                       // Illegal name
-                       return null;
-               }
-
-               if ( !( $flags & self::READ_LATEST ) && isset( self::$idCacheByName[$name] ) ) {
-                       return self::$idCacheByName[$name];
-               }
-
-               $db = ( $flags & self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-
-               $s = $db->selectRow(
-                       'user',
-                       array( 'user_id' ),
-                       array( 'user_name' => $nt->getText() ),
-                       __METHOD__
-               );
-
-               if ( $s === false ) {
-                       $result = null;
-               } else {
-                       $result = $s->user_id;
-               }
-
-               self::$idCacheByName[$name] = $result;
-
-               if ( count( self::$idCacheByName ) > 1000 ) {
-                       self::$idCacheByName = array();
-               }
-
-               return $result;
-       }
-
-       /**
-        * Reset the cache used in idFromName(). For use in tests.
-        */
-       public static function resetIdByNameCache() {
-               self::$idCacheByName = array();
-       }
-
-       /**
-        * Does the string match an anonymous IPv4 address?
-        *
-        * This function exists for username validation, in order to reject
-        * usernames which are similar in form to IP addresses. Strings such
-        * as 300.300.300.300 will return true because it looks like an IP
-        * address, despite not being strictly valid.
-        *
-        * We match "\d{1,3}\.\d{1,3}\.\d{1,3}\.xxx" as an anonymous IP
-        * address because the usemod software would "cloak" anonymous IP
-        * addresses like this, if we allowed accounts like this to be created
-        * new users could get the old edits of these anonymous users.
-        *
-        * @param string $name Name to match
-        * @return bool
-        */
-       public static function isIP( $name ) {
-               return preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/', $name )
-                       || IP::isIPv6( $name );
-       }
-
-       /**
-        * Is the input a valid username?
-        *
-        * Checks if the input is a valid username, we don't want an empty string,
-        * an IP address, anything that contains slashes (would mess up subpages),
-        * is longer than the maximum allowed username size or doesn't begin with
-        * a capital letter.
-        *
-        * @param string $name Name to match
-        * @return bool
-        */
-       public static function isValidUserName( $name ) {
-               global $wgContLang, $wgMaxNameChars;
-
-               if ( $name == ''
-                       || User::isIP( $name )
-                       || strpos( $name, '/' ) !== false
-                       || strlen( $name ) > $wgMaxNameChars
-                       || $name != $wgContLang->ucfirst( $name )
-               ) {
-                       wfDebugLog( 'username', __METHOD__ .
-                               ": '$name' invalid due to empty, IP, slash, length, or lowercase" );
-                       return false;
-               }
-
-               // Ensure that the name can't be misresolved as a different title,
-               // such as with extra namespace keys at the start.
-               $parsed = Title::newFromText( $name );
-               if ( is_null( $parsed )
-                       || $parsed->getNamespace()
-                       || strcmp( $name, $parsed->getPrefixedText() ) ) {
-                       wfDebugLog( 'username', __METHOD__ .
-                               ": '$name' invalid due to ambiguous prefixes" );
-                       return false;
-               }
-
-               // Check an additional blacklist of troublemaker characters.
-               // Should these be merged into the title char list?
-               $unicodeBlacklist = '/[' .
-                       '\x{0080}-\x{009f}' . # iso-8859-1 control chars
-                       '\x{00a0}' .          # non-breaking space
-                       '\x{2000}-\x{200f}' . # various whitespace
-                       '\x{2028}-\x{202f}' . # breaks and control chars
-                       '\x{3000}' .          # ideographic space
-                       '\x{e000}-\x{f8ff}' . # private use
-                       ']/u';
-               if ( preg_match( $unicodeBlacklist, $name ) ) {
-                       wfDebugLog( 'username', __METHOD__ .
-                               ": '$name' invalid due to blacklisted characters" );
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Usernames which fail to pass this function will be blocked
-        * from user login and new account registrations, but may be used
-        * internally by batch processes.
-        *
-        * If an account already exists in this form, login will be blocked
-        * by a failure to pass this function.
-        *
-        * @param string $name Name to match
-        * @return bool
-        */
-       public static function isUsableName( $name ) {
-               global $wgReservedUsernames;
-               // Must be a valid username, obviously ;)
-               if ( !self::isValidUserName( $name ) ) {
-                       return false;
-               }
-
-               static $reservedUsernames = false;
-               if ( !$reservedUsernames ) {
-                       $reservedUsernames = $wgReservedUsernames;
-                       Hooks::run( 'UserGetReservedNames', array( &$reservedUsernames ) );
-               }
-
-               // Certain names may be reserved for batch processes.
-               foreach ( $reservedUsernames as $reserved ) {
-                       if ( substr( $reserved, 0, 4 ) == 'msg:' ) {
-                               $reserved = wfMessage( substr( $reserved, 4 ) )->inContentLanguage()->text();
-                       }
-                       if ( $reserved == $name ) {
-                               return false;
-                       }
-               }
-               return true;
-       }
-
-       /**
-        * Usernames which fail to pass this function will be blocked
-        * from new account registrations, but may be used internally
-        * either by batch processes or by user accounts which have
-        * already been created.
-        *
-        * Additional blacklisting may be added here rather than in
-        * isValidUserName() to avoid disrupting existing accounts.
-        *
-        * @param string $name String to match
-        * @return bool
-        */
-       public static function isCreatableName( $name ) {
-               global $wgInvalidUsernameCharacters;
-
-               // Ensure that the username isn't longer than 235 bytes, so that
-               // (at least for the builtin skins) user javascript and css files
-               // will work. (bug 23080)
-               if ( strlen( $name ) > 235 ) {
-                       wfDebugLog( 'username', __METHOD__ .
-                               ": '$name' invalid due to length" );
-                       return false;
-               }
-
-               // Preg yells if you try to give it an empty string
-               if ( $wgInvalidUsernameCharacters !== '' ) {
-                       if ( preg_match( '/[' . preg_quote( $wgInvalidUsernameCharacters, '/' ) . ']/', $name ) ) {
-                               wfDebugLog( 'username', __METHOD__ .
-                                       ": '$name' invalid due to wgInvalidUsernameCharacters" );
-                               return false;
-                       }
-               }
-
-               return self::isUsableName( $name );
-       }
-
-       /**
-        * Is the input a valid password for this user?
-        *
-        * @param string $password Desired password
-        * @return bool
-        */
-       public function isValidPassword( $password ) {
-               // simple boolean wrapper for getPasswordValidity
-               return $this->getPasswordValidity( $password ) === true;
-       }
-
-
-       /**
-        * Given unvalidated password input, return error message on failure.
-        *
-        * @param string $password Desired password
-        * @return bool|string|array True on success, string or array of error message on failure
-        */
-       public function getPasswordValidity( $password ) {
-               $result = $this->checkPasswordValidity( $password );
-               if ( $result->isGood() ) {
-                       return true;
-               } else {
-                       $messages = array();
-                       foreach ( $result->getErrorsByType( 'error' ) as $error ) {
-                               $messages[] = $error['message'];
-                       }
-                       foreach ( $result->getErrorsByType( 'warning' ) as $warning ) {
-                               $messages[] = $warning['message'];
-                       }
-                       if ( count( $messages ) === 1 ) {
-                               return $messages[0];
-                       }
-                       return $messages;
-               }
-       }
-
-       /**
-        * Check if this is a valid password for this user
-        *
-        * Create a Status object based on the password's validity.
-        * The Status should be set to fatal if the user should not
-        * be allowed to log in, and should have any errors that
-        * would block changing the password.
-        *
-        * If the return value of this is not OK, the password
-        * should not be checked. If the return value is not Good,
-        * the password can be checked, but the user should not be
-        * able to set their password to this.
-        *
-        * @param string $password Desired password
-        * @param string $purpose one of 'login', 'create', 'reset'
-        * @return Status
-        * @since 1.23
-        */
-       public function checkPasswordValidity( $password, $purpose = 'login' ) {
-               global $wgPasswordPolicy;
-
-               $upp = new UserPasswordPolicy(
-                       $wgPasswordPolicy['policies'],
-                       $wgPasswordPolicy['checks']
-               );
-
-               $status = Status::newGood();
-               $result = false; // init $result to false for the internal checks
-
-               if ( !Hooks::run( 'isValidPassword', array( $password, &$result, $this ) ) ) {
-                       $status->error( $result );
-                       return $status;
-               }
-
-               if ( $result === false ) {
-                       $status->merge( $upp->checkUserPassword( $this, $password, $purpose ) );
-                       return $status;
-               } elseif ( $result === true ) {
-                       return $status;
-               } else {
-                       $status->error( $result );
-                       return $status; // the isValidPassword hook set a string $result and returned true
-               }
-       }
-
-       /**
-        * Given unvalidated user input, return a canonical username, or false if
-        * the username is invalid.
-        * @param string $name User input
-        * @param string|bool $validate Type of validation to use:
-        *   - false        No validation
-        *   - 'valid'      Valid for batch processes
-        *   - 'usable'     Valid for batch processes and login
-        *   - 'creatable'  Valid for batch processes, login and account creation
-        *
-        * @throws InvalidArgumentException
-        * @return bool|string
-        */
-       public static function getCanonicalName( $name, $validate = 'valid' ) {
-               // Force usernames to capital
-               global $wgContLang;
-               $name = $wgContLang->ucfirst( $name );
-
-               # Reject names containing '#'; these will be cleaned up
-               # with title normalisation, but then it's too late to
-               # check elsewhere
-               if ( strpos( $name, '#' ) !== false ) {
-                       return false;
-               }
-
-               // Clean up name according to title rules,
-               // but only when validation is requested (bug 12654)
-               $t = ( $validate !== false ) ?
-                       Title::newFromText( $name ) : Title::makeTitle( NS_USER, $name );
-               // Check for invalid titles
-               if ( is_null( $t ) ) {
-                       return false;
-               }
-
-               // Reject various classes of invalid names
-               global $wgAuth;
-               $name = $wgAuth->getCanonicalName( $t->getText() );
-
-               switch ( $validate ) {
-                       case false:
-                               break;
-                       case 'valid':
-                               if ( !User::isValidUserName( $name ) ) {
-                                       $name = false;
-                               }
-                               break;
-                       case 'usable':
-                               if ( !User::isUsableName( $name ) ) {
-                                       $name = false;
-                               }
-                               break;
-                       case 'creatable':
-                               if ( !User::isCreatableName( $name ) ) {
-                                       $name = false;
-                               }
-                               break;
-                       default:
-                               throw new InvalidArgumentException(
-                                       'Invalid parameter value for $validate in ' . __METHOD__ );
-               }
-               return $name;
-       }
-
-       /**
-        * Count the number of edits of a user
-        *
-        * @param int $uid User ID to check
-        * @return int The user's edit count
-        *
-        * @deprecated since 1.21 in favour of User::getEditCount
-        */
-       public static function edits( $uid ) {
-               wfDeprecated( __METHOD__, '1.21' );
-               $user = self::newFromId( $uid );
-               return $user->getEditCount();
-       }
-
-       /**
-        * Return a random password.
-        *
-        * @deprecated since 1.27, use PasswordFactory::generateRandomPasswordString()
-        * @return string New random password
-        */
-       public static function randomPassword() {
-               global $wgMinimalPasswordLength;
-               return PasswordFactory::generateRandomPasswordString( $wgMinimalPasswordLength );
-       }
-
-       /**
-        * Set cached properties to default.
-        *
-        * @note This no longer clears uncached lazy-initialised properties;
-        *       the constructor does that instead.
-        *
-        * @param string|bool $name
-        */
-       public function loadDefaults( $name = false ) {
-               $this->mId = 0;
-               $this->mName = $name;
-               $this->mRealName = '';
-               $this->mEmail = '';
-               $this->mOptionOverrides = null;
-               $this->mOptionsLoaded = false;
-
-               $loggedOut = $this->getRequest()->getCookie( 'LoggedOut' );
-               if ( $loggedOut !== null ) {
-                       $this->mTouched = wfTimestamp( TS_MW, $loggedOut );
-               } else {
-                       $this->mTouched = '1'; # Allow any pages to be cached
-               }
-
-               $this->mToken = null; // Don't run cryptographic functions till we need a token
-               $this->mEmailAuthenticated = null;
-               $this->mEmailToken = '';
-               $this->mEmailTokenExpires = null;
-               $this->mRegistration = wfTimestamp( TS_MW );
-               $this->mGroups = array();
-
-               Hooks::run( 'UserLoadDefaults', array( $this, $name ) );
-       }
-
-       /**
-        * Return whether an item has been loaded.
-        *
-        * @param string $item Item to check. Current possibilities:
-        *   - id
-        *   - name
-        *   - realname
-        * @param string $all 'all' to check if the whole object has been loaded
-        *   or any other string to check if only the item is available (e.g.
-        *   for optimisation)
-        * @return bool
-        */
-       public function isItemLoaded( $item, $all = 'all' ) {
-               return ( $this->mLoadedItems === true && $all === 'all' ) ||
-                       ( isset( $this->mLoadedItems[$item] ) && $this->mLoadedItems[$item] === true );
-       }
-
-       /**
-        * Set that an item has been loaded
-        *
-        * @param string $item
-        */
-       protected function setItemLoaded( $item ) {
-               if ( is_array( $this->mLoadedItems ) ) {
-                       $this->mLoadedItems[$item] = true;
-               }
-       }
-
-       /**
-        * Load user data from the session or login cookie.
-        *
-        * @return bool True if the user is logged in, false otherwise.
-        */
-       private function loadFromSession() {
-               $result = null;
-               Hooks::run( 'UserLoadFromSession', array( $this, &$result ) );
-               if ( $result !== null ) {
-                       return $result;
-               }
-
-               $request = $this->getRequest();
-
-               $cookieId = $request->getCookie( 'UserID' );
-               $sessId = $request->getSessionData( 'wsUserID' );
-
-               if ( $cookieId !== null ) {
-                       $sId = intval( $cookieId );
-                       if ( $sessId !== null && $cookieId != $sessId ) {
-                               wfDebugLog( 'loginSessions', "Session user ID ($sessId) and
-                                       cookie user ID ($sId) don't match!" );
-                               return false;
-                       }
-                       $request->setSessionData( 'wsUserID', $sId );
-               } elseif ( $sessId !== null && $sessId != 0 ) {
-                       $sId = $sessId;
-               } else {
-                       return false;
-               }
-
-               if ( $request->getSessionData( 'wsUserName' ) !== null ) {
-                       $sName = $request->getSessionData( 'wsUserName' );
-               } elseif ( $request->getCookie( 'UserName' ) !== null ) {
-                       $sName = $request->getCookie( 'UserName' );
-                       $request->setSessionData( 'wsUserName', $sName );
-               } else {
-                       return false;
-               }
-
-               $proposedUser = User::newFromId( $sId );
-               if ( !$proposedUser->isLoggedIn() ) {
-                       // Not a valid ID
-                       return false;
-               }
-
-               global $wgBlockDisablesLogin;
-               if ( $wgBlockDisablesLogin && $proposedUser->isBlocked() ) {
-                       // User blocked and we've disabled blocked user logins
-                       return false;
-               }
-
-               if ( $request->getSessionData( 'wsToken' ) ) {
-                       $passwordCorrect =
-                               ( $proposedUser->getToken( false ) === $request->getSessionData( 'wsToken' ) );
-                       $from = 'session';
-               } elseif ( $request->getCookie( 'Token' ) ) {
-                       # Get the token from DB/cache and clean it up to remove garbage padding.
-                       # This deals with historical problems with bugs and the default column value.
-                       $token = rtrim( $proposedUser->getToken( false ) ); // correct token
-                       // Make comparison in constant time (bug 61346)
-                       $passwordCorrect = strlen( $token )
-                               && hash_equals( $token, $request->getCookie( 'Token' ) );
-                       $from = 'cookie';
-               } else {
-                       // No session or persistent login cookie
-                       return false;
-               }
-
-               if ( ( $sName === $proposedUser->getName() ) && $passwordCorrect ) {
-                       $this->loadFromUserObject( $proposedUser );
-                       $request->setSessionData( 'wsToken', $this->mToken );
-                       wfDebug( "User: logged in from $from\n" );
-                       return true;
-               } else {
-                       // Invalid credentials
-                       wfDebug( "User: can't log in from $from, invalid credentials\n" );
-                       return false;
-               }
-       }
-
-       /**
-        * Load user and user_group data from the database.
-        * $this->mId must be set, this is how the user is identified.
-        *
-        * @param integer $flags User::READ_* constant bitfield
-        * @return bool True if the user exists, false if the user is anonymous
-        */
-       public function loadFromDatabase( $flags = self::READ_LATEST ) {
-               // Paranoia
-               $this->mId = intval( $this->mId );
-
-               // Anonymous user
-               if ( !$this->mId ) {
-                       $this->loadDefaults();
-                       return false;
-               }
-
-               list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
-               $db = wfGetDB( $index );
-
-               $s = $db->selectRow(
-                       'user',
-                       self::selectFields(),
-                       array( 'user_id' => $this->mId ),
-                       __METHOD__,
-                       $options
-               );
-
-               $this->queryFlagsUsed = $flags;
-               Hooks::run( 'UserLoadFromDatabase', array( $this, &$s ) );
-
-               if ( $s !== false ) {
-                       // Initialise user table data
-                       $this->loadFromRow( $s );
-                       $this->mGroups = null; // deferred
-                       $this->getEditCount(); // revalidation for nulls
-                       return true;
-               } else {
-                       // Invalid user_id
-                       $this->mId = 0;
-                       $this->loadDefaults();
-                       return false;
-               }
-       }
-
-       /**
-        * Initialize this object from a row from the user table.
-        *
-        * @param stdClass $row Row from the user table to load.
-        * @param array $data Further user data to load into the object
-        *
-        *      user_groups             Array with groups out of the user_groups table
-        *      user_properties         Array with properties out of the user_properties table
-        */
-       protected function loadFromRow( $row, $data = null ) {
-               $all = true;
-
-               $this->mGroups = null; // deferred
-
-               if ( isset( $row->user_name ) ) {
-                       $this->mName = $row->user_name;
-                       $this->mFrom = 'name';
-                       $this->setItemLoaded( 'name' );
-               } else {
-                       $all = false;
-               }
-
-               if ( isset( $row->user_real_name ) ) {
-                       $this->mRealName = $row->user_real_name;
-                       $this->setItemLoaded( 'realname' );
-               } else {
-                       $all = false;
-               }
-
-               if ( isset( $row->user_id ) ) {
-                       $this->mId = intval( $row->user_id );
-                       $this->mFrom = 'id';
-                       $this->setItemLoaded( 'id' );
-               } else {
-                       $all = false;
-               }
-
-               if ( isset( $row->user_id ) && isset( $row->user_name ) ) {
-                       self::$idCacheByName[$row->user_name] = $row->user_id;
-               }
-
-               if ( isset( $row->user_editcount ) ) {
-                       $this->mEditCount = $row->user_editcount;
-               } else {
-                       $all = false;
-               }
-
-               if ( isset( $row->user_email ) ) {
-                       $this->mEmail = $row->user_email;
-                       $this->mTouched = wfTimestamp( TS_MW, $row->user_touched );
-                       $this->mToken = $row->user_token;
-                       if ( $this->mToken == '' ) {
-                               $this->mToken = null;
-                       }
-                       $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
-                       $this->mEmailToken = $row->user_email_token;
-                       $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
-                       $this->mRegistration = wfTimestampOrNull( TS_MW, $row->user_registration );
-               } else {
-                       $all = false;
-               }
-
-               if ( $all ) {
-                       $this->mLoadedItems = true;
-               }
-
-               if ( is_array( $data ) ) {
-                       if ( isset( $data['user_groups'] ) && is_array( $data['user_groups'] ) ) {
-                               $this->mGroups = $data['user_groups'];
-                       }
-                       if ( isset( $data['user_properties'] ) && is_array( $data['user_properties'] ) ) {
-                               $this->loadOptions( $data['user_properties'] );
-                       }
-               }
-       }
-
-       /**
-        * Load the data for this user object from another user object.
-        *
-        * @param User $user
-        */
-       protected function loadFromUserObject( $user ) {
-               $user->load();
-               $user->loadGroups();
-               $user->loadOptions();
-               foreach ( self::$mCacheVars as $var ) {
-                       $this->$var = $user->$var;
-               }
-       }
-
-       /**
-        * Load the groups from the database if they aren't already loaded.
-        */
-       private function loadGroups() {
-               if ( is_null( $this->mGroups ) ) {
-                       $db = ( $this->queryFlagsUsed & self::READ_LATEST )
-                               ? wfGetDB( DB_MASTER )
-                               : wfGetDB( DB_SLAVE );
-                       $res = $db->select( 'user_groups',
-                               array( 'ug_group' ),
-                               array( 'ug_user' => $this->mId ),
-                               __METHOD__ );
-                       $this->mGroups = array();
-                       foreach ( $res as $row ) {
-                               $this->mGroups[] = $row->ug_group;
-                       }
-               }
-       }
-
-       /**
-        * Add the user to the group if he/she meets given criteria.
-        *
-        * Contrary to autopromotion by \ref $wgAutopromote, the group will be
-        *   possible to remove manually via Special:UserRights. In such case it
-        *   will not be re-added automatically. The user will also not lose the
-        *   group if they no longer meet the criteria.
-        *
-        * @param string $event Key in $wgAutopromoteOnce (each one has groups/criteria)
-        *
-        * @return array Array of groups the user has been promoted to.
-        *
-        * @see $wgAutopromoteOnce
-        */
-       public function addAutopromoteOnceGroups( $event ) {
-               global $wgAutopromoteOnceLogInRC, $wgAuth;
-
-               if ( wfReadOnly() || !$this->getId() ) {
-                       return array();
-               }
-
-               $toPromote = Autopromote::getAutopromoteOnceGroups( $this, $event );
-               if ( !count( $toPromote ) ) {
-                       return array();
-               }
-
-               if ( !$this->checkAndSetTouched() ) {
-                       return array(); // raced out (bug T48834)
-               }
-
-               $oldGroups = $this->getGroups(); // previous groups
-               foreach ( $toPromote as $group ) {
-                       $this->addGroup( $group );
-               }
-               // update groups in external authentication database
-               Hooks::run( 'UserGroupsChanged', array( $this, $toPromote, array(), false ) );
-               $wgAuth->updateExternalDBGroups( $this, $toPromote );
-
-               $newGroups = array_merge( $oldGroups, $toPromote ); // all groups
-
-               $logEntry = new ManualLogEntry( 'rights', 'autopromote' );
-               $logEntry->setPerformer( $this );
-               $logEntry->setTarget( $this->getUserPage() );
-               $logEntry->setParameters( array(
-                       '4::oldgroups' => $oldGroups,
-                       '5::newgroups' => $newGroups,
-               ) );
-               $logid = $logEntry->insert();
-               if ( $wgAutopromoteOnceLogInRC ) {
-                       $logEntry->publish( $logid );
-               }
-
-               return $toPromote;
-       }
-
-       /**
-        * Bump user_touched if it didn't change since this object was loaded
-        *
-        * On success, the mTouched field is updated.
-        * The user serialization cache is always cleared.
-        *
-        * @return bool Whether user_touched was actually updated
-        * @since 1.26
-        */
-       protected function checkAndSetTouched() {
-               $this->load();
-
-               if ( !$this->mId ) {
-                       return false; // anon
-               }
-
-               // Get a new user_touched that is higher than the old one
-               $oldTouched = $this->mTouched;
-               $newTouched = $this->newTouchedTimestamp();
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update( 'user',
-                       array( 'user_touched' => $dbw->timestamp( $newTouched ) ),
-                       array(
-                               'user_id' => $this->mId,
-                               'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
-                       ),
-                       __METHOD__
-               );
-               $success = ( $dbw->affectedRows() > 0 );
-
-               if ( $success ) {
-                       $this->mTouched = $newTouched;
-                       $this->clearSharedCache();
-               } else {
-                       // Clears on failure too since that is desired if the cache is stale
-                       $this->clearSharedCache( 'refresh' );
-               }
-
-               return $success;
-       }
-
-       /**
-        * Clear various cached data stored in this object. The cache of the user table
-        * data (i.e. self::$mCacheVars) is not cleared unless $reloadFrom is given.
-        *
-        * @param bool|string $reloadFrom Reload user and user_groups table data from a
-        *   given source. May be "name", "id", "defaults", "session", or false for no reload.
-        */
-       public function clearInstanceCache( $reloadFrom = false ) {
-               $this->mNewtalk = -1;
-               $this->mDatePreference = null;
-               $this->mBlockedby = -1; # Unset
-               $this->mHash = false;
-               $this->mRights = null;
-               $this->mEffectiveGroups = null;
-               $this->mImplicitGroups = null;
-               $this->mGroups = null;
-               $this->mOptions = null;
-               $this->mOptionsLoaded = false;
-               $this->mEditCount = null;
-
-               if ( $reloadFrom ) {
-                       $this->mLoadedItems = array();
-                       $this->mFrom = $reloadFrom;
-               }
-       }
-
-       /**
-        * Combine the language default options with any site-specific options
-        * and add the default language variants.
-        *
-        * @return array Array of String options
-        */
-       public static function getDefaultOptions() {
-               global $wgNamespacesToBeSearchedDefault, $wgDefaultUserOptions, $wgContLang, $wgDefaultSkin;
-
-               static $defOpt = null;
-               if ( !defined( 'MW_PHPUNIT_TEST' ) && $defOpt !== null ) {
-                       // Disabling this for the unit tests, as they rely on being able to change $wgContLang
-                       // mid-request and see that change reflected in the return value of this function.
-                       // Which is insane and would never happen during normal MW operation
-                       return $defOpt;
-               }
-
-               $defOpt = $wgDefaultUserOptions;
-               // Default language setting
-               $defOpt['language'] = $wgContLang->getCode();
-               foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
-                       $defOpt[$langCode == $wgContLang->getCode() ? 'variant' : "variant-$langCode"] = $langCode;
-               }
-               foreach ( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
-                       $defOpt['searchNs' . $nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
-               }
-               $defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
-
-               Hooks::run( 'UserGetDefaultOptions', array( &$defOpt ) );
-
-               return $defOpt;
-       }
-
-       /**
-        * Get a given default option value.
-        *
-        * @param string $opt Name of option to retrieve
-        * @return string Default option value
-        */
-       public static function getDefaultOption( $opt ) {
-               $defOpts = self::getDefaultOptions();
-               if ( isset( $defOpts[$opt] ) ) {
-                       return $defOpts[$opt];
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Get blocking information
-        * @param bool $bFromSlave Whether to check the slave database first.
-        *   To improve performance, non-critical checks are done against slaves.
-        *   Check when actually saving should be done against master.
-        */
-       private function getBlockedStatus( $bFromSlave = true ) {
-               global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff;
-
-               if ( -1 != $this->mBlockedby ) {
-                       return;
-               }
-
-               wfDebug( __METHOD__ . ": checking...\n" );
-
-               // Initialize data...
-               // Otherwise something ends up stomping on $this->mBlockedby when
-               // things get lazy-loaded later, causing false positive block hits
-               // due to -1 !== 0. Probably session-related... Nothing should be
-               // overwriting mBlockedby, surely?
-               $this->load();
-
-               # We only need to worry about passing the IP address to the Block generator if the
-               # user is not immune to autoblocks/hardblocks, and they are the current user so we
-               # know which IP address they're actually coming from
-               if ( !$this->isAllowed( 'ipblock-exempt' ) && $this->equals( $wgUser ) ) {
-                       $ip = $this->getRequest()->getIP();
-               } else {
-                       $ip = null;
-               }
-
-               // User/IP blocking
-               $block = Block::newFromTarget( $this, $ip, !$bFromSlave );
-
-               // Proxy blocking
-               if ( !$block instanceof Block && $ip !== null && !$this->isAllowed( 'proxyunbannable' )
-                       && !in_array( $ip, $wgProxyWhitelist )
-               ) {
-                       // Local list
-                       if ( self::isLocallyBlockedProxy( $ip ) ) {
-                               $block = new Block;
-                               $block->setBlocker( wfMessage( 'proxyblocker' )->text() );
-                               $block->mReason = wfMessage( 'proxyblockreason' )->text();
-                               $block->setTarget( $ip );
-                       } elseif ( $this->isAnon() && $this->isDnsBlacklisted( $ip ) ) {
-                               $block = new Block;
-                               $block->setBlocker( wfMessage( 'sorbs' )->text() );
-                               $block->mReason = wfMessage( 'sorbsreason' )->text();
-                               $block->setTarget( $ip );
-                       }
-               }
-
-               // (bug 23343) Apply IP blocks to the contents of XFF headers, if enabled
-               if ( !$block instanceof Block
-                       && $wgApplyIpBlocksToXff
-                       && $ip !== null
-                       && !$this->isAllowed( 'proxyunbannable' )
-                       && !in_array( $ip, $wgProxyWhitelist )
-               ) {
-                       $xff = $this->getRequest()->getHeader( 'X-Forwarded-For' );
-                       $xff = array_map( 'trim', explode( ',', $xff ) );
-                       $xff = array_diff( $xff, array( $ip ) );
-                       $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$bFromSlave );
-                       $block = Block::chooseBlock( $xffblocks, $xff );
-                       if ( $block instanceof Block ) {
-                               # Mangle the reason to alert the user that the block
-                               # originated from matching the X-Forwarded-For header.
-                               $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->text();
-                       }
-               }
-
-               if ( $block instanceof Block ) {
-                       wfDebug( __METHOD__ . ": Found block.\n" );
-                       $this->mBlock = $block;
-                       $this->mBlockedby = $block->getByName();
-                       $this->mBlockreason = $block->mReason;
-                       $this->mHideName = $block->mHideName;
-                       $this->mAllowUsertalk = !$block->prevents( 'editownusertalk' );
-               } else {
-                       $this->mBlockedby = '';
-                       $this->mHideName = 0;
-                       $this->mAllowUsertalk = false;
-               }
-
-               // Extensions
-               Hooks::run( 'GetBlockedStatus', array( &$this ) );
-
-       }
-
-       /**
-        * Whether the given IP is in a DNS blacklist.
-        *
-        * @param string $ip IP to check
-        * @param bool $checkWhitelist Whether to check the whitelist first
-        * @return bool True if blacklisted.
-        */
-       public function isDnsBlacklisted( $ip, $checkWhitelist = false ) {
-               global $wgEnableDnsBlacklist, $wgDnsBlacklistUrls, $wgProxyWhitelist;
-
-               if ( !$wgEnableDnsBlacklist ) {
-                       return false;
-               }
-
-               if ( $checkWhitelist && in_array( $ip, $wgProxyWhitelist ) ) {
-                       return false;
-               }
-
-               return $this->inDnsBlacklist( $ip, $wgDnsBlacklistUrls );
-       }
-
-       /**
-        * Whether the given IP is in a given DNS blacklist.
-        *
-        * @param string $ip IP to check
-        * @param string|array $bases Array of Strings: URL of the DNS blacklist
-        * @return bool True if blacklisted.
-        */
-       public function inDnsBlacklist( $ip, $bases ) {
-
-               $found = false;
-               // @todo FIXME: IPv6 ???  (http://bugs.php.net/bug.php?id=33170)
-               if ( IP::isIPv4( $ip ) ) {
-                       // Reverse IP, bug 21255
-                       $ipReversed = implode( '.', array_reverse( explode( '.', $ip ) ) );
-
-                       foreach ( (array)$bases as $base ) {
-                               // Make hostname
-                               // If we have an access key, use that too (ProjectHoneypot, etc.)
-                               $basename = $base;
-                               if ( is_array( $base ) ) {
-                                       if ( count( $base ) >= 2 ) {
-                                               // Access key is 1, base URL is 0
-                                               $host = "{$base[1]}.$ipReversed.{$base[0]}";
-                                       } else {
-                                               $host = "$ipReversed.{$base[0]}";
-                                       }
-                                       $basename = $base[0];
-                               } else {
-                                       $host = "$ipReversed.$base";
-                               }
-
-                               // Send query
-                               $ipList = gethostbynamel( $host );
-
-                               if ( $ipList ) {
-                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $basename!" );
-                                       $found = true;
-                                       break;
-                               } else {
-                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $basename." );
-                               }
-                       }
-               }
-
-               return $found;
-       }
-
-       /**
-        * Check if an IP address is in the local proxy list
-        *
-        * @param string $ip
-        *
-        * @return bool
-        */
-       public static function isLocallyBlockedProxy( $ip ) {
-               global $wgProxyList;
-
-               if ( !$wgProxyList ) {
-                       return false;
-               }
-
-               if ( !is_array( $wgProxyList ) ) {
-                       // Load from the specified file
-                       $wgProxyList = array_map( 'trim', file( $wgProxyList ) );
-               }
-
-               if ( !is_array( $wgProxyList ) ) {
-                       $ret = false;
-               } elseif ( array_search( $ip, $wgProxyList ) !== false ) {
-                       $ret = true;
-               } elseif ( array_key_exists( $ip, $wgProxyList ) ) {
-                       // Old-style flipped proxy list
-                       $ret = true;
-               } else {
-                       $ret = false;
-               }
-               return $ret;
-       }
-
-       /**
-        * Is this user subject to rate limiting?
-        *
-        * @return bool True if rate limited
-        */
-       public function isPingLimitable() {
-               global $wgRateLimitsExcludedIPs;
-               if ( in_array( $this->getRequest()->getIP(), $wgRateLimitsExcludedIPs ) ) {
-                       // No other good way currently to disable rate limits
-                       // for specific IPs. :P
-                       // But this is a crappy hack and should die.
-                       return false;
-               }
-               return !$this->isAllowed( 'noratelimit' );
-       }
-
-       /**
-        * Primitive rate limits: enforce maximum actions per time period
-        * to put a brake on flooding.
-        *
-        * The method generates both a generic profiling point and a per action one
-        * (suffix being "-$action".
-        *
-        * @note When using a shared cache like memcached, IP-address
-        * last-hit counters will be shared across wikis.
-        *
-        * @param string $action Action to enforce; 'edit' if unspecified
-        * @param int $incrBy Positive amount to increment counter by [defaults to 1]
-        * @return bool True if a rate limiter was tripped
-        */
-       public function pingLimiter( $action = 'edit', $incrBy = 1 ) {
-               // Call the 'PingLimiter' hook
-               $result = false;
-               if ( !Hooks::run( 'PingLimiter', array( &$this, $action, &$result, $incrBy ) ) ) {
-                       return $result;
-               }
-
-               global $wgRateLimits;
-               if ( !isset( $wgRateLimits[$action] ) ) {
-                       return false;
-               }
-
-               // Some groups shouldn't trigger the ping limiter, ever
-               if ( !$this->isPingLimitable() ) {
-                       return false;
-               }
-
-               $limits = $wgRateLimits[$action];
-               $keys = array();
-               $id = $this->getId();
-               $userLimit = false;
-
-               if ( isset( $limits['anon'] ) && $id == 0 ) {
-                       $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
-               }
-
-               if ( isset( $limits['user'] ) && $id != 0 ) {
-                       $userLimit = $limits['user'];
-               }
-               if ( $this->isNewbie() ) {
-                       if ( isset( $limits['newbie'] ) && $id != 0 ) {
-                               $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
-                       }
-                       if ( isset( $limits['ip'] ) ) {
-                               $ip = $this->getRequest()->getIP();
-                               $keys["mediawiki:limiter:$action:ip:$ip"] = $limits['ip'];
-                       }
-                       if ( isset( $limits['subnet'] ) ) {
-                               $ip = $this->getRequest()->getIP();
-                               $matches = array();
-                               $subnet = false;
-                               if ( IP::isIPv6( $ip ) ) {
-                                       $parts = IP::parseRange( "$ip/64" );
-                                       $subnet = $parts[0];
-                               } elseif ( preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
-                                       // IPv4
-                                       $subnet = $matches[1];
-                               }
-                               if ( $subnet !== false ) {
-                                       $keys["mediawiki:limiter:$action:subnet:$subnet"] = $limits['subnet'];
-                               }
-                       }
-               }
-               // Check for group-specific permissions
-               // If more than one group applies, use the group with the highest limit
-               foreach ( $this->getGroups() as $group ) {
-                       if ( isset( $limits[$group] ) ) {
-                               if ( $userLimit === false
-                                       || $limits[$group][0] / $limits[$group][1] > $userLimit[0] / $userLimit[1]
-                               ) {
-                                       $userLimit = $limits[$group];
-                               }
-                       }
-               }
-               // Set the user limit key
-               if ( $userLimit !== false ) {
-                       list( $max, $period ) = $userLimit;
-                       wfDebug( __METHOD__ . ": effective user limit: $max in {$period}s\n" );
-                       $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
-               }
-
-               $cache = ObjectCache::getLocalClusterInstance();
-
-               $triggered = false;
-               foreach ( $keys as $key => $limit ) {
-                       list( $max, $period ) = $limit;
-                       $summary = "(limit $max in {$period}s)";
-                       $count = $cache->get( $key );
-                       // Already pinged?
-                       if ( $count ) {
-                               if ( $count >= $max ) {
-                                       wfDebugLog( 'ratelimit', "User '{$this->getName()}' " .
-                                               "(IP {$this->getRequest()->getIP()}) tripped $key at $count $summary" );
-                                       $triggered = true;
-                               } else {
-                                       wfDebug( __METHOD__ . ": ok. $key at $count $summary\n" );
-                               }
-                       } else {
-                               wfDebug( __METHOD__ . ": adding record for $key $summary\n" );
-                               if ( $incrBy > 0 ) {
-                                       $cache->add( $key, 0, intval( $period ) ); // first ping
-                               }
-                       }
-                       if ( $incrBy > 0 ) {
-                               $cache->incr( $key, $incrBy );
-                       }
-               }
-
-               return $triggered;
-       }
-
-       /**
-        * Check if user is blocked
-        *
-        * @param bool $bFromSlave Whether to check the slave database instead of
-        *   the master. Hacked from false due to horrible probs on site.
-        * @return bool True if blocked, false otherwise
-        */
-       public function isBlocked( $bFromSlave = true ) {
-               return $this->getBlock( $bFromSlave ) instanceof Block && $this->getBlock()->prevents( 'edit' );
-       }
-
-       /**
-        * Get the block affecting the user, or null if the user is not blocked
-        *
-        * @param bool $bFromSlave Whether to check the slave database instead of the master
-        * @return Block|null
-        */
-       public function getBlock( $bFromSlave = true ) {
-               $this->getBlockedStatus( $bFromSlave );
-               return $this->mBlock instanceof Block ? $this->mBlock : null;
-       }
-
-       /**
-        * Check if user is blocked from editing a particular article
-        *
-        * @param Title $title Title to check
-        * @param bool $bFromSlave Whether to check the slave database instead of the master
-        * @return bool
-        */
-       public function isBlockedFrom( $title, $bFromSlave = false ) {
-               global $wgBlockAllowsUTEdit;
-
-               $blocked = $this->isBlocked( $bFromSlave );
-               $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk : false );
-               // If a user's name is suppressed, they cannot make edits anywhere
-               if ( !$this->mHideName && $allowUsertalk && $title->getText() === $this->getName()
-                       && $title->getNamespace() == NS_USER_TALK ) {
-                       $blocked = false;
-                       wfDebug( __METHOD__ . ": self-talk page, ignoring any blocks\n" );
-               }
-
-               Hooks::run( 'UserIsBlockedFrom', array( $this, $title, &$blocked, &$allowUsertalk ) );
-
-               return $blocked;
-       }
-
-       /**
-        * If user is blocked, return the name of the user who placed the block
-        * @return string Name of blocker
-        */
-       public function blockedBy() {
-               $this->getBlockedStatus();
-               return $this->mBlockedby;
-       }
-
-       /**
-        * If user is blocked, return the specified reason for the block
-        * @return string Blocking reason
-        */
-       public function blockedFor() {
-               $this->getBlockedStatus();
-               return $this->mBlockreason;
-       }
-
-       /**
-        * If user is blocked, return the ID for the block
-        * @return int Block ID
-        */
-       public function getBlockId() {
-               $this->getBlockedStatus();
-               return ( $this->mBlock ? $this->mBlock->getId() : false );
-       }
-
-       /**
-        * Check if user is blocked on all wikis.
-        * Do not use for actual edit permission checks!
-        * This is intended for quick UI checks.
-        *
-        * @param string $ip IP address, uses current client if none given
-        * @return bool True if blocked, false otherwise
-        */
-       public function isBlockedGlobally( $ip = '' ) {
-               if ( $this->mBlockedGlobally !== null ) {
-                       return $this->mBlockedGlobally;
-               }
-               // User is already an IP?
-               if ( IP::isIPAddress( $this->getName() ) ) {
-                       $ip = $this->getName();
-               } elseif ( !$ip ) {
-                       $ip = $this->getRequest()->getIP();
-               }
-               $blocked = false;
-               Hooks::run( 'UserIsBlockedGlobally', array( &$this, $ip, &$blocked ) );
-               $this->mBlockedGlobally = (bool)$blocked;
-               return $this->mBlockedGlobally;
-       }
-
-       /**
-        * Check if user account is locked
-        *
-        * @return bool True if locked, false otherwise
-        */
-       public function isLocked() {
-               if ( $this->mLocked !== null ) {
-                       return $this->mLocked;
-               }
-               global $wgAuth;
-               $authUser = $wgAuth->getUserInstance( $this );
-               $this->mLocked = (bool)$authUser->isLocked();
-               Hooks::run( 'UserIsLocked', array( $this, &$this->mLocked ) );
-               return $this->mLocked;
-       }
-
-       /**
-        * Check if user account is hidden
-        *
-        * @return bool True if hidden, false otherwise
-        */
-       public function isHidden() {
-               if ( $this->mHideName !== null ) {
-                       return $this->mHideName;
-               }
-               $this->getBlockedStatus();
-               if ( !$this->mHideName ) {
-                       global $wgAuth;
-                       $authUser = $wgAuth->getUserInstance( $this );
-                       $this->mHideName = (bool)$authUser->isHidden();
-                       Hooks::run( 'UserIsHidden', array( $this, &$this->mHideName ) );
-               }
-               return $this->mHideName;
-       }
-
-       /**
-        * Get the user's ID.
-        * @return int The user's ID; 0 if the user is anonymous or nonexistent
-        */
-       public function getId() {
-               if ( $this->mId === null && $this->mName !== null && User::isIP( $this->mName ) ) {
-                       // Special case, we know the user is anonymous
-                       return 0;
-               } elseif ( !$this->isItemLoaded( 'id' ) ) {
-                       // Don't load if this was initialized from an ID
-                       $this->load();
-               }
-               return $this->mId;
-       }
-
-       /**
-        * Set the user and reload all fields according to a given ID
-        * @param int $v User ID to reload
-        */
-       public function setId( $v ) {
-               $this->mId = $v;
-               $this->clearInstanceCache( 'id' );
-       }
-
-       /**
-        * Get the user name, or the IP of an anonymous user
-        * @return string User's name or IP address
-        */
-       public function getName() {
-               if ( $this->isItemLoaded( 'name', 'only' ) ) {
-                       // Special case optimisation
-                       return $this->mName;
-               } else {
-                       $this->load();
-                       if ( $this->mName === false ) {
-                               // Clean up IPs
-                               $this->mName = IP::sanitizeIP( $this->getRequest()->getIP() );
-                       }
-                       return $this->mName;
-               }
-       }
-
-       /**
-        * Set the user name.
-        *
-        * This does not reload fields from the database according to the given
-        * name. Rather, it is used to create a temporary "nonexistent user" for
-        * later addition to the database. It can also be used to set the IP
-        * address for an anonymous user to something other than the current
-        * remote IP.
-        *
-        * @note User::newFromName() has roughly the same function, when the named user
-        * does not exist.
-        * @param string $str New user name to set
-        */
-       public function setName( $str ) {
-               $this->load();
-               $this->mName = $str;
-       }
-
-       /**
-        * Get the user's name escaped by underscores.
-        * @return string Username escaped by underscores.
-        */
-       public function getTitleKey() {
-               return str_replace( ' ', '_', $this->getName() );
-       }
-
-       /**
-        * Check if the user has new messages.
-        * @return bool True if the user has new messages
-        */
-       public function getNewtalk() {
-               $this->load();
-
-               // Load the newtalk status if it is unloaded (mNewtalk=-1)
-               if ( $this->mNewtalk === -1 ) {
-                       $this->mNewtalk = false; # reset talk page status
-
-                       // Check memcached separately for anons, who have no
-                       // entire User object stored in there.
-                       if ( !$this->mId ) {
-                               global $wgDisableAnonTalk;
-                               if ( $wgDisableAnonTalk ) {
-                                       // Anon newtalk disabled by configuration.
-                                       $this->mNewtalk = false;
-                               } else {
-                                       $this->mNewtalk = $this->checkNewtalk( 'user_ip', $this->getName() );
-                               }
-                       } else {
-                               $this->mNewtalk = $this->checkNewtalk( 'user_id', $this->mId );
-                       }
-               }
-
-               return (bool)$this->mNewtalk;
-       }
-
-       /**
-        * Return the data needed to construct links for new talk page message
-        * alerts. If there are new messages, this will return an associative array
-        * with the following data:
-        *     wiki: The database name of the wiki
-        *     link: Root-relative link to the user's talk page
-        *     rev: The last talk page revision that the user has seen or null. This
-        *         is useful for building diff links.
-        * If there are no new messages, it returns an empty array.
-        * @note This function was designed to accomodate multiple talk pages, but
-        * currently only returns a single link and revision.
-        * @return array
-        */
-       public function getNewMessageLinks() {
-               $talks = array();
-               if ( !Hooks::run( 'UserRetrieveNewTalks', array( &$this, &$talks ) ) ) {
-                       return $talks;
-               } elseif ( !$this->getNewtalk() ) {
-                       return array();
-               }
-               $utp = $this->getTalkPage();
-               $dbr = wfGetDB( DB_SLAVE );
-               // Get the "last viewed rev" timestamp from the oldest message notification
-               $timestamp = $dbr->selectField( 'user_newtalk',
-                       'MIN(user_last_timestamp)',
-                       $this->isAnon() ? array( 'user_ip' => $this->getName() ) : array( 'user_id' => $this->getID() ),
-                       __METHOD__ );
-               $rev = $timestamp ? Revision::loadFromTimestamp( $dbr, $utp, $timestamp ) : null;
-               return array( array( 'wiki' => wfWikiID(), 'link' => $utp->getLocalURL(), 'rev' => $rev ) );
-       }
-
-       /**
-        * Get the revision ID for the last talk page revision viewed by the talk
-        * page owner.
-        * @return int|null Revision ID or null
-        */
-       public function getNewMessageRevisionId() {
-               $newMessageRevisionId = null;
-               $newMessageLinks = $this->getNewMessageLinks();
-               if ( $newMessageLinks ) {
-                       // Note: getNewMessageLinks() never returns more than a single link
-                       // and it is always for the same wiki, but we double-check here in
-                       // case that changes some time in the future.
-                       if ( count( $newMessageLinks ) === 1
-                               && $newMessageLinks[0]['wiki'] === wfWikiID()
-                               && $newMessageLinks[0]['rev']
-                       ) {
-                               /** @var Revision $newMessageRevision */
-                               $newMessageRevision = $newMessageLinks[0]['rev'];
-                               $newMessageRevisionId = $newMessageRevision->getId();
-                       }
-               }
-               return $newMessageRevisionId;
-       }
-
-       /**
-        * Internal uncached check for new messages
-        *
-        * @see getNewtalk()
-        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
-        * @param string|int $id User's IP address for anonymous users, User ID otherwise
-        * @return bool True if the user has new messages
-        */
-       protected function checkNewtalk( $field, $id ) {
-               $dbr = wfGetDB( DB_SLAVE );
-
-               $ok = $dbr->selectField( 'user_newtalk', $field, array( $field => $id ), __METHOD__ );
-
-               return $ok !== false;
-       }
-
-       /**
-        * Add or update the new messages flag
-        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
-        * @param string|int $id User's IP address for anonymous users, User ID otherwise
-        * @param Revision|null $curRev New, as yet unseen revision of the user talk page. Ignored if null.
-        * @return bool True if successful, false otherwise
-        */
-       protected function updateNewtalk( $field, $id, $curRev = null ) {
-               // Get timestamp of the talk page revision prior to the current one
-               $prevRev = $curRev ? $curRev->getPrevious() : false;
-               $ts = $prevRev ? $prevRev->getTimestamp() : null;
-               // Mark the user as having new messages since this revision
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->insert( 'user_newtalk',
-                       array( $field => $id, 'user_last_timestamp' => $dbw->timestampOrNull( $ts ) ),
-                       __METHOD__,
-                       'IGNORE' );
-               if ( $dbw->affectedRows() ) {
-                       wfDebug( __METHOD__ . ": set on ($field, $id)\n" );
-                       return true;
-               } else {
-                       wfDebug( __METHOD__ . " already set ($field, $id)\n" );
-                       return false;
-               }
-       }
-
-       /**
-        * Clear the new messages flag for the given user
-        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
-        * @param string|int $id User's IP address for anonymous users, User ID otherwise
-        * @return bool True if successful, false otherwise
-        */
-       protected function deleteNewtalk( $field, $id ) {
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'user_newtalk',
-                       array( $field => $id ),
-                       __METHOD__ );
-               if ( $dbw->affectedRows() ) {
-                       wfDebug( __METHOD__ . ": killed on ($field, $id)\n" );
-                       return true;
-               } else {
-                       wfDebug( __METHOD__ . ": already gone ($field, $id)\n" );
-                       return false;
-               }
-       }
-
-       /**
-        * Update the 'You have new messages!' status.
-        * @param bool $val Whether the user has new messages
-        * @param Revision $curRev New, as yet unseen revision of the user talk
-        *   page. Ignored if null or !$val.
-        */
-       public function setNewtalk( $val, $curRev = null ) {
-               if ( wfReadOnly() ) {
-                       return;
-               }
-
-               $this->load();
-               $this->mNewtalk = $val;
-
-               if ( $this->isAnon() ) {
-                       $field = 'user_ip';
-                       $id = $this->getName();
-               } else {
-                       $field = 'user_id';
-                       $id = $this->getId();
-               }
-
-               if ( $val ) {
-                       $changed = $this->updateNewtalk( $field, $id, $curRev );
-               } else {
-                       $changed = $this->deleteNewtalk( $field, $id );
-               }
-
-               if ( $changed ) {
-                       $this->invalidateCache();
-               }
-       }
-
-       /**
-        * Generate a current or new-future timestamp to be stored in the
-        * user_touched field when we update things.
-        * @return string Timestamp in TS_MW format
-        */
-       private function newTouchedTimestamp() {
-               global $wgClockSkewFudge;
-
-               $time = wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
-               if ( $this->mTouched && $time <= $this->mTouched ) {
-                       $time = wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $this->mTouched ) + 1 );
-               }
-
-               return $time;
-       }
-
-       /**
-        * Clear user data from memcached
-        *
-        * Use after applying updates to the database; caller's
-        * responsibility to update user_touched if appropriate.
-        *
-        * Called implicitly from invalidateCache() and saveSettings().
-        *
-        * @param string $mode Use 'refresh' to clear now; otherwise before DB commit
-        */
-       public function clearSharedCache( $mode = 'changed' ) {
-               if ( !$this->getId() ) {
-                       return;
-               }
-
-               $cache = ObjectCache::getMainWANInstance();
-               $key = $this->getCacheKey( $cache );
-               if ( $mode === 'refresh' ) {
-                       $cache->delete( $key, 1 );
-               } else {
-                       wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $cache, $key ) {
-                               $cache->delete( $key );
-                       } );
-               }
-       }
-
-       /**
-        * Immediately touch the user data cache for this account
-        *
-        * Calls touch() and removes account data from memcached
-        */
-       public function invalidateCache() {
-               $this->touch();
-               $this->clearSharedCache();
-       }
-
-       /**
-        * Update the "touched" timestamp for the user
-        *
-        * This is useful on various login/logout events when making sure that
-        * a browser or proxy that has multiple tenants does not suffer cache
-        * pollution where the new user sees the old users content. The value
-        * of getTouched() is checked when determining 304 vs 200 responses.
-        * Unlike invalidateCache(), this preserves the User object cache and
-        * avoids database writes.
-        *
-        * @since 1.25
-        */
-       public function touch() {
-               $id = $this->getId();
-               if ( $id ) {
-                       $key = wfMemcKey( 'user-quicktouched', 'id', $id );
-                       ObjectCache::getMainWANInstance()->touchCheckKey( $key );
-                       $this->mQuickTouched = null;
-               }
-       }
-
-       /**
-        * Validate the cache for this account.
-        * @param string $timestamp A timestamp in TS_MW format
-        * @return bool
-        */
-       public function validateCache( $timestamp ) {
-               return ( $timestamp >= $this->getTouched() );
-       }
-
-       /**
-        * Get the user touched timestamp
-        *
-        * Use this value only to validate caches via inequalities
-        * such as in the case of HTTP If-Modified-Since response logic
-        *
-        * @return string TS_MW Timestamp
-        */
-       public function getTouched() {
-               $this->load();
-
-               if ( $this->mId ) {
-                       if ( $this->mQuickTouched === null ) {
-                               $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId );
-                               $cache = ObjectCache::getMainWANInstance();
-
-                               $this->mQuickTouched = wfTimestamp( TS_MW, $cache->getCheckKeyTime( $key ) );
-                       }
-
-                       return max( $this->mTouched, $this->mQuickTouched );
-               }
-
-               return $this->mTouched;
-       }
-
-       /**
-        * Get the user_touched timestamp field (time of last DB updates)
-        * @return string TS_MW Timestamp
-        * @since 1.26
-        */
-       public function getDBTouched() {
-               $this->load();
-
-               return $this->mTouched;
-       }
-
-       /**
-        * @deprecated Removed in 1.27.
-        * @return Password
-        * @since 1.24
-        */
-       public function getPassword() {
-               throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
-       }
-
-       /**
-        * @deprecated Removed in 1.27.
-        * @return Password
-        * @since 1.24
-        */
-       public function getTemporaryPassword() {
-               throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
-       }
-
-       /**
-        * Set the password and reset the random token.
-        * Calls through to authentication plugin if necessary;
-        * will have no effect if the auth plugin refuses to
-        * pass the change through or if the legal password
-        * checks fail.
-        *
-        * As a special case, setting the password to null
-        * wipes it, so the account cannot be logged in until
-        * a new password is set, for instance via e-mail.
-        *
-        * @deprecated since 1.27. AuthManager is coming.
-        * @param string $str New password to set
-        * @throws PasswordError On failure
-        * @return bool
-        */
-       public function setPassword( $str ) {
-               global $wgAuth;
-
-               if ( $str !== null ) {
-                       if ( !$wgAuth->allowPasswordChange() ) {
-                               throw new PasswordError( wfMessage( 'password-change-forbidden' )->text() );
-                       }
-
-                       $status = $this->checkPasswordValidity( $str );
-                       if ( !$status->isGood() ) {
-                               throw new PasswordError( $status->getMessage()->text() );
-                       }
-               }
-
-               if ( !$wgAuth->setPassword( $this, $str ) ) {
-                       throw new PasswordError( wfMessage( 'externaldberror' )->text() );
-               }
-
-               $this->setToken();
-               $this->setOption( 'watchlisttoken', false );
-               $this->setPasswordInternal( $str );
-
-               return true;
-       }
-
-       /**
-        * Set the password and reset the random token unconditionally.
-        *
-        * @deprecated since 1.27. AuthManager is coming.
-        * @param string|null $str New password to set or null to set an invalid
-        *  password hash meaning that the user will not be able to log in
-        *  through the web interface.
-        */
-       public function setInternalPassword( $str ) {
-               global $wgAuth;
-
-               if ( $wgAuth->allowSetLocalPassword() ) {
-                       $this->setToken();
-                       $this->setOption( 'watchlisttoken', false );
-                       $this->setPasswordInternal( $str );
-               }
-       }
-
-       /**
-        * Actually set the password and such
-        * @since 1.27 cannot set a password for a user not in the database
-        * @param string|null $str New password to set or null to set an invalid
-        *  password hash meaning that the user will not be able to log in
-        *  through the web interface.
-        */
-       private function setPasswordInternal( $str ) {
-               $id = self::idFromName( $this->getName(), self::READ_LATEST );
-               if ( $id == 0 ) {
-                       throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
-               }
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update(
-                       'user',
-                       array(
-                               'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
-                               'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
-                               'user_newpass_time' => $dbw->timestampOrNull( null ),
-                       ),
-                       array(
-                               'user_id' => $id,
-                       ),
-                       __METHOD__
-               );
-       }
-
-       /**
-        * Get the user's current token.
-        * @param bool $forceCreation Force the generation of a new token if the
-        *   user doesn't have one (default=true for backwards compatibility).
-        * @return string Token
-        */
-       public function getToken( $forceCreation = true ) {
-               $this->load();
-               if ( !$this->mToken && $forceCreation ) {
-                       $this->setToken();
-               }
-               return $this->mToken;
-       }
-
-       /**
-        * Set the random token (used for persistent authentication)
-        * Called from loadDefaults() among other places.
-        *
-        * @param string|bool $token If specified, set the token to this value
-        */
-       public function setToken( $token = false ) {
-               $this->load();
-               if ( !$token ) {
-                       $this->mToken = MWCryptRand::generateHex( self::TOKEN_LENGTH );
-               } else {
-                       $this->mToken = $token;
-               }
-       }
-
-       /**
-        * Set the password for a password reminder or new account email
-        *
-        * @deprecated since 1.27, AuthManager is coming
-        * @param string $str New password to set or null to set an invalid
-        *  password hash meaning that the user will not be able to use it
-        * @param bool $throttle If true, reset the throttle timestamp to the present
-        */
-       public function setNewpassword( $str, $throttle = true ) {
-               $id = $this->getId();
-               if ( $id == 0 ) {
-                       throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $update = array(
-                       'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
-               );
-
-               if ( $str === null ) {
-                       $update['user_newpass_time'] = null;
-               } elseif ( $throttle ) {
-                       $update['user_newpass_time'] = $dbw->timestamp();
-               }
-
-               $dbw->update( 'user', $update, array( 'user_id' => $id ), __METHOD__ );
-       }
-
-       /**
-        * Has password reminder email been sent within the last
-        * $wgPasswordReminderResendTime hours?
-        * @return bool
-        */
-       public function isPasswordReminderThrottled() {
-               global $wgPasswordReminderResendTime;
-
-               if ( !$wgPasswordReminderResendTime ) {
-                       return false;
-               }
-
-               $this->load();
-
-               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-               $newpassTime = $db->selectField(
-                       'user',
-                       'user_newpass_time',
-                       array( 'user_id' => $this->getId() ),
-                       __METHOD__
-               );
-
-               if ( $newpassTime === null ) {
-                       return false;
-               }
-               $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
-               return time() < $expiry;
-       }
-
-       /**
-        * Get the user's e-mail address
-        * @return string User's email address
-        */
-       public function getEmail() {
-               $this->load();
-               Hooks::run( 'UserGetEmail', array( $this, &$this->mEmail ) );
-               return $this->mEmail;
-       }
-
-       /**
-        * Get the timestamp of the user's e-mail authentication
-        * @return string TS_MW timestamp
-        */
-       public function getEmailAuthenticationTimestamp() {
-               $this->load();
-               Hooks::run( 'UserGetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
-               return $this->mEmailAuthenticated;
-       }
-
-       /**
-        * Set the user's e-mail address
-        * @param string $str New e-mail address
-        */
-       public function setEmail( $str ) {
-               $this->load();
-               if ( $str == $this->mEmail ) {
-                       return;
-               }
-               $this->invalidateEmail();
-               $this->mEmail = $str;
-               Hooks::run( 'UserSetEmail', array( $this, &$this->mEmail ) );
-       }
-
-       /**
-        * Set the user's e-mail address and a confirmation mail if needed.
-        *
-        * @since 1.20
-        * @param string $str New e-mail address
-        * @return Status
-        */
-       public function setEmailWithConfirmation( $str ) {
-               global $wgEnableEmail, $wgEmailAuthentication;
-
-               if ( !$wgEnableEmail ) {
-                       return Status::newFatal( 'emaildisabled' );
-               }
-
-               $oldaddr = $this->getEmail();
-               if ( $str === $oldaddr ) {
-                       return Status::newGood( true );
-               }
-
-               $this->setEmail( $str );
-
-               if ( $str !== '' && $wgEmailAuthentication ) {
-                       // Send a confirmation request to the new address if needed
-                       $type = $oldaddr != '' ? 'changed' : 'set';
-                       $result = $this->sendConfirmationMail( $type );
-                       if ( $result->isGood() ) {
-                               // Say to the caller that a confirmation mail has been sent
-                               $result->value = 'eauth';
-                       }
-               } else {
-                       $result = Status::newGood( true );
-               }
-
-               return $result;
-       }
-
-       /**
-        * Get the user's real name
-        * @return string User's real name
-        */
-       public function getRealName() {
-               if ( !$this->isItemLoaded( 'realname' ) ) {
-                       $this->load();
-               }
-
-               return $this->mRealName;
-       }
-
-       /**
-        * Set the user's real name
-        * @param string $str New real name
-        */
-       public function setRealName( $str ) {
-               $this->load();
-               $this->mRealName = $str;
-       }
-
-       /**
-        * Get the user's current setting for a given option.
-        *
-        * @param string $oname The option to check
-        * @param string $defaultOverride A default value returned if the option does not exist
-        * @param bool $ignoreHidden Whether to ignore the effects of $wgHiddenPrefs
-        * @return string User's current value for the option
-        * @see getBoolOption()
-        * @see getIntOption()
-        */
-       public function getOption( $oname, $defaultOverride = null, $ignoreHidden = false ) {
-               global $wgHiddenPrefs;
-               $this->loadOptions();
-
-               # We want 'disabled' preferences to always behave as the default value for
-               # users, even if they have set the option explicitly in their settings (ie they
-               # set it, and then it was disabled removing their ability to change it).  But
-               # we don't want to erase the preferences in the database in case the preference
-               # is re-enabled again.  So don't touch $mOptions, just override the returned value
-               if ( !$ignoreHidden && in_array( $oname, $wgHiddenPrefs ) ) {
-                       return self::getDefaultOption( $oname );
-               }
-
-               if ( array_key_exists( $oname, $this->mOptions ) ) {
-                       return $this->mOptions[$oname];
-               } else {
-                       return $defaultOverride;
-               }
-       }
-
-       /**
-        * Get all user's options
-        *
-        * @param int $flags Bitwise combination of:
-        *   User::GETOPTIONS_EXCLUDE_DEFAULTS  Exclude user options that are set
-        *                                      to the default value. (Since 1.25)
-        * @return array
-        */
-       public function getOptions( $flags = 0 ) {
-               global $wgHiddenPrefs;
-               $this->loadOptions();
-               $options = $this->mOptions;
-
-               # We want 'disabled' preferences to always behave as the default value for
-               # users, even if they have set the option explicitly in their settings (ie they
-               # set it, and then it was disabled removing their ability to change it).  But
-               # we don't want to erase the preferences in the database in case the preference
-               # is re-enabled again.  So don't touch $mOptions, just override the returned value
-               foreach ( $wgHiddenPrefs as $pref ) {
-                       $default = self::getDefaultOption( $pref );
-                       if ( $default !== null ) {
-                               $options[$pref] = $default;
-                       }
-               }
-
-               if ( $flags & self::GETOPTIONS_EXCLUDE_DEFAULTS ) {
-                       $options = array_diff_assoc( $options, self::getDefaultOptions() );
-               }
-
-               return $options;
-       }
-
-       /**
-        * Get the user's current setting for a given option, as a boolean value.
-        *
-        * @param string $oname The option to check
-        * @return bool User's current value for the option
-        * @see getOption()
-        */
-       public function getBoolOption( $oname ) {
-               return (bool)$this->getOption( $oname );
-       }
-
-       /**
-        * Get the user's current setting for a given option, as an integer value.
-        *
-        * @param string $oname The option to check
-        * @param int $defaultOverride A default value returned if the option does not exist
-        * @return int User's current value for the option
-        * @see getOption()
-        */
-       public function getIntOption( $oname, $defaultOverride = 0 ) {
-               $val = $this->getOption( $oname );
-               if ( $val == '' ) {
-                       $val = $defaultOverride;
-               }
-               return intval( $val );
-       }
-
-       /**
-        * Set the given option for a user.
-        *
-        * You need to call saveSettings() to actually write to the database.
-        *
-        * @param string $oname The option to set
-        * @param mixed $val New value to set
-        */
-       public function setOption( $oname, $val ) {
-               $this->loadOptions();
-
-               // Explicitly NULL values should refer to defaults
-               if ( is_null( $val ) ) {
-                       $val = self::getDefaultOption( $oname );
-               }
-
-               $this->mOptions[$oname] = $val;
-       }
-
-       /**
-        * Get a token stored in the preferences (like the watchlist one),
-        * resetting it if it's empty (and saving changes).
-        *
-        * @param string $oname The option name to retrieve the token from
-        * @return string|bool User's current value for the option, or false if this option is disabled.
-        * @see resetTokenFromOption()
-        * @see getOption()
-        * @deprecated 1.26 Applications should use the OAuth extension
-        */
-       public function getTokenFromOption( $oname ) {
-               global $wgHiddenPrefs;
-
-               $id = $this->getId();
-               if ( !$id || in_array( $oname, $wgHiddenPrefs ) ) {
-                       return false;
-               }
-
-               $token = $this->getOption( $oname );
-               if ( !$token ) {
-                       // Default to a value based on the user token to avoid space
-                       // wasted on storing tokens for all users. When this option
-                       // is set manually by the user, only then is it stored.
-                       $token = hash_hmac( 'sha1', "$oname:$id", $this->getToken() );
-               }
-
-               return $token;
-       }
-
-       /**
-        * Reset a token stored in the preferences (like the watchlist one).
-        * *Does not* save user's preferences (similarly to setOption()).
-        *
-        * @param string $oname The option name to reset the token in
-        * @return string|bool New token value, or false if this option is disabled.
-        * @see getTokenFromOption()
-        * @see setOption()
-        */
-       public function resetTokenFromOption( $oname ) {
-               global $wgHiddenPrefs;
-               if ( in_array( $oname, $wgHiddenPrefs ) ) {
-                       return false;
-               }
-
-               $token = MWCryptRand::generateHex( 40 );
-               $this->setOption( $oname, $token );
-               return $token;
-       }
-
-       /**
-        * Return a list of the types of user options currently returned by
-        * User::getOptionKinds().
-        *
-        * Currently, the option kinds are:
-        * - 'registered' - preferences which are registered in core MediaWiki or
-        *                  by extensions using the UserGetDefaultOptions hook.
-        * - 'registered-multiselect' - as above, using the 'multiselect' type.
-        * - 'registered-checkmatrix' - as above, using the 'checkmatrix' type.
-        * - 'userjs' - preferences with names starting with 'userjs-', intended to
-        *              be used by user scripts.
-        * - 'special' - "preferences" that are not accessible via User::getOptions
-        *               or User::setOptions.
-        * - 'unused' - preferences about which MediaWiki doesn't know anything.
-        *              These are usually legacy options, removed in newer versions.
-        *
-        * The API (and possibly others) use this function to determine the possible
-        * option types for validation purposes, so make sure to update this when a
-        * new option kind is added.
-        *
-        * @see User::getOptionKinds
-        * @return array Option kinds
-        */
-       public static function listOptionKinds() {
-               return array(
-                       'registered',
-                       'registered-multiselect',
-                       'registered-checkmatrix',
-                       'userjs',
-                       'special',
-                       'unused'
-               );
-       }
-
-       /**
-        * Return an associative array mapping preferences keys to the kind of a preference they're
-        * used for. Different kinds are handled differently when setting or reading preferences.
-        *
-        * See User::listOptionKinds for the list of valid option types that can be provided.
-        *
-        * @see User::listOptionKinds
-        * @param IContextSource $context
-        * @param array $options Assoc. array with options keys to check as keys.
-        *   Defaults to $this->mOptions.
-        * @return array The key => kind mapping data
-        */
-       public function getOptionKinds( IContextSource $context, $options = null ) {
-               $this->loadOptions();
-               if ( $options === null ) {
-                       $options = $this->mOptions;
-               }
-
-               $prefs = Preferences::getPreferences( $this, $context );
-               $mapping = array();
-
-               // Pull out the "special" options, so they don't get converted as
-               // multiselect or checkmatrix.
-               $specialOptions = array_fill_keys( Preferences::getSaveBlacklist(), true );
-               foreach ( $specialOptions as $name => $value ) {
-                       unset( $prefs[$name] );
-               }
-
-               // Multiselect and checkmatrix options are stored in the database with
-               // one key per option, each having a boolean value. Extract those keys.
-               $multiselectOptions = array();
-               foreach ( $prefs as $name => $info ) {
-                       if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
-                                       ( isset( $info['class'] ) && $info['class'] == 'HTMLMultiSelectField' ) ) {
-                               $opts = HTMLFormField::flattenOptions( $info['options'] );
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
-
-                               foreach ( $opts as $value ) {
-                                       $multiselectOptions["$prefix$value"] = true;
-                               }
-
-                               unset( $prefs[$name] );
-                       }
-               }
-               $checkmatrixOptions = array();
-               foreach ( $prefs as $name => $info ) {
-                       if ( ( isset( $info['type'] ) && $info['type'] == 'checkmatrix' ) ||
-                                       ( isset( $info['class'] ) && $info['class'] == 'HTMLCheckMatrix' ) ) {
-                               $columns = HTMLFormField::flattenOptions( $info['columns'] );
-                               $rows = HTMLFormField::flattenOptions( $info['rows'] );
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
-
-                               foreach ( $columns as $column ) {
-                                       foreach ( $rows as $row ) {
-                                               $checkmatrixOptions["$prefix$column-$row"] = true;
-                                       }
-                               }
-
-                               unset( $prefs[$name] );
-                       }
-               }
-
-               // $value is ignored
-               foreach ( $options as $key => $value ) {
-                       if ( isset( $prefs[$key] ) ) {
-                               $mapping[$key] = 'registered';
-                       } elseif ( isset( $multiselectOptions[$key] ) ) {
-                               $mapping[$key] = 'registered-multiselect';
-                       } elseif ( isset( $checkmatrixOptions[$key] ) ) {
-                               $mapping[$key] = 'registered-checkmatrix';
-                       } elseif ( isset( $specialOptions[$key] ) ) {
-                               $mapping[$key] = 'special';
-                       } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
-                               $mapping[$key] = 'userjs';
-                       } else {
-                               $mapping[$key] = 'unused';
-                       }
-               }
-
-               return $mapping;
-       }
-
-       /**
-        * Reset certain (or all) options to the site defaults
-        *
-        * The optional parameter determines which kinds of preferences will be reset.
-        * Supported values are everything that can be reported by getOptionKinds()
-        * and 'all', which forces a reset of *all* preferences and overrides everything else.
-        *
-        * @param array|string $resetKinds Which kinds of preferences to reset. Defaults to
-        *  array( 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' )
-        *  for backwards-compatibility.
-        * @param IContextSource|null $context Context source used when $resetKinds
-        *  does not contain 'all', passed to getOptionKinds().
-        *  Defaults to RequestContext::getMain() when null.
-        */
-       public function resetOptions(
-               $resetKinds = array( 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' ),
-               IContextSource $context = null
-       ) {
-               $this->load();
-               $defaultOptions = self::getDefaultOptions();
-
-               if ( !is_array( $resetKinds ) ) {
-                       $resetKinds = array( $resetKinds );
-               }
-
-               if ( in_array( 'all', $resetKinds ) ) {
-                       $newOptions = $defaultOptions;
-               } else {
-                       if ( $context === null ) {
-                               $context = RequestContext::getMain();
-                       }
-
-                       $optionKinds = $this->getOptionKinds( $context );
-                       $resetKinds = array_intersect( $resetKinds, self::listOptionKinds() );
-                       $newOptions = array();
-
-                       // Use default values for the options that should be deleted, and
-                       // copy old values for the ones that shouldn't.
-                       foreach ( $this->mOptions as $key => $value ) {
-                               if ( in_array( $optionKinds[$key], $resetKinds ) ) {
-                                       if ( array_key_exists( $key, $defaultOptions ) ) {
-                                               $newOptions[$key] = $defaultOptions[$key];
-                                       }
-                               } else {
-                                       $newOptions[$key] = $value;
-                               }
-                       }
-               }
-
-               Hooks::run( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) );
-
-               $this->mOptions = $newOptions;
-               $this->mOptionsLoaded = true;
-       }
-
-       /**
-        * Get the user's preferred date format.
-        * @return string User's preferred date format
-        */
-       public function getDatePreference() {
-               // Important migration for old data rows
-               if ( is_null( $this->mDatePreference ) ) {
-                       global $wgLang;
-                       $value = $this->getOption( 'date' );
-                       $map = $wgLang->getDatePreferenceMigrationMap();
-                       if ( isset( $map[$value] ) ) {
-                               $value = $map[$value];
-                       }
-                       $this->mDatePreference = $value;
-               }
-               return $this->mDatePreference;
-       }
-
-       /**
-        * Determine based on the wiki configuration and the user's options,
-        * whether this user must be over HTTPS no matter what.
-        *
-        * @return bool
-        */
-       public function requiresHTTPS() {
-               global $wgSecureLogin;
-               if ( !$wgSecureLogin ) {
-                       return false;
-               } else {
-                       $https = $this->getBoolOption( 'prefershttps' );
-                       Hooks::run( 'UserRequiresHTTPS', array( $this, &$https ) );
-                       if ( $https ) {
-                               $https = wfCanIPUseHTTPS( $this->getRequest()->getIP() );
-                       }
-                       return $https;
-               }
-       }
-
-       /**
-        * Get the user preferred stub threshold
-        *
-        * @return int
-        */
-       public function getStubThreshold() {
-               global $wgMaxArticleSize; # Maximum article size, in Kb
-               $threshold = $this->getIntOption( 'stubthreshold' );
-               if ( $threshold > $wgMaxArticleSize * 1024 ) {
-                       // If they have set an impossible value, disable the preference
-                       // so we can use the parser cache again.
-                       $threshold = 0;
-               }
-               return $threshold;
-       }
-
-       /**
-        * Get the permissions this user has.
-        * @return array Array of String permission names
-        */
-       public function getRights() {
-               if ( is_null( $this->mRights ) ) {
-                       $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
-                       Hooks::run( 'UserGetRights', array( $this, &$this->mRights ) );
-                       // Force reindexation of rights when a hook has unset one of them
-                       $this->mRights = array_values( array_unique( $this->mRights ) );
-               }
-               return $this->mRights;
-       }
-
-       /**
-        * Get the list of explicit group memberships this user has.
-        * The implicit * and user groups are not included.
-        * @return array Array of String internal group names
-        */
-       public function getGroups() {
-               $this->load();
-               $this->loadGroups();
-               return $this->mGroups;
-       }
-
-       /**
-        * Get the list of implicit group memberships this user has.
-        * This includes all explicit groups, plus 'user' if logged in,
-        * '*' for all accounts, and autopromoted groups
-        * @param bool $recache Whether to avoid the cache
-        * @return array Array of String internal group names
-        */
-       public function getEffectiveGroups( $recache = false ) {
-               if ( $recache || is_null( $this->mEffectiveGroups ) ) {
-                       $this->mEffectiveGroups = array_unique( array_merge(
-                               $this->getGroups(), // explicit groups
-                               $this->getAutomaticGroups( $recache ) // implicit groups
-                       ) );
-                       // Hook for additional groups
-                       Hooks::run( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
-                       // Force reindexation of groups when a hook has unset one of them
-                       $this->mEffectiveGroups = array_values( array_unique( $this->mEffectiveGroups ) );
-               }
-               return $this->mEffectiveGroups;
-       }
-
-       /**
-        * Get the list of implicit group memberships this user has.
-        * This includes 'user' if logged in, '*' for all accounts,
-        * and autopromoted groups
-        * @param bool $recache Whether to avoid the cache
-        * @return array Array of String internal group names
-        */
-       public function getAutomaticGroups( $recache = false ) {
-               if ( $recache || is_null( $this->mImplicitGroups ) ) {
-                       $this->mImplicitGroups = array( '*' );
-                       if ( $this->getId() ) {
-                               $this->mImplicitGroups[] = 'user';
-
-                               $this->mImplicitGroups = array_unique( array_merge(
-                                       $this->mImplicitGroups,
-                                       Autopromote::getAutopromoteGroups( $this )
-                               ) );
-                       }
-                       if ( $recache ) {
-                               // Assure data consistency with rights/groups,
-                               // as getEffectiveGroups() depends on this function
-                               $this->mEffectiveGroups = null;
-                       }
-               }
-               return $this->mImplicitGroups;
-       }
-
-       /**
-        * Returns the groups the user has belonged to.
-        *
-        * The user may still belong to the returned groups. Compare with getGroups().
-        *
-        * The function will not return groups the user had belonged to before MW 1.17
-        *
-        * @return array Names of the groups the user has belonged to.
-        */
-       public function getFormerGroups() {
-               $this->load();
-
-               if ( is_null( $this->mFormerGroups ) ) {
-                       $db = ( $this->queryFlagsUsed & self::READ_LATEST )
-                               ? wfGetDB( DB_MASTER )
-                               : wfGetDB( DB_SLAVE );
-                       $res = $db->select( 'user_former_groups',
-                               array( 'ufg_group' ),
-                               array( 'ufg_user' => $this->mId ),
-                               __METHOD__ );
-                       $this->mFormerGroups = array();
-                       foreach ( $res as $row ) {
-                               $this->mFormerGroups[] = $row->ufg_group;
-                       }
-               }
-
-               return $this->mFormerGroups;
-       }
-
-       /**
-        * Get the user's edit count.
-        * @return int|null Null for anonymous users
-        */
-       public function getEditCount() {
-               if ( !$this->getId() ) {
-                       return null;
-               }
-
-               if ( $this->mEditCount === null ) {
-                       /* Populate the count, if it has not been populated yet */
-                       $dbr = wfGetDB( DB_SLAVE );
-                       // check if the user_editcount field has been initialized
-                       $count = $dbr->selectField(
-                               'user', 'user_editcount',
-                               array( 'user_id' => $this->mId ),
-                               __METHOD__
-                       );
-
-                       if ( $count === null ) {
-                               // it has not been initialized. do so.
-                               $count = $this->initEditCount();
-                       }
-                       $this->mEditCount = $count;
-               }
-               return (int)$this->mEditCount;
-       }
-
-       /**
-        * Add the user to the given group.
-        * This takes immediate effect.
-        * @param string $group Name of the group to add
-        * @return bool
-        */
-       public function addGroup( $group ) {
-               $this->load();
-
-               if ( !Hooks::run( 'UserAddGroup', array( $this, &$group ) ) ) {
-                       return false;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               if ( $this->getId() ) {
-                       $dbw->insert( 'user_groups',
-                               array(
-                                       'ug_user' => $this->getID(),
-                                       'ug_group' => $group,
-                               ),
-                               __METHOD__,
-                               array( 'IGNORE' ) );
-               }
-
-               $this->loadGroups();
-               $this->mGroups[] = $group;
-               // In case loadGroups was not called before, we now have the right twice.
-               // Get rid of the duplicate.
-               $this->mGroups = array_unique( $this->mGroups );
-
-               // Refresh the groups caches, and clear the rights cache so it will be
-               // refreshed on the next call to $this->getRights().
-               $this->getEffectiveGroups( true );
-               $this->mRights = null;
-
-               $this->invalidateCache();
-
-               return true;
-       }
-
-       /**
-        * Remove the user from the given group.
-        * This takes immediate effect.
-        * @param string $group Name of the group to remove
-        * @return bool
-        */
-       public function removeGroup( $group ) {
-               $this->load();
-               if ( !Hooks::run( 'UserRemoveGroup', array( $this, &$group ) ) ) {
-                       return false;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'user_groups',
-                       array(
-                               'ug_user' => $this->getID(),
-                               'ug_group' => $group,
-                       ), __METHOD__
-               );
-               // Remember that the user was in this group
-               $dbw->insert( 'user_former_groups',
-                       array(
-                               'ufg_user' => $this->getID(),
-                               'ufg_group' => $group,
-                       ),
-                       __METHOD__,
-                       array( 'IGNORE' )
-               );
-
-               $this->loadGroups();
-               $this->mGroups = array_diff( $this->mGroups, array( $group ) );
-
-               // Refresh the groups caches, and clear the rights cache so it will be
-               // refreshed on the next call to $this->getRights().
-               $this->getEffectiveGroups( true );
-               $this->mRights = null;
-
-               $this->invalidateCache();
-
-               return true;
-       }
-
-       /**
-        * Get whether the user is logged in
-        * @return bool
-        */
-       public function isLoggedIn() {
-               return $this->getID() != 0;
-       }
-
-       /**
-        * Get whether the user is anonymous
-        * @return bool
-        */
-       public function isAnon() {
-               return !$this->isLoggedIn();
-       }
-
-       /**
-        * Check if user is allowed to access a feature / make an action
-        *
-        * @param string ... Permissions to test
-        * @return bool True if user is allowed to perform *any* of the given actions
-        */
-       public function isAllowedAny() {
-               $permissions = func_get_args();
-               foreach ( $permissions as $permission ) {
-                       if ( $this->isAllowed( $permission ) ) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-
-       /**
-        *
-        * @param string ... Permissions to test
-        * @return bool True if the user is allowed to perform *all* of the given actions
-        */
-       public function isAllowedAll() {
-               $permissions = func_get_args();
-               foreach ( $permissions as $permission ) {
-                       if ( !$this->isAllowed( $permission ) ) {
-                               return false;
-                       }
-               }
-               return true;
-       }
-
-       /**
-        * Internal mechanics of testing a permission
-        * @param string $action
-        * @return bool
-        */
-       public function isAllowed( $action = '' ) {
-               if ( $action === '' ) {
-                       return true; // In the spirit of DWIM
-               }
-               // Patrolling may not be enabled
-               if ( $action === 'patrol' || $action === 'autopatrol' ) {
-                       global $wgUseRCPatrol, $wgUseNPPatrol;
-                       if ( !$wgUseRCPatrol && !$wgUseNPPatrol ) {
-                               return false;
-                       }
-               }
-               // Use strict parameter to avoid matching numeric 0 accidentally inserted
-               // by misconfiguration: 0 == 'foo'
-               return in_array( $action, $this->getRights(), true );
-       }
-
-       /**
-        * Check whether to enable recent changes patrol features for this user
-        * @return bool True or false
-        */
-       public function useRCPatrol() {
-               global $wgUseRCPatrol;
-               return $wgUseRCPatrol && $this->isAllowedAny( 'patrol', 'patrolmarks' );
-       }
-
-       /**
-        * Check whether to enable new pages patrol features for this user
-        * @return bool True or false
-        */
-       public function useNPPatrol() {
-               global $wgUseRCPatrol, $wgUseNPPatrol;
-               return (
-                       ( $wgUseRCPatrol || $wgUseNPPatrol )
-                               && ( $this->isAllowedAny( 'patrol', 'patrolmarks' ) )
-               );
-       }
-
-       /**
-        * Get the WebRequest object to use with this object
-        *
-        * @return WebRequest
-        */
-       public function getRequest() {
-               if ( $this->mRequest ) {
-                       return $this->mRequest;
-               } else {
-                       global $wgRequest;
-                       return $wgRequest;
-               }
-       }
-
-       /**
-        * Get the current skin, loading it if required
-        * @return Skin The current skin
-        * @todo FIXME: Need to check the old failback system [AV]
-        * @deprecated since 1.18 Use ->getSkin() in the most relevant outputting context you have
-        */
-       public function getSkin() {
-               wfDeprecated( __METHOD__, '1.18' );
-               return RequestContext::getMain()->getSkin();
-       }
-
-       /**
-        * Get a WatchedItem for this user and $title.
-        *
-        * @since 1.22 $checkRights parameter added
-        * @param Title $title
-        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
-        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
-        * @return WatchedItem
-        */
-       public function getWatchedItem( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
-               $key = $checkRights . ':' . $title->getNamespace() . ':' . $title->getDBkey();
-
-               if ( isset( $this->mWatchedItems[$key] ) ) {
-                       return $this->mWatchedItems[$key];
-               }
-
-               if ( count( $this->mWatchedItems ) >= self::MAX_WATCHED_ITEMS_CACHE ) {
-                       $this->mWatchedItems = array();
-               }
-
-               $this->mWatchedItems[$key] = WatchedItem::fromUserTitle( $this, $title, $checkRights );
-               return $this->mWatchedItems[$key];
-       }
-
-       /**
-        * Check the watched status of an article.
-        * @since 1.22 $checkRights parameter added
-        * @param Title $title Title of the article to look at
-        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
-        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
-        * @return bool
-        */
-       public function isWatched( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
-               return $this->getWatchedItem( $title, $checkRights )->isWatched();
-       }
-
-       /**
-        * Watch an article.
-        * @since 1.22 $checkRights parameter added
-        * @param Title $title Title of the article to look at
-        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
-        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
-        */
-       public function addWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
-               $this->getWatchedItem( $title, $checkRights )->addWatch();
-               $this->invalidateCache();
-       }
-
-       /**
-        * Stop watching an article.
-        * @since 1.22 $checkRights parameter added
-        * @param Title $title Title of the article to look at
-        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
-        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
-        */
-       public function removeWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
-               $this->getWatchedItem( $title, $checkRights )->removeWatch();
-               $this->invalidateCache();
-       }
-
-       /**
-        * Clear the user's notification timestamp for the given title.
-        * If e-notif e-mails are on, they will receive notification mails on
-        * the next change of the page if it's watched etc.
-        * @note If the user doesn't have 'editmywatchlist', this will do nothing.
-        * @param Title $title Title of the article to look at
-        * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed.
-        */
-       public function clearNotification( &$title, $oldid = 0 ) {
-               global $wgUseEnotif, $wgShowUpdatedMarker;
-
-               // Do nothing if the database is locked to writes
-               if ( wfReadOnly() ) {
-                       return;
-               }
-
-               // Do nothing if not allowed to edit the watchlist
-               if ( !$this->isAllowed( 'editmywatchlist' ) ) {
-                       return;
-               }
-
-               // If we're working on user's talk page, we should update the talk page message indicator
-               if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
-                       if ( !Hooks::run( 'UserClearNewTalkNotification', array( &$this, $oldid ) ) ) {
-                               return;
-                       }
-
-                       $that = $this;
-                       // Try to update the DB post-send and only if needed...
-                       DeferredUpdates::addCallableUpdate( function() use ( $that, $title, $oldid ) {
-                               if ( !$that->getNewtalk() ) {
-                                       return; // no notifications to clear
-                               }
-
-                               // Delete the last notifications (they stack up)
-                               $that->setNewtalk( false );
-
-                               // If there is a new, unseen, revision, use its timestamp
-                               $nextid = $oldid
-                                       ? $title->getNextRevisionID( $oldid, Title::GAID_FOR_UPDATE )
-                                       : null;
-                               if ( $nextid ) {
-                                       $that->setNewtalk( true, Revision::newFromId( $nextid ) );
-                               }
-                       } );
-               }
-
-               if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
-                       return;
-               }
-
-               if ( $this->isAnon() ) {
-                       // Nothing else to do...
-                       return;
-               }
-
-               // Only update the timestamp if the page is being watched.
-               // The query to find out if it is watched is cached both in memcached and per-invocation,
-               // and when it does have to be executed, it can be on a slave
-               // If this is the user's newtalk page, we always update the timestamp
-               $force = '';
-               if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
-                       $force = 'force';
-               }
-
-               $this->getWatchedItem( $title )->resetNotificationTimestamp(
-                       $force, $oldid, WatchedItem::DEFERRED
-               );
-       }
-
-       /**
-        * Resets all of the given user's page-change notification timestamps.
-        * If e-notif e-mails are on, they will receive notification mails on
-        * the next change of any watched page.
-        * @note If the user doesn't have 'editmywatchlist', this will do nothing.
-        */
-       public function clearAllNotifications() {
-               if ( wfReadOnly() ) {
-                       return;
-               }
-
-               // Do nothing if not allowed to edit the watchlist
-               if ( !$this->isAllowed( 'editmywatchlist' ) ) {
-                       return;
-               }
-
-               global $wgUseEnotif, $wgShowUpdatedMarker;
-               if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
-                       $this->setNewtalk( false );
-                       return;
-               }
-               $id = $this->getId();
-               if ( $id != 0 ) {
-                       $dbw = wfGetDB( DB_MASTER );
-                       $dbw->update( 'watchlist',
-                               array( /* SET */ 'wl_notificationtimestamp' => null ),
-                               array( /* WHERE */ 'wl_user' => $id, 'wl_notificationtimestamp IS NOT NULL' ),
-                               __METHOD__
-                       );
-                       // We also need to clear here the "you have new message" notification for the own user_talk page;
-                       // it's cleared one page view later in WikiPage::doViewUpdates().
-               }
-       }
-
-       /**
-        * Set a cookie on the user's client. Wrapper for
-        * WebResponse::setCookie
-        * @param string $name Name of the cookie to set
-        * @param string $value Value to set
-        * @param int $exp Expiration time, as a UNIX time value;
-        *                   if 0 or not specified, use the default $wgCookieExpiration
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        * @param array $params Array of options sent passed to WebResponse::setcookie()
-        * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
-        *        is passed.
-        */
-       protected function setCookie(
-               $name, $value, $exp = 0, $secure = null, $params = array(), $request = null
-       ) {
-               if ( $request === null ) {
-                       $request = $this->getRequest();
-               }
-               $params['secure'] = $secure;
-               $request->response()->setCookie( $name, $value, $exp, $params );
-       }
-
-       /**
-        * Clear a cookie on the user's client
-        * @param string $name Name of the cookie to clear
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        * @param array $params Array of options sent passed to WebResponse::setcookie()
-        */
-       protected function clearCookie( $name, $secure = null, $params = array() ) {
-               $this->setCookie( $name, '', time() - 86400, $secure, $params );
-       }
-
-       /**
-        * Set an extended login cookie on the user's client. The expiry of the cookie
-        * is controlled by the $wgExtendedLoginCookieExpiration configuration
-        * variable.
-        *
-        * @see User::setCookie
-        *
-        * @param string $name Name of the cookie to set
-        * @param string $value Value to set
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        */
-       protected function setExtendedLoginCookie( $name, $value, $secure ) {
-               global $wgExtendedLoginCookieExpiration, $wgCookieExpiration;
-
-               $exp = time();
-               $exp += $wgExtendedLoginCookieExpiration !== null
-                       ? $wgExtendedLoginCookieExpiration
-                       : $wgCookieExpiration;
-
-               $this->setCookie( $name, $value, $exp, $secure );
-       }
-
-       /**
-        * Set the default cookies for this session on the user's client.
-        *
-        * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
-        *        is passed.
-        * @param bool $secure Whether to force secure/insecure cookies or use default
-        * @param bool $rememberMe Whether to add a Token cookie for elongated sessions
-        */
-       public function setCookies( $request = null, $secure = null, $rememberMe = false ) {
-               global $wgExtendedLoginCookies;
-
-               if ( $request === null ) {
-                       $request = $this->getRequest();
-               }
-
-               $this->load();
-               if ( 0 == $this->mId ) {
-                       return;
-               }
-               if ( !$this->mToken ) {
-                       // When token is empty or NULL generate a new one and then save it to the database
-                       // This allows a wiki to re-secure itself after a leak of it's user table or $wgSecretKey
-                       // Simply by setting every cell in the user_token column to NULL and letting them be
-                       // regenerated as users log back into the wiki.
-                       $this->setToken();
-                       if ( !wfReadOnly() ) {
-                               $this->saveSettings();
-                       }
-               }
-               $session = array(
-                       'wsUserID' => $this->mId,
-                       'wsToken' => $this->mToken,
-                       'wsUserName' => $this->getName()
-               );
-               $cookies = array(
-                       'UserID' => $this->mId,
-                       'UserName' => $this->getName(),
-               );
-               if ( $rememberMe ) {
-                       $cookies['Token'] = $this->mToken;
-               } else {
-                       $cookies['Token'] = false;
-               }
-
-               Hooks::run( 'UserSetCookies', array( $this, &$session, &$cookies ) );
-
-               foreach ( $session as $name => $value ) {
-                       $request->setSessionData( $name, $value );
-               }
-               foreach ( $cookies as $name => $value ) {
-                       if ( $value === false ) {
-                               $this->clearCookie( $name );
-                       } elseif ( $rememberMe && in_array( $name, $wgExtendedLoginCookies ) ) {
-                               $this->setExtendedLoginCookie( $name, $value, $secure );
-                       } else {
-                               $this->setCookie( $name, $value, 0, $secure, array(), $request );
-                       }
-               }
-
-               /**
-                * If wpStickHTTPS was selected, also set an insecure cookie that
-                * will cause the site to redirect the user to HTTPS, if they access
-                * it over HTTP. Bug 29898. Use an un-prefixed cookie, so it's the same
-                * as the one set by centralauth (bug 53538). Also set it to session, or
-                * standard time setting, based on if rememberme was set.
-                */
-               if ( $request->getCheck( 'wpStickHTTPS' ) || $this->requiresHTTPS() ) {
-                       $this->setCookie(
-                               'forceHTTPS',
-                               'true',
-                               $rememberMe ? 0 : null,
-                               false,
-                               array( 'prefix' => '' ) // no prefix
-                       );
-               }
-       }
-
-       /**
-        * Log this user out.
-        */
-       public function logout() {
-               if ( Hooks::run( 'UserLogout', array( &$this ) ) ) {
-                       $this->doLogout();
-               }
-       }
-
-       /**
-        * Clear the user's cookies and session, and reset the instance cache.
-        * @see logout()
-        */
-       public function doLogout() {
-               $this->clearInstanceCache( 'defaults' );
-
-               $this->getRequest()->setSessionData( 'wsUserID', 0 );
-
-               $this->clearCookie( 'UserID' );
-               $this->clearCookie( 'Token' );
-               $this->clearCookie( 'forceHTTPS', false, array( 'prefix' => '' ) );
-
-               // Remember when user logged out, to prevent seeing cached pages
-               $this->setCookie( 'LoggedOut', time(), time() + 86400 );
-       }
-
-       /**
-        * Save this user's settings into the database.
-        * @todo Only rarely do all these fields need to be set!
-        */
-       public function saveSettings() {
-               if ( wfReadOnly() ) {
-                       // @TODO: caller should deal with this instead!
-                       // This should really just be an exception.
-                       MWExceptionHandler::logException( new DBExpectedError(
-                               null,
-                               "Could not update user with ID '{$this->mId}'; DB is read-only."
-                       ) );
-                       return;
-               }
-
-               $this->load();
-               if ( 0 == $this->mId ) {
-                       return; // anon
-               }
-
-               // Get a new user_touched that is higher than the old one.
-               // This will be used for a CAS check as a last-resort safety
-               // check against race conditions and slave lag.
-               $oldTouched = $this->mTouched;
-               $newTouched = $this->newTouchedTimestamp();
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update( 'user',
-                       array( /* SET */
-                               'user_name' => $this->mName,
-                               'user_real_name' => $this->mRealName,
-                               'user_email' => $this->mEmail,
-                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
-                               'user_touched' => $dbw->timestamp( $newTouched ),
-                               'user_token' => strval( $this->mToken ),
-                               'user_email_token' => $this->mEmailToken,
-                               'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
-                       ), array( /* WHERE */
-                               'user_id' => $this->mId,
-                               'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
-                       ), __METHOD__
-               );
-
-               if ( !$dbw->affectedRows() ) {
-                       // Maybe the problem was a missed cache update; clear it to be safe
-                       $this->clearSharedCache( 'refresh' );
-                       // User was changed in the meantime or loaded with stale data
-                       $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave';
-                       throw new MWException(
-                               "CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" .
-                               " the version of the user to be saved is older than the current version."
-                       );
-               }
-
-               $this->mTouched = $newTouched;
-               $this->saveOptions();
-
-               Hooks::run( 'UserSaveSettings', array( $this ) );
-               $this->clearSharedCache();
-               $this->getUserPage()->invalidateCache();
-       }
-
-       /**
-        * If only this user's username is known, and it exists, return the user ID.
-        *
-        * @param int $flags Bitfield of User:READ_* constants; useful for existence checks
-        * @return int
-        */
-       public function idForName( $flags = 0 ) {
-               $s = trim( $this->getName() );
-               if ( $s === '' ) {
-                       return 0;
-               }
-
-               $db = ( ( $flags & self::READ_LATEST ) == self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-
-               $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
-                       ? array( 'LOCK IN SHARE MODE' )
-                       : array();
-
-               $id = $db->selectField( 'user',
-                       'user_id', array( 'user_name' => $s ), __METHOD__, $options );
-
-               return (int)$id;
-       }
-
-       /**
-        * Add a user to the database, return the user object
-        *
-        * @param string $name Username to add
-        * @param array $params Array of Strings Non-default parameters to save to
-        *   the database as user_* fields:
-        *   - email: The user's email address.
-        *   - email_authenticated: The email authentication timestamp.
-        *   - real_name: The user's real name.
-        *   - options: An associative array of non-default options.
-        *   - token: Random authentication token. Do not set.
-        *   - registration: Registration timestamp. Do not set.
-        *
-        * @return User|null User object, or null if the username already exists.
-        */
-       public static function createNew( $name, $params = array() ) {
-               foreach ( array( 'password', 'newpassword', 'newpass_time', 'password_expires' ) as $field ) {
-                       if ( isset( $params[$field] ) ) {
-                               wfDeprecated( __METHOD__ . " with param '$field'", '1.27' );
-                               unset( $params[$field] );
-                       }
-               }
-
-               $user = new User;
-               $user->load();
-               $user->setToken(); // init token
-               if ( isset( $params['options'] ) ) {
-                       $user->mOptions = $params['options'] + (array)$user->mOptions;
-                       unset( $params['options'] );
-               }
-               $dbw = wfGetDB( DB_MASTER );
-               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
-
-               $noPass = PasswordFactory::newInvalidPassword()->toString();
-
-               $fields = array(
-                       'user_id' => $seqVal,
-                       'user_name' => $name,
-                       'user_password' => $noPass,
-                       'user_newpassword' => $noPass,
-                       'user_email' => $user->mEmail,
-                       'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
-                       'user_real_name' => $user->mRealName,
-                       'user_token' => strval( $user->mToken ),
-                       'user_registration' => $dbw->timestamp( $user->mRegistration ),
-                       'user_editcount' => 0,
-                       'user_touched' => $dbw->timestamp( $user->newTouchedTimestamp() ),
-               );
-               foreach ( $params as $name => $value ) {
-                       $fields["user_$name"] = $value;
-               }
-               $dbw->insert( 'user', $fields, __METHOD__, array( 'IGNORE' ) );
-               if ( $dbw->affectedRows() ) {
-                       $newUser = User::newFromId( $dbw->insertId() );
-               } else {
-                       $newUser = null;
-               }
-               return $newUser;
-       }
-
-       /**
-        * Add this existing user object to the database. If the user already
-        * exists, a fatal status object is returned, and the user object is
-        * initialised with the data from the database.
-        *
-        * Previously, this function generated a DB error due to a key conflict
-        * if the user already existed. Many extension callers use this function
-        * in code along the lines of:
-        *
-        *   $user = User::newFromName( $name );
-        *   if ( !$user->isLoggedIn() ) {
-        *       $user->addToDatabase();
-        *   }
-        *   // do something with $user...
-        *
-        * However, this was vulnerable to a race condition (bug 16020). By
-        * initialising the user object if the user exists, we aim to support this
-        * calling sequence as far as possible.
-        *
-        * Note that if the user exists, this function will acquire a write lock,
-        * so it is still advisable to make the call conditional on isLoggedIn(),
-        * and to commit the transaction after calling.
-        *
-        * @throws MWException
-        * @return Status
-        */
-       public function addToDatabase() {
-               $this->load();
-               if ( !$this->mToken ) {
-                       $this->setToken(); // init token
-               }
-
-               $this->mTouched = $this->newTouchedTimestamp();
-
-               $noPass = PasswordFactory::newInvalidPassword()->toString();
-
-               $dbw = wfGetDB( DB_MASTER );
-               $inWrite = $dbw->writesOrCallbacksPending();
-               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
-               $dbw->insert( 'user',
-                       array(
-                               'user_id' => $seqVal,
-                               'user_name' => $this->mName,
-                               'user_password' => $noPass,
-                               'user_newpassword' => $noPass,
-                               'user_email' => $this->mEmail,
-                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
-                               'user_real_name' => $this->mRealName,
-                               'user_token' => strval( $this->mToken ),
-                               'user_registration' => $dbw->timestamp( $this->mRegistration ),
-                               'user_editcount' => 0,
-                               'user_touched' => $dbw->timestamp( $this->mTouched ),
-                       ), __METHOD__,
-                       array( 'IGNORE' )
-               );
-               if ( !$dbw->affectedRows() ) {
-                       // The queries below cannot happen in the same REPEATABLE-READ snapshot.
-                       // Handle this by COMMIT, if possible, or by LOCK IN SHARE MODE otherwise.
-                       if ( $inWrite ) {
-                               // Can't commit due to pending writes that may need atomicity.
-                               // This may cause some lock contention unlike the case below.
-                               $options = array( 'LOCK IN SHARE MODE' );
-                               $flags = self::READ_LOCKING;
-                       } else {
-                               // Often, this case happens early in views before any writes when
-                               // using CentralAuth. It's should be OK to commit and break the snapshot.
-                               $dbw->commit( __METHOD__, 'flush' );
-                               $options = array();
-                               $flags = self::READ_LATEST;
-                       }
-                       $this->mId = $dbw->selectField( 'user', 'user_id',
-                               array( 'user_name' => $this->mName ), __METHOD__, $options );
-                       $loaded = false;
-                       if ( $this->mId ) {
-                               if ( $this->loadFromDatabase( $flags ) ) {
-                                       $loaded = true;
-                               }
-                       }
-                       if ( !$loaded ) {
-                               throw new MWException( __METHOD__ . ": hit a key conflict attempting " .
-                                       "to insert user '{$this->mName}' row, but it was not present in select!" );
-                       }
-                       return Status::newFatal( 'userexists' );
-               }
-               $this->mId = $dbw->insertId();
-               self::$idCacheByName[$this->mName] = $this->mId;
-
-               // Clear instance cache other than user table data, which is already accurate
-               $this->clearInstanceCache();
-
-               $this->saveOptions();
-               return Status::newGood();
-       }
-
-       /**
-        * If this user is logged-in and blocked,
-        * block any IP address they've successfully logged in from.
-        * @return bool A block was spread
-        */
-       public function spreadAnyEditBlock() {
-               if ( $this->isLoggedIn() && $this->isBlocked() ) {
-                       return $this->spreadBlock();
-               }
-               return false;
-       }
-
-       /**
-        * If this (non-anonymous) user is blocked,
-        * block the IP address they've successfully logged in from.
-        * @return bool A block was spread
-        */
-       protected function spreadBlock() {
-               wfDebug( __METHOD__ . "()\n" );
-               $this->load();
-               if ( $this->mId == 0 ) {
-                       return false;
-               }
-
-               $userblock = Block::newFromTarget( $this->getName() );
-               if ( !$userblock ) {
-                       return false;
-               }
-
-               return (bool)$userblock->doAutoblock( $this->getRequest()->getIP() );
-       }
-
-       /**
-        * Get whether the user is explicitly blocked from account creation.
-        * @return bool|Block
-        */
-       public function isBlockedFromCreateAccount() {
-               $this->getBlockedStatus();
-               if ( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ) {
-                       return $this->mBlock;
-               }
-
-               # bug 13611: if the IP address the user is trying to create an account from is
-               # blocked with createaccount disabled, prevent new account creation there even
-               # when the user is logged in
-               if ( $this->mBlockedFromCreateAccount === false && !$this->isAllowed( 'ipblock-exempt' ) ) {
-                       $this->mBlockedFromCreateAccount = Block::newFromTarget( null, $this->getRequest()->getIP() );
-               }
-               return $this->mBlockedFromCreateAccount instanceof Block
-                       && $this->mBlockedFromCreateAccount->prevents( 'createaccount' )
-                       ? $this->mBlockedFromCreateAccount
-                       : false;
-       }
-
-       /**
-        * Get whether the user is blocked from using Special:Emailuser.
-        * @return bool
-        */
-       public function isBlockedFromEmailuser() {
-               $this->getBlockedStatus();
-               return $this->mBlock && $this->mBlock->prevents( 'sendemail' );
-       }
-
-       /**
-        * Get whether the user is allowed to create an account.
-        * @return bool
-        */
-       public function isAllowedToCreateAccount() {
-               return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
-       }
-
-       /**
-        * Get this user's personal page title.
-        *
-        * @return Title User's personal page title
-        */
-       public function getUserPage() {
-               return Title::makeTitle( NS_USER, $this->getName() );
-       }
-
-       /**
-        * Get this user's talk page title.
-        *
-        * @return Title User's talk page title
-        */
-       public function getTalkPage() {
-               $title = $this->getUserPage();
-               return $title->getTalkPage();
-       }
-
-       /**
-        * Determine whether the user is a newbie. Newbies are either
-        * anonymous IPs, or the most recently created accounts.
-        * @return bool
-        */
-       public function isNewbie() {
-               return !$this->isAllowed( 'autoconfirmed' );
-       }
-
-       /**
-        * Check to see if the given clear-text password is one of the accepted passwords
-        * @deprecated since 1.27. AuthManager is coming.
-        * @param string $password User password
-        * @return bool True if the given password is correct, otherwise False
-        */
-       public function checkPassword( $password ) {
-               global $wgAuth, $wgLegacyEncoding;
-
-               $this->load();
-
-               // Some passwords will give a fatal Status, which means there is
-               // some sort of technical or security reason for this password to
-               // be completely invalid and should never be checked (e.g., T64685)
-               if ( !$this->checkPasswordValidity( $password )->isOK() ) {
-                       return false;
-               }
-
-               // Certain authentication plugins do NOT want to save
-               // domain passwords in a mysql database, so we should
-               // check this (in case $wgAuth->strict() is false).
-               if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
-                       return true;
-               } elseif ( $wgAuth->strict() ) {
-                       // Auth plugin doesn't allow local authentication
-                       return false;
-               } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
-                       // Auth plugin doesn't allow local authentication for this user name
-                       return false;
-               }
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-
-               try {
-                       $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
-                               'user', 'user_password', array( 'user_id' => $this->getId() ), __METHOD__
-                       ) );
-               } catch ( PasswordError $e ) {
-                       wfDebug( 'Invalid password hash found in database.' );
-                       $mPassword = PasswordFactory::newInvalidPassword();
-               }
-
-               if ( !$mPassword->equals( $password ) ) {
-                       if ( $wgLegacyEncoding ) {
-                               // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
-                               // Check for this with iconv
-                               $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
-                               if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
-                                       return false;
-                               }
-                       } else {
-                               return false;
-                       }
-               }
-
-               if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
-                       $this->setPasswordInternal( $password );
-               }
-
-               return true;
-       }
-
-       /**
-        * Check if the given clear-text password matches the temporary password
-        * sent by e-mail for password reset operations.
-        *
-        * @deprecated since 1.27. AuthManager is coming.
-        * @param string $plaintext
-        * @return bool True if matches, false otherwise
-        */
-       public function checkTemporaryPassword( $plaintext ) {
-               global $wgNewPasswordExpiry;
-
-               $this->load();
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
-
-               $row = $db->selectRow(
-                       'user',
-                       array( 'user_newpassword', 'user_newpass_time' ),
-                       array( 'user_id' => $this->getId() ),
-                       __METHOD__
-               );
-               try {
-                       $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
-               } catch ( PasswordError $e ) {
-                       wfDebug( 'Invalid password hash found in database.' );
-                       $newPassword = PasswordFactory::newInvalidPassword();
-               }
-
-               if ( $newPassword->equals( $plaintext ) ) {
-                       if ( is_null( $row->user_newpass_time ) ) {
-                               return true;
-                       }
-                       $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
-                       return ( time() < $expiry );
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Alias for getEditToken.
-        * @deprecated since 1.19, use getEditToken instead.
-        *
-        * @param string|array $salt Array of Strings Optional function-specific data for hashing
-        * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
-        * @return string The new edit token
-        */
-       public function editToken( $salt = '', $request = null ) {
-               wfDeprecated( __METHOD__, '1.19' );
-               return $this->getEditToken( $salt, $request );
-       }
-
-       /**
-        * Internal implementation for self::getEditToken() and
-        * self::matchEditToken().
-        *
-        * @param string|array $salt
-        * @param WebRequest $request
-        * @param string|int $timestamp
-        * @return string
-        */
-       private function getEditTokenAtTimestamp( $salt, $request, $timestamp ) {
-               if ( $this->isAnon() ) {
-                       return self::EDIT_TOKEN_SUFFIX;
-               } else {
-                       $token = $request->getSessionData( 'wsEditToken' );
-                       if ( $token === null ) {
-                               $token = MWCryptRand::generateHex( 32 );
-                               $request->setSessionData( 'wsEditToken', $token );
-                       }
-                       if ( is_array( $salt ) ) {
-                               $salt = implode( '|', $salt );
-                       }
-                       return hash_hmac( 'md5', $timestamp . $salt, $token, false ) .
-                               dechex( $timestamp ) .
-                               self::EDIT_TOKEN_SUFFIX;
-               }
-       }
-
-       /**
-        * Initialize (if necessary) and return a session token value
-        * which can be used in edit forms to show that the user's
-        * login credentials aren't being hijacked with a foreign form
-        * submission.
-        *
-        * @since 1.19
-        *
-        * @param string|array $salt Array of Strings Optional function-specific data for hashing
-        * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
-        * @return string The new edit token
-        */
-       public function getEditToken( $salt = '', $request = null ) {
-               return $this->getEditTokenAtTimestamp(
-                       $salt, $request ?: $this->getRequest(), wfTimestamp()
-               );
-       }
-
-       /**
-        * Generate a looking random token for various uses.
-        *
-        * @return string The new random token
-        * @deprecated since 1.20: Use MWCryptRand for secure purposes or
-        *   wfRandomString for pseudo-randomness.
-        */
-       public static function generateToken() {
-               return MWCryptRand::generateHex( 32 );
-       }
-
-       /**
-        * Get the embedded timestamp from a token.
-        * @param string $val Input token
-        * @return int|null
-        */
-       public static function getEditTokenTimestamp( $val ) {
-               $suffixLen = strlen( self::EDIT_TOKEN_SUFFIX );
-               if ( strlen( $val ) <= 32 + $suffixLen ) {
-                       return null;
-               }
-
-               return hexdec( substr( $val, 32, -$suffixLen ) );
-       }
-
-       /**
-        * Check given value against the token value stored in the session.
-        * A match should confirm that the form was submitted from the
-        * user's own login session, not a form submission from a third-party
-        * site.
-        *
-        * @param string $val Input value to compare
-        * @param string $salt Optional function-specific data for hashing
-        * @param WebRequest|null $request Object to use or null to use $wgRequest
-        * @param int $maxage Fail tokens older than this, in seconds
-        * @return bool Whether the token matches
-        */
-       public function matchEditToken( $val, $salt = '', $request = null, $maxage = null ) {
-               if ( $this->isAnon() ) {
-                       return $val === self::EDIT_TOKEN_SUFFIX;
-               }
-
-               $timestamp = self::getEditTokenTimestamp( $val );
-               if ( $timestamp === null ) {
-                       return false;
-               }
-               if ( $maxage !== null && $timestamp < wfTimestamp() - $maxage ) {
-                       // Expired token
-                       return false;
-               }
-
-               $sessionToken = $this->getEditTokenAtTimestamp(
-                       $salt, $request ?: $this->getRequest(), $timestamp
-               );
-
-               if ( $val != $sessionToken ) {
-                       wfDebug( "User::matchEditToken: broken session data\n" );
-               }
-
-               return hash_equals( $sessionToken, $val );
-       }
-
-       /**
-        * Check given value against the token value stored in the session,
-        * ignoring the suffix.
-        *
-        * @param string $val Input value to compare
-        * @param string $salt Optional function-specific data for hashing
-        * @param WebRequest|null $request Object to use or null to use $wgRequest
-        * @param int $maxage Fail tokens older than this, in seconds
-        * @return bool Whether the token matches
-        */
-       public function matchEditTokenNoSuffix( $val, $salt = '', $request = null, $maxage = null ) {
-               $val = substr( $val, 0, strspn( $val, '0123456789abcdef' ) ) . self::EDIT_TOKEN_SUFFIX;
-               return $this->matchEditToken( $val, $salt, $request, $maxage );
-       }
-
-       /**
-        * Generate a new e-mail confirmation token and send a confirmation/invalidation
-        * mail to the user's given address.
-        *
-        * @param string $type Message to send, either "created", "changed" or "set"
-        * @return Status
-        */
-       public function sendConfirmationMail( $type = 'created' ) {
-               global $wgLang;
-               $expiration = null; // gets passed-by-ref and defined in next line.
-               $token = $this->confirmationToken( $expiration );
-               $url = $this->confirmationTokenUrl( $token );
-               $invalidateURL = $this->invalidationTokenUrl( $token );
-               $this->saveSettings();
-
-               if ( $type == 'created' || $type === false ) {
-                       $message = 'confirmemail_body';
-               } elseif ( $type === true ) {
-                       $message = 'confirmemail_body_changed';
-               } else {
-                       // Messages: confirmemail_body_changed, confirmemail_body_set
-                       $message = 'confirmemail_body_' . $type;
-               }
-
-               return $this->sendMail( wfMessage( 'confirmemail_subject' )->text(),
-                       wfMessage( $message,
-                               $this->getRequest()->getIP(),
-                               $this->getName(),
-                               $url,
-                               $wgLang->timeanddate( $expiration, false ),
-                               $invalidateURL,
-                               $wgLang->date( $expiration, false ),
-                               $wgLang->time( $expiration, false ) )->text() );
-       }
-
-       /**
-        * Send an e-mail to this user's account. Does not check for
-        * confirmed status or validity.
-        *
-        * @param string $subject Message subject
-        * @param string $body Message body
-        * @param User|null $from Optional sending user; if unspecified, default
-        *   $wgPasswordSender will be used.
-        * @param string $replyto Reply-To address
-        * @return Status
-        */
-       public function sendMail( $subject, $body, $from = null, $replyto = null ) {
-               global $wgPasswordSender;
-
-               if ( $from instanceof User ) {
-                       $sender = MailAddress::newFromUser( $from );
-               } else {
-                       $sender = new MailAddress( $wgPasswordSender,
-                               wfMessage( 'emailsender' )->inContentLanguage()->text() );
-               }
-               $to = MailAddress::newFromUser( $this );
-
-               return UserMailer::send( $to, $sender, $subject, $body, array(
-                       'replyTo' => $replyto,
-               ) );
-       }
-
-       /**
-        * Generate, store, and return a new e-mail confirmation code.
-        * A hash (unsalted, since it's used as a key) is stored.
-        *
-        * @note Call saveSettings() after calling this function to commit
-        * this change to the database.
-        *
-        * @param string &$expiration Accepts the expiration time
-        * @return string New token
-        */
-       protected function confirmationToken( &$expiration ) {
-               global $wgUserEmailConfirmationTokenExpiry;
-               $now = time();
-               $expires = $now + $wgUserEmailConfirmationTokenExpiry;
-               $expiration = wfTimestamp( TS_MW, $expires );
-               $this->load();
-               $token = MWCryptRand::generateHex( 32 );
-               $hash = md5( $token );
-               $this->mEmailToken = $hash;
-               $this->mEmailTokenExpires = $expiration;
-               return $token;
-       }
-
-       /**
-        * Return a URL the user can use to confirm their email address.
-        * @param string $token Accepts the email confirmation token
-        * @return string New token URL
-        */
-       protected function confirmationTokenUrl( $token ) {
-               return $this->getTokenUrl( 'ConfirmEmail', $token );
-       }
-
-       /**
-        * Return a URL the user can use to invalidate their email address.
-        * @param string $token Accepts the email confirmation token
-        * @return string New token URL
-        */
-       protected function invalidationTokenUrl( $token ) {
-               return $this->getTokenUrl( 'InvalidateEmail', $token );
-       }
-
-       /**
-        * Internal function to format the e-mail validation/invalidation URLs.
-        * This uses a quickie hack to use the
-        * hardcoded English names of the Special: pages, for ASCII safety.
-        *
-        * @note Since these URLs get dropped directly into emails, using the
-        * short English names avoids insanely long URL-encoded links, which
-        * also sometimes can get corrupted in some browsers/mailers
-        * (bug 6957 with Gmail and Internet Explorer).
-        *
-        * @param string $page Special page
-        * @param string $token Token
-        * @return string Formatted URL
-        */
-       protected function getTokenUrl( $page, $token ) {
-               // Hack to bypass localization of 'Special:'
-               $title = Title::makeTitle( NS_MAIN, "Special:$page/$token" );
-               return $title->getCanonicalURL();
-       }
-
-       /**
-        * Mark the e-mail address confirmed.
-        *
-        * @note Call saveSettings() after calling this function to commit the change.
-        *
-        * @return bool
-        */
-       public function confirmEmail() {
-               // Check if it's already confirmed, so we don't touch the database
-               // and fire the ConfirmEmailComplete hook on redundant confirmations.
-               if ( !$this->isEmailConfirmed() ) {
-                       $this->setEmailAuthenticationTimestamp( wfTimestampNow() );
-                       Hooks::run( 'ConfirmEmailComplete', array( $this ) );
-               }
-               return true;
-       }
-
-       /**
-        * Invalidate the user's e-mail confirmation, and unauthenticate the e-mail
-        * address if it was already confirmed.
-        *
-        * @note Call saveSettings() after calling this function to commit the change.
-        * @return bool Returns true
-        */
-       public function invalidateEmail() {
-               $this->load();
-               $this->mEmailToken = null;
-               $this->mEmailTokenExpires = null;
-               $this->setEmailAuthenticationTimestamp( null );
-               $this->mEmail = '';
-               Hooks::run( 'InvalidateEmailComplete', array( $this ) );
-               return true;
-       }
-
-       /**
-        * Set the e-mail authentication timestamp.
-        * @param string $timestamp TS_MW timestamp
-        */
-       public function setEmailAuthenticationTimestamp( $timestamp ) {
-               $this->load();
-               $this->mEmailAuthenticated = $timestamp;
-               Hooks::run( 'UserSetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
-       }
-
-       /**
-        * Is this user allowed to send e-mails within limits of current
-        * site configuration?
-        * @return bool
-        */
-       public function canSendEmail() {
-               global $wgEnableEmail, $wgEnableUserEmail;
-               if ( !$wgEnableEmail || !$wgEnableUserEmail || !$this->isAllowed( 'sendemail' ) ) {
-                       return false;
-               }
-               $canSend = $this->isEmailConfirmed();
-               Hooks::run( 'UserCanSendEmail', array( &$this, &$canSend ) );
-               return $canSend;
-       }
-
-       /**
-        * Is this user allowed to receive e-mails within limits of current
-        * site configuration?
-        * @return bool
-        */
-       public function canReceiveEmail() {
-               return $this->isEmailConfirmed() && !$this->getOption( 'disablemail' );
-       }
-
-       /**
-        * Is this user's e-mail address valid-looking and confirmed within
-        * limits of the current site configuration?
-        *
-        * @note If $wgEmailAuthentication is on, this may require the user to have
-        * confirmed their address by returning a code or using a password
-        * sent to the address from the wiki.
-        *
-        * @return bool
-        */
-       public function isEmailConfirmed() {
-               global $wgEmailAuthentication;
-               $this->load();
-               $confirmed = true;
-               if ( Hooks::run( 'EmailConfirmed', array( &$this, &$confirmed ) ) ) {
-                       if ( $this->isAnon() ) {
-                               return false;
-                       }
-                       if ( !Sanitizer::validateEmail( $this->mEmail ) ) {
-                               return false;
-                       }
-                       if ( $wgEmailAuthentication && !$this->getEmailAuthenticationTimestamp() ) {
-                               return false;
-                       }
-                       return true;
-               } else {
-                       return $confirmed;
-               }
-       }
-
-       /**
-        * Check whether there is an outstanding request for e-mail confirmation.
-        * @return bool
-        */
-       public function isEmailConfirmationPending() {
-               global $wgEmailAuthentication;
-               return $wgEmailAuthentication &&
-                       !$this->isEmailConfirmed() &&
-                       $this->mEmailToken &&
-                       $this->mEmailTokenExpires > wfTimestamp();
-       }
-
-       /**
-        * Get the timestamp of account creation.
-        *
-        * @return string|bool|null Timestamp of account creation, false for
-        *  non-existent/anonymous user accounts, or null if existing account
-        *  but information is not in database.
-        */
-       public function getRegistration() {
-               if ( $this->isAnon() ) {
-                       return false;
-               }
-               $this->load();
-               return $this->mRegistration;
-       }
-
-       /**
-        * Get the timestamp of the first edit
-        *
-        * @return string|bool Timestamp of first edit, or false for
-        *  non-existent/anonymous user accounts.
-        */
-       public function getFirstEditTimestamp() {
-               if ( $this->getId() == 0 ) {
-                       return false; // anons
-               }
-               $dbr = wfGetDB( DB_SLAVE );
-               $time = $dbr->selectField( 'revision', 'rev_timestamp',
-                       array( 'rev_user' => $this->getId() ),
-                       __METHOD__,
-                       array( 'ORDER BY' => 'rev_timestamp ASC' )
-               );
-               if ( !$time ) {
-                       return false; // no edits
-               }
-               return wfTimestamp( TS_MW, $time );
-       }
-
-       /**
-        * Get the permissions associated with a given list of groups
-        *
-        * @param array $groups Array of Strings List of internal group names
-        * @return array Array of Strings List of permission key names for given groups combined
-        */
-       public static function getGroupPermissions( $groups ) {
-               global $wgGroupPermissions, $wgRevokePermissions;
-               $rights = array();
-               // grant every granted permission first
-               foreach ( $groups as $group ) {
-                       if ( isset( $wgGroupPermissions[$group] ) ) {
-                               $rights = array_merge( $rights,
-                                       // array_filter removes empty items
-                                       array_keys( array_filter( $wgGroupPermissions[$group] ) ) );
-                       }
-               }
-               // now revoke the revoked permissions
-               foreach ( $groups as $group ) {
-                       if ( isset( $wgRevokePermissions[$group] ) ) {
-                               $rights = array_diff( $rights,
-                                       array_keys( array_filter( $wgRevokePermissions[$group] ) ) );
-                       }
-               }
-               return array_unique( $rights );
-       }
-
-       /**
-        * Get all the groups who have a given permission
-        *
-        * @param string $role Role to check
-        * @return array Array of Strings List of internal group names with the given permission
-        */
-       public static function getGroupsWithPermission( $role ) {
-               global $wgGroupPermissions;
-               $allowedGroups = array();
-               foreach ( array_keys( $wgGroupPermissions ) as $group ) {
-                       if ( self::groupHasPermission( $group, $role ) ) {
-                               $allowedGroups[] = $group;
-                       }
-               }
-               return $allowedGroups;
-       }
-
-       /**
-        * Check, if the given group has the given permission
-        *
-        * If you're wanting to check whether all users have a permission, use
-        * User::isEveryoneAllowed() instead. That properly checks if it's revoked
-        * from anyone.
-        *
-        * @since 1.21
-        * @param string $group Group to check
-        * @param string $role Role to check
-        * @return bool
-        */
-       public static function groupHasPermission( $group, $role ) {
-               global $wgGroupPermissions, $wgRevokePermissions;
-               return isset( $wgGroupPermissions[$group][$role] ) && $wgGroupPermissions[$group][$role]
-                       && !( isset( $wgRevokePermissions[$group][$role] ) && $wgRevokePermissions[$group][$role] );
-       }
-
-       /**
-        * Check if all users have the given permission
-        *
-        * @since 1.22
-        * @param string $right Right to check
-        * @return bool
-        */
-       public static function isEveryoneAllowed( $right ) {
-               global $wgGroupPermissions, $wgRevokePermissions;
-               static $cache = array();
-
-               // Use the cached results, except in unit tests which rely on
-               // being able change the permission mid-request
-               if ( isset( $cache[$right] ) && !defined( 'MW_PHPUNIT_TEST' ) ) {
-                       return $cache[$right];
-               }
-
-               if ( !isset( $wgGroupPermissions['*'][$right] ) || !$wgGroupPermissions['*'][$right] ) {
-                       $cache[$right] = false;
-                       return false;
-               }
-
-               // If it's revoked anywhere, then everyone doesn't have it
-               foreach ( $wgRevokePermissions as $rights ) {
-                       if ( isset( $rights[$right] ) && $rights[$right] ) {
-                               $cache[$right] = false;
-                               return false;
-                       }
-               }
-
-               // Allow extensions (e.g. OAuth) to say false
-               if ( !Hooks::run( 'UserIsEveryoneAllowed', array( $right ) ) ) {
-                       $cache[$right] = false;
-                       return false;
-               }
-
-               $cache[$right] = true;
-               return true;
-       }
-
-       /**
-        * Get the localized descriptive name for a group, if it exists
-        *
-        * @param string $group Internal group name
-        * @return string Localized descriptive group name
-        */
-       public static function getGroupName( $group ) {
-               $msg = wfMessage( "group-$group" );
-               return $msg->isBlank() ? $group : $msg->text();
-       }
-
-       /**
-        * Get the localized descriptive name for a member of a group, if it exists
-        *
-        * @param string $group Internal group name
-        * @param string $username Username for gender (since 1.19)
-        * @return string Localized name for group member
-        */
-       public static function getGroupMember( $group, $username = '#' ) {
-               $msg = wfMessage( "group-$group-member", $username );
-               return $msg->isBlank() ? $group : $msg->text();
-       }
-
-       /**
-        * Return the set of defined explicit groups.
-        * The implicit groups (by default *, 'user' and 'autoconfirmed')
-        * are not included, as they are defined automatically, not in the database.
-        * @return array Array of internal group names
-        */
-       public static function getAllGroups() {
-               global $wgGroupPermissions, $wgRevokePermissions;
-               return array_diff(
-                       array_merge( array_keys( $wgGroupPermissions ), array_keys( $wgRevokePermissions ) ),
-                       self::getImplicitGroups()
-               );
-       }
-
-       /**
-        * Get a list of all available permissions.
-        * @return string[] Array of permission names
-        */
-       public static function getAllRights() {
-               if ( self::$mAllRights === false ) {
-                       global $wgAvailableRights;
-                       if ( count( $wgAvailableRights ) ) {
-                               self::$mAllRights = array_unique( array_merge( self::$mCoreRights, $wgAvailableRights ) );
-                       } else {
-                               self::$mAllRights = self::$mCoreRights;
-                       }
-                       Hooks::run( 'UserGetAllRights', array( &self::$mAllRights ) );
-               }
-               return self::$mAllRights;
-       }
-
-       /**
-        * Get a list of implicit groups
-        * @return array Array of Strings Array of internal group names
-        */
-       public static function getImplicitGroups() {
-               global $wgImplicitGroups;
-
-               $groups = $wgImplicitGroups;
-               # Deprecated, use $wgImplicitGroups instead
-               Hooks::run( 'UserGetImplicitGroups', array( &$groups ), '1.25' );
-
-               return $groups;
-       }
-
-       /**
-        * Get the title of a page describing a particular group
-        *
-        * @param string $group Internal group name
-        * @return Title|bool Title of the page if it exists, false otherwise
-        */
-       public static function getGroupPage( $group ) {
-               $msg = wfMessage( 'grouppage-' . $group )->inContentLanguage();
-               if ( $msg->exists() ) {
-                       $title = Title::newFromText( $msg->text() );
-                       if ( is_object( $title ) ) {
-                               return $title;
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * Create a link to the group in HTML, if available;
-        * else return the group name.
-        *
-        * @param string $group Internal name of the group
-        * @param string $text The text of the link
-        * @return string HTML link to the group
-        */
-       public static function makeGroupLinkHTML( $group, $text = '' ) {
-               if ( $text == '' ) {
-                       $text = self::getGroupName( $group );
-               }
-               $title = self::getGroupPage( $group );
-               if ( $title ) {
-                       return Linker::link( $title, htmlspecialchars( $text ) );
-               } else {
-                       return htmlspecialchars( $text );
-               }
-       }
-
-       /**
-        * Create a link to the group in Wikitext, if available;
-        * else return the group name.
-        *
-        * @param string $group Internal name of the group
-        * @param string $text The text of the link
-        * @return string Wikilink to the group
-        */
-       public static function makeGroupLinkWiki( $group, $text = '' ) {
-               if ( $text == '' ) {
-                       $text = self::getGroupName( $group );
-               }
-               $title = self::getGroupPage( $group );
-               if ( $title ) {
-                       $page = $title->getFullText();
-                       return "[[$page|$text]]";
-               } else {
-                       return $text;
-               }
-       }
-
-       /**
-        * Returns an array of the groups that a particular group can add/remove.
-        *
-        * @param string $group The group to check for whether it can add/remove
-        * @return array Array( 'add' => array( addablegroups ),
-        *     'remove' => array( removablegroups ),
-        *     'add-self' => array( addablegroups to self),
-        *     'remove-self' => array( removable groups from self) )
-        */
-       public static function changeableByGroup( $group ) {
-               global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
-
-               $groups = array(
-                       'add' => array(),
-                       'remove' => array(),
-                       'add-self' => array(),
-                       'remove-self' => array()
-               );
-
-               if ( empty( $wgAddGroups[$group] ) ) {
-                       // Don't add anything to $groups
-               } elseif ( $wgAddGroups[$group] === true ) {
-                       // You get everything
-                       $groups['add'] = self::getAllGroups();
-               } elseif ( is_array( $wgAddGroups[$group] ) ) {
-                       $groups['add'] = $wgAddGroups[$group];
-               }
-
-               // Same thing for remove
-               if ( empty( $wgRemoveGroups[$group] ) ) {
-                       // Do nothing
-               } elseif ( $wgRemoveGroups[$group] === true ) {
-                       $groups['remove'] = self::getAllGroups();
-               } elseif ( is_array( $wgRemoveGroups[$group] ) ) {
-                       $groups['remove'] = $wgRemoveGroups[$group];
-               }
-
-               // Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility
-               if ( empty( $wgGroupsAddToSelf['user'] ) || $wgGroupsAddToSelf['user'] !== true ) {
-                       foreach ( $wgGroupsAddToSelf as $key => $value ) {
-                               if ( is_int( $key ) ) {
-                                       $wgGroupsAddToSelf['user'][] = $value;
-                               }
-                       }
-               }
-
-               if ( empty( $wgGroupsRemoveFromSelf['user'] ) || $wgGroupsRemoveFromSelf['user'] !== true ) {
-                       foreach ( $wgGroupsRemoveFromSelf as $key => $value ) {
-                               if ( is_int( $key ) ) {
-                                       $wgGroupsRemoveFromSelf['user'][] = $value;
-                               }
-                       }
-               }
-
-               // Now figure out what groups the user can add to him/herself
-               if ( empty( $wgGroupsAddToSelf[$group] ) ) {
-                       // Do nothing
-               } elseif ( $wgGroupsAddToSelf[$group] === true ) {
-                       // No idea WHY this would be used, but it's there
-                       $groups['add-self'] = User::getAllGroups();
-               } elseif ( is_array( $wgGroupsAddToSelf[$group] ) ) {
-                       $groups['add-self'] = $wgGroupsAddToSelf[$group];
-               }
-
-               if ( empty( $wgGroupsRemoveFromSelf[$group] ) ) {
-                       // Do nothing
-               } elseif ( $wgGroupsRemoveFromSelf[$group] === true ) {
-                       $groups['remove-self'] = User::getAllGroups();
-               } elseif ( is_array( $wgGroupsRemoveFromSelf[$group] ) ) {
-                       $groups['remove-self'] = $wgGroupsRemoveFromSelf[$group];
-               }
-
-               return $groups;
-       }
-
-       /**
-        * Returns an array of groups that this user can add and remove
-        * @return array Array( 'add' => array( addablegroups ),
-        *  'remove' => array( removablegroups ),
-        *  'add-self' => array( addablegroups to self),
-        *  'remove-self' => array( removable groups from self) )
-        */
-       public function changeableGroups() {
-               if ( $this->isAllowed( 'userrights' ) ) {
-                       // This group gives the right to modify everything (reverse-
-                       // compatibility with old "userrights lets you change
-                       // everything")
-                       // Using array_merge to make the groups reindexed
-                       $all = array_merge( User::getAllGroups() );
-                       return array(
-                               'add' => $all,
-                               'remove' => $all,
-                               'add-self' => array(),
-                               'remove-self' => array()
-                       );
-               }
-
-               // Okay, it's not so simple, we will have to go through the arrays
-               $groups = array(
-                       'add' => array(),
-                       'remove' => array(),
-                       'add-self' => array(),
-                       'remove-self' => array()
-               );
-               $addergroups = $this->getEffectiveGroups();
-
-               foreach ( $addergroups as $addergroup ) {
-                       $groups = array_merge_recursive(
-                               $groups, $this->changeableByGroup( $addergroup )
-                       );
-                       $groups['add'] = array_unique( $groups['add'] );
-                       $groups['remove'] = array_unique( $groups['remove'] );
-                       $groups['add-self'] = array_unique( $groups['add-self'] );
-                       $groups['remove-self'] = array_unique( $groups['remove-self'] );
-               }
-               return $groups;
-       }
-
-       /**
-        * Deferred version of incEditCountImmediate()
-        */
-       public function incEditCount() {
-               $that = $this;
-               wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $that ) {
-                       $that->incEditCountImmediate();
-               } );
-       }
-
-       /**
-        * Increment the user's edit-count field.
-        * Will have no effect for anonymous users.
-        * @since 1.26
-        */
-       public function incEditCountImmediate() {
-               if ( $this->isAnon() ) {
-                       return;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               // No rows will be "affected" if user_editcount is NULL
-               $dbw->update(
-                       'user',
-                       array( 'user_editcount=user_editcount+1' ),
-                       array( 'user_id' => $this->getId(), 'user_editcount IS NOT NULL' ),
-                       __METHOD__
-               );
-               // Lazy initialization check...
-               if ( $dbw->affectedRows() == 0 ) {
-                       // Now here's a goddamn hack...
-                       $dbr = wfGetDB( DB_SLAVE );
-                       if ( $dbr !== $dbw ) {
-                               // If we actually have a slave server, the count is
-                               // at least one behind because the current transaction
-                               // has not been committed and replicated.
-                               $this->initEditCount( 1 );
-                       } else {
-                               // But if DB_SLAVE is selecting the master, then the
-                               // count we just read includes the revision that was
-                               // just added in the working transaction.
-                               $this->initEditCount();
-                       }
-               }
-               // Edit count in user cache too
-               $this->invalidateCache();
-       }
-
-       /**
-        * Initialize user_editcount from data out of the revision table
-        *
-        * @param int $add Edits to add to the count from the revision table
-        * @return int Number of edits
-        */
-       protected function initEditCount( $add = 0 ) {
-               // Pull from a slave to be less cruel to servers
-               // Accuracy isn't the point anyway here
-               $dbr = wfGetDB( DB_SLAVE );
-               $count = (int)$dbr->selectField(
-                       'revision',
-                       'COUNT(rev_user)',
-                       array( 'rev_user' => $this->getId() ),
-                       __METHOD__
-               );
-               $count = $count + $add;
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update(
-                       'user',
-                       array( 'user_editcount' => $count ),
-                       array( 'user_id' => $this->getId() ),
-                       __METHOD__
-               );
-
-               return $count;
-       }
-
-       /**
-        * Get the description of a given right
-        *
-        * @param string $right Right to query
-        * @return string Localized description of the right
-        */
-       public static function getRightDescription( $right ) {
-               $key = "right-$right";
-               $msg = wfMessage( $key );
-               return $msg->isBlank() ? $right : $msg->text();
-       }
-
-       /**
-        * Make a new-style password hash
-        *
-        * @param string $password Plain-text password
-        * @param bool|string $salt Optional salt, may be random or the user ID.
-        *  If unspecified or false, will generate one automatically
-        * @return string Password hash
-        * @deprecated since 1.24, use Password class
-        */
-       public static function crypt( $password, $salt = false ) {
-               wfDeprecated( __METHOD__, '1.24' );
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $hash = $passwordFactory->newFromPlaintext( $password );
-               return $hash->toString();
-       }
-
-       /**
-        * Compare a password hash with a plain-text password. Requires the user
-        * ID if there's a chance that the hash is an old-style hash.
-        *
-        * @param string $hash Password hash
-        * @param string $password Plain-text password to compare
-        * @param string|bool $userId User ID for old-style password salt
-        *
-        * @return bool
-        * @deprecated since 1.24, use Password class
-        */
-       public static function comparePasswords( $hash, $password, $userId = false ) {
-               wfDeprecated( __METHOD__, '1.24' );
-
-               // Check for *really* old password hashes that don't even have a type
-               // The old hash format was just an md5 hex hash, with no type information
-               if ( preg_match( '/^[0-9a-f]{32}$/', $hash ) ) {
-                       global $wgPasswordSalt;
-                       if ( $wgPasswordSalt ) {
-                               $password = ":B:{$userId}:{$hash}";
-                       } else {
-                               $password = ":A:{$hash}";
-                       }
-               }
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $hash = $passwordFactory->newFromCiphertext( $hash );
-               return $hash->equals( $password );
-       }
-
-       /**
-        * Add a newuser log entry for this user.
-        * Before 1.19 the return value was always true.
-        *
-        * @param string|bool $action Account creation type.
-        *   - String, one of the following values:
-        *     - 'create' for an anonymous user creating an account for himself.
-        *       This will force the action's performer to be the created user itself,
-        *       no matter the value of $wgUser
-        *     - 'create2' for a logged in user creating an account for someone else
-        *     - 'byemail' when the created user will receive its password by e-mail
-        *     - 'autocreate' when the user is automatically created (such as by CentralAuth).
-        *   - Boolean means whether the account was created by e-mail (deprecated):
-        *     - true will be converted to 'byemail'
-        *     - false will be converted to 'create' if this object is the same as
-        *       $wgUser and to 'create2' otherwise
-        *
-        * @param string $reason User supplied reason
-        *
-        * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
-        */
-       public function addNewUserLogEntry( $action = false, $reason = '' ) {
-               global $wgUser, $wgNewUserLog;
-               if ( empty( $wgNewUserLog ) ) {
-                       return true; // disabled
-               }
-
-               if ( $action === true ) {
-                       $action = 'byemail';
-               } elseif ( $action === false ) {
-                       if ( $this->equals( $wgUser ) ) {
-                               $action = 'create';
-                       } else {
-                               $action = 'create2';
-                       }
-               }
-
-               if ( $action === 'create' || $action === 'autocreate' ) {
-                       $performer = $this;
-               } else {
-                       $performer = $wgUser;
-               }
-
-               $logEntry = new ManualLogEntry( 'newusers', $action );
-               $logEntry->setPerformer( $performer );
-               $logEntry->setTarget( $this->getUserPage() );
-               $logEntry->setComment( $reason );
-               $logEntry->setParameters( array(
-                       '4::userid' => $this->getId(),
-               ) );
-               $logid = $logEntry->insert();
-
-               if ( $action !== 'autocreate' ) {
-                       $logEntry->publish( $logid );
-               }
-
-               return (int)$logid;
-       }
-
-       /**
-        * Add an autocreate newuser log entry for this user
-        * Used by things like CentralAuth and perhaps other authplugins.
-        * Consider calling addNewUserLogEntry() directly instead.
-        *
-        * @return bool
-        */
-       public function addNewUserLogEntryAutoCreate() {
-               $this->addNewUserLogEntry( 'autocreate' );
-
-               return true;
-       }
-
-       /**
-        * Load the user options either from cache, the database or an array
-        *
-        * @param array $data Rows for the current user out of the user_properties table
-        */
-       protected function loadOptions( $data = null ) {
-               global $wgContLang;
-
-               $this->load();
-
-               if ( $this->mOptionsLoaded ) {
-                       return;
-               }
-
-               $this->mOptions = self::getDefaultOptions();
-
-               if ( !$this->getId() ) {
-                       // For unlogged-in users, load language/variant options from request.
-                       // There's no need to do it for logged-in users: they can set preferences,
-                       // and handling of page content is done by $pageLang->getPreferredVariant() and such,
-                       // so don't override user's choice (especially when the user chooses site default).
-                       $variant = $wgContLang->getDefaultVariant();
-                       $this->mOptions['variant'] = $variant;
-                       $this->mOptions['language'] = $variant;
-                       $this->mOptionsLoaded = true;
-                       return;
-               }
-
-               // Maybe load from the object
-               if ( !is_null( $this->mOptionOverrides ) ) {
-                       wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" );
-                       foreach ( $this->mOptionOverrides as $key => $value ) {
-                               $this->mOptions[$key] = $value;
-                       }
-               } else {
-                       if ( !is_array( $data ) ) {
-                               wfDebug( "User: loading options for user " . $this->getId() . " from database.\n" );
-                               // Load from database
-                               $dbr = ( $this->queryFlagsUsed & self::READ_LATEST )
-                                       ? wfGetDB( DB_MASTER )
-                                       : wfGetDB( DB_SLAVE );
-
-                               $res = $dbr->select(
-                                       'user_properties',
-                                       array( 'up_property', 'up_value' ),
-                                       array( 'up_user' => $this->getId() ),
-                                       __METHOD__
-                               );
-
-                               $this->mOptionOverrides = array();
-                               $data = array();
-                               foreach ( $res as $row ) {
-                                       $data[$row->up_property] = $row->up_value;
-                               }
-                       }
-                       foreach ( $data as $property => $value ) {
-                               $this->mOptionOverrides[$property] = $value;
-                               $this->mOptions[$property] = $value;
-                       }
-               }
-
-               $this->mOptionsLoaded = true;
-
-               Hooks::run( 'UserLoadOptions', array( $this, &$this->mOptions ) );
-       }
-
-       /**
-        * Saves the non-default options for this user, as previously set e.g. via
-        * setOption(), in the database's "user_properties" (preferences) table.
-        * Usually used via saveSettings().
-        */
-       protected function saveOptions() {
-               $this->loadOptions();
-
-               // Not using getOptions(), to keep hidden preferences in database
-               $saveOptions = $this->mOptions;
-
-               // Allow hooks to abort, for instance to save to a global profile.
-               // Reset options to default state before saving.
-               if ( !Hooks::run( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) {
-                       return;
-               }
-
-               $userId = $this->getId();
-
-               $insert_rows = array(); // all the new preference rows
-               foreach ( $saveOptions as $key => $value ) {
-                       // Don't bother storing default values
-                       $defaultOption = self::getDefaultOption( $key );
-                       if ( ( $defaultOption === null && $value !== false && $value !== null )
-                               || $value != $defaultOption
-                       ) {
-                               $insert_rows[] = array(
-                                       'up_user' => $userId,
-                                       'up_property' => $key,
-                                       'up_value' => $value,
-                               );
-                       }
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-
-               $res = $dbw->select( 'user_properties',
-                       array( 'up_property', 'up_value' ), array( 'up_user' => $userId ), __METHOD__ );
-
-               // Find prior rows that need to be removed or updated. These rows will
-               // all be deleted (the later so that INSERT IGNORE applies the new values).
-               $keysDelete = array();
-               foreach ( $res as $row ) {
-                       if ( !isset( $saveOptions[$row->up_property] )
-                               || strcmp( $saveOptions[$row->up_property], $row->up_value ) != 0
-                       ) {
-                               $keysDelete[] = $row->up_property;
-                       }
-               }
-
-               if ( count( $keysDelete ) ) {
-                       // Do the DELETE by PRIMARY KEY for prior rows.
-                       // In the past a very large portion of calls to this function are for setting
-                       // 'rememberpassword' for new accounts (a preference that has since been removed).
-                       // Doing a blanket per-user DELETE for new accounts with no rows in the table
-                       // caused gap locks on [max user ID,+infinity) which caused high contention since
-                       // updates would pile up on each other as they are for higher (newer) user IDs.
-                       // It might not be necessary these days, but it shouldn't hurt either.
-                       $dbw->delete( 'user_properties',
-                               array( 'up_user' => $userId, 'up_property' => $keysDelete ), __METHOD__ );
-               }
-               // Insert the new preference rows
-               $dbw->insert( 'user_properties', $insert_rows, __METHOD__, array( 'IGNORE' ) );
-       }
-
-       /**
-        * Lazily instantiate and return a factory object for making passwords
-        *
-        * @deprecated since 1.27, create a PasswordFactory directly instead
-        * @return PasswordFactory
-        */
-       public static function getPasswordFactory() {
-               wfDeprecated( __METHOD__, '1.27' );
-               $ret = new PasswordFactory();
-               $ret->init( RequestContext::getMain()->getConfig() );
-               return $ret;
-       }
-
-       /**
-        * Provide an array of HTML5 attributes to put on an input element
-        * intended for the user to enter a new password.  This may include
-        * required, title, and/or pattern, depending on $wgMinimalPasswordLength.
-        *
-        * Do *not* use this when asking the user to enter his current password!
-        * Regardless of configuration, users may have invalid passwords for whatever
-        * reason (e.g., they were set before requirements were tightened up).
-        * Only use it when asking for a new password, like on account creation or
-        * ResetPass.
-        *
-        * Obviously, you still need to do server-side checking.
-        *
-        * NOTE: A combination of bugs in various browsers means that this function
-        * actually just returns array() unconditionally at the moment.  May as
-        * well keep it around for when the browser bugs get fixed, though.
-        *
-        * @todo FIXME: This does not belong here; put it in Html or Linker or somewhere
-        *
-        * @deprecated since 1.27
-        * @return array Array of HTML attributes suitable for feeding to
-        *   Html::element(), directly or indirectly.  (Don't feed to Xml::*()!
-        *   That will get confused by the boolean attribute syntax used.)
-        */
-       public static function passwordChangeInputAttribs() {
-               global $wgMinimalPasswordLength;
-
-               if ( $wgMinimalPasswordLength == 0 ) {
-                       return array();
-               }
-
-               # Note that the pattern requirement will always be satisfied if the
-               # input is empty, so we need required in all cases.
-
-               # @todo FIXME: Bug 23769: This needs to not claim the password is required
-               # if e-mail confirmation is being used.  Since HTML5 input validation
-               # is b0rked anyway in some browsers, just return nothing.  When it's
-               # re-enabled, fix this code to not output required for e-mail
-               # registration.
-               # $ret = array( 'required' );
-               $ret = array();
-
-               # We can't actually do this right now, because Opera 9.6 will print out
-               # the entered password visibly in its error message!  When other
-               # browsers add support for this attribute, or Opera fixes its support,
-               # we can add support with a version check to avoid doing this on Opera
-               # versions where it will be a problem.  Reported to Opera as
-               # DSK-262266, but they don't have a public bug tracker for us to follow.
-               /*
-               if ( $wgMinimalPasswordLength > 1 ) {
-                       $ret['pattern'] = '.{' . intval( $wgMinimalPasswordLength ) . ',}';
-                       $ret['title'] = wfMessage( 'passwordtooshort' )
-                               ->numParams( $wgMinimalPasswordLength )->text();
-               }
-               */
-
-               return $ret;
-       }
-
-       /**
-        * Return the list of user fields that should be selected to create
-        * a new user object.
-        * @return array
-        */
-       public static function selectFields() {
-               return array(
-                       'user_id',
-                       'user_name',
-                       'user_real_name',
-                       'user_email',
-                       'user_touched',
-                       'user_token',
-                       'user_email_authenticated',
-                       'user_email_token',
-                       'user_email_token_expires',
-                       'user_registration',
-                       'user_editcount',
-               );
-       }
-
-       /**
-        * Factory function for fatal permission-denied errors
-        *
-        * @since 1.22
-        * @param string $permission User right required
-        * @return Status
-        */
-       static function newFatalPermissionDeniedStatus( $permission ) {
-               global $wgLang;
-
-               $groups = array_map(
-                       array( 'User', 'makeGroupLinkWiki' ),
-                       User::getGroupsWithPermission( $permission )
-               );
-
-               if ( $groups ) {
-                       return Status::newFatal( 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
-               } else {
-                       return Status::newFatal( 'badaccess-group0' );
-               }
-       }
-
-       /**
-        * Checks if two user objects point to the same user.
-        *
-        * @since 1.25
-        * @param User $user
-        * @return bool
-        */
-       public function equals( User $user ) {
-               return $this->getName() === $user->getName();
-       }
-}
diff --git a/includes/UserArray.php b/includes/UserArray.php
deleted file mode 100644 (file)
index 31bd601..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/**
- * Class to walk into a list of User objects.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-abstract class UserArray implements Iterator {
-       /**
-        * @param ResultWrapper $res
-        * @return UserArrayFromResult
-        */
-       static function newFromResult( $res ) {
-               $userArray = null;
-               if ( !Hooks::run( 'UserArrayFromResult', array( &$userArray, $res ) ) ) {
-                       return null;
-               }
-               if ( $userArray === null ) {
-                       $userArray = self::newFromResult_internal( $res );
-               }
-               return $userArray;
-       }
-
-       /**
-        * @param array $ids
-        * @return UserArrayFromResult
-        */
-       static function newFromIDs( $ids ) {
-               $ids = array_map( 'intval', (array)$ids ); // paranoia
-               if ( !$ids ) {
-                       // Database::select() doesn't like empty arrays
-                       return new ArrayIterator( array() );
-               }
-               $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select(
-                       'user',
-                       User::selectFields(),
-                       array( 'user_id' => array_unique( $ids ) ),
-                       __METHOD__
-               );
-               return self::newFromResult( $res );
-       }
-
-       /**
-        * @since 1.25
-        * @param array $names
-        * @return UserArrayFromResult
-        */
-       static function newFromNames( $names ) {
-               $names = array_map( 'strval', (array)$names ); // paranoia
-               if ( !$names ) {
-                       // Database::select() doesn't like empty arrays
-                       return new ArrayIterator( array() );
-               }
-               $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select(
-                       'user',
-                       User::selectFields(),
-                       array( 'user_name' => array_unique( $names ) ),
-                       __METHOD__
-               );
-               return self::newFromResult( $res );
-       }
-
-       /**
-        * @param ResultWrapper $res
-        * @return UserArrayFromResult
-        */
-       protected static function newFromResult_internal( $res ) {
-               return new UserArrayFromResult( $res );
-       }
-}
diff --git a/includes/UserArrayFromResult.php b/includes/UserArrayFromResult.php
deleted file mode 100644 (file)
index fb533d0..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-/**
- * Class to walk into a list of User objects.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-class UserArrayFromResult extends UserArray implements Countable {
-       /** @var ResultWrapper */
-       public $res;
-
-       /** @var int */
-       public $key;
-
-       /** @var bool|stdClass */
-       public $current;
-
-       /**
-        * @param ResultWrapper $res
-        */
-       function __construct( $res ) {
-               $this->res = $res;
-               $this->key = 0;
-               $this->setCurrent( $this->res->current() );
-       }
-
-       /**
-        * @param bool|stdClass $row
-        * @return void
-        */
-       protected function setCurrent( $row ) {
-               if ( $row === false ) {
-                       $this->current = false;
-               } else {
-                       $this->current = User::newFromRow( $row );
-               }
-       }
-
-       /**
-        * @return int
-        */
-       public function count() {
-               return $this->res->numRows();
-       }
-
-       /**
-        * @return User
-        */
-       function current() {
-               return $this->current;
-       }
-
-       function key() {
-               return $this->key;
-       }
-
-       function next() {
-               $row = $this->res->next();
-               $this->setCurrent( $row );
-               $this->key++;
-       }
-
-       function rewind() {
-               $this->res->rewind();
-               $this->key = 0;
-               $this->setCurrent( $this->res->current() );
-       }
-
-       /**
-        * @return bool
-        */
-       function valid() {
-               return $this->current !== false;
-       }
-}
diff --git a/includes/UserRightsProxy.php b/includes/UserRightsProxy.php
deleted file mode 100644 (file)
index e686ae3..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-<?php
-/**
- * Representation of an user on a other locally-hosted wiki.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Cut-down copy of User interface for local-interwiki-database
- * user rights manipulation.
- */
-class UserRightsProxy {
-
-       /**
-        * Constructor.
-        *
-        * @see newFromId()
-        * @see newFromName()
-        * @param IDatabase $db Db connection
-        * @param string $database Database name
-        * @param string $name User name
-        * @param int $id User ID
-        */
-       private function __construct( $db, $database, $name, $id ) {
-               $this->db = $db;
-               $this->database = $database;
-               $this->name = $name;
-               $this->id = intval( $id );
-               $this->newOptions = array();
-       }
-
-       /**
-        * Accessor for $this->database
-        *
-        * @return string Database name
-        */
-       public function getDBName() {
-               return $this->database;
-       }
-
-       /**
-        * Confirm the selected database name is a valid local interwiki database name.
-        *
-        * @param string $database Database name
-        * @return bool
-        */
-       public static function validDatabase( $database ) {
-               global $wgLocalDatabases;
-               return in_array( $database, $wgLocalDatabases );
-       }
-
-       /**
-        * Same as User::whoIs()
-        *
-        * @param string $database Database name
-        * @param int $id User ID
-        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
-        * @return string User name or false if the user doesn't exist
-        */
-       public static function whoIs( $database, $id, $ignoreInvalidDB = false ) {
-               $user = self::newFromId( $database, $id, $ignoreInvalidDB );
-               if ( $user ) {
-                       return $user->name;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Factory function; get a remote user entry by ID number.
-        *
-        * @param string $database Database name
-        * @param int $id User ID
-        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
-        * @return UserRightsProxy|null If doesn't exist
-        */
-       public static function newFromId( $database, $id, $ignoreInvalidDB = false ) {
-               return self::newFromLookup( $database, 'user_id', intval( $id ), $ignoreInvalidDB );
-       }
-
-       /**
-        * Factory function; get a remote user entry by name.
-        *
-        * @param string $database Database name
-        * @param string $name User name
-        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
-        * @return UserRightsProxy|null If doesn't exist
-        */
-       public static function newFromName( $database, $name, $ignoreInvalidDB = false ) {
-               return self::newFromLookup( $database, 'user_name', $name, $ignoreInvalidDB );
-       }
-
-       /**
-        * @param string $database
-        * @param string $field
-        * @param string $value
-        * @param bool $ignoreInvalidDB
-        * @return null|UserRightsProxy
-        */
-       private static function newFromLookup( $database, $field, $value, $ignoreInvalidDB = false ) {
-               global $wgSharedDB, $wgSharedTables;
-               // If the user table is shared, perform the user query on it,
-               // but don't pass it to the UserRightsProxy,
-               // as user rights are normally not shared.
-               if ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) {
-                       $userdb = self::getDB( $wgSharedDB, $ignoreInvalidDB );
-               } else {
-                       $userdb = self::getDB( $database, $ignoreInvalidDB );
-               }
-
-               $db = self::getDB( $database, $ignoreInvalidDB );
-
-               if ( $db && $userdb ) {
-                       $row = $userdb->selectRow( 'user',
-                               array( 'user_id', 'user_name' ),
-                               array( $field => $value ),
-                               __METHOD__ );
-
-                       if ( $row !== false ) {
-                               return new UserRightsProxy( $db, $database,
-                                       $row->user_name,
-                                       intval( $row->user_id ) );
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * Open a database connection to work on for the requested user.
-        * This may be a new connection to another database for remote users.
-        *
-        * @param string $database
-        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
-        * @return IDatabase|null If invalid selection
-        */
-       public static function getDB( $database, $ignoreInvalidDB = false ) {
-               global $wgDBname;
-               if ( $ignoreInvalidDB || self::validDatabase( $database ) ) {
-                       if ( $database == $wgDBname ) {
-                               // Hmm... this shouldn't happen though. :)
-                               return wfGetDB( DB_MASTER );
-                       } else {
-                               return wfGetDB( DB_MASTER, array(), $database );
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * @return int
-        */
-       public function getId() {
-               return $this->id;
-       }
-
-       /**
-        * @return bool
-        */
-       public function isAnon() {
-               return $this->getId() == 0;
-       }
-
-       /**
-        * Same as User::getName()
-        *
-        * @return string
-        */
-       public function getName() {
-               return $this->name . '@' . $this->database;
-       }
-
-       /**
-        * Same as User::getUserPage()
-        *
-        * @return Title
-        */
-       public function getUserPage() {
-               return Title::makeTitle( NS_USER, $this->getName() );
-       }
-
-       /**
-        * Replaces User::getUserGroups()
-        * @return array
-        */
-       function getGroups() {
-               $res = $this->db->select( 'user_groups',
-                       array( 'ug_group' ),
-                       array( 'ug_user' => $this->id ),
-                       __METHOD__ );
-               $groups = array();
-               foreach ( $res as $row ) {
-                       $groups[] = $row->ug_group;
-               }
-               return $groups;
-       }
-
-       /**
-        * Replaces User::addUserGroup()
-        * @param string $group
-        *
-        * @return bool
-        */
-       function addGroup( $group ) {
-               $this->db->insert( 'user_groups',
-                       array(
-                               'ug_user' => $this->id,
-                               'ug_group' => $group,
-                       ),
-                       __METHOD__,
-                       array( 'IGNORE' ) );
-
-               return true;
-       }
-
-       /**
-        * Replaces User::removeUserGroup()
-        * @param string $group
-        *
-        * @return bool
-        */
-       function removeGroup( $group ) {
-               $this->db->delete( 'user_groups',
-                       array(
-                               'ug_user' => $this->id,
-                               'ug_group' => $group,
-                       ),
-                       __METHOD__ );
-
-               return true;
-       }
-
-       /**
-        * Replaces User::setOption()
-        * @param string $option
-        * @param mixed $value
-        */
-       public function setOption( $option, $value ) {
-               $this->newOptions[$option] = $value;
-       }
-
-       public function saveSettings() {
-               $rows = array();
-               foreach ( $this->newOptions as $option => $value ) {
-                       $rows[] = array(
-                               'up_user' => $this->id,
-                               'up_property' => $option,
-                               'up_value' => $value,
-                       );
-               }
-               $this->db->replace( 'user_properties',
-                       array( array( 'up_user', 'up_property' ) ),
-                       $rows, __METHOD__
-               );
-               $this->invalidateCache();
-       }
-
-       /**
-        * Replaces User::touchUser()
-        */
-       function invalidateCache() {
-               $this->db->update( 'user',
-                       array( 'user_touched' => $this->db->timestamp() ),
-                       array( 'user_id' => $this->id ),
-                       __METHOD__ );
-
-               $wikiId = $this->db->getWikiID();
-               $userId = $this->id;
-               $this->db->onTransactionPreCommitOrIdle( function() use ( $wikiId, $userId ) {
-                       User::purge( $wikiId, $userId );
-               } );
-       }
-}
index a81adf9..4da51c9 100644 (file)
@@ -192,7 +192,7 @@ class HistoryAction extends FormlessAction {
                        ( $tagSelector ? ( implode( '&#160;', $tagSelector ) . '&#160;' ) : '' ) .
                        $checkDeleted .
                        Html::submitButton(
-                               $this->msg( 'allpagessubmit' )->text(),
+                               $this->msg( 'historyaction-submit' )->text(),
                                array(),
                                array( 'mw-ui-progressive' )
                        ) . "\n" .
index b71b0e9..6de95a0 100644 (file)
@@ -80,12 +80,12 @@ class RawAction extends FormlessAction {
                        if ( $this->gen ) {
                                $smaxage = $config->get( 'SquidMaxage' );
                        } elseif ( $contentType == 'text/css' || $contentType == 'text/javascript' ) {
-                               // CSS/JS raw content has its own squid max age configuration.
-                               // Note: Title::getSquidURLs() includes action=raw for css/js pages,
+                               // CSS/JS raw content has its own CDN max age configuration.
+                               // Note: Title::getCdnUrls() includes action=raw for css/js pages,
                                // so if using the canonical url, this will get HTCP purges.
                                $smaxage = intval( $config->get( 'ForcedRawSMaxage' ) );
                        } else {
-                               // No squid cache for anything else
+                               // No CDN cache for anything else
                                $smaxage = 0;
                        }
                }
index 8e5cdcc..8a98197 100644 (file)
@@ -97,7 +97,7 @@ abstract class ApiBase extends ContextSource {
        /** (integer) Lowest value allowed for the parameter, for PARAM_TYPE 'integer' and 'limit'. */
        const PARAM_MIN = 5;
 
-       /** (boolean) Allow the same value to be set more than once when PARAM_MULTI is true? */
+       /** (boolean) Allow the same value to be set more than once when PARAM_ISMULTI is true? */
        const PARAM_ALLOW_DUPLICATES = 6;
 
        /** (boolean) Is the parameter deprecated (will show a warning)? */
index 8a63070..72adaf8 100644 (file)
@@ -115,7 +115,7 @@ class ApiExpandTemplates extends ApiBase {
                                                foreach ( $categories as $category => $sortkey ) {
                                                        $entry = array();
                                                        $entry['sortkey'] = $sortkey;
-                                                       ApiResult::setContentValue( $entry, 'category', $category );
+                                                       ApiResult::setContentValue( $entry, 'category', (string)$category );
                                                        $categories_result[] = $entry;
                                                }
                                                ApiResult::setIndexedTagName( $categories_result, 'category' );
index 77a3a21..c841d83 100644 (file)
@@ -265,7 +265,9 @@ class ApiFeedWatchlist extends ApiBase {
                                if ( !isset( $p[ApiBase::PARAM_HELP_MSG] ) ) {
                                        $p[ApiBase::PARAM_HELP_MSG] = "apihelp-query+watchlist-param-$from";
                                }
-                               if ( is_array( $p[ApiBase::PARAM_TYPE] ) && isset( $p[ApiBase::PARAM_HELP_MSG_PER_VALUE] ) ) {
+                               if ( isset( $p[ApiBase::PARAM_TYPE] ) && is_array( $p[ApiBase::PARAM_TYPE] ) &&
+                                       isset( $p[ApiBase::PARAM_HELP_MSG_PER_VALUE] )
+                               ) {
                                        foreach ( $p[ApiBase::PARAM_TYPE] as $v ) {
                                                if ( !isset( $p[ApiBase::PARAM_HELP_MSG_PER_VALUE][$v] ) ) {
                                                        $p[ApiBase::PARAM_HELP_MSG_PER_VALUE][$v] = "apihelp-query+watchlist-paramvalue-$from-$v";
index 9dbd4a5..b1a9c98 100644 (file)
@@ -36,7 +36,7 @@ class ApiFormatRaw extends ApiFormatBase {
 
        /**
         * @param ApiMain $main
-        * @param ApiFormatBase |null $errorFallback Object to fall back on for errors
+        * @param ApiFormatBase|null $errorFallback Object to fall back on for errors
         */
        public function __construct( ApiMain $main, ApiFormatBase $errorFallback = null ) {
                parent::__construct( $main, 'raw' );
index 9de5a02..5754c23 100644 (file)
@@ -634,7 +634,8 @@ class ApiParse extends ApiBase {
                foreach ( $links as $link => $sortkey ) {
                        $entry = array();
                        $entry['sortkey'] = $sortkey;
-                       ApiResult::setContentValue( $entry, 'category', $link );
+                       // array keys will cast numeric category names to ints, so cast back to string
+                       ApiResult::setContentValue( $entry, 'category', (string)$link );
                        if ( !isset( $hiddencats[$link] ) ) {
                                $entry['missing'] = true;
                        } elseif ( $hiddencats[$link] ) {
index ffcb2f5..9ea1b1e 100644 (file)
@@ -59,9 +59,10 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        $fld_rights = isset( $prop['rights'] );
                        $fld_registration = isset( $prop['registration'] );
                        $fld_implicitgroups = isset( $prop['implicitgroups'] );
+                       $fld_centralids = isset( $prop['centralids'] );
                } else {
                        $fld_blockinfo = $fld_editcount = $fld_groups = $fld_registration =
-                               $fld_rights = $fld_implicitgroups = false;
+                               $fld_rights = $fld_implicitgroups = $fld_centralids = false;
                }
 
                $limit = $params['limit'];
@@ -239,6 +240,12 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                'name' => $row->user_name,
                        );
 
+                       if ( $fld_centralids ) {
+                               $data += ApiQueryUserInfo::getCentralUserInfo(
+                                       $this->getConfig(), User::newFromId( $row->user_id ), $params['attachedwiki']
+                               );
+                       }
+
                        if ( $fld_blockinfo && !is_null( $row->ipb_by_text ) ) {
                                $data['blockid'] = (int)$row->ipb_id;
                                $data['blockedby'] = $row->ipb_by_text;
@@ -338,7 +345,8 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                        'implicitgroups',
                                        'rights',
                                        'editcount',
-                                       'registration'
+                                       'registration',
+                                       'centralids',
                                ),
                                ApiBase::PARAM_HELP_MSG_PER_VALUE => array(),
                        ),
@@ -357,6 +365,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                        $this->getConfig()->get( 'ActiveUserDays' )
                                ),
                        ),
+                       'attachedwiki' => null,
                );
        }
 
index 7047339..ca9ceca 100644 (file)
@@ -245,6 +245,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
                $data['misermode'] = (bool)$config->get( 'MiserMode' );
 
+               $data['uploadsenabled'] = UploadBase::isEnabled();
                $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
                $data['minuploadchunksize'] = (int)$this->getConfig()->get( 'MinUploadChunkSize' );
 
@@ -265,6 +266,10 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                        $data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
                }
 
+               $data['centralidlookupprovider'] = $this->getConfig()->get( 'CentralIdLookupProvider' );
+               $providerIds = array_keys( $this->getConfig()->get( 'CentralIdLookupProviders' ) );
+               $data['allcentralidlookupproviders'] = $providerIds;
+
                Hooks::run( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
 
                return $this->getResult()->addValue( 'query', $property, $data );
index 93c0dd0..27663a1 100644 (file)
@@ -33,6 +33,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
 
        const WL_UNREAD_LIMIT = 1000;
 
+       private $params = array();
        private $prop = array();
 
        public function __construct( ApiQuery $query, $moduleName ) {
@@ -40,11 +41,11 @@ class ApiQueryUserInfo extends ApiQueryBase {
        }
 
        public function execute() {
-               $params = $this->extractRequestParams();
+               $this->params = $this->extractRequestParams();
                $result = $this->getResult();
 
-               if ( !is_null( $params['prop'] ) ) {
-                       $this->prop = array_flip( $params['prop'] );
+               if ( !is_null( $this->params['prop'] ) ) {
+                       $this->prop = array_flip( $this->params['prop'] );
                }
 
                $r = $this->getCurrentUserInfo();
@@ -76,6 +77,45 @@ class ApiQueryUserInfo extends ApiQueryBase {
                return $vals;
        }
 
+       /**
+        * Get central user info
+        * @param Config $config
+        * @param User $user
+        * @param string|null $attachedWiki
+        * @return array Central user info
+        *  - centralids: Array mapping non-local Central ID provider names to IDs
+        *  - attachedlocal: Array mapping Central ID provider names to booleans
+        *    indicating whether the local user is attached.
+        *  - attachedwiki: Array mapping Central ID provider names to booleans
+        *    indicating whether the user is attached to $attachedWiki.
+        */
+       public static function getCentralUserInfo( Config $config, User $user, $attachedWiki = null ) {
+               $providerIds = array_keys( $config->get( 'CentralIdLookupProviders' ) );
+
+               $ret = array(
+                       'centralids' => array(),
+                       'attachedlocal' => array(),
+               );
+               ApiResult::setArrayType( $ret['centralids'], 'assoc' );
+               ApiResult::setArrayType( $ret['attachedlocal'], 'assoc' );
+               if ( $attachedWiki ) {
+                       $ret['attachedwiki'] = array();
+                       ApiResult::setArrayType( $ret['attachedwiki'], 'assoc' );
+               }
+
+               $name = $user->getName();
+               foreach ( $providerIds as $providerId ) {
+                       $provider = CentralIdLookup::factory( $providerId );
+                       $ret['centralids'][$providerId] = $provider->centralIdFromName( $name );
+                       $ret['attachedlocal'][$providerId] = $provider->isAttached( $user );
+                       if ( $attachedWiki ) {
+                               $ret['attachedwiki'][$providerId] = $provider->isAttached( $user, $attachedWiki );
+                       }
+               }
+
+               return $ret;
+       }
+
        protected function getCurrentUserInfo() {
                $user = $this->getUser();
                $vals = array();
@@ -205,6 +245,12 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        }
                }
 
+               if ( isset( $this->prop['centralids'] ) ) {
+                       $vals += self::getCentralUserInfo(
+                               $this->getConfig(), $this->getUser(), $this->params['attachedwiki']
+                       );
+               }
+
                return $vals;
        }
 
@@ -267,6 +313,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
                                        'acceptlang',
                                        'registrationdate',
                                        'unreadcount',
+                                       'centralids',
                                ),
                                ApiBase::PARAM_HELP_MSG_PER_VALUE => array(
                                        'unreadcount' => array(
@@ -275,7 +322,8 @@ class ApiQueryUserInfo extends ApiQueryBase {
                                                self::WL_UNREAD_LIMIT . '+',
                                        ),
                                ),
-                       )
+                       ),
+                       'attachedwiki' => null,
                );
        }
 
index a826c1b..db5fb65 100644 (file)
@@ -48,6 +48,7 @@ class ApiQueryUsers extends ApiQueryBase {
                'registration',
                'emailable',
                'gender',
+               'centralids',
        );
 
        public function __construct( ApiQuery $query, $moduleName ) {
@@ -213,6 +214,12 @@ class ApiQueryUsers extends ApiQueryBase {
                                        $data[$name]['gender'] = $gender;
                                }
 
+                               if ( isset( $this->prop['centralids'] ) ) {
+                                       $data[$name] += ApiQueryUserInfo::getCentralUserInfo(
+                                               $this->getConfig(), $user, $params['attachedwiki']
+                                       );
+                               }
+
                                if ( !is_null( $params['token'] ) ) {
                                        $tokenFunctions = $this->getTokenFunctions();
                                        foreach ( $params['token'] as $t ) {
@@ -304,9 +311,11 @@ class ApiQueryUsers extends ApiQueryBase {
                                        'registration',
                                        'emailable',
                                        'gender',
+                                       'centralids',
                                ),
                                ApiBase::PARAM_HELP_MSG_PER_VALUE => array(),
                        ),
+                       'attachedwiki' => null,
                        'users' => array(
                                ApiBase::PARAM_ISMULTI => true
                        ),
index e28cb82..bd5fe08 100644 (file)
@@ -1090,7 +1090,7 @@ class ApiResult implements ApiSerializable {
                $s = 0;
                if ( is_array( $value ) ) {
                        foreach ( $value as $k => $v ) {
-                               if ( !self::isMetadataKey( $s ) ) {
+                               if ( !self::isMetadataKey( $k ) ) {
                                        $s += self::valueSize( $v );
                                }
                        }
index ebddd51..c6d267c 100644 (file)
@@ -19,6 +19,8 @@
  * @author Aaron Schulz
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * Prepare an edit in shared cache so that it can be reused on edit
  *
@@ -133,6 +135,7 @@ class ApiStashEdit extends ApiBase {
         */
        public static function parseAndStash( WikiPage $page, Content $content, User $user ) {
                $cache = ObjectCache::getLocalClusterInstance();
+               $logger = LoggerFactory::getInstance( 'StashEdit' );
 
                $format = $content->getDefaultFormat();
                $editInfo = $page->prepareContentForEdit( $content, null, $user, $format, false );
@@ -147,14 +150,14 @@ class ApiStashEdit extends ApiBase {
                        if ( $stashInfo ) {
                                $ok = $cache->set( $key, $stashInfo, $ttl );
                                if ( $ok ) {
-                                       wfDebugLog( 'StashEdit', "Cached parser output for key '$key'." );
+                                       $logger->debug( "Cached parser output for key '$key'." );
                                        return self::ERROR_NONE;
                                } else {
-                                       wfDebugLog( 'StashEdit', "Failed to cache parser output for key '$key'." );
+                                       $logger->error( "Failed to cache parser output for key '$key'." );
                                        return self::ERROR_CACHE;
                                }
                        } else {
-                               wfDebugLog( 'StashEdit', "Uncacheable parser output for key '$key'." );
+                               $logger->info( "Uncacheable parser output for key '$key'." );
                                return self::ERROR_UNCACHEABLE;
                        }
                }
@@ -186,6 +189,7 @@ class ApiStashEdit extends ApiBase {
                ParserOptions $pstOpts, ParserOptions $pOpts, $timestamp
        ) {
                $cache = ObjectCache::getLocalClusterInstance();
+               $logger = LoggerFactory::getInstance( 'StashEdit' );
 
                // getIsPreview() controls parser function behavior that references things
                // like user/revision that don't exists yet. The user/text should already
@@ -207,22 +211,22 @@ class ApiStashEdit extends ApiBase {
                $canonicalPOpts->setIsPreview( true ); // force match
                $canonicalPOpts->setTimestamp( $pOpts->getTimestamp() ); // force match
                if ( !$pOpts->matches( $canonicalPOpts ) ) {
-                       wfDebugLog( 'StashEdit', "Uncacheable preview output for key '$key' (options)." );
+                       $logger->info( "Uncacheable preview output for key '$key' (options)." );
                        return false;
                }
 
                // Build a value to cache with a proper TTL
                list( $stashInfo, $ttl ) = self::buildStashValue( $pstContent, $pOut, $timestamp );
                if ( !$stashInfo ) {
-                       wfDebugLog( 'StashEdit', "Uncacheable parser output for key '$key' (rev/TTL)." );
+                       $logger->info( "Uncacheable parser output for key '$key' (rev/TTL)." );
                        return false;
                }
 
                $ok = $cache->set( $key, $stashInfo, $ttl );
                if ( !$ok ) {
-                       wfDebugLog( 'StashEdit', "Failed to cache preview parser output for key '$key'." );
+                       $logger->error( "Failed to cache preview parser output for key '$key'." );
                } else {
-                       wfDebugLog( 'StashEdit', "Cached preview output for key '$key'." );
+                       $logger->debug( "Cached preview output for key '$key'." );
                }
 
                return $ok;
@@ -247,6 +251,7 @@ class ApiStashEdit extends ApiBase {
         */
        public static function checkCache( Title $title, Content $content, User $user ) {
                $cache = ObjectCache::getLocalClusterInstance();
+               $logger = LoggerFactory::getInstance( 'StashEdit' );
 
                $key = self::getStashKey( $title, $content, $user );
                $editInfo = $cache->get( $key );
@@ -260,18 +265,18 @@ class ApiStashEdit extends ApiBase {
                        }
                        $sec = microtime( true ) - $start;
                        if ( $sec > .01 ) {
-                               wfDebugLog( 'StashEdit', "Waited $sec seconds on '$key'." );
+                               $logger->warning( "Waited $sec seconds on '$key'." );
                        }
                }
 
                if ( !is_object( $editInfo ) || !$editInfo->output ) {
-                       wfDebugLog( 'StashEdit', "No cache value for key '$key'." );
+                       $logger->debug( "No cache value for key '$key'." );
                        return false;
                }
 
                $time = wfTimestamp( TS_UNIX, $editInfo->output->getTimestamp() );
                if ( ( time() - $time ) <= 3 ) {
-                       wfDebugLog( 'StashEdit', "Timestamp-based cache hit for key '$key'." );
+                       $logger->debug( "Timestamp-based cache hit for key '$key'." );
                        return $editInfo; // assume nothing changed
                }
 
@@ -299,7 +304,7 @@ class ApiStashEdit extends ApiBase {
                        }
 
                        if ( $changed || $res->numRows() != $templateUses ) {
-                               wfDebugLog( 'StashEdit', "Stale cache for key '$key'; template changed." );
+                               $logger->info( "Stale cache for key '$key'; template changed." );
                                return false;
                        }
                }
@@ -322,12 +327,12 @@ class ApiStashEdit extends ApiBase {
                        }
 
                        if ( $changed || $res->numRows() != count( $files ) ) {
-                               wfDebugLog( 'StashEdit', "Stale cache for key '$key'; file changed." );
+                               $logger->info( "Stale cache for key '$key'; file changed." );
                                return false;
                        }
                }
 
-               wfDebugLog( 'StashEdit', "Cache hit for key '$key'." );
+               $logger->debug( "Cache hit for key '$key'." );
 
                return $editInfo;
        }
index c188d15..684b7b5 100644 (file)
@@ -14,7 +14,8 @@
                        "Anomie",
                        "Duder",
                        "Ljonka",
-                       "FriedhelmW"
+                       "FriedhelmW",
+                       "Predatorix"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page/de|Dokumentation]]\n* [[mw:API:FAQ/de|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:API:Errors_and_warnings|API: Fehler und Warnungen]].",
        "apihelp-expandtemplates-param-title": "Titel der Seite.",
        "apihelp-expandtemplates-param-text": "Zu konvertierender Wikitext.",
        "apihelp-expandtemplates-param-revid": "Versionsnummer, die für die Anzeige von <nowiki>{{REVISIONID}}</nowiki> und ähnlichen Variablen verwendet wird.",
+       "apihelp-expandtemplates-param-prop": "Welche Informationen abgerufen werden sollen.\n\nBeachte bitte, dass das Ergebnis Wikitext enthält, aber die Ausgabe in einem veralteten Format ist, falls keine Werte ausgewählt sind.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Der expandierte Wikitext.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "Seiteneigenschaften, die durch expandierte magische Wörter im Wikitext definiert sind.",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "Die maximale Zeit, nach der der Ergebnis-Cache ungültig wird.",
        "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Gibt die JavaScript-Konfigurationsvariablen speziell für die Seite aus.",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Gibt die JavaScript-Konfigurationsvariablen speziell für die Seite als JSON-Zeichenfolge aus.",
        "apihelp-paraminfo-description": "Ruft Informationen über API-Module ab.",
        "apihelp-paraminfo-param-helpformat": "Format der Hilfe-Zeichenfolgen.",
        "apihelp-parse-param-summary": "Zu parsende Zusammenfassung.",
+       "apihelp-parse-param-prop": "Welche Informationen bezogen werden sollen:",
+       "apihelp-parse-paramvalue-prop-text": "Gibt den geparsten Text des Wikitextes zurück.",
        "apihelp-parse-paramvalue-prop-langlinks": "Gibt die Sprachlinks im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-categories": "Gibt die Kategorien im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "Gibt die HTML-Version der Kategorien zurück.",
        "apihelp-parse-paramvalue-prop-templates": "Gibt die Vorlagen im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-images": "Gibt die Bilder im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-externallinks": "Gibt die externen Links im geparsten Wikitext zurück.",
+       "apihelp-parse-paramvalue-prop-sections": "Gibt die Abschnitte im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-revid": "Ergänzt die Versionskennung der geparsten Seite.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Ergänzt den Titel des geparsten Wikitextes.",
+       "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Gibt die JavaScript-Konfigurationsvariablen speziell für die Seite als JSON-Zeichenfolge aus.",
+       "apihelp-parse-paramvalue-prop-indicators": "Gibt das HTML der Seitenstatusindikatoren zurück, die auf der Seite verwendet werden.",
+       "apihelp-parse-paramvalue-prop-iwlinks": "Gibt Interwiki-Links des geparsten Wikitextes zurück.",
+       "apihelp-parse-paramvalue-prop-wikitext": "Gibt den originalen Wikitext zurück, der geparst wurde.",
+       "apihelp-parse-paramvalue-prop-properties": "Gibt verschiedene Eigenschaften zurück, die im geparsten Wikitext definiert sind.",
        "apihelp-parse-param-section": "Parst nur den Inhalt dieser Abschnittsnummer.\n\nFalls <kbd>new</kbd>, parst <var>$1text</var> und <var>$1sectiontitle</var>, als ob ein neuer Abschnitt der Seite hinzugefügt wird.\n\n<kbd>new</kbd> ist nur erlaubt mit der Angabe <var>text</var>.",
        "apihelp-parse-param-sectiontitle": "Überschrift des neuen Abschnittes, wenn <var>section</var> = <kbd>new</kbd> ist.\n\nAnders als beim Bearbeiten der Seite wird der Parameter nicht durch die <var>summary</var> ersetzt, wenn er weggelassen oder leer ist.",
        "apihelp-parse-param-disableeditsection": "Lässt Abschnittsbearbeitungslinks in der Parserausgabe weg.",
        "apihelp-query+prefixsearch-param-search": "Such-Zeichenfolge.",
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Ergänzt den Zeitstempel für die Bearbeitung.",
        "apihelp-query+recentchanges-paramvalue-prop-tags": "Listet Markierungen für den Eintrag auf.",
+       "apihelp-query+recentchanges-example-simple": "Listet die letzten Änderungen auf.",
+       "apihelp-query+redirects-paramvalue-prop-pageid": "Seitenkennung einer jeden Weiterleitung.",
+       "apihelp-query+redirects-paramvalue-prop-title": "Titel einer jeden Weiterleitung.",
+       "apihelp-query+revisions+base-paramvalue-prop-ids": "Die Kennung der Version.",
+       "apihelp-query+revisions+base-paramvalue-prop-timestamp": "Der Zeitstempel der Version.",
+       "apihelp-query+revisions+base-paramvalue-prop-size": "Länge in Bytes der Version.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Text der Version.",
        "apihelp-query+search-param-prop": "Eigenschaften zur Rückgabe:",
        "apihelp-query+search-example-simple": "Nach <kbd>meaning</kbd> suchen.",
index 033904d..c737355 100644 (file)
@@ -1,15 +1,33 @@
 {
        "@metadata": {
                "authors": [
-                       "Gorizon"
+                       "Gorizon",
+                       "Mirzali"
                ]
        },
        "apihelp-createaccount-param-name": "Nameyê karberi.",
        "apihelp-delete-description": "Pele bestere.",
+       "apihelp-disabled-description": "Eno modul aktiv niyo.",
+       "apihelp-edit-description": "Vıraze û pelan bıvurne.",
        "apihelp-edit-param-text": "Zerreki pele",
+       "apihelp-edit-param-minor": "Vurnayışo qıckek.",
+       "apihelp-edit-param-notminor": "Vurnayışo qıckek niyo.",
+       "apihelp-edit-param-bot": "Nê vurnayışi zey boti nişan ke.",
        "apihelp-edit-example-edit": "Şeker bıvurne",
+       "apihelp-emailuser-description": "Yew karberi rê e-poste bırışe.",
+       "apihelp-emailuser-param-target": "Karbero ke cı rê e-poste do bırışiyo.",
+       "apihelp-emailuser-param-subject": "Sernameyê mewzuyi.",
+       "apihelp-emailuser-param-text": "Metınê e-posteyi.",
+       "apihelp-emailuser-param-ccme": "Yew kopyaya nê posteyi mı rê bırışe.",
+       "apihelp-expandtemplates-param-title": "Sernameyê pele.",
+       "apihelp-expandtemplates-param-text": "Wikimetıni açarnê.",
+       "apihelp-feedrecentchanges-param-hideminor": "Vurnayışanê qıckekan bınımne.",
+       "apihelp-feedrecentchanges-param-hidebots": "Vurnayışanê botan bınımne.",
+       "apihelp-feedrecentchanges-param-hideanons": "Vurnayışanê karberanê anoniman bınımne.",
+       "apihelp-feedrecentchanges-param-hideliu": "Vurnayışanê karberanê qeydınan bınımne.",
        "apihelp-login-param-name": "Nameyê karberi.",
        "apihelp-login-param-password": "Parola.",
        "apihelp-login-param-domain": "Domain (optional).",
-       "apihelp-login-example-login": "Dekew."
+       "apihelp-login-example-login": "Dekew.",
+       "apihelp-move-description": "Yew pele bere."
 }
index 4c2d0be..897c05e 100644 (file)
        "apihelp-query+allusers-paramvalue-prop-rights": "Lists rights that the user has.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "Adds the edit count of the user.",
        "apihelp-query+allusers-paramvalue-prop-registration": "Adds the timestamp of when the user registered if available (may be blank).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "Adds the central IDs and attachment status for the user.",
        "apihelp-query+allusers-param-limit": "How many total user names to return.",
        "apihelp-query+allusers-param-witheditsonly": "Only list users who have made edits.",
        "apihelp-query+allusers-param-activeusers": "Only list users active in the last $1 {{PLURAL:$1|day|days}}.",
+       "apihelp-query+allusers-param-attachedwiki": "With <kbd>$1prop=centralids</kbd>, also indicate whether the user is attached with the wiki identified by this ID.",
        "apihelp-query+allusers-example-Y": "List users starting at <kbd>Y</kbd>.",
 
        "apihelp-query+backlinks-description": "Find all pages that link to the given page.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Echoes the <code>Accept-Language</code> header sent by the client in a structured format.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Adds the user's registration date.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "Adds the central IDs and attachment status for the user.",
+       "apihelp-query+userinfo-param-attachedwiki": "With <kbd>$1prop=centralids</kbd>, indicate whether the user is attached with the wiki identified by this ID.",
        "apihelp-query+userinfo-example-simple": "Get information about the current user.",
        "apihelp-query+userinfo-example-data": "Get additional information about the current user.",
 
        "apihelp-query+users-paramvalue-prop-registration": "Adds the user's registration timestamp.",
        "apihelp-query+users-paramvalue-prop-emailable": "Tags if the user can and wants to receive email through [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "Tags the gender of the user. Returns \"male\", \"female\", or \"unknown\".",
+       "apihelp-query+users-paramvalue-prop-centralids": "Adds the central IDs and attachment status for the user.",
+       "apihelp-query+users-param-attachedwiki": "With <kbd>$1prop=centralids</kbd>, indicate whether the user is attached with the wiki identified by this ID.",
        "apihelp-query+users-param-users": "A list of users to obtain information for.",
        "apihelp-query+users-param-token": "Use <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> instead.",
        "apihelp-query+users-example-simple": "Return information for user <kbd>Example</kbd>.",
index 370ee0d..079eeb2 100644 (file)
@@ -2,9 +2,11 @@
        "@metadata": {
                "authors": [
                        "Subi",
-                       "Sator"
+                       "Sator",
+                       "An13sa"
                ]
        },
+       "apihelp-main-param-action": "Zein ekintza burutuko da.",
        "apihelp-main-param-format": "Irteerako formatua.",
        "apihelp-block-description": "Blokeatu erabiltzaile bat.",
        "apihelp-block-param-reason": "Blokeatzeko arrazoia.",
@@ -14,7 +16,9 @@
        "apihelp-createaccount-param-realname": "Erabiltzailearen benetako izena (aukerakoa).",
        "apihelp-delete-description": "Orrialde bat ezabatu.",
        "apihelp-delete-example-simple": "Ezabatu <kbd>Main Page</kbd>.",
+       "apihelp-disabled-description": "Modulu hau ezgaitu da.",
        "apihelp-edit-description": "Orrialdeak sortu eta aldatu.",
+       "apihelp-edit-param-sectiontitle": "Atal berri baten titulua.",
        "apihelp-edit-param-text": "Orrialdearen edukia.",
        "apihelp-edit-param-minor": "Aldaketa txikia.",
        "apihelp-edit-example-edit": "Orrialde bat aldatu",
@@ -22,6 +26,7 @@
        "apihelp-emailuser-param-subject": "Gaiaren goiburua.",
        "apihelp-emailuser-param-text": "Mezuaren gorputza.",
        "apihelp-expandtemplates-param-title": "Orrialdearen izenburua.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "Wikitestu zabaldua.",
        "apihelp-feedcontributions-param-year": "Urtetik aurrera (eta lehenagotik)",
        "apihelp-feedcontributions-param-month": "Hilabetetik aurrera (eta lehenagotik)",
        "apihelp-feedrecentchanges-param-hideminor": "Ezkutatu aldaketa txikiak.",
        "apihelp-feedrecentchanges-example-simple": "Erakutsi aldaketa berriak",
        "apihelp-feedrecentchanges-example-30days": "Erakutsi aldaketa berriak 30 egunez",
        "apihelp-filerevert-param-comment": "Iruzkina igo.",
+       "apihelp-help-example-recursive": "Laguntza guztia orrialde batean.",
        "apihelp-imagerotate-description": "Irudi bat edo gehiago biratu.",
+       "apihelp-import-param-summary": "Inportazioaren laburpena.",
+       "apihelp-import-param-xml": "XML fitxategia igo da.",
        "apihelp-login-param-name": "Erabiltzaile izena.",
        "apihelp-login-param-password": "Pasahitza.",
        "apihelp-login-param-domain": "Domeinua (hautazkoa).",
        "apihelp-login-example-login": "Saioa hasi",
        "apihelp-move-description": "Orrialde bat mugitu",
        "apihelp-move-param-reason": "Berrizenpenaren arrazoia.",
+       "apihelp-move-param-noredirect": "Birzuzenketarik ez sortu.",
+       "apihelp-move-param-ignorewarnings": "Edozein ohar ezikusi.",
+       "apihelp-opensearch-param-namespace": "Bilatzeko izen-tarteak.",
+       "apihelp-opensearch-param-format": "Irteerako formatua.",
        "apihelp-options-example-reset": "Berrezarri hobespen guztiak.",
+       "apihelp-paraminfo-description": "API moduluei buruzko informazioa eskuratu.",
+       "apihelp-parse-param-summary": "Analizatzeko laburpena.",
        "apihelp-protect-param-reason": "Babesteko edo babesa kentzeko zergatia.",
        "apihelp-protect-example-protect": "Orrialde bat babestu",
+       "apihelp-query+allcategories-description": "Kategoria guztiak zenbakitu.",
        "apihelp-query+allusers-param-witheditsonly": "Bakarrik zerrendatu aldaketak egin dituzten erabiltzaileak.",
        "apihelp-query+allusers-param-activeusers": "Bakarrik zerrendatu azken {{PLURAL:$1|eguneko|$1 egunetako}} erabiltzaile aktiboak.",
        "apihelp-query+blocks-description": "Zerrendatu blokeatutako erabiltzaile eta IP helbide guztiak.",
@@ -53,6 +68,8 @@
        "apihelp-query+prefixsearch-param-search": "Bilatu katea.",
        "apihelp-query+protectedtitles-example-simple": "Zerrendatu babestutako izenburuak",
        "apihelp-query+recentchanges-example-simple": "Zerrendatu aldaketa berriak.",
+       "apihelp-query+revisions-example-last5": "<kbd>Orrialde Nagusiaren</kbd> azken 5 berrikuspenak eskuratu.",
+       "apihelp-query+revisions-example-first5": "<kbd>Orrialde Nagusiaren</kbd> lehen 5 berrikuspenak eskuratu.",
        "apihelp-upload-param-file": "Fitxategiaren edukia.",
        "apihelp-upload-example-url": "Igo URL batetik.",
        "apihelp-userrights-param-reason": "Aldaketarako arrazoia.",
index 1518bcb..d306c3e 100644 (file)
        "apihelp-query+allusers-paramvalue-prop-rights": "Liste les droits qu’à l’utilisateur.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "Ajoute le compteur de modifications de l’utilisateur.",
        "apihelp-query+allusers-paramvalue-prop-registration": "Ajoute l’horodatage de l’inscription de l’utilisateur, s’il est disponible (peut être vide).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "Ajoute les IDs centraux et l’état d’attachement de l’utilisateur.",
        "apihelp-query+allusers-param-limit": "Combien de noms d’utilisateur renvoyer au total.",
        "apihelp-query+allusers-param-witheditsonly": "Ne lister que les utilisateurs qui ont fait des modifications.",
        "apihelp-query+allusers-param-activeusers": "Lister uniquement les utilisateurs actifs durant {{PLURAL:$1|le dernier jour|les $1 derniers jours}}.",
+       "apihelp-query+allusers-param-attachedwiki": "Avec <kbd>$1prop=centralids</kbd>, indiquer aussi si l’utilisateur est attaché avec le wiki identifié par cet ID.",
        "apihelp-query+allusers-example-Y": "Lister les utilisateurs en commençant à <kbd>Y</kbd>.",
        "apihelp-query+backlinks-description": "Trouver toutes les pages qui ont un lien vers la page donnée.",
        "apihelp-query+backlinks-param-title": "Titre à rechercher. Impossible à utiliser avec <var>$1pageid</var>.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Renvoie en écho l’entête <code>Accept-Language</code> envoyé par le client dans un format structuré.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Ajoute la date d’inscription de l’utilisateur.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Ajoute le compteur de pages non lues de la liste de suivi de l’utilisateur (au maximum $1 ; renvoie <samp>$2</samp> s’il y en a plus).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "Ajoute les IDs centraux et l’état d’attachement de l’utilisateur.",
+       "apihelp-query+userinfo-param-attachedwiki": "Avec <kbd>$1prop=centralids</kbd>, indiquer si l’utilisateur est attaché au wiki identifié par cet ID.",
        "apihelp-query+userinfo-example-simple": "Obtenir de l’information sur l’utilisateur actuel",
        "apihelp-query+userinfo-example-data": "Obtenir des informations supplémentaires sur l’utilisateur actuel",
        "apihelp-query+users-description": "Obtenir des information sur une liste d’utilisateurs",
        "apihelp-query+users-paramvalue-prop-registration": "Ajoute l’horodatage d’inscription de l’utilisateur.",
        "apihelp-query+users-paramvalue-prop-emailable": "Marque si l’utilisateur peut et veut recevoir des courriels via [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "Marque le sexe de l’utilisateur. Renvoie « male », « female », ou « unknown ».",
+       "apihelp-query+users-paramvalue-prop-centralids": "Ajoute les IDs centraux et l’état d’attachement de l’utilisateur.",
+       "apihelp-query+users-param-attachedwiki": "Avec <kbd>$1prop=centralids</kbd>, indiquer si l’utilisateur est attaché au wiki identifié par cet ID.",
        "apihelp-query+users-param-users": "Une liste des utilisateurs sur lesquels obtenir de l’information.",
        "apihelp-query+users-param-token": "Utiliser plutôt <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
        "apihelp-query+users-example-simple": "Renvoyer des informations pour l'utilisateur <kbd>Example</kbd>.",
index 577cd31..9d69078 100644 (file)
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Reenvía a cabeceira <code>Accept-Language</code> enviada polo cliente nun formato estruturado.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Engade a data de rexistro do usuario.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Engade o número de páxinas sen ler da lista de vixiancia do usuario (máximo $1; devolve <samp>$2</samp> se son máis).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "Engade os identificadores centrais e o estado de acoplamento do usuario.",
+       "apihelp-query+userinfo-param-attachedwiki": "Con <kbd>$1prop=centralids</kbd>, \nindica que o usuario está acoplado á wiki identificada por este identificador.",
        "apihelp-query+userinfo-example-simple": "Obter información sobre o usuario actual.",
        "apihelp-query+userinfo-example-data": "Obter información adicional sobre o usuario actual.",
        "apihelp-query+users-description": "Obter información sobre unha lista de usuarios.",
        "apihelp-query+users-paramvalue-prop-registration": "Engade o selo de tempo do rexistro do usuario.",
        "apihelp-query+users-paramvalue-prop-emailable": "Marca se o usuario pode e quere recibir correos usando [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "Marca o xénero do usuario. Devolve \"home\", \"muller\" ou \"descoñecido\".",
+       "apihelp-query+users-paramvalue-prop-centralids": "Engade os identificadores centrais e o estado de acoplamento do usuario.",
+       "apihelp-query+users-param-attachedwiki": "Con <kbd>$1prop=centralids</kbd>, \nindica que o usuario está acoplado á wiki identificada por este identificador.",
        "apihelp-query+users-param-users": "Lista de usuarios para os que obter información.",
        "apihelp-query+users-param-token": "Usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> no canto diso.",
        "apihelp-query+users-example-simple": "Mostar información para o usuario <kbd>Example</kbd>.",
index 60e9f6d..b2fe5b8 100644 (file)
        "apihelp-query+allusers-paramvalue-prop-rights": "רשימת הההרשאות שיש למשתמש.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "הוספת מניין העריכות של המשתמש .",
        "apihelp-query+allusers-paramvalue-prop-registration": "הוספת חותם־הזמן של זמן הרישום של המשתמש (יכול להיות ריק).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "הוספת המזהה המרכזי ומצב השיוך למשתמש.",
        "apihelp-query+allusers-param-limit": "כמה שמות משתמש בסך הכול לשנות.",
        "apihelp-query+allusers-param-witheditsonly": "לרשום רק משתמשים שעשו עריכות.",
        "apihelp-query+allusers-param-activeusers": "לרשום רק משתמשים שהיו פעילים {{PLURAL:$1|ביום האחרון|ביומיים האחרונים|ב־$1 הימים האחרונים}}.",
+       "apihelp-query+allusers-param-attachedwiki": "עם <kbd>$1prop=centralids</kbd>, לציין גם האם המשתמש משויך לוויקי עם המזהה הזה.",
        "apihelp-query+allusers-example-Y": "לרשום משתמשים שמתחילים ב־<kbd>Y</kbd>.",
        "apihelp-query+backlinks-description": "מציאת כל הדפים שמקשרים לדף הנתון.",
        "apihelp-query+backlinks-param-title": "איזו כותרת לחפש. לא ניתן להשתמש בזה יחד עם <var>$1pageid</var>.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "מדפיס את כותרת <code>Accept-Language</code> ששלח הלקוח בתסדיר מובנה.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "הוספת תאריך הרישום של המשתמש.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "הוספת מניין הדפים שלא נקראו ברשימת המעקב של המשתמש (לכל היותר $1; מחזיר <samp>$2</samp> אם יש יותר).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "הוספת המזהה המרכזי ומצב השיוך למשתמש.",
+       "apihelp-query+userinfo-param-attachedwiki": "עם <kbd>$1prop=centralids</kbd>, לציין האם המשתמש משויך לוויקי עם המזהה הזה.",
        "apihelp-query+userinfo-example-simple": "קבלת מידע על המשתמש הנוכחי.",
        "apihelp-query+userinfo-example-data": "קבלת מידע נוסף על המשתמש הנוכחי.",
        "apihelp-query+users-description": "קבלת מידע על רשימת משתמשים.",
        "apihelp-query+users-paramvalue-prop-registration": "הוספת חותם־הזמן של רישום המשתמש.",
        "apihelp-query+users-paramvalue-prop-emailable": "מתייג אם המשתמש יכול ורוצה לקבל דואר אלקטרוני דרך [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "מתייג את המגדר של המשתמש. מחזיר \"male\"‏, \"female\" או \"unknown\".",
+       "apihelp-query+users-paramvalue-prop-centralids": "הוספת המזהה המרכזי ומצב השיוך למשתמש.",
+       "apihelp-query+users-param-attachedwiki": "עם <kbd>$1prop=centralids</kbd>, לציין האם המשתמש משויך לוויקי עם המזהה הזה.",
        "apihelp-query+users-param-users": "רשימת משתמשים שעליהם צריך לקבל מידע.",
        "apihelp-query+users-param-token": "יש להשתמש ב־<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> במקום.",
        "apihelp-query+users-example-simple": "החזרת מידע עבור המשתמש <kbd>Example</kbd>.",
index 2734a8e..c4f7a3f 100644 (file)
@@ -9,7 +9,8 @@
                        "Ricordisamoa",
                        "Valepert",
                        "Sannita",
-                       "Macofe"
+                       "Macofe",
+                       "Nemo bis"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentazione (in inglese)]]\n* [[mw:API:FAQ|FAQ (in inglese)]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> Tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma l'API è ancora in fase d'attivo sviluppo, e potrebbe cambiare in qualsiasi momenento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite all'API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e sia al valore dell'intestazione sia al codice d'errore verrà impostato lo stesso valore. Per maggiori informazioni leggi [[mw:API:Errors_and_warnings|API:Errori ed avvertimenti (in inglese)]].",
@@ -22,6 +23,7 @@
        "apihelp-block-description": "Blocca  un utente.",
        "apihelp-block-param-user": "Nome utente, indirizzo IP o range di IP da bloccare.",
        "apihelp-block-param-reason": "Motivo del blocco.",
+       "apihelp-block-param-anononly": "Blocca solo gli utenti non registrati (cioè disattiva i contributi anonimi da questo indirizzo IP).",
        "apihelp-block-param-nocreate": "Impedisci creazione di utenze.",
        "apihelp-block-param-hidename": "Nascondi il nome utente dal registro dei blocchi (Richiede i permessi di <code>hideuser</code>).",
        "apihelp-block-param-reblock": "Se l'utente è già bloccato, sovrascrivere il blocco esistente.",
index 1a5fcea..287e147 100644 (file)
        "apihelp-query+alllinks-param-from": "列挙を開始するリンクのページ名。",
        "apihelp-query+alllinks-param-to": "列挙を終了するリンクのページ名。",
        "apihelp-query+alllinks-param-prefix": "この値で始まるすべてのリンクされたページを検索する。",
+       "apihelp-query+alllinks-param-unique": "リンクされたページ名を一度だけ表示します。<kbd>$1prop=ids</kbd> とは同時に使用できません。ジェネレーターとして使用される場合、リンク元ではなくリンク先のページを生成します。",
        "apihelp-query+alllinks-param-prop": "どの情報を結果に含めるか:",
        "apihelp-query+alllinks-paramvalue-prop-title": "リンクのページ名を追加します。",
        "apihelp-query+alllinks-param-namespace": "列挙する名前空間。",
        "apihelp-query+allredirects-param-from": "列挙を開始するリダイレクトのページ名。",
        "apihelp-query+allredirects-param-to": "列挙を終了するリダイレクトのページ名。",
        "apihelp-query+allredirects-param-prefix": "この値で始まるすべてのページを検索する。",
+       "apihelp-query+allredirects-param-unique": "転送先ページ名を一度だけ表示します。<kbd>$1prop=ids|fragment|interwiki</kbd> とは同時に使用できません。ジェネレーターとして使用される場合、転送元ではなく転送先のページを生成します。",
        "apihelp-query+allredirects-param-prop": "どの情報を結果に含めるか:",
        "apihelp-query+allredirects-paramvalue-prop-title": "転送ページのページ名を追加します。",
        "apihelp-query+allredirects-param-namespace": "列挙する名前空間。",
        "apihelp-query+info-param-prop": "追加で取得するプロパティ:",
        "apihelp-query+info-paramvalue-prop-protection": "それぞれのページの保護レベルを一覧表示する。",
        "apihelp-query+info-example-simple": "<kbd>Main Page</kbd> に関する情報を取得する。",
+       "apihelp-query+iwbacklinks-param-prefix": "インターウィキ接頭辞。",
+       "apihelp-query+iwbacklinks-param-title": "検索するウィキ間リンク。<var>$1blprefix</var>と同時に使用しなければなりません。",
+       "apihelp-query+iwbacklinks-param-limit": "返すページの総数。",
        "apihelp-query+iwbacklinks-param-prop": "取得するプロパティ:",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "インターウィキ接頭辞を追加します。",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "ウィキ間リンクのページ名を追加します。",
+       "apihelp-query+iwbacklinks-param-dir": "一覧表示する方向。",
        "apihelp-query+iwbacklinks-example-simple": "[[wikibooks:Test]] へリンクしているページを取得する。",
        "apihelp-query+iwbacklinks-example-generator": "[[wikibooks:Test]] へリンクしているページの情報を取得する。",
+       "apihelp-query+iwlinks-description": "ページからのすべてのウィキ間リンクを返します。",
+       "apihelp-query+iwlinks-param-url": "完全なURLを取得するかどうか (<var>$1prop</var>とは同時に使用できません).",
+       "apihelp-query+iwlinks-param-prop": "各言語間リンクについて取得する追加のプロパティ:",
        "apihelp-query+iwlinks-paramvalue-prop-url": "完全なURLを追加します。",
        "apihelp-query+iwlinks-param-limit": "返すウィキ間リンクの数。",
        "apihelp-query+iwlinks-param-prefix": "この接頭辞のウィキ間リンクのみを返す。",
        "apihelp-query+iwlinks-param-title": "検索するウィキ間リンク。<var>$1</var> と同時に使用しなければなりません。",
+       "apihelp-query+iwlinks-param-dir": "一覧表示する方向。",
        "apihelp-query+iwlinks-example-simple": "<kbd>Main Page</kbd> にあるウィキ間リンクを取得する。",
        "apihelp-query+langbacklinks-param-lang": "言語間リンクの言語。",
        "apihelp-query+langbacklinks-param-title": "検索する言語間リンク。$1lang と同時に使用しなければなりません。",
        "apihelp-query+langbacklinks-param-limit": "返すページの総数。",
        "apihelp-query+langbacklinks-param-prop": "取得するプロパティ:",
+       "apihelp-query+langbacklinks-paramvalue-prop-lllang": "言語間リンクの言語コードを追加します。",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "言語間リンクのページ名を追加します。",
+       "apihelp-query+langbacklinks-param-dir": "一覧表示する方向。",
        "apihelp-query+langbacklinks-example-simple": "[[:fr:Test]] へリンクしているページを取得する。",
        "apihelp-query+langbacklinks-example-generator": "[[:fr:Test]] へリンクしているページの情報を取得する。",
+       "apihelp-query+langlinks-description": "ページからのすべての言語間リンクを返します。",
        "apihelp-query+langlinks-param-limit": "返す言語間リンクの数。",
        "apihelp-query+langlinks-param-url": "完全なURLを取得するかどうか (<var>$1prop</var>とは同時に使用できません).",
+       "apihelp-query+langlinks-param-prop": "各言語間リンクについて取得する追加のプロパティ:",
        "apihelp-query+langlinks-paramvalue-prop-url": "完全なURLを追加します。",
        "apihelp-query+langlinks-paramvalue-prop-autonym": "ネイティブ言語名を追加します。",
        "apihelp-query+langlinks-param-lang": "この言語コードの言語間リンクのみを返す。",
index 866cb0d..cf45cae 100644 (file)
@@ -13,7 +13,7 @@
                        "Yearning"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|설명문서]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 공지 사항] * [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청] </div>\n<strong>상태:</strong> 이 페이지에 표시된 모든 기능은 정상 작동할 것이지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 바뀔 수 있습니다. 업데이트 정보를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 [[mw:API:Errors_and_warnings|API:오류 및 경고]]를 참조하십시오.",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|설명문서]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 공지 사항] * [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청] </div>\n<strong>상태:</strong> 이 페이지에 표시된 모든 기능은 정상적으로 작동하지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 변경될 수 있습니다. 업데이트 정보를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 [[mw:API:Errors_and_warnings|API:오류와 경고]]를 참조하십시오.",
        "apihelp-main-param-action": "수행할 동작",
        "apihelp-main-param-format": "출력값의 형식.",
        "apihelp-main-param-maxlag": "최대 랙은 미디어위키가 데이터베이스 복제된 클러스터에 설치되었을 때 사용될 수 있습니다. 특정한 행동이 사이트 복제 랙을 유발할 때, 이 변수는 클라이언트가 복제 랙이 설정된 숫자 아래로 내려갈 때까지 기다리도록 지시합니다. 과도한 랙의 경우, <samp>maxlag</samp> 오류 코드와 <samp>Waiting for $host: $lag seconds lagged</samp> 메시지가 제공됩니다.<br />[[mw:Manual:Maxlag_parameter|매뉴얼: Maxlag 변수]] 에서 더 많은 정보를 얻을 수 있습니다.",
index c3197f8..c6b08c1 100644 (file)
        "apihelp-parse-paramvalue-prop-sections": "Jitt de Affschnedde em jepahßde Wikkitäx uß.",
        "apihelp-parse-paramvalue-prop-revid": "Deiht de Kännong vun de Väsjohn vun dä jepahßde Sigg derbei.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Deiht de Övverschreff vum jepahßde Wikkitäx derbei.",
+       "apihelp-parse-paramvalue-prop-headitems": "Jitt de Saacher för enn der <code>&lt;head&gt;</code> vun dä Sigg ze donn.",
        "apihelp-parse-paramvalue-prop-modules": "Jitt dem <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Delivery system in MediaWiki for the optimized run-time loading and managing of modules\">ResourceLoader</i> sing Moduhle uß, di en dä Sigg jebruch wähde. Äntwehder „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">jsconfigvars</kbd>“ udder „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">encodedjsconfigvars</kbd>“ moß mer met „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">modules</kbd>“ zesamme aanforrdere.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Livvert de Varrejahble vun dä Ennschtällonge vum JavaSkrep, di äxtra för heh di Sigg enjeschtallt sin.",
        "apihelp-parse-paramvalue-prop-iwlinks": "Jitt de Engewikkilengks em jepahßde Wikkitäx uß.",
        "apihelp-xml-description": "Donn de Dahte em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Extensible Markup Language\">XML</i>-Fommahd ußjävve.",
        "apihelp-xml-param-includexmlnamespace": "Wann aanjejovve, deihd en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Extensible Markup Language\">XML</i>-Appachtemand derbei.",
        "apihelp-xmlfm-description": "Donn de Dahte em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Extensible Markup Language\">XML</i>-Fommahd schöhn jemaht met <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Markup Language\">HTML</i> ußjävve.",
-       "apihelp-yaml-description": "Donn de Dahte em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"YAML Ain't Markup Language\">YAML</i>-Fommahd ußjävve.",
-       "apihelp-yamlfm-description": "Donn de Dahte em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"YAML Ain't Markup Language\">YAML</i>-Fommahd schöhn met <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Markup Language\">HTML</i> ußjävve.",
        "api-format-title": "Wat et <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> ußjohv.",
        "api-format-prettyprint-header-only-html": "Dat heh es en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Markup Language\">HTML</i>_Daaschtällong un för et Fähersöhke jedaach. Dadd is för Aanwändongsprojramme nit ze bruche.\n\nEn de [[mw:API|complete Dokkemäntazjohn]] un de [[Special:ApiHelp/main|API Hölp_Sigg]] kam_mer doh mih drövver lässe.",
        "api-pageset-param-titles": "En Leß vun Övverschreffte för ze beärbeide.",
diff --git a/includes/api/i18n/lki.json b/includes/api/i18n/lki.json
new file mode 100644 (file)
index 0000000..b2c230a
--- /dev/null
@@ -0,0 +1,25 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Hosseinblue",
+                       "Arash71",
+                       "Lakzon"
+               ]
+       },
+       "apihelp-main-param-action": "کام عملیات انجؤم بِ.",
+       "apihelp-main-param-format": "فرمت خروجی",
+       "apihelp-block-description": "بستن کاربر.",
+       "apihelp-createaccount-param-name": ":نؤم بهرۀگر-کاربر",
+       "apihelp-delete-description": "حةذف وةڵگة",
+       "apihelp-edit-description": "دؤرس کردن و دۀسکاری وۀلگۀ",
+       "apihelp-edit-param-sectiontitle": "نام سۀر وۀلگ تازۀ",
+       "apihelp-edit-example-edit": ".دةسکاری وةڵگة",
+       "apihelp-emailuser-param-subject": "موضوع سةر وةڵگ",
+       "apihelp-emailuser-param-text": "متن رایانه.",
+       "apihelp-login-param-name": "نام کاربری",
+       "apihelp-login-param-password": ".رمز",
+       "apihelp-login-example-login": "نؤم هۀتن.",
+       "apihelp-logout-description": "دۀرچئن و پاک کردن داده متن",
+       "apihelp-logout-example-logout": "خروج کاربر فعلی",
+       "apihelp-options-example-reset": "بازنشانی همه تنظیمات."
+}
index 1a0e181..432d9c0 100644 (file)
        "apihelp-query+allusers-paramvalue-prop-rights": "सदस्यास असलेल्या अधिकारांची यादी करते.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "सदस्याची संपादन मोजणी जोडते.",
        "apihelp-query+allusers-paramvalue-prop-registration": "जर उपलब्ध असेल तर,सदस्याने केंव्हा नोंदणी केली त्याचा वेळठसा(रिक्त असू शकतो)",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "सदस्याची केंद्रीय ओळखण्या व जुळल्याची स्थिती जोडते.",
        "apihelp-query+allusers-param-witheditsonly": "फक्त संपादन केलेल्या सदस्यांचीच यादी करा.",
        "apihelp-query+allusers-param-activeusers": "मागील $1 {{PLURAL:$1|दिवसात}} सक्रिय सदस्यांचीच यादी करा.",
+       "apihelp-query+allusers-param-attachedwiki": "<kbd>$1prop=centralids</kbd> याद्वारे असेही दर्शविण्यात येते कि सदस्य हा या विकिशी जुळलेला असून तो या ओळखणीद्वारे ओळखल्या जातो.",
        "apihelp-query+allusers-example-Y": "<kbd>य</kbd> पासून सदस्यनाव सुरु होणाऱ्या सदस्यांचीच यादी करा.",
        "apihelp-query+backlinks-description": "दिलेल्या पानास दुवे असणारी सर्व पाने शोधा.",
        "apihelp-query+backlinks-param-title": "शोधावयाचे शीर्षक.<var>$1pageid</var>यासमवेत वापरु शकत नाही.",
        "apihelp-query+langlinks-param-dir": "कोणत्या दिशेस यादी करावयाची.",
        "apihelp-query+links-param-dir": "कोणत्या दिशेस यादी करावयाची.",
        "apihelp-query+recentchanges-param-end": "कुठपर्यंत प्रगणना संपवायची त्याचा वेळठसा.",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "सदस्याची केंद्रीय ओळखण्या व जुळल्याची स्थिती जोडते.",
+       "apihelp-query+userinfo-param-attachedwiki": "<kbd>$1prop=centralids</kbd> याद्वारे असे दर्शविण्यात येते कि सदस्य हा या विकिशी जुळलेला असून तो या ओळखणीद्वारे ओळखल्या जातो.",
+       "apihelp-query+users-paramvalue-prop-centralids": "सदस्याची केंद्रीय ओळखण्या व जुळल्याची स्थिती जोडते.",
+       "apihelp-query+users-param-attachedwiki": "<kbd>$1prop=centralids</kbd> याद्वारे असे दर्शविण्यात येते कि सदस्य हा या विकिशी जुळलेला असून तो या ओळखणीद्वारे ओळखल्या जातो.",
        "apihelp-query+watchlist-param-type": "कोणत्या प्रकारचे बदल दाखवायचे:",
        "apihelp-query+watchlist-paramvalue-type-edit": "नित्याची पान संपादने.",
        "apihelp-query+watchlist-paramvalue-type-external": "बाह्य बदल.",
index ca77d1c..949b4e7 100644 (file)
        "apihelp-help-param-helpformat": "Format wyjściowy pomocy.",
        "apihelp-help-param-toc": "Dołącz spis treści do wyjściowego HTML.",
        "apihelp-help-example-main": "Pomoc dla modułu głównego",
+       "apihelp-help-example-submodules": "Pomoc dla <kbd>action=query</kbd> i wszystkich jej podmodułów.",
        "apihelp-help-example-recursive": "Cała pomoc na jednej stronie.",
        "apihelp-help-example-help": "Pomoc dla modułu pomocy",
        "apihelp-help-example-query": "Pomoc dla dwóch podmodułów zapytań.",
index bb3aa46..e94d13b 100644 (file)
@@ -5,6 +5,7 @@
                        "Macofe"
                ]
        },
+       "apihelp-main-param-action": "کومه کړنه ترسره کړم.",
        "apihelp-block-description": "په يو کارن بنديز لگول.",
        "apihelp-block-param-user": "کارن-نوم، IP پته، يا IP سيمې باندې بنديز لگول.",
        "apihelp-block-param-reason": "د بنديز سبب.",
        "apihelp-stashedit-param-sectiontitle": "د يوې نوې برخې سرليک.",
        "apihelp-tag-param-reason": "د بدلون سبب.",
        "apihelp-unblock-param-reason": "د بنديز ليرې کولو سبب.",
+       "apihelp-undelete-param-reason": "د بيازېرملو سبب.",
        "apihelp-upload-param-watch": "مخ کتل.",
        "apihelp-upload-param-file": "د دوتنې مېنځپانگه.",
        "apihelp-userrights-param-user": "کارن نوم.",
        "apihelp-userrights-param-userid": "کارن پېژند.",
        "apihelp-userrights-param-reason": "د بدلون سبب.",
+       "api-help-title": "د مېډياويکي API لارښود",
+       "api-help-main-header": "آر ماډيول",
        "api-help-source": "سرچينه: $1",
        "api-help-source-unknown": "سرچينه: <span class=\"apihelp-unknown\">ناجوت</span>",
        "api-help-license": "منښتليک: [[$1|$2]]",
        "api-help-license-noname": "منښتليک: [[$1|تړنه وڅارئ]]",
        "api-help-license-unknown": "منښتليک: <span class=\"apihelp-unknown\">ناجوت</span>",
+       "api-help-parameters": "{{PLURAL:$1|پاراميټر|پاراميټرونه}}:",
+       "api-help-param-required": "دې پاراميټر ته اړتيا ده.",
        "api-help-datatypes-header": "اومتوگ ډولونه",
        "api-help-param-default": "تلواليز: $1",
        "api-help-param-default-empty": "تلواليز: <span class=\"apihelp-empty\">(تش)</span>",
index 047a806..0cd7596 100644 (file)
        "apihelp-query+allusers-paramvalue-prop-rights": "{{doc-apihelp-paramvalue|query+allusers|prop|rights}}",
        "apihelp-query+allusers-paramvalue-prop-editcount": "{{doc-apihelp-paramvalue|query+allusers|prop|editcount}}",
        "apihelp-query+allusers-paramvalue-prop-registration": "{{doc-apihelp-paramvalue|query+allusers|prop|registration}}",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "{{doc-apihelp-paramvalue|query+allusers|prop|centralids}}",
        "apihelp-query+allusers-param-limit": "{{doc-apihelp-param|query+allusers|limit}}",
        "apihelp-query+allusers-param-witheditsonly": "{{doc-apihelp-param|query+allusers|witheditsonly}}",
        "apihelp-query+allusers-param-activeusers": "{{doc-apihelp-param|query+allusers|activeusers|params=* $1 - Value of [[mw:Manual:$wgActiveUserDays]]|paramstart=2}}",
+       "apihelp-query+allusers-param-attachedwiki": "{{doc-apihelp-param|query+allusers|attachedwiki}}",
        "apihelp-query+allusers-example-Y": "{{doc-apihelp-example|query+allusers}}",
        "apihelp-query+backlinks-description": "{{doc-apihelp-description|query+backlinks}}",
        "apihelp-query+backlinks-param-title": "{{doc-apihelp-param|query+backlinks|title}}",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "{{doc-apihelp-paramvalue|query+userinfo|prop|acceptlang}}",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "{{doc-apihelp-paramvalue|query+userinfo|prop|registrationdate}}",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "{{doc-apihelp-paramvalue|query+userinfo|prop|unreadcount|params=* $1 - Maximum value for the \"unreadcount\" property.\n* $2 - Return value when there are more unread pages.|paramstart=3}}",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "{{doc-apihelp-paramvalue|query+userinfo|prop|centralids}}",
+       "apihelp-query+userinfo-param-attachedwiki": "{{doc-apihelp-param|query+userinfo|attachedwiki}}",
        "apihelp-query+userinfo-example-simple": "{{doc-apihelp-example|query+userinfo}}",
        "apihelp-query+userinfo-example-data": "{{doc-apihelp-example|query+userinfo}}",
        "apihelp-query+users-description": "{{doc-apihelp-description|query+users}}",
        "apihelp-query+users-paramvalue-prop-registration": "{{doc-apihelp-paramvalue|query+users|prop|registration}}",
        "apihelp-query+users-paramvalue-prop-emailable": "{{doc-apihelp-paramvalue|query+users|prop|emailable}}",
        "apihelp-query+users-paramvalue-prop-gender": "{{doc-apihelp-paramvalue|query+users|prop|gender}}",
+       "apihelp-query+users-paramvalue-prop-centralids": "{{doc-apihelp-paramvalue|query+users|prop|centralids}}",
+       "apihelp-query+users-param-attachedwiki": "{{doc-apihelp-param|query+users|attachedwiki}}",
        "apihelp-query+users-param-users": "{{doc-apihelp-param|query+users|users}}",
        "apihelp-query+users-param-token": "{{doc-apihelp-param|query+users|token}}",
        "apihelp-query+users-example-simple": "{{doc-apihelp-example|query+users}}",
index 1366f5e..14e32ba 100644 (file)
        "api-help-parameters": "{{PLURAL:$1|Parameter|Parametrar}}:",
        "api-help-param-deprecated": "Föråldrad.",
        "api-help-param-required": "Denna parameter är obligatorisk.",
-       "api-help-param-list": "{{PLURAL:$1|1=Ett värde|2=Värden (separerade med <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=Ett av följande värden|2=Värden (separerade med <kbd>{{!}}</kbd>)}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Måste vara tom|Kan vara tom, eller $2}}",
        "api-help-param-limit": "Inte mer än $1 tillåts.",
        "api-help-param-limit2": "Inte mer än $1 ($2 för robotar) tillåts."
index 4f88d77..d8c5cfb 100644 (file)
@@ -5,6 +5,8 @@
                        "Macofe"
                ]
        },
+       "apihelp-feedrecentchanges-param-categories": "Ipakita lamang ang mga pagbababgo sa mga pahina sa lahat ng mga kategoriyang ito.",
+       "apihelp-feedrecentchanges-param-categories_any": "Ipakita na lang ang mga pagbabago sa mga pahina sa kahit na anong mga kategoriya.",
        "apihelp-feedrecentchanges-example-simple": "Ipakit ang mga kamakailangang pagbabago.",
        "apihelp-feedrecentchanges-example-30days": "Ipakita ang mga huling pagbabago sa loob para sa 30 araw.",
        "apihelp-help-example-main": "Tulong para sa pangunahing modulo.",
index a643343..338a670 100644 (file)
        "apihelp-edit-param-undo": "撤销此次修订。覆盖$1text、$1prependtext和$1appendtext。",
        "apihelp-edit-param-undoafter": "撤销从$1undo至此的所有修订。如果不设置就撤销一次修订。",
        "apihelp-edit-param-redirect": "自动解决重定向。",
-       "apihelp-edit-param-contentformat": "用于输入文本的内容串行化格式。",
+       "apihelp-edit-param-contentformat": "用于输入文本的内容序列化格式。",
        "apihelp-edit-param-contentmodel": "新内容的内容模型。",
        "apihelp-edit-param-token": "令牌应总是发送为最后参数,或至少在$1text参数之后。",
        "apihelp-edit-example-edit": "编辑一个页面。",
        "apihelp-expandtemplates-param-revid": "修订版本ID,用于<nowiki>{{REVISIONID}}</nowiki>和类似变体。",
        "apihelp-expandtemplates-param-prop": "要获取的那条信息。\n\n注意如果没有选定值,结果将包含wiki文本,但将以弃用的格式显示。",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "扩充的wiki文本。",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "任何在输出中提供的,未在wiki文本输出中表现的分类。",
        "apihelp-expandtemplates-paramvalue-prop-properties": "由wiki文本中扩充的魔术字定义的页面属性。",
        "apihelp-expandtemplates-paramvalue-prop-volatile": "无论输出是否常常变动,均不应被在页面中其他任何位置重用。",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "结果缓存应无效化后的最长时间。",
        "apihelp-query+allmessages-description": "返回来自该网站的消息。",
        "apihelp-query+allmessages-param-messages": "要输出的消息。<kbd>*</kbd>(默认)表示所有消息。",
        "apihelp-query+allmessages-param-prop": "要获取的属性。",
+       "apihelp-query+allmessages-param-enableparser": "设置以启用解析器,将处理消息的wiki文本(替代魔术字、处理模板等)。",
        "apihelp-query+allmessages-param-nocontent": "如果设置,不要在输出中包含消息内容。",
        "apihelp-query+allmessages-param-args": "要替代进消息的参数。",
        "apihelp-query+allmessages-param-filter": "只返回名称包含此字符串的消息。",
        "apihelp-query+allmessages-param-lang": "返回这种语言的信息。",
        "apihelp-query+allmessages-param-from": "从此消息开始返回消息。",
        "apihelp-query+allmessages-param-to": "返回消息至此消息为止。",
+       "apihelp-query+allmessages-param-title": "当解析消息时,要用作环境的页面(用于$1enableparser选项)。",
        "apihelp-query+allmessages-param-prefix": "返回带有该前缀的消息。",
        "apihelp-query+allmessages-example-ipb": "显示以<kbd>ipb-</kbd>开始的消息。",
        "apihelp-query+allmessages-example-de": "显示德语版的<kbd>august</kbd>和<kbd>mainpage</kbd>消息。",
        "apihelp-query+allpages-param-minsize": "限于至少这么多字节的页面。",
        "apihelp-query+allpages-param-maxsize": "限于至多这么多字节的页面。",
        "apihelp-query+allpages-param-prtype": "仅限于受保护页面。",
+       "apihelp-query+allpages-param-prlevel": "过滤基于保护等级的保护(必须与$1prtype=参数一起使用)。",
        "apihelp-query+allpages-param-prfiltercascade": "过滤基于cascadingness的保护(当$1prtype未设置时忽略)。",
        "apihelp-query+allpages-param-limit": "返回的总计页面数。",
        "apihelp-query+allpages-param-dir": "罗列所采用的方向。",
        "apihelp-query+allusers-paramvalue-prop-rights": "用户拥有的权限列表。",
        "apihelp-query+allusers-paramvalue-prop-editcount": "添加用户的编辑计数。",
        "apihelp-query+allusers-paramvalue-prop-registration": "如果可能,添加用户注册时的时间戳(可能为空白)。",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+allusers-param-limit": "返回的总计用户数。",
        "apihelp-query+allusers-param-witheditsonly": "只列出有编辑的用户。",
        "apihelp-query+allusers-param-activeusers": "只列出最近$1{{PLURAL:$1|天}}内活跃的用户。",
        "apihelp-query+blocks-param-end": "枚举的结束时间戳。",
        "apihelp-query+blocks-param-ids": "要列出的封禁ID列表(可选)。",
        "apihelp-query+blocks-param-users": "要搜索的用户列表(可选)。",
+       "apihelp-query+blocks-param-ip": "获取应用到此IP地址或者CIDR范围的所有封禁,包括范围封禁。不能与<var>$3users</var>一起使用。CIDR范围不允许比IPv4/$1或IPv6/$2更宽。",
        "apihelp-query+blocks-param-limit": "封禁列表的最大数量。",
        "apihelp-query+blocks-param-prop": "要获取的属性:",
        "apihelp-query+blocks-paramvalue-prop-id": "添加封禁ID。",
        "apihelp-query+blocks-paramvalue-prop-reason": "添加封禁原因。",
        "apihelp-query+blocks-paramvalue-prop-range": "添加受封禁影响的IP地址段。",
        "apihelp-query+blocks-paramvalue-prop-flags": "标记编辑禁止(自动封禁、仅限匿名用户等)。",
+       "apihelp-query+blocks-param-show": "只显示符合这些标准的项目。\n例如,要只查看IP地址的无限期封禁,设置<kbd>$1show=ip|!temp</kbd>。",
        "apihelp-query+blocks-example-simple": "封禁列表。",
        "apihelp-query+blocks-example-users": "列出用户<kbd>Alice</kbd>和<kbd>Bob</kbd>的封禁。",
        "apihelp-query+categories-description": "页面属于的所有分类列表。",
        "apihelp-query+categories-paramvalue-prop-hidden": "标记由<code>_&#95;HIDDENCAT_&#95;</code>隐藏的分类。",
        "apihelp-query+categories-param-show": "显示何种分类。",
        "apihelp-query+categories-param-limit": "返回多少分类。",
+       "apihelp-query+categories-param-categories": "只列出这些分类。对于检查某一页面使用某一分类很有用。",
        "apihelp-query+categories-param-dir": "罗列所采用的方向。",
        "apihelp-query+categories-example-simple": "获取属于<kbd>Albert Einstein</kbd>的分类列表。",
        "apihelp-query+categories-example-generator": "获得有关用于<kbd>Albert Einstein</kbd>的分类的信息。",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "添加用于非最新版本的存档版本的文件名。",
        "apihelp-query+filearchive-example-simple": "显示已删除文件列表。",
        "apihelp-query+filerepoinfo-description": "返回有关wiki配置的图片存储库的元信息。",
+       "apihelp-query+filerepoinfo-param-prop": "要获取的存储库属性(这在一些wiki上可能有更多可用选项):\n;apiurl:链接至API的URL - 对从主机获取图片信息有用。\n;name:The key of the repository - used in e.g. <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.\n;displayname:The human-readable name of the repository wiki.\n;rooturl:Root URL for image paths.\n;local:Whether that repository is the local one or not.",
        "apihelp-query+filerepoinfo-example-simple": "获得有关文件存储库的信息。",
        "apihelp-query+fileusage-description": "查找所有使用指定文件的页面。",
        "apihelp-query+fileusage-param-prop": "要获取的属性:",
        "apihelp-query+userinfo-param-prop": "要包含的信息束:",
        "apihelp-query+userinfo-paramvalue-prop-blockinfo": "如果当前用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。",
        "apihelp-query+userinfo-paramvalue-prop-hasmsg": "如果当前用户有等待中的消息的话,添加标签<samp>messages</samp>。",
-       "apihelp-query+userinfo-paramvalue-prop-groups": "Lists all the groups the current user belongs to.",
+       "apihelp-query+userinfo-paramvalue-prop-groups": "列举当前用户隶属的所有群组。",
        "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "Lists all the groups the current user is automatically a member of.",
        "apihelp-query+userinfo-paramvalue-prop-rights": "Lists all the rights the current user has.",
        "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Lists the groups the current user can add to and remove from.",
        "apihelp-query+userinfo-paramvalue-prop-options": "Lists all preferences the current user has set.",
-       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "<span class=\"apihelp-deprecated\">Deprecated.</span> Get a token to change current user's preferences.",
-       "apihelp-query+userinfo-paramvalue-prop-editcount": "Adds the current user's edit count.",
+       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "<span class=\"apihelp-deprecated\">已弃用。</span>获取令牌以更改当前用户的参数设置。",
+       "apihelp-query+userinfo-paramvalue-prop-editcount": "添加当前用户的编辑计数。",
        "apihelp-query+userinfo-paramvalue-prop-ratelimits": "Lists all rate limits applying to the current user.",
        "apihelp-query+userinfo-paramvalue-prop-realname": "添加用户的真实姓名。",
        "apihelp-query+userinfo-paramvalue-prop-email": "Adds the user's email address and email authentication date.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Echoes the <code>Accept-Language</code> header sent by the client in a structured format.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "添加用户的注册时间。",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+userinfo-example-simple": "获取有关当前用户的信息。",
        "apihelp-query+userinfo-example-data": "获取有关当前用户的额外信息。",
        "apihelp-query+users-description": "获取有关列出用户的信息。",
        "apihelp-query+users-paramvalue-prop-registration": "Adds the user's registration timestamp.",
        "apihelp-query+users-paramvalue-prop-emailable": "Tags if the user can and wants to receive email through [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "Tags the gender of the user. Returns \"male\", \"female\", or \"unknown\".",
+       "apihelp-query+users-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+users-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
        "apihelp-query+users-example-simple": "返回用户<kbd>Example</kbd>的信息。",
        "apihelp-query+watchlist-description": "在当前用户的监视列表中获取对页面的最近更改。",
        "apihelp-stashedit-param-sectiontitle": "新段落的标题。",
        "apihelp-stashedit-param-text": "页面内容。",
        "apihelp-stashedit-param-contentmodel": "新内容的内容模型。",
+       "apihelp-stashedit-param-contentformat": "用于输入文本的内容序列化格式。",
        "apihelp-stashedit-param-baserevid": "基础修订的修订ID。",
        "apihelp-tag-description": "从个别修订或日志记录中添加或移除更改标签。",
        "apihelp-tag-param-rcid": "要添加或移除标签的一个或更多的最近更改ID。",
        "apihelp-undelete-param-reason": "恢复的原因。",
        "apihelp-undelete-param-timestamps": "要回复的修订的时间戳。如果<var>$1timestamps</var>和<var>$1fileids</var>都为空,所有将被恢复。",
        "apihelp-undelete-param-fileids": "要恢复的文件修订ID。如果<var>$1timestamps</var>和<var>$1fileids</var>都为空,所有将被恢复。",
+       "apihelp-undelete-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
        "apihelp-undelete-example-page": "恢复页面<kbd>Main Page</kbd>。",
        "apihelp-undelete-example-revisions": "恢复<kbd>Main Page</kbd>的两个修订。",
        "apihelp-upload-description": "上传一个文件,或获取正在等待中的上传的状态。\n\n可以使用的几种方法:\n* 直接上传文件内容,使用<var>$1file</var>参数。\n* 成批上传文件,使用<var>$1filesize</var>、<var>$1chunk</var>和<var>$1offset</var>参数。\n* 有MediaWiki服务器从URL检索一个文件,使用<var>$1url</var>参数。\n* 完成一次由于警告而失败的早前上传,使用<var>$1filekey</var>参数。\n需要注意,当发送<var>$1file</var>时,HTTP POST必须做为一次文件上传(也就是使用<code>multipart/form-data</code>)完成。",
        "apihelp-upload-param-offset": "块的偏移量(字节)。",
        "apihelp-upload-param-chunk": "大块内容。",
        "apihelp-upload-param-leavemessage": "如果asyncdownload被使用,当完成时,在用户讨论页留下一条消息。",
+       "apihelp-upload-param-statuskey": "检索此文件密钥的上传状态(通过URL上传)。",
+       "apihelp-upload-param-checkstatus": "只检索指定文件密钥的上传状态。",
        "apihelp-upload-example-url": "从URL上传。",
        "apihelp-upload-example-filekey": "完成一次由于警告而失败的上传。",
        "apihelp-userrights-description": "更改一位用户的组成员。",
index fbcdcab..4b0a81c 100644 (file)
@@ -6,7 +6,8 @@
                        "LNDDYL",
                        "EagerLin",
                        "Zhxy 519",
-                       "Macofe"
+                       "Macofe",
+                       "Jasonzhuocn"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文件]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 郵件清單]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug與請求]\n</div>\n<strong>狀態資訊:</strong>本頁所展示的所有功能都應正常工作,但是 API 仍在開發當中,將會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵件清單]以便得到更新通知。\n\n<strong>錯誤請求:</strong>當 API 收到錯誤請求時, HTTP header 將會返回一個包含「MediaWiki-API-Error」的值,隨後 header 的值與錯誤碼將會送回並設定為相同的值。詳細資訊請參閱[[mw:API:Errors_and_warnings|API: 錯誤與警告]]。",
        "apihelp-feedrecentchanges-param-hideanons": "隱藏匿名使用者做的變更。",
        "apihelp-feedrecentchanges-param-hideliu": "隱藏已註冊使用者做的變更。",
        "apihelp-feedrecentchanges-param-hidepatrolled": "隱藏已巡查的變更。",
-       "apihelp-feedrecentchanges-example-simple": "顯示最近更改。",
+       "apihelp-feedrecentchanges-example-simple": "顯示最近變更。",
        "apihelp-feedrecentchanges-example-30days": "顯示近期30天內的變動",
        "apihelp-feedwatchlist-description": "返回監視清單 feed。",
        "apihelp-feedwatchlist-param-feedformat": "Feed 的格式。",
        "apihelp-query+categorymembers-param-limit": "回傳的頁面數量上限。",
        "apihelp-query+contributors-param-limit": "要回傳的貢獻人員數量。",
        "apihelp-query+duplicatefiles-param-limit": "要回傳的重複檔案數量。",
+       "apihelp-query+embeddedin-param-filterredir": "如何過濾重定向。",
        "apihelp-query+embeddedin-param-limit": "要回傳的頁面總數。",
        "apihelp-query+extlinks-description": "回傳所有指定頁面的外部 URL (非 interwiki)。",
        "apihelp-query+extlinks-param-limit": "要回傳的連結數量。",
index 483eaa5..298f6e2 100644 (file)
@@ -96,12 +96,12 @@ class HTMLFileCache extends FileCacheBase {
         * @return bool
         */
        public static function useFileCache( IContextSource $context ) {
-               global $wgUseFileCache, $wgShowIPinHeader, $wgDebugToolbar, $wgContLang;
+               global $wgUseFileCache, $wgDebugToolbar, $wgContLang;
                if ( !$wgUseFileCache ) {
                        return false;
                }
-               if ( $wgShowIPinHeader || $wgDebugToolbar ) {
-                       wfDebug( "HTML file cache skipped. Either \$wgShowIPinHeader and/or \$wgDebugToolbar on\n" );
+               if ( $wgDebugToolbar ) {
+                       wfDebug( "HTML file cache skipped. \$wgDebugToolbar on\n" );
 
                        return false;
                }
index 6054ecc..a2e46d3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Resource message blobs storage used by ResourceLoader.
+ * Message blobs storage used by ResourceLoader.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * @file
  * @author Roan Kattouw
  * @author Trevor Parscal
+ * @author Timo Tijhof
  */
 
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
 /**
- * This class provides access to the message blobs used by ResourceLoader modules.
+ * This class generates message blobs for use by ResourceLoader modules.
  *
- * A message blob is a JSON object containing the interface messages for a
- * certain module in a certain language. These message blobs are cached
- * in the automatically invalidated when one of their constituent messages,
- * or the module definition, is changed.
+ * A message blob is a JSON object containing the interface messages for a certain module in
+ * a certain language.
  */
-class MessageBlobStore {
+class MessageBlobStore implements LoggerAwareInterface {
+
+       /* @var ResourceLoader|null */
+       private $resourceloader;
+
        /**
-        * In-process cache for message blobs.
-        *
-        * Keyed by language code, then module name.
-        *
-        * @var array
+        * @var LoggerInterface
+        */
+       protected $logger;
+
+       /**
+        * @var WANObjectCache
         */
-       protected $blobCache = array();
+       protected $wanCache;
 
-       /* @var ResourceLoader */
-       protected $resourceloader;
+       /**
+        * @param ResourceLoader $rl
+        * @param LoggerInterface $logger
+        */
+       public function __construct( ResourceLoader $rl = null, LoggerInterface $logger = null ) {
+               $this->resourceloader = $rl;
+               $this->logger = $logger ?: new NullLogger();
+               $this->wanCache = ObjectCache::getMainWANInstance();
+       }
 
        /**
-        * @param ResourceLoader $resourceloader
+        * @since 1.27
+        * @param LoggerInterface $logger
         */
-       public function __construct( ResourceLoader $resourceloader = null ) {
-               $this->resourceloader = $resourceloader;
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
        }
 
        /**
@@ -67,55 +83,46 @@ class MessageBlobStore {
         * Get the message blobs for a set of modules
         *
         * @since 1.27
-        * @param ResourceLoader $resourceLoader
-        * @param array $modules Array of module objects keyed by module name
+        * @param ResourceLoaderModule[] $modules Array of module objects keyed by name
         * @param string $lang Language code
         * @return array An array mapping module names to message blobs
         */
-       public function getBlobs( $modules, $lang ) {
-               if ( !count( $modules ) ) {
-                       return array();
+       public function getBlobs( array $modules, $lang ) {
+               // Each cache key for a message blob by module name and language code also has a generic
+               // check key without language code. This is used to invalidate any and all language subkeys
+               // that exist for a module from the updateMessage() method.
+               $cache = $this->wanCache;
+               $checkKeys = array(
+                       // Global check key, see clear()
+                       $cache->makeKey( __CLASS__ )
+               );
+               $cacheKeys = array();
+               foreach ( $modules as $name => $module ) {
+                       $cacheKey = $this->makeCacheKey( $module, $lang );
+                       $cacheKeys[$name] = $cacheKey;
+                       // Per-module check key, see updateMessage()
+                       $checkKeys[$cacheKey][] = $cache->makeKey( __CLASS__, $name );
                }
+               $curTTLs = array();
+               $result = $cache->getMulti( array_values( $cacheKeys ), $curTTLs, $checkKeys );
 
                $blobs = array();
-
-               // Try in-process cache
-               $missingFromCache = array();
                foreach ( $modules as $name => $module ) {
-                       if ( isset( $this->blobCache[$lang][$name] ) ) {
-                               $blobs[$name] = $this->blobCache[$lang][$name];
+                       $key = $cacheKeys[$name];
+                       if ( !isset( $result[$key] ) || $curTTLs[$key] === null || $curTTLs[$key] < 0 ) {
+                               $this->logger->info( 'Message blob cache-miss for {module}',
+                                       array( 'module' => $name, 'cacheKey' => $key )
+                               );
+                               $blobs[$name] = $this->recacheMessageBlob( $key, $module, $lang );
                        } else {
-                               $missingFromCache[$name] = $module;
-                       }
-               }
-
-               // Try DB cache
-               if ( $missingFromCache ) {
-                       $blobs += $this->getFromDB( $missingFromCache, $lang );
-               }
-
-               // Generate new blobs for any remaining modules and store in DB
-               $missingFromDb = array_diff( array_keys( $modules ), array_keys( $blobs ) );
-               foreach ( $missingFromDb as $name ) {
-                       $blob = $this->insertMessageBlob( $name, $modules[$name], $lang );
-                       if ( $blob ) {
-                               $blobs[$name] = $blob;
+                               // Use unexpired cache
+                               $blobs[$name] = $result[$key];
                        }
                }
-
-               // Update in-process cache
-               if ( isset( $this->blobCache[$lang] ) ) {
-                       $this->blobCache[$lang] += $blobs;
-               } else {
-                       $this->blobCache[$lang] = $blobs;
-               }
-
                return $blobs;
        }
 
        /**
-        * Get the message blobs for a set of modules
-        *
         * @deprecated since 1.27 Use getBlobs() instead
         * @return array
         */
@@ -124,281 +131,100 @@ class MessageBlobStore {
        }
 
        /**
-        * Generate and insert a new message blob. If the blob was already
-        * present, it is not regenerated; instead, the preexisting blob
-        * is fetched and returned.
-        *
-        * @param string $name Module name
-        * @param ResourceLoaderModule $module
-        * @param string $lang Language code
-        * @return string JSON blob
+        * @deprecated since 1.27 Obsolete. Used to populate a cache table in the database.
+        * @return bool
         */
        public function insertMessageBlob( $name, ResourceLoaderModule $module, $lang ) {
-               $blob = $this->generateMessageBlob( $module, $lang );
-
-               if ( !$blob ) {
-                       return false;
-               }
-
-               try {
-                       $dbw = wfGetDB( DB_MASTER );
-                       $success = $dbw->insert( 'msg_resource', array(
-                                       'mr_lang' => $lang,
-                                       'mr_resource' => $name,
-                                       'mr_blob' => $blob,
-                                       'mr_timestamp' => $dbw->timestamp()
-                               ),
-                               __METHOD__,
-                               array( 'IGNORE' )
-                       );
-
-                       if ( $success && $dbw->affectedRows() == 0 ) {
-                               // Blob was already present, fetch it
-                               $blob = $dbw->selectField( 'msg_resource', 'mr_blob', array(
-                                               'mr_resource' => $name,
-                                               'mr_lang' => $lang,
-                                       ),
-                                       __METHOD__
-                               );
-                       }
-               } catch ( DBError $e ) {
-                       wfDebug( __METHOD__ . " failed to update DB: $e\n" );
-               }
-               return $blob;
+               return false;
        }
 
        /**
-        * Update the message blob for a given module in a given language
-        *
-        * @param string $name Module name
+        * @since 1.27
         * @param ResourceLoaderModule $module
-        * @param string $lang Language code
-        * @return string|null Regenerated message blob, or null if there was no blob for
-        *   the given module/language pair.
+        * @param string $lang
+        * @return string Cache key
         */
-       public function updateModule( $name, ResourceLoaderModule $module, $lang ) {
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow( 'msg_resource', 'mr_blob',
-                       array( 'mr_resource' => $name, 'mr_lang' => $lang ),
-                       __METHOD__
+       private function makeCacheKey( ResourceLoaderModule $module, $lang ) {
+               $messages = array_values( array_unique( $module->getMessages() ) );
+               sort( $messages );
+               return $this->wanCache->makeKey( __CLASS__, $module->getName(), $lang,
+                       md5( json_encode( $messages ) )
                );
-               if ( !$row ) {
-                       return null;
-               }
-
-               $newBlob = $this->generateMessageBlob( $module, $lang );
-
-               try {
-                       $newRow = array(
-                               'mr_resource' => $name,
-                               'mr_lang' => $lang,
-                               'mr_blob' => $newBlob,
-                               'mr_timestamp' => $dbw->timestamp()
-                       );
+       }
 
-                       $dbw->replace( 'msg_resource',
-                               array( array( 'mr_resource', 'mr_lang' ) ),
-                               $newRow, __METHOD__
-                       );
-               } catch ( Exception $e ) {
-                       wfDebug( __METHOD__ . " failed to update DB: $e\n" );
-               }
-               return $newBlob;
+       /**
+        * @since 1.27
+        * @param string $cacheKey
+        * @param ResourceLoaderModule $module
+        * @param string $lang
+        * @return string JSON blob
+        */
+       protected function recacheMessageBlob( $cacheKey, ResourceLoaderModule $module, $lang ) {
+               $blob = $this->generateMessageBlob( $module, $lang );
+               $cache = $this->wanCache;
+               $cache->set( $cacheKey, $blob,
+                       // Add part of a day to TTL to avoid all modules expiring at once
+                       $cache::TTL_WEEK + mt_rand( 0, $cache::TTL_DAY ),
+                       Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) )
+               );
+               return $blob;
        }
 
        /**
-        * Update a single message in all message blobs it occurs in.
+        * Invalidate cache keys for modules using this message key.
+        * Called by MessageCache when a message has changed.
         *
         * @param string $key Message key
         */
        public function updateMessage( $key ) {
-               try {
-                       $dbw = wfGetDB( DB_MASTER );
-
-                       // Keep running until the updates queue is empty.
-                       // Due to update conflicts, the queue might not be emptied
-                       // in one iteration.
-                       $updates = null;
-                       do {
-                               $updates = $this->getUpdatesForMessage( $key, $updates );
-
-                               foreach ( $updates as $k => $update ) {
-                                       // Update the row on the condition that it
-                                       // didn't change since we fetched it by putting
-                                       // the timestamp in the WHERE clause.
-                                       $success = $dbw->update( 'msg_resource',
-                                               array(
-                                                       'mr_blob' => $update['newBlob'],
-                                                       'mr_timestamp' => $dbw->timestamp() ),
-                                               array(
-                                                       'mr_resource' => $update['resource'],
-                                                       'mr_lang' => $update['lang'],
-                                                       'mr_timestamp' => $update['timestamp'] ),
-                                               __METHOD__
-                                       );
-
-                                       // Only requeue conflicted updates.
-                                       // If update() returned false, don't retry, for
-                                       // fear of getting into an infinite loop
-                                       if ( !( $success && $dbw->affectedRows() == 0 ) ) {
-                                               // Not conflicted
-                                               unset( $updates[$k] );
-                                       }
-                               }
-                       } while ( count( $updates ) );
-
-               } catch ( Exception $e ) {
-                       wfDebug( __METHOD__ . " failed to update DB: $e\n" );
+               $moduleNames = $this->getResourceLoader()->getModulesByMessage( $key );
+               foreach ( $moduleNames as $moduleName ) {
+                       // Uses a holdoff to account for database slave lag (for MessageCache)
+                       $this->wanCache->touchCheckKey( $this->wanCache->makeKey( __CLASS__, $moduleName ) );
                }
        }
 
+       /**
+        * Invalidate cache keys for all known modules.
+        * Called by LocalisationCache after cache is regenerated.
+        */
        public function clear() {
-               try {
-                       // Not using TRUNCATE, because that needs extra permissions,
-                       // which maybe not granted to the database user.
-                       $dbw = wfGetDB( DB_MASTER );
-                       $dbw->delete( 'msg_resource', '*', __METHOD__ );
-               } catch ( Exception $e ) {
-                       wfDebug( __METHOD__ . " failed to update DB: $e\n" );
-               }
+               $cache = $this->wanCache;
+               // Disable holdoff because this invalidates all modules and also not needed since
+               // LocalisationCache is stored outside the database and doesn't have lag.
+               $cache->touchCheckKey( $cache->makeKey( __CLASS__ ), $cache::HOLDOFF_NONE );
        }
 
        /**
+        * @since 1.27
         * @return ResourceLoader
         */
        protected function getResourceLoader() {
-               // For back-compat this class supports instantiation without passing ResourceLoader
+               // Back-compat: This class supports instantiation without a ResourceLoader object.
                // Lazy-initialise this property because most callers don't need it.
                if ( $this->resourceloader === null ) {
-                       wfDebug( __CLASS__ . ' created without a ResourceLoader instance' );
+                       $this->logger->warning( __CLASS__ . ' created without a ResourceLoader instance' );
                        $this->resourceloader = new ResourceLoader();
                }
-
                return $this->resourceloader;
        }
 
        /**
-        * Create an update queue for updateMessage()
-        *
-        * @param string $key Message key
-        * @param array $prevUpdates Updates queue to refresh or null to build a fresh update queue
-        * @return array Updates queue
-        */
-       private function getUpdatesForMessage( $key, $prevUpdates = null ) {
-               $dbw = wfGetDB( DB_MASTER );
-
-               if ( is_null( $prevUpdates ) ) {
-                       $rl = $this->getResourceLoader();
-                       $moduleNames = $rl->getModulesByMessage( $key );
-                       // Fetch all blobs referencing $key
-                       $res = $dbw->select(
-                               array( 'msg_resource' ),
-                               array( 'mr_resource', 'mr_lang', 'mr_blob', 'mr_timestamp' ),
-                               array(
-                                       'mr_resource' => $moduleNames,
-                               ),
-                               __METHOD__
-                       );
-               } else {
-                       // Refetch the blobs referenced by $prevUpdates
-
-                       // Reorganize the (resource, lang) pairs in the format
-                       // expected by makeWhereFrom2d()
-                       $twoD = array();
-
-                       foreach ( $prevUpdates as $update ) {
-                               $twoD[$update['resource']][$update['lang']] = true;
-                       }
-
-                       $res = $dbw->select( 'msg_resource',
-                               array( 'mr_resource', 'mr_lang', 'mr_blob', 'mr_timestamp' ),
-                               $dbw->makeWhereFrom2d( $twoD, 'mr_resource', 'mr_lang' ),
-                               __METHOD__
-                       );
-               }
-
-               // Build the new updates queue
-               $updates = array();
-
-               foreach ( $res as $row ) {
-                       $updates[] = array(
-                               'resource' => $row->mr_resource,
-                               'lang' => $row->mr_lang,
-                               'timestamp' => $row->mr_timestamp,
-                               'newBlob' => $this->reencodeBlob( $row->mr_blob, $key, $row->mr_lang )
-                       );
-               }
-
-               return $updates;
-       }
-
-       /**
+        * @since 1.27
         * @param string $key Message key
         * @param string $lang Language code
         * @return string
         */
        protected function fetchMessage( $key, $lang ) {
                $message = wfMessage( $key )->inLanguage( $lang );
+               $value = $message->plain();
                if ( !$message->exists() ) {
-                       wfDebugLog( 'resourceloader', __METHOD__ . " failed to find: '$key' ($lang)" );
-               }
-               return $message->plain();
-       }
-
-       /**
-        * Reencode a message blob with the updated value for a message
-        *
-        * @param string $blob Message blob (JSON object)
-        * @param string $key Message key
-        * @param string $lang Language code
-        * @return string Message blob with $key replaced with its new value
-        */
-       private function reencodeBlob( $blob, $key, $lang ) {
-               $decoded = FormatJson::decode( $blob, true );
-               $decoded[$key] = $this->fetchMessage( $key, $lang );
-               return FormatJson::encode( (object)$decoded );
-       }
-
-       /**
-        * Get the message blobs for a set of modules from the database.
-        * Modules whose blobs are not in the database are silently dropped.
-        *
-        * @param array $modules Array of module objects by name
-        * @param string $lang Language code
-        * @throws MWException
-        * @return array Array mapping module names to blobs
-        */
-       private function getFromDB( $modules, $lang ) {
-               if ( !count( $modules ) ) {
-                       return array();
+                       $this->logger->warning( 'Failed to find {messageKey} ({lang})', array(
+                               'messageKey' => $key,
+                               'lang' => $lang,
+                       ) );
                }
-
-               $retval = array();
-               $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select( 'msg_resource',
-                       array( 'mr_blob', 'mr_resource', 'mr_timestamp' ),
-                       array( 'mr_resource' => array_keys( $modules ), 'mr_lang' => $lang ),
-                       __METHOD__
-               );
-
-               foreach ( $res as $row ) {
-                       if ( !isset( $modules[ $row->mr_resource ] ) ) {
-                               // This shouldn't be possible
-                               throw new MWException( __METHOD__ . ' passed an invalid module name' );
-                       }
-                       $module = $modules[ $row->mr_resource ];
-
-                       // Update the module's blob if the list of messages changed
-                       $blobKeys = array_keys( FormatJson::decode( $row->mr_blob, true ) );
-                       $moduleMsgs = array_values( array_unique( $module->getMessages() ) );
-                       if ( $blobKeys !== $moduleMsgs ) {
-                               $retval[$row->mr_resource] = $this->updateModule( $row->mr_resource, $module, $lang );
-                       } else {
-                               $retval[$row->mr_resource] = $row->mr_blob;
-                       }
-               }
-
-               return $retval;
+               return $value;
        }
 
        /**
@@ -410,11 +236,18 @@ class MessageBlobStore {
         */
        private function generateMessageBlob( ResourceLoaderModule $module, $lang ) {
                $messages = array();
-
                foreach ( $module->getMessages() as $key ) {
                        $messages[$key] = $this->fetchMessage( $key, $lang );
                }
 
-               return FormatJson::encode( (object)$messages );
+               $json = FormatJson::encode( (object)$messages );
+               if ( $json === false ) {
+                       $this->logger->warning( 'Failed to encode message blob for {module} ({lang})', array(
+                               'module' => $module->getName(),
+                               'lang' => $lang,
+                       ) );
+                       $json = '{}';
+               }
+               return $json;
        }
 }
index 47960ca..24df574 100644 (file)
@@ -98,7 +98,7 @@ class MessageCache {
         * @return MessageCache
         */
        public static function singleton() {
-               if ( is_null( self::$instance ) ) {
+               if ( self::$instance === null ) {
                        global $wgUseDatabaseMessages, $wgMsgCacheExpiry;
                        self::$instance = new self(
                                wfGetMessageCacheStorage(),
index b4086f9..af6f9d9 100644 (file)
@@ -178,6 +178,7 @@ class CategoryMembershipChange {
                        }
                }
 
+               /** @var RecentChange $rc */
                $rc = call_user_func_array(
                        $this->newForCategorizationCallback,
                        array(
index 0883982..ed374b0 100644 (file)
@@ -178,18 +178,24 @@ class EnhancedChangesList extends ChangesList {
                # Collate list of users
                $userlinks = array();
                # Other properties
-               $unpatrolled = false;
-               $isnew = false;
-               $allBots = true;
-               $allMinors = true;
                $curId = 0;
                # Some catalyst variables...
                $namehidden = true;
                $allLogs = true;
                $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
+               $collectedRcFlags = array(
+                       // All are by bots?
+                       'bot' => true,
+                       // Includes a new page?
+                       'newpage' => false,
+                       // All are minor edits?
+                       'minor' => true,
+                       // Contains an unpatrolled edit?
+                       'unpatrolled' => false,
+               );
                foreach ( $block as $rcObj ) {
                        if ( $rcObj->mAttribs['rc_type'] == RC_NEW ) {
-                               $isnew = true;
+                               $collectedRcFlags['newpage'] = true;
                        }
                        // If all log actions to this page were hidden, then don't
                        // give the name of the affected page for this block!
@@ -201,7 +207,7 @@ class EnhancedChangesList extends ChangesList {
                                $userlinks[$u] = 0;
                        }
                        if ( $rcObj->unpatrolled ) {
-                               $unpatrolled = true;
+                               $collectedRcFlags['unpatrolled'] = true;
                        }
                        if ( $rcObj->mAttribs['rc_type'] != RC_LOG ) {
                                $allLogs = false;
@@ -213,10 +219,10 @@ class EnhancedChangesList extends ChangesList {
                        }
 
                        if ( !$rcObj->mAttribs['rc_bot'] ) {
-                               $allBots = false;
+                               $collectedRcFlags['bot'] = false;
                        }
                        if ( !$rcObj->mAttribs['rc_minor'] ) {
-                               $allMinors = false;
+                               $collectedRcFlags['minor'] = false;
                        }
 
                        $userlinks[$u]++;
@@ -247,12 +253,9 @@ class EnhancedChangesList extends ChangesList {
                $r .= "<td>$tl</td>";
 
                # Main line
-               $r .= '<td class="mw-enhanced-rc">' . $this->recentChangesFlags( array(
-                       'newpage' => $isnew, # show, when one have this flag
-                       'minor' => $allMinors, # show only, when all have this flag
-                       'unpatrolled' => $unpatrolled, # show, when one have this flag
-                       'bot' => $allBots, # show only, when all have this flag
-               ) );
+               $r .= '<td class="mw-enhanced-rc">' . $this->recentChangesFlags(
+                       $collectedRcFlags
+               );
 
                # Timestamp
                $r .= '&#160;' . $block[0]->timestamp . '&#160;</td><td>';
@@ -289,7 +292,8 @@ class EnhancedChangesList extends ChangesList {
                        return '';
                }
 
-               $r .= $this->getLogText( $block, $queryParams, $allLogs, $isnew, $namehidden );
+               $r .= $this->getLogText( $block, $queryParams, $allLogs,
+                       $collectedRcFlags['newpage'], $namehidden );
 
                $r .= ' <span class="mw-changeslist-separator">. .</span> ';
 
index 64db0d6..1b9f9b3 100644 (file)
@@ -166,6 +166,14 @@ class RedisConnectionPool implements LoggerAwareInterface {
                return self::$instances[$id];
        }
 
+       /**
+        * Destroy all singleton() instances
+        * @since 1.27
+        */
+       public static function destroySingletons() {
+               self::$instances = array();
+       }
+
        /**
         * Get a connection to a redis server. Based on code in RedisBagOStuff.php.
         *
index 91100e9..24b8b8e 100644 (file)
@@ -196,7 +196,7 @@ class SquidPurgeClient {
         */
        public function queuePurge( $url ) {
                global $wgSquidPurgeUseHostHeader;
-               $url = SquidUpdate::expand( str_replace( "\n", '', $url ) );
+               $url = CdnCacheUpdate::expand( str_replace( "\n", '', $url ) );
                $request = array();
                if ( $wgSquidPurgeUseHostHeader ) {
                        $url = wfParseUrl( $url );
index 4f8e65d..9b6e1f3 100644 (file)
@@ -22,6 +22,8 @@
  * @file
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * Group all the pieces relevant to the context of a request into one instance
  */
@@ -135,10 +137,7 @@ class RequestContext implements IContextSource, MutableContext {
         */
        public function getStats() {
                if ( $this->stats === null ) {
-                       $config = $this->getConfig();
-                       $prefix = $config->get( 'StatsdMetricPrefix' )
-                               ? rtrim( $config->get( 'StatsdMetricPrefix' ), '.' )
-                               : 'MediaWiki';
+                       $prefix = rtrim( $this->getConfig()->get( 'StatsdMetricPrefix' ), '.' );
                        $this->stats = new BufferingStatsdDataFactory( $prefix );
                }
                return $this->stats;
@@ -151,7 +150,9 @@ class RequestContext implements IContextSource, MutableContext {
         */
        public function getTiming() {
                if ( $this->timing === null ) {
-                       $this->timing = new Timing();
+                       $this->timing = new Timing( array(
+                               'logger' => LoggerFactory::getInstance( 'Timing' )
+                       ) );
                }
                return $this->timing;
        }
index c0cf067..dea4a59 100644 (file)
@@ -3308,7 +3308,11 @@ abstract class DatabaseBase implements IDatabase {
                                        list( $phpCallback ) = $callback;
                                        $this->clearFlag( DBO_TRX ); // make each query its own transaction
                                        call_user_func( $phpCallback );
-                                       $this->setFlag( $autoTrx ? DBO_TRX : 0 ); // restore automatic begin()
+                                       if ( $autoTrx ) {
+                                               $this->setFlag( DBO_TRX ); // restore automatic begin()
+                                       } else {
+                                               $this->clearFlag( DBO_TRX ); // restore auto-commit
+                                       }
                                } catch ( Exception $e ) {
                                        if ( $ePrior ) {
                                                MWExceptionHandler::logException( $ePrior );
@@ -3820,7 +3824,7 @@ abstract class DatabaseBase implements IDatabase {
         * @param IDatabase $db1
         * @param IDatabase ...
         * @return array Map of values:
-        *   - lag: highest lag of any of the DBs
+        *   - lag: highest lag of any of the DBs or false on error (e.g. replication stopped)
         *   - since: oldest UNIX timestamp of any of the DB lag estimates
         *   - pending: whether any of the DBs have uncommitted changes
         * @since 1.27
@@ -3830,7 +3834,11 @@ abstract class DatabaseBase implements IDatabase {
                foreach ( func_get_args() as $db ) {
                        /** @var IDatabase $db */
                        $status = $db->getSessionLagStatus();
-                       $res['lag'] = max( $res['lag'], $status['lag'] );
+                       if ( $status['lag'] === false ) {
+                               $res['lag'] = false;
+                       } elseif ( $res['lag'] !== false ) {
+                               $res['lag'] = max( $res['lag'], $status['lag'] );
+                       }
                        $res['since'] = min( $res['since'], $status['since'] );
                        $res['pending'] = $res['pending'] ?: $db->writesPending();
                }
index 78d26ae..4993eac 100644 (file)
@@ -464,3 +464,9 @@ class DBReadOnlyError extends DBExpectedError {
                return $this->msg( 'readonly', 'Database is locked' );
        }
 }
+
+/**
+ * @ingroup Database
+ */
+class DBTransactionError extends DBExpectedError {
+}
index dea7d94..7fcb68e 100644 (file)
@@ -113,11 +113,11 @@ class ResultWrapper implements Iterator {
        }
 
        /**
-        * Fetch the next row from the given result object, in object form.
-        * Fields can be retrieved with $row->fieldname, with fields acting like
-        * member variables.
+        * Fetch the next row from the given result object, in object form. Fields can be retrieved with
+        * $row->fieldname, with fields acting like member variables. If no more rows are available,
+        * false is returned.
         *
-        * @return stdClass
+        * @return stdClass|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        function fetchObject() {
@@ -125,10 +125,10 @@ class ResultWrapper implements Iterator {
        }
 
        /**
-        * Fetch the next row from the given result object, in associative array
-        * form. Fields are retrieved with $row['fieldname'].
+        * Fetch the next row from the given result object, in associative array form. Fields are
+        * retrieved with $row['fieldname']. If no more rows are available, false is returned.
         *
-        * @return array
+        * @return array|bool
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        function fetchRow() {
index 09954a0..510d42a 100644 (file)
@@ -37,6 +37,10 @@ use Monolog\Formatter\FormatterInterface;
  * @copyright © 2015 Erik Bernhardson and Wikimedia Foundation.
  */
 class AvroFormatter implements FormatterInterface {
+       /**
+        * @var Magic byte to encode schema revision id.
+        */
+       const MAGIC = 0x0;
        /**
         * @var array Map from schema name to schema definition
         */
@@ -80,6 +84,7 @@ class AvroFormatter implements FormatterInterface {
        public function format( array $record ) {
                $this->io->truncate();
                $schema = $this->getSchema( $record['channel'] );
+               $revId = $this->getSchemaRevisionId( $record['channel'] );
                if ( $schema === null ) {
                        trigger_error( "The schema for channel '{$record['channel']}' is not available" );
                        return null;
@@ -92,6 +97,10 @@ class AvroFormatter implements FormatterInterface {
                        trigger_error( "Avro failed to serialize record for {$record['channel']} : {$json}" );
                        return null;
                }
+               if ( $revId !== null ) {
+                       return chr( self::MAGIC ) . $this->encode_long( $revId ) . $this->io->string();
+               }
+               // @todo: remove backward compat code and do not send messages without rev id.
                return $this->io->string();
        }
 
@@ -123,17 +132,55 @@ class AvroFormatter implements FormatterInterface {
                if ( !isset( $this->schemas[$channel] ) ) {
                        return null;
                }
-               if ( !$this->schemas[$channel] instanceof AvroSchema ) {
-                       if ( is_string( $this->schemas[$channel] ) ) {
-                               $this->schemas[$channel] = AvroSchema::parse( $this->schemas[$channel] );
+               $schemaDetails = &$this->schemas[$channel];
+               $schema = null;
+               if ( isset( $schemaDetails['revision'] ) && isset( $schemaDetails['schema'] ) ) {
+                       $schema = &$schemaDetails['schema'];
+               } else {
+                       // @todo: Remove backward compat code
+                       $schema = &$schemaDetails;
+               }
+
+               if ( !$schema instanceof AvroSchema ) {
+                       if ( is_string( $schema ) ) {
+                               $schema = AvroSchema::parse( $schema );
                        } else {
-                               $this->schemas[$channel] = AvroSchema::real_parse(
+                               $schema = AvroSchema::real_parse(
                                        $this->schemas[$channel],
                                        null,
                                        new AvroNamedSchemata()
                                );
                        }
                }
-               return $this->schemas[$channel];
+               return $schema;
+       }
+
+       /**
+        * Get the writer for the named channel
+        *
+        * @var string $channel Name of the schema
+        * @return int|null
+        */
+       public function getSchemaRevisionId( $channel ) {
+               // @todo: remove backward compat code
+               if ( isset( $this->schemas[$channel] )
+                               && is_array( $this->schemas[$channel] )
+                               && isset( $this->schemas[$channel]['revision'] ) ) {
+                       return (int) $this->schemas[$channel]['revision'];
+               }
+               return null;
+       }
+
+
+       /**
+        * convert an integer to a 64bits big endian long (Java compatible)
+        * NOTE: certainly only compatible with PHP 64bits
+        * @param int $id
+        * @return string the binary representation of $id
+        */
+       private function encode_long( $id ) {
+               $high   = ( $id & 0xffffffff00000000 ) >> 32;
+               $low    = $id & 0x00000000ffffffff;
+               return pack( 'NN', $high, $low );
        }
 }
diff --git a/includes/deferred/CdnCacheUpdate.php b/includes/deferred/CdnCacheUpdate.php
new file mode 100644 (file)
index 0000000..9f7d8ca
--- /dev/null
@@ -0,0 +1,275 @@
+<?php
+/**
+ * CDN cache purging.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+use Wikimedia\Assert\Assert;
+
+/**
+ * Handles purging appropriate CDN URLs given a title (or titles)
+ * @ingroup Cache
+ */
+class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate {
+       /** @var string[] Collection of URLs to purge */
+       protected $urls = array();
+
+       /**
+        * @param string[] $urlArr Collection of URLs to purge
+        */
+       public function __construct( array $urlArr ) {
+               $this->urls = $urlArr;
+       }
+
+       public function merge( MergeableUpdate $update ) {
+               /** @var CdnCacheUpdate $update */
+               Assert::parameterType( __CLASS__, $update, '$update' );
+
+               $this->urls = array_merge( $this->urls, $update->urls );
+       }
+
+       /**
+        * Create an update object from an array of Title objects, or a TitleArray object
+        *
+        * @param Traversable|array $titles
+        * @param string[] $urlArr
+        * @return CdnCacheUpdate
+        */
+       public static function newFromTitles( $titles, $urlArr = array() ) {
+               /** @var Title $title */
+               foreach ( $titles as $title ) {
+                       $urlArr = array_merge( $urlArr, $title->getCdnUrls() );
+               }
+
+               return new CdnCacheUpdate( $urlArr );
+       }
+
+       /**
+        * @param Title $title
+        * @return CdnCacheUpdate
+        * @deprecated 1.27
+        */
+       public static function newSimplePurge( Title $title ) {
+               return new CdnCacheUpdate( $title->getCdnUrls() );
+       }
+
+       /**
+        * Purges the list of URLs passed to the constructor.
+        */
+       public function doUpdate() {
+               global $wgCdnReboundPurgeDelay;
+
+               self::purge( $this->urls );
+
+               if ( $wgCdnReboundPurgeDelay > 0 ) {
+                       JobQueueGroup::singleton()->lazyPush( new CdnPurgeJob(
+                               Title::makeTitle( NS_SPECIAL, 'Badtitle/' . __CLASS__ ),
+                               array(
+                                       'urls' => $this->urls,
+                                       'jobReleaseTimestamp' => time() + $wgCdnReboundPurgeDelay
+                               )
+                       ) );
+               }
+       }
+
+       /**
+        * Purges a list of CDN nodes defined in $wgSquidServers.
+        * $urlArr should contain the full URLs to purge as values
+        * (example: $urlArr[] = 'http://my.host/something')
+        *
+        * @param string[] $urlArr List of full URLs to purge
+        */
+       public static function purge( array $urlArr ) {
+               global $wgSquidServers, $wgHTCPRouting;
+
+               if ( !$urlArr ) {
+                       return;
+               }
+
+               // Remove duplicate URLs from list
+               $urlArr = array_unique( $urlArr );
+
+               wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
+
+               if ( $wgHTCPRouting ) {
+                       self::HTCPPurge( $urlArr );
+               }
+
+               if ( $wgSquidServers ) {
+                       // Maximum number of parallel connections per squid
+                       $maxSocketsPerSquid = 8;
+                       // Number of requests to send per socket
+                       // 400 seems to be a good tradeoff, opening a socket takes a while
+                       $urlsPerSocket = 400;
+                       $socketsPerSquid = ceil( count( $urlArr ) / $urlsPerSocket );
+                       if ( $socketsPerSquid > $maxSocketsPerSquid ) {
+                               $socketsPerSquid = $maxSocketsPerSquid;
+                       }
+
+                       $pool = new SquidPurgeClientPool;
+                       $chunks = array_chunk( $urlArr, ceil( count( $urlArr ) / $socketsPerSquid ) );
+                       foreach ( $wgSquidServers as $server ) {
+                               foreach ( $chunks as $chunk ) {
+                                       $client = new SquidPurgeClient( $server );
+                                       foreach ( $chunk as $url ) {
+                                               $client->queuePurge( $url );
+                                       }
+                                       $pool->addClient( $client );
+                               }
+                       }
+
+                       $pool->run();
+               }
+       }
+
+       /**
+        * Send Hyper Text Caching Protocol (HTCP) CLR requests.
+        *
+        * @throws MWException
+        * @param string[] $urlArr Collection of URLs to purge
+        */
+       private static function HTCPPurge( array $urlArr ) {
+               global $wgHTCPRouting, $wgHTCPMulticastTTL;
+
+               // HTCP CLR operation
+               $htcpOpCLR = 4;
+
+               // @todo FIXME: PHP doesn't support these socket constants (include/linux/in.h)
+               if ( !defined( "IPPROTO_IP" ) ) {
+                       define( "IPPROTO_IP", 0 );
+                       define( "IP_MULTICAST_LOOP", 34 );
+                       define( "IP_MULTICAST_TTL", 33 );
+               }
+
+               // pfsockopen doesn't work because we need set_sock_opt
+               $conn = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
+               if ( !$conn ) {
+                       $errstr = socket_strerror( socket_last_error() );
+                       wfDebugLog( 'squid', __METHOD__ .
+                               ": Error opening UDP socket: $errstr" );
+
+                       return;
+               }
+
+               // Set socket options
+               socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_LOOP, 0 );
+               if ( $wgHTCPMulticastTTL != 1 ) {
+                       // Set multicast time to live (hop count) option on socket
+                       socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_TTL,
+                               $wgHTCPMulticastTTL );
+               }
+
+               // Get sequential trx IDs for packet loss counting
+               $ids = UIDGenerator::newSequentialPerNodeIDs(
+                       'squidhtcppurge', 32, count( $urlArr ), UIDGenerator::QUICK_VOLATILE
+               );
+
+               foreach ( $urlArr as $url ) {
+                       if ( !is_string( $url ) ) {
+                               throw new MWException( 'Bad purge URL' );
+                       }
+                       $url = self::expand( $url );
+                       $conf = self::getRuleForURL( $url, $wgHTCPRouting );
+                       if ( !$conf ) {
+                               wfDebugLog( 'squid', __METHOD__ .
+                                       "No HTCP rule configured for URL {$url} , skipping" );
+                               continue;
+                       }
+
+                       if ( isset( $conf['host'] ) && isset( $conf['port'] ) ) {
+                               // Normalize single entries
+                               $conf = array( $conf );
+                       }
+                       foreach ( $conf as $subconf ) {
+                               if ( !isset( $subconf['host'] ) || !isset( $subconf['port'] ) ) {
+                                       throw new MWException( "Invalid HTCP rule for URL $url\n" );
+                               }
+                       }
+
+                       // Construct a minimal HTCP request diagram
+                       // as per RFC 2756
+                       // Opcode 'CLR', no response desired, no auth
+                       $htcpTransID = current( $ids );
+                       next( $ids );
+
+                       $htcpSpecifier = pack( 'na4na*na8n',
+                               4, 'HEAD', strlen( $url ), $url,
+                               8, 'HTTP/1.0', 0 );
+
+                       $htcpDataLen = 8 + 2 + strlen( $htcpSpecifier );
+                       $htcpLen = 4 + $htcpDataLen + 2;
+
+                       // Note! Squid gets the bit order of the first
+                       // word wrong, wrt the RFC. Apparently no other
+                       // implementation exists, so adapt to Squid
+                       $htcpPacket = pack( 'nxxnCxNxxa*n',
+                               $htcpLen, $htcpDataLen, $htcpOpCLR,
+                               $htcpTransID, $htcpSpecifier, 2 );
+
+                       wfDebugLog( 'squid', __METHOD__ .
+                               "Purging URL $url via HTCP" );
+                       foreach ( $conf as $subconf ) {
+                               socket_sendto( $conn, $htcpPacket, $htcpLen, 0,
+                                       $subconf['host'], $subconf['port'] );
+                       }
+               }
+       }
+
+       /**
+        * Expand local URLs to fully-qualified URLs using the internal protocol
+        * and host defined in $wgInternalServer. Input that's already fully-
+        * qualified will be passed through unchanged.
+        *
+        * This is used to generate purge URLs that may be either local to the
+        * main wiki or include a non-native host, such as images hosted on a
+        * second internal server.
+        *
+        * Client functions should not need to call this.
+        *
+        * @param string $url
+        * @return string
+        */
+       public static function expand( $url ) {
+               return wfExpandUrl( $url, PROTO_INTERNAL );
+       }
+
+       /**
+        * Find the HTCP routing rule to use for a given URL.
+        * @param string $url URL to match
+        * @param array $rules Array of rules, see $wgHTCPRouting for format and behavior
+        * @return mixed Element of $rules that matched, or false if nothing matched
+        */
+       private static function getRuleForURL( $url, $rules ) {
+               foreach ( $rules as $regex => $routing ) {
+                       if ( $regex === '' || preg_match( $regex, $url ) ) {
+                               return $routing;
+                       }
+               }
+
+               return false;
+       }
+}
+
+/**
+ * @deprecated since 1.27
+ */
+class SquidUpdate extends CdnCacheUpdate {
+       // Keep class name for b/c
+}
diff --git a/includes/deferred/DeferrableUpdate.php b/includes/deferred/DeferrableUpdate.php
new file mode 100644 (file)
index 0000000..5f4d821
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * Interface that deferrable updates should implement. Basically required so we
+ * can validate input on DeferredUpdates::addUpdate()
+ *
+ * @since 1.19
+ */
+interface DeferrableUpdate {
+       /**
+        * Perform the actual work
+        */
+       function doUpdate();
+}
index 8eec202..fb6ef13 100644 (file)
  * @file
  */
 
-/**
- * Interface that deferrable updates should implement. Basically required so we
- * can validate input on DeferredUpdates::addUpdate()
- *
- * @since 1.19
- */
-interface DeferrableUpdate {
-       /**
-        * Perform the actual work
-        */
-       function doUpdate();
-}
-
 /**
  * Class for managing the deferred updates
  *
- * Deferred updates can be run at the end of the request,
- * after the HTTP response has been sent. In CLI mode, updates
- * are only deferred until there is no local master DB transaction.
- * When updates are deferred, they go into a simple FIFO queue.
+ * In web request mode, deferred updates can be run at the end of the request, either before or
+ * after the HTTP response has been sent. In either case, they run after the DB commit step. If
+ * an update runs after the response is sent, it will not block clients. If sent before, it will
+ * run synchronously. If such an update works via queueing, it will be more likely to complete by
+ * the time the client makes their next request after this one.
+ *
+ * In CLI mode, updates are only deferred until the current wiki has no DB write transaction
+ * active within this request.
+ *
+ * When updates are deferred, they use a FIFO queue (one for pre-send and one for post-send).
  *
  * @since 1.19
  */
 class DeferredUpdates {
-       /** @var DeferrableUpdate[] Updates to be deferred until the end of the request */
-       private static $updates = array();
-       /** @var bool Defer updates fully even in CLI mode */
-       private static $forceDeferral = false;
+       /** @var DeferrableUpdate[] Updates to be deferred until before request end */
+       private static $preSendUpdates = array();
+       /** @var DeferrableUpdate[] Updates to be deferred until after request end */
+       private static $postSendUpdates = array();
+
+       const ALL = 0; // all updates
+       const PRESEND = 1; // for updates that should run before flushing output buffer
+       const POSTSEND = 2; // for updates that should run after flushing output buffer
 
        /**
         * Add an update to the deferred list
+        *
         * @param DeferrableUpdate $update Some object that implements doUpdate()
+        * @param integer $type DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27)
+        */
+       public static function addUpdate( DeferrableUpdate $update, $type = self::POSTSEND ) {
+               if ( $type === self::PRESEND ) {
+                       self::push( self::$preSendUpdates, $update );
+               } else {
+                       self::push( self::$postSendUpdates, $update );
+               }
+       }
+
+       /**
+        * Add a callable update.  In a lot of cases, we just need a callback/closure,
+        * defining a new DeferrableUpdate object is not necessary
+        *
+        * @see MWCallableUpdate::__construct()
+        *
+        * @param callable $callable
+        * @param integer $type DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27)
+        */
+       public static function addCallableUpdate( $callable, $type = self::POSTSEND ) {
+               self::addUpdate( new MWCallableUpdate( $callable ), $type );
+       }
+
+       /**
+        * Do any deferred updates and clear the list
+        *
+        * @param string $mode Use "enqueue" to use the job queue when possible [Default: "run"]
+        * @param integer $type DeferredUpdates constant (PRESEND, POSTSEND, or ALL) (since 1.27)
         */
-       public static function addUpdate( DeferrableUpdate $update ) {
+       public static function doUpdates( $mode = 'run', $type = self::ALL ) {
+               if ( $type === self::ALL || $type == self::PRESEND ) {
+                       self::execute( self::$preSendUpdates, $mode );
+               }
+
+               if ( $type === self::ALL || $type == self::POSTSEND ) {
+                       self::execute( self::$postSendUpdates, $mode );
+               }
+       }
+
+       private static function push( array &$queue, DeferrableUpdate $update ) {
                global $wgCommandLineMode;
 
-               array_push( self::$updates, $update );
-               if ( self::$forceDeferral ) {
-                       return;
+               if ( $update instanceof MergeableUpdate ) {
+                       $class = get_class( $update ); // fully-qualified class
+                       if ( isset( $queue[$class] ) ) {
+                               /** @var $existingUpdate MergeableUpdate */
+                               $existingUpdate = $queue[$class];
+                               $existingUpdate->merge( $update );
+                       } else {
+                               $queue[$class] = $update;
+                       }
+               } else {
+                       $queue[] = $update;
                }
 
                // CLI scripts may forget to periodically flush these updates,
-               // so try to handle that rather than OOMing and losing them.
-               // Try to run the updates as soon as there is no local transaction.
+               // so try to handle that rather than OOMing and losing them entirely.
+               // Try to run the updates as soon as there is no current wiki transaction.
                static $waitingOnTrx = false; // de-duplicate callback
                if ( $wgCommandLineMode && !$waitingOnTrx ) {
                        $lb = wfGetLB();
@@ -81,34 +125,12 @@ class DeferredUpdates {
                }
        }
 
-       /**
-        * Add a callable update.  In a lot of cases, we just need a callback/closure,
-        * defining a new DeferrableUpdate object is not necessary
-        * @see MWCallableUpdate::__construct()
-        * @param callable $callable
-        */
-       public static function addCallableUpdate( $callable ) {
-               self::addUpdate( new MWCallableUpdate( $callable ) );
-       }
-
-       /**
-        * Do any deferred updates and clear the list
-        *
-        * @param string $mode Use "enqueue" to use the job queue when possible [Default: run]
-        *   prevent lock contention
-        * @param string $oldMode Unused
-        */
-       public static function doUpdates( $mode = 'run', $oldMode = '' ) {
-               // B/C for ( $commit, $mode ) args
-               $mode = $oldMode ?: $mode;
-               if ( $mode === 'commit' ) {
-                       $mode = 'run';
-               }
-
-               $updates = self::$updates;
+       public static function execute( array &$queue, $mode ) {
+               $updates = $queue; // snapshot of queue
 
+               // Keep doing rounds of updates until none get enqueued
                while ( count( $updates ) ) {
-                       self::clearPendingUpdates();
+                       $queue = array(); // clear the queue
                        /** @var DataUpdate[] $dataUpdates */
                        $dataUpdates = array();
                        /** @var DeferrableUpdate[] $otherUpdates */
@@ -140,7 +162,7 @@ class DeferredUpdates {
                                }
                        }
 
-                       $updates = self::$updates;
+                       $updates = $queue; // new snapshot of queue (check for new entries)
                }
        }
 
@@ -149,15 +171,7 @@ class DeferredUpdates {
         * want or need to call this. Unit tests need it though.
         */
        public static function clearPendingUpdates() {
-               self::$updates = array();
-       }
-
-       /**
-        * @note This method is intended for testing purposes
-        * @param bool $value Whether to *always* defer updates, even in CLI mode
-        * @since 1.27
-        */
-       public static function forceDeferral( $value ) {
-               self::$forceDeferral = $value;
+               self::$preSendUpdates = array();
+               self::$postSendUpdates = array();
        }
 }
index a480aec..db3790f 100644 (file)
@@ -43,24 +43,8 @@ class HTMLCacheUpdate implements DeferrableUpdate {
        }
 
        public function doUpdate() {
-               $job = new HTMLCacheUpdateJob(
-                       $this->mTitle,
-                       array(
-                               'table' => $this->mTable,
-                               'recursive' => true
-                       ) + Job::newRootJobParams( // "overall" refresh links job info
-                               "htmlCacheUpdate:{$this->mTable}:{$this->mTitle->getPrefixedText()}"
-                       )
-               );
+               $job = HTMLCacheUpdateJob::newForBacklinks( $this->mTitle, $this->mTable );
 
-               $count = $this->mTitle->getBacklinkCache()->getNumLinks( $this->mTable, 100 );
-               if ( $count >= 100 ) { // many backlinks
-                       JobQueueGroup::singleton()->lazyPush( $job );
-               } else { // few backlinks ($count might be off even if 0)
-                       $dbw = wfGetDB( DB_MASTER );
-                       $dbw->onTransactionIdle( function () use ( $job ) {
-                               $job->run(); // just do the purge query now
-                       } );
-               }
+               JobQueueGroup::singleton()->lazyPush( $job );
        }
 }
index a6290ed..3021af1 100644 (file)
@@ -61,9 +61,6 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
        /** @var bool Whether to queue jobs for recursive updates */
        public $mRecursive;
 
-       /** @var bool Whether this job was triggered by a recursive update job */
-       private $mTriggeredRecursive;
-
        /** @var Revision Revision for which this update has been triggered */
        private $mRevision;
 
@@ -94,7 +91,7 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                parent::__construct( false ); // no implicit transaction
 
                $this->mTitle = $title;
-               $this->mId = $title->getArticleID();
+               $this->mId = $title->getArticleID( Title::GAID_FOR_UPDATE );
 
                if ( !$this->mId ) {
                        throw new InvalidArgumentException(
@@ -153,8 +150,6 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
        }
 
        protected function doIncrementalUpdate() {
-               global $wgRCWatchCategoryMembership;
-
                # Page links
                $existing = $this->getExistingLinks();
                $this->linkDeletions = $this->getLinkDeletions( $existing );
@@ -206,14 +201,6 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                $this->invalidateCategories( $categoryUpdates );
                $this->updateCategoryCounts( $categoryInserts, $categoryDeletes );
 
-               # Category membership changes
-               if (
-                       $wgRCWatchCategoryMembership &&
-                       !$this->mTriggeredRecursive && ( $categoryInserts || $categoryDeletes )
-               ) {
-                       $this->triggerCategoryChanges( $categoryInserts, $categoryDeletes );
-               }
-
                # Page properties
                $existing = $this->getExistingProperties();
 
@@ -237,24 +224,6 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
 
        }
 
-       private function triggerCategoryChanges( $categoryInserts, $categoryDeletes ) {
-               $catMembChange = new CategoryMembershipChange( $this->mTitle, $this->mRevision );
-
-               if ( $this->mRecursive ) {
-                       $catMembChange->checkTemplateLinks();
-               }
-
-               foreach ( $categoryInserts as $categoryName => $value ) {
-                       $categoryTitle = Title::newFromText( $categoryName, NS_CATEGORY );
-                       $catMembChange->triggerCategoryAddedNotification( $categoryTitle );
-               }
-
-               foreach ( $categoryDeletes as $categoryName => $value ) {
-                       $categoryTitle = Title::newFromText( $categoryName, NS_CATEGORY );
-                       $catMembChange->triggerCategoryRemovedNotification( $categoryTitle );
-               }
-       }
-
        /**
         * Queue recursive jobs for this page
         *
@@ -896,15 +865,6 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                return $this->mImages;
        }
 
-       /**
-        * Set this object as being triggered by a recursive LinksUpdate
-        *
-        * @since 1.27
-        */
-       public function setTriggeredRecursive() {
-               $this->mTriggeredRecursive = true;
-       }
-
        /**
         * Set the revision corresponding to this LinksUpdate
         *
@@ -948,8 +908,7 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                                        $inv = array( $inv );
                                }
                                foreach ( $inv as $table ) {
-                                       $update = new HTMLCacheUpdate( $this->mTitle, $table );
-                                       $update->doUpdate();
+                                       DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, $table ) );
                                }
                        }
                }
diff --git a/includes/deferred/MergeableUpdate.php b/includes/deferred/MergeableUpdate.php
new file mode 100644 (file)
index 0000000..70760ce
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Interface that deferrable updates can implement. DeferredUpdates uses this to merge
+ * all pending updates of PHP class into a single update by calling merge().
+ *
+ * @since 1.27
+ */
+interface MergeableUpdate {
+       /**
+        * Merge this update with $update
+        *
+        * @param MergeableUpdate $update Update of the same class type
+        */
+       function merge( MergeableUpdate $update );
+}
index 6ed1d00..2abf028 100644 (file)
@@ -38,6 +38,9 @@ class SearchUpdate implements DeferrableUpdate {
        /** @var Content|bool Content of the page (not text) */
        private $content;
 
+       /** @var WikiPage **/
+       private $page;
+
        /**
         * Constructor
         *
@@ -78,18 +81,15 @@ class SearchUpdate implements DeferrableUpdate {
                        return;
                }
 
-               $page = WikiPage::newFromID( $this->id, WikiPage::READ_LATEST );
-
                foreach ( SearchEngine::getSearchTypes() as $type ) {
                        $search = SearchEngine::create( $type );
-                       $indexTitle = $this->indexTitle( $search );
                        if ( !$search->supports( 'search-update' ) ) {
                                continue;
                        }
 
-                       $normalTitle = $search->normalizeText( $indexTitle );
+                       $normalTitle = $this->getNormalizedTitle( $search );
 
-                       if ( $page === null ) {
+                       if ( $this->getLatestPage() === null ) {
                                $search->delete( $this->id, $normalTitle );
                                continue;
                        } elseif ( $this->content === false ) {
@@ -174,13 +174,30 @@ class SearchUpdate implements DeferrableUpdate {
        }
 
        /**
-        * Get a string representation of a title suitable for
+        * Get WikiPage for the SearchUpdate $id using WikiPage::READ_LATEST
+        * and ensure using the same WikiPage object if there are multiple
+        * SearchEngine types.
+        *
+        * Returns null if a page has been deleted or is not found.
+        *
+        * @return WikiPage|null
+        */
+       private function getLatestPage() {
+               if ( !isset( $this->page ) ) {
+                       $this->page = WikiPage::newFromID( $this->id, WikiPage::READ_LATEST );
+               }
+
+               return $this->page;
+       }
+
+       /**
+        * Get a normalized string representation of a title suitable for
         * including in a search index
         *
         * @param SearchEngine $search
         * @return string A stripped-down title string ready for the search index
         */
-       private function indexTitle( SearchEngine $search ) {
+       private function getNormalizedTitle( SearchEngine $search ) {
                global $wgContLang;
 
                $ns = $this->title->getNamespace();
@@ -200,6 +217,7 @@ class SearchUpdate implements DeferrableUpdate {
                if ( $ns == NS_FILE ) {
                        $t = preg_replace( "/ (png|gif|jpg|jpeg|ogg)$/", "", $t );
                }
-               return trim( $t );
+
+               return $search->normalizeText( trim( $t ) );
        }
 }
diff --git a/includes/deferred/SquidUpdate.php b/includes/deferred/SquidUpdate.php
deleted file mode 100644 (file)
index d33e4a5..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-<?php
-/**
- * Squid cache purging.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Cache
- */
-
-/**
- * Handles purging appropriate Squid URLs given a title (or titles)
- * @ingroup Cache
- */
-class SquidUpdate implements DeferrableUpdate {
-       /** @var string[] Collection of URLs to purge */
-       protected $urls = array();
-
-       /**
-        * @param string[] $urlArr Collection of URLs to purge
-        */
-       public function __construct( array $urlArr ) {
-               // Remove duplicate URLs from list
-               $this->urls = array_unique( $urlArr );
-       }
-
-       /**
-        * Create a SquidUpdate from an array of Title objects, or a TitleArray object
-        *
-        * @param Traversable|array $titles
-        * @param string[] $urlArr
-        * @return SquidUpdate
-        */
-       public static function newFromTitles( $titles, $urlArr = array() ) {
-               /** @var Title $title */
-               foreach ( $titles as $title ) {
-                       $urlArr = array_merge( $urlArr, $title->getSquidURLs() );
-               }
-
-               return new SquidUpdate( $urlArr );
-       }
-
-       /**
-        * @param Title $title
-        * @return SquidUpdate
-        * @deprecated 1.27
-        */
-       public static function newSimplePurge( Title $title ) {
-               $urlArr = $title->getSquidURLs();
-
-               return new SquidUpdate( $urlArr );
-       }
-
-       /**
-        * Purges the list of URLs passed to the constructor.
-        */
-       public function doUpdate() {
-               self::purge( $this->urls );
-       }
-
-       /**
-        * Purges a list of Squids defined in $wgSquidServers.
-        * $urlArr should contain the full URLs to purge as values
-        * (example: $urlArr[] = 'http://my.host/something')
-        * XXX report broken Squids per mail or log
-        *
-        * @param string[] $urlArr List of full URLs to purge
-        */
-       public static function purge( array $urlArr ) {
-               global $wgSquidServers, $wgHTCPRouting;
-
-               if ( !$urlArr ) {
-                       return;
-               }
-
-               wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
-
-               if ( $wgHTCPRouting ) {
-                       self::HTCPPurge( $urlArr );
-               }
-
-               if ( $wgSquidServers ) {
-                       // Remove duplicate URLs
-                       $urlArr = array_unique( $urlArr );
-                       // Maximum number of parallel connections per squid
-                       $maxSocketsPerSquid = 8;
-                       // Number of requests to send per socket
-                       // 400 seems to be a good tradeoff, opening a socket takes a while
-                       $urlsPerSocket = 400;
-                       $socketsPerSquid = ceil( count( $urlArr ) / $urlsPerSocket );
-                       if ( $socketsPerSquid > $maxSocketsPerSquid ) {
-                               $socketsPerSquid = $maxSocketsPerSquid;
-                       }
-
-                       $pool = new SquidPurgeClientPool;
-                       $chunks = array_chunk( $urlArr, ceil( count( $urlArr ) / $socketsPerSquid ) );
-                       foreach ( $wgSquidServers as $server ) {
-                               foreach ( $chunks as $chunk ) {
-                                       $client = new SquidPurgeClient( $server );
-                                       foreach ( $chunk as $url ) {
-                                               $client->queuePurge( $url );
-                                       }
-                                       $pool->addClient( $client );
-                               }
-                       }
-
-                       $pool->run();
-               }
-       }
-
-       /**
-        * Send Hyper Text Caching Protocol (HTCP) CLR requests.
-        *
-        * @throws MWException
-        * @param string[] $urlArr Collection of URLs to purge
-        */
-       protected static function HTCPPurge( array $urlArr ) {
-               global $wgHTCPRouting, $wgHTCPMulticastTTL;
-
-               // HTCP CLR operation
-               $htcpOpCLR = 4;
-
-               // @todo FIXME: PHP doesn't support these socket constants (include/linux/in.h)
-               if ( !defined( "IPPROTO_IP" ) ) {
-                       define( "IPPROTO_IP", 0 );
-                       define( "IP_MULTICAST_LOOP", 34 );
-                       define( "IP_MULTICAST_TTL", 33 );
-               }
-
-               // pfsockopen doesn't work because we need set_sock_opt
-               $conn = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
-               if ( !$conn ) {
-                       $errstr = socket_strerror( socket_last_error() );
-                       wfDebugLog( 'squid', __METHOD__ .
-                               ": Error opening UDP socket: $errstr" );
-
-                       return;
-               }
-
-               // Set socket options
-               socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_LOOP, 0 );
-               if ( $wgHTCPMulticastTTL != 1 ) {
-                       // Set multicast time to live (hop count) option on socket
-                       socket_set_option( $conn, IPPROTO_IP, IP_MULTICAST_TTL,
-                               $wgHTCPMulticastTTL );
-               }
-
-               // Remove duplicate URLs from collection
-               $urlArr = array_unique( $urlArr );
-               // Get sequential trx IDs for packet loss counting
-               $ids = UIDGenerator::newSequentialPerNodeIDs(
-                       'squidhtcppurge', 32, count( $urlArr ), UIDGenerator::QUICK_VOLATILE
-               );
-
-               foreach ( $urlArr as $url ) {
-                       if ( !is_string( $url ) ) {
-                               throw new MWException( 'Bad purge URL' );
-                       }
-                       $url = self::expand( $url );
-                       $conf = self::getRuleForURL( $url, $wgHTCPRouting );
-                       if ( !$conf ) {
-                               wfDebugLog( 'squid', __METHOD__ .
-                                       "No HTCP rule configured for URL {$url} , skipping" );
-                               continue;
-                       }
-
-                       if ( isset( $conf['host'] ) && isset( $conf['port'] ) ) {
-                               // Normalize single entries
-                               $conf = array( $conf );
-                       }
-                       foreach ( $conf as $subconf ) {
-                               if ( !isset( $subconf['host'] ) || !isset( $subconf['port'] ) ) {
-                                       throw new MWException( "Invalid HTCP rule for URL $url\n" );
-                               }
-                       }
-
-                       // Construct a minimal HTCP request diagram
-                       // as per RFC 2756
-                       // Opcode 'CLR', no response desired, no auth
-                       $htcpTransID = current( $ids );
-                       next( $ids );
-
-                       $htcpSpecifier = pack( 'na4na*na8n',
-                               4, 'HEAD', strlen( $url ), $url,
-                               8, 'HTTP/1.0', 0 );
-
-                       $htcpDataLen = 8 + 2 + strlen( $htcpSpecifier );
-                       $htcpLen = 4 + $htcpDataLen + 2;
-
-                       // Note! Squid gets the bit order of the first
-                       // word wrong, wrt the RFC. Apparently no other
-                       // implementation exists, so adapt to Squid
-                       $htcpPacket = pack( 'nxxnCxNxxa*n',
-                               $htcpLen, $htcpDataLen, $htcpOpCLR,
-                               $htcpTransID, $htcpSpecifier, 2 );
-
-                       wfDebugLog( 'squid', __METHOD__ .
-                               "Purging URL $url via HTCP" );
-                       foreach ( $conf as $subconf ) {
-                               socket_sendto( $conn, $htcpPacket, $htcpLen, 0,
-                                       $subconf['host'], $subconf['port'] );
-                       }
-               }
-       }
-
-       /**
-        * Expand local URLs to fully-qualified URLs using the internal protocol
-        * and host defined in $wgInternalServer. Input that's already fully-
-        * qualified will be passed through unchanged.
-        *
-        * This is used to generate purge URLs that may be either local to the
-        * main wiki or include a non-native host, such as images hosted on a
-        * second internal server.
-        *
-        * Client functions should not need to call this.
-        *
-        * @param string $url
-        * @return string
-        */
-       public static function expand( $url ) {
-               return wfExpandUrl( $url, PROTO_INTERNAL );
-       }
-
-       /**
-        * Find the HTCP routing rule to use for a given URL.
-        * @param string $url URL to match
-        * @param array $rules Array of rules, see $wgHTCPRouting for format and behavior
-        * @return mixed Element of $rules that matched, or false if nothing matched
-        */
-       private static function getRuleForURL( $url, $rules ) {
-               foreach ( $rules as $regex => $routing ) {
-                       if ( $regex === '' || preg_match( $regex, $url ) ) {
-                               return $routing;
-                       }
-               }
-
-               return false;
-       }
-}
index 264c87f..7401992 100644 (file)
@@ -296,9 +296,9 @@ class DiffEngine {
                        $this->xchanged = $this->ychanged = array();
                        $this->xv = $this->yv = array();
                        $this->xind = $this->yind = array();
-                       unset( $this->seq );
-                       unset( $this->in_seq );
-                       unset( $this->lcs );
+                       $this->seq = array();
+                       $this->in_seq = array();
+                       $this->lcs = 0;
 
                        // Skip leading common lines.
                        for ( $skip = 0; $skip < $n_from && $skip < $n_to; $skip++ ) {
index 5734902..26960ff 100644 (file)
@@ -197,6 +197,7 @@ class MWExceptionHandler {
         * @param string $message
         * @param string $file
         * @param int $line
+        * @return bool
         *
         * @see logError()
         */
@@ -369,6 +370,7 @@ TXT;
        public static function prettyPrintTrace( array $trace, $pad = '' ) {
                $text = '';
 
+               $level = 0;
                foreach ( $trace as $level => $frame ) {
                        if ( isset( $frame['file'] ) && isset( $frame['line'] ) ) {
                                $text .= "{$pad}#{$level} {$frame['file']}({$frame['line']}): ";
index 647dbec..15007af 100644 (file)
@@ -123,13 +123,13 @@ class FileRepo {
        /** @var bool Whether all zones should be private (e.g. private wiki repo) */
        protected $isPrivate;
 
-       /**
-        * Factory functions for creating new files
-        * Override these in the base class
-        */
+       /** @var array callable Override these in the base class */
        protected $fileFactory = array( 'UnregisteredLocalFile', 'newFromTitle' );
+       /** @var array callable|bool Override these in the base class */
        protected $oldFileFactory = false;
+       /** @var array callable|bool Override these in the base class */
        protected $fileFactoryKey = false;
+       /** @var array callable|bool Override these in the base class */
        protected $oldFileFactoryKey = false;
 
        /**
@@ -1031,8 +1031,10 @@ class FileRepo {
                                $headers = array( 'Content-Disposition' => $triple[2] );
                        } elseif ( is_array( $triple[2] ) && isset( $triple[2]['headers'] ) ) {
                                $headers = $triple[2]['headers'];
+                       } else {
+                               $headers = array();
                        }
-                       // @fixme: $headers might not be defined
+
                        $operations[] = array(
                                'op' => FileBackend::isStoragePath( $src ) ? 'copy' : 'store',
                                'src' => $src,
index c2bbb4e..0da1ae8 100644 (file)
@@ -858,14 +858,14 @@ class LocalFile extends File {
        }
 
        /**
-        * Refresh metadata in memcached, but don't touch thumbnails or squid
+        * Refresh metadata in memcached, but don't touch thumbnails or CDN
         */
        function purgeMetadataCache() {
                $this->invalidateCache();
        }
 
        /**
-        * Delete all previously generated thumbnails, refresh metadata in memcached and purge the squid.
+        * Delete all previously generated thumbnails, refresh metadata in memcached and purge the CDN.
         *
         * @param array $options An array potentially with the key forThumbRefresh.
         *
@@ -878,8 +878,11 @@ class LocalFile extends File {
                // Delete thumbnails
                $this->purgeThumbnails( $options );
 
-               // Purge squid cache for this file
-               SquidUpdate::purge( array( $this->getURL() ) );
+               // Purge CDN cache for this file
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( array( $this->getUrl() ) ),
+                       DeferredUpdates::PRESEND
+               );
        }
 
        /**
@@ -887,8 +890,6 @@ class LocalFile extends File {
         * @param string $archiveName Name of the archived file
         */
        function purgeOldThumbnails( $archiveName ) {
-               global $wgUseSquid;
-
                // Get a list of old thumbnails and URLs
                $files = $this->getThumbnails( $archiveName );
 
@@ -898,15 +899,12 @@ class LocalFile extends File {
                $dir = array_shift( $files );
                $this->purgeThumbList( $dir, $files );
 
-               // Purge the squid
-               if ( $wgUseSquid ) {
-                       $urls = array();
-                       foreach ( $files as $file ) {
-                               $urls[] = $this->getArchiveThumbUrl( $archiveName, $file );
-                       }
-                       SquidUpdate::purge( $urls );
+               // Purge the CDN
+               $urls = array();
+               foreach ( $files as $file ) {
+                       $urls[] = $this->getArchiveThumbUrl( $archiveName, $file );
                }
-
+               DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND );
        }
 
        /**
@@ -914,18 +912,14 @@ class LocalFile extends File {
         * @param array $options
         */
        public function purgeThumbnails( $options = array() ) {
-               global $wgUseSquid;
-
                // Delete thumbnails
                $files = $this->getThumbnails();
-               // Always purge all files from squid regardless of handler filters
+               // Always purge all files from CDN regardless of handler filters
                $urls = array();
-               if ( $wgUseSquid ) {
-                       foreach ( $files as $file ) {
-                               $urls[] = $this->getThumbUrl( $file );
-                       }
-                       array_shift( $urls ); // don't purge directory
+               foreach ( $files as $file ) {
+                       $urls[] = $this->getThumbUrl( $file );
                }
+               array_shift( $urls ); // don't purge directory
 
                // Give media handler a chance to filter the file purge list
                if ( !empty( $options['forThumbRefresh'] ) ) {
@@ -941,11 +935,8 @@ class LocalFile extends File {
                $dir = array_shift( $files );
                $this->purgeThumbList( $dir, $files );
 
-               // Purge the squid
-               if ( $wgUseSquid ) {
-                       SquidUpdate::purge( $urls );
-               }
-
+               // Purge the CDN
+               DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND );
        }
 
        /**
@@ -1408,7 +1399,7 @@ class LocalFile extends File {
                        if ( $newPageContent ) {
                                # New file page; create the description page.
                                # There's already a log entry, so don't make a second RC entry
-                               # Squid and file cache for the description page are purged by doEditContent.
+                               # CDN and file cache for the description page are purged by doEditContent.
                                $status = $wikiPage->doEditContent(
                                        $newPageContent,
                                        $comment,
@@ -1443,8 +1434,11 @@ class LocalFile extends File {
                        if ( $reupload ) {
                                # Delete old thumbnails
                                $that->purgeThumbnails();
-                               # Remove the old file from the squid cache
-                               SquidUpdate::purge( array( $that->getURL() ) );
+                               # Remove the old file from the CDN cache
+                               DeferredUpdates::addUpdate(
+                                       new CdnCacheUpdate( array( $that->getUrl() ) ),
+                                       DeferredUpdates::PRESEND
+                               );
                        } else {
                                # Update backlink pages pointing to this title if created
                                LinksUpdate::queueRecursiveJobsForTable( $that->getTitle(), 'imagelinks' );
@@ -1631,24 +1625,20 @@ class LocalFile extends File {
                $that = $this;
                $this->getRepo()->getMasterDB()->onTransactionIdle(
                        function () use ( $that, $archiveNames ) {
-                               global $wgUseSquid;
-
                                $that->purgeEverything();
                                foreach ( $archiveNames as $archiveName ) {
                                        $that->purgeOldThumbnails( $archiveName );
                                }
-
-                               if ( $wgUseSquid ) {
-                                       // Purge the squid
-                                       $purgeUrls = array();
-                                       foreach ( $archiveNames as $archiveName ) {
-                                               $purgeUrls[] = $that->getArchiveUrl( $archiveName );
-                                       }
-                                       SquidUpdate::purge( $purgeUrls );
-                               }
                        }
                );
 
+               // Purge the CDN
+               $purgeUrls = array();
+               foreach ( $archiveNames as $archiveName ) {
+                       $purgeUrls[] = $this->getArchiveUrl( $archiveName );
+               }
+               DeferredUpdates::addUpdate( new CdnCacheUpdate( $purgeUrls ), DeferredUpdates::PRESEND );
+
                return $status;
        }
 
@@ -1668,7 +1658,6 @@ class LocalFile extends File {
         * @return FileRepoStatus
         */
        function deleteOld( $archiveName, $reason, $suppress = false, $user = null ) {
-               global $wgUseSquid;
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
                }
@@ -1685,10 +1674,10 @@ class LocalFile extends File {
                        $this->purgeDescription();
                }
 
-               if ( $wgUseSquid ) {
-                       // Purge the squid
-                       SquidUpdate::purge( array( $this->getArchiveUrl( $archiveName ) ) );
-               }
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( array( $this->getArchiveUrl( $archiveName ) ) ),
+                       DeferredUpdates::PRESEND
+               );
 
                return $status;
        }
index c89c6b6..9ea9702 100644 (file)
@@ -98,7 +98,8 @@ abstract class ImageGalleryBase extends ContextSource {
                $mode = $wgContLang->lc( $mode );
 
                if ( isset( self::$modeMapping[$mode] ) ) {
-                       return new self::$modeMapping[$mode]( $mode, $context );
+                       $class = self::$modeMapping[$mode];
+                       return new $class( $mode, $context );
                } else {
                        throw new MWException( "No gallery class registered for mode $mode" );
                }
index 369a23b..4cbd0cc 100644 (file)
@@ -9,14 +9,15 @@
                        "Jmarchn",
                        "Alvaro Vidal-Abarca",
                        "ESM",
-                       "Xavier Dengra"
+                       "Xavier Dengra",
+                       "Jaumeortola"
                ]
        },
        "config-desc": "L'instal·lador del MediaWiki",
        "config-title": "Instal·lació del MediaWiki $1",
        "config-information": "Informació",
        "config-localsettings-upgrade": "S'ha detectat un fitxer <code>LocalSettings.php</code>. \nPer tal d'actualitzar la instal·lació, introduïu el valor de <code>$wgUpgradeKey</code> en el quadre a continuació. El trobareu a <code>LocalSettings.php</code>.",
-       "config-localsettings-cli-upgrade": "S'ha detectat un fitxer <code>LocalSettings.php</code>.\nPer tal d'actualitzar la instal·lació, executeu <code>update.php</code>.",
+       "config-localsettings-cli-upgrade": "S'ha detectat un fitxer <code>LocalSettings.php</code>.\nPer actualitzar la instal·lació, executeu <code>update.php</code>.",
        "config-localsettings-key": "Clau d'actualització:",
        "config-localsettings-badkey": "La clau que heu proporcionat no és correcta.",
        "config-upgrade-key-missing": "S'ha detectat una instal·lació ja existent del MediaWiki.\nPer actualitzar-la, poseu la línia següent al final de <code>LocalSettings.php</code>:\n\n$1",
@@ -87,7 +88,7 @@
        "config-db-wiki-account": "Compte d'usuari per al funcionament normal",
        "config-db-wiki-help": "Introduïu el nom d'usuari i la contrasenya que s'utilitzarà per connectar-se a la base de dades durant l'operació normal del wiki.\nSi el compte no existeix, i el compte d'instal·lació té prou privilegis, es crearà aquest compte d'usuari amb els privilegis mínims necessaris per operar el wiki.",
        "config-db-prefix": "Prefix de la base de dades:",
-       "config-db-prefix-help": "Si heu de compartir una base de dades entre diversos wikis, o entre el MediaWiki i una altra aplicació web, podeu afegir un prefix al tots els noms de taula per tal d'evitar conflictes.\nNo utilitzeu espais.\n\nAquest camp acostuma a quedar en blanc.",
+       "config-db-prefix-help": "Si heu de compartir una base de dades entre diversos wikis, o entre el MediaWiki i una altra aplicació web, podeu afegir un prefix al tots els noms de taula per evitar conflictes.\nNo utilitzeu espais.\n\nAquest camp acostuma a quedar en blanc.",
        "config-db-charset": "Joc de caràcters de la base de dades",
        "config-charset-mysql5-binary": "Binari de MySQL 4.1/5.0",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
        "config-mssql-old": "Cal utilitzar el Microsoft SQL Server $1 o posterior. Teniu la versió $2.",
        "config-sqlite-name-help": "Trieu un nom per identificar el wiki.\nNo feu servir espais ni guionets.\nAquest nom s’utilitzarà per a denominar el fitxer de les dades de l’SQLite.",
        "config-sqlite-mkdir-error": "S'ha produït un error en crear el directori de dades «$1».\nComproveu la ubicació i torneu-ho a provar.",
-       "config-sqlite-dir-unwritable": "No s'ha pogut escriure al directori «$1».\nCanvieu els seus permisos per tal que el servidor web pugui escriure-hi i torneu-ho a provar.",
+       "config-sqlite-dir-unwritable": "No s'ha pogut escriure al directori «$1».\nCanvieu els permisos perquè el servidor web pugui escriure-hi i torneu-ho a provar.",
        "config-sqlite-connection-error": "$1. \n\nComproveu el directori de dades i el nom de la base de dades a continuació i torneu-ho a provar.",
        "config-sqlite-readonly": "El fitxer <code>$1</code> no es pot escriure.",
        "config-sqlite-cant-create-db": "No s'ha pogut crear el fitxer de base de dades <code>$1</code>.",
        "config-upload-settings": "Imatges i càrregues de fitxers",
        "config-upload-enable": "Habilita la càrrega de fitxers",
        "config-upload-deleted": "Directori pels arxius suprimits:",
-       "config-upload-deleted-help": "Trieu un directori on arxivar els fitxers suprimits.\nIdealment no hauria de ser accessible des del web.",
+       "config-upload-deleted-help": "Trieu un directori per a arxivar els fitxers suprimits.\nIdealment no hauria de ser accessible des del web.",
        "config-logo": "URL del logo:",
        "config-instantcommons": "Habilita Instant Commons",
        "config-cc-error": "El selector de llicència Creative Commons no ha donat cap resultat.\nIntroduïu la llicència manualment.",
index 1a77d18..44c6b14 100644 (file)
@@ -80,7 +80,7 @@
        "config-charset-mysql5-binary": "MySQL 4.1/5.0 δυαδικό",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
        "config-charset-mysql4": "UTF-8 συμβατό προς τα πίσω με MySQL 4.0",
-       "config-mysql-old": "Î\91Ï\80αιÏ\84είÏ\84αι Microsoft SQL Server $1 Î® Î½ÎµÏ\8eτερο. Εσείς έχετε $2.",
+       "config-mysql-old": "Î\91Ï\80αιÏ\84είÏ\84αι Microsoft SQL Server $1 Î® Î½ÎµÏ\8cτερο. Εσείς έχετε $2.",
        "config-db-port": "Θύρα βάσης δεδομένων:",
        "config-db-schema": "Σχήμα για MediaWiki:",
        "config-db-schema-help": "Αυτό το σχήμα συνήθως θα είναι εντάξει.\nΆλλαξε το μόνο αν ξέρεις ότι το χρειάζεσαι.",
        "config-missing-db-server-oracle": "Πρέπει να εισαγάγετε μια τιμή για \"{{int:config-db-host-oracle}}\".",
        "config-connection-error": "$1.\n\nΕλέγξτε τη διεύθυνση, το όνομα χρήστη και τον κωδικό πρόσβασης και προσπαθήστε ξανά.",
        "config-db-sys-user-exists-oracle": "Ο λογαριασμός χρήστη \"$1\" υπάρχει ήδη. Το SYSDBA μπορεί να χρησιμοποιηθεί μόνο για τη δημιουργία ενός νέου λογαριασμού!",
-       "config-postgres-old": "Î\91Ï\80αιÏ\84είÏ\84αι PostgreSQL $1 Î® Î½ÎµÏ\8eτερο. Εσείς έχετε $2.",
-       "config-mssql-old": "Î\91Ï\80αιÏ\84είÏ\84αι Microsoft SQL Server $1 Î® Î½ÎµÏ\8eτερο. Εσείς έχετε $2.",
+       "config-postgres-old": "Î\91Ï\80αιÏ\84είÏ\84αι PostgreSQL $1 Î® Î½ÎµÏ\8cτερο. Εσείς έχετε $2.",
+       "config-mssql-old": "Î\91Ï\80αιÏ\84είÏ\84αι Microsoft SQL Server $1 Î® Î½ÎµÏ\8cτερο. Εσείς έχετε $2.",
        "config-sqlite-readonly": "Το αρχείο <code>$1</code> δεν είναι εγγράψιμο.",
        "config-sqlite-cant-create-db": "Δεν ήταν δυνατή η δημιουργία του αρχείου βάσης δεδομένων <code>$1</code>.",
        "config-upgrade-done-no-regenerate": "Η αναβάθμιση ολοκληρώθηκε.\n\nΜπορείτε τώρα να [$1 ξεκινήσετε να χρησιμοποιείτε το wiki σας].",
index 60d1f57..75475ad 100644 (file)
@@ -22,6 +22,7 @@
        "config-page-language": "Hizkuntza",
        "config-page-welcome": "Ongi etorri MediaWikira!",
        "config-page-dbconnect": "Datu-basera konektatu",
+       "config-page-upgrade": "Oraingo instalazioa eguneratu",
        "config-page-dbsettings": "Datu-basearen ezarpenak",
        "config-page-name": "Izena",
        "config-page-options": "Aukerak",
        "config-page-complete": "Bukatua!",
        "config-page-restart": "Instalazioa berriz hasi",
        "config-page-readme": "Irakur nazazu",
+       "config-page-releasenotes": "Bertsioko oharrak",
        "config-page-copying": "Kopiatzea",
        "config-page-upgradedoc": "Eguneratu",
+       "config-page-existingwiki": "Existitzen den wikia",
        "config-restart": "Bai, berriz hasi",
        "config-sidebar": "* [//www.mediawiki.org MediaWiki nagusia]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Erabiltzaileentzako Gida]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Administratzaileentzako Gida]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MEG]\n----\n* <doclink href=Readme>Irakur nazazu</doclink>\n* <doclink href=ReleaseNotes>Oharren argitalpena</doclink>\n* <doclink href=Copying>Kopiaketa</doclink>\n* <doclink href=UpgradeDoc>Eguneratzea</doclink>",
        "config-env-php": "PHP $1 instalatuta dago.",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] instalatuta dago",
        "config-diff3-bad": "GNU diff3 ez da aurkitu.",
        "config-db-type": "Datu-base mota:",
+       "config-db-host-oracle": "Datu-baseko TNS:",
        "config-db-wiki-settings": "Wiki hau identifikatu",
        "config-db-name": "Datu-base izena:",
+       "config-db-name-oracle": "Datu-baseko eskema:",
        "config-db-username": "Datu-base lankide izena:",
        "config-db-password": "Datu-base pasahitza:",
        "config-charset-mysql5-binary": "MySQL 4.1/5.0 bitarra",
        "config-admin-password-confirm": "Pasahitza berriz:",
        "config-admin-password-mismatch": "Sartutako bi pasahitzak ez datoz bat.",
        "config-admin-email": "E-posta helbidea:",
+       "config-admin-error-bademail": "Helbide elektroniko okerra idatzi duzu.",
+       "config-optional-continue": "Galdera gehiago egin.",
+       "config-optional-skip": "Aspertuta nago, wikia instalatu bakarrik.",
        "config-profile-wiki": "Wikia ireki",
+       "config-profile-no-anon": "Kontua sortzea beharrezkoa da",
+       "config-profile-fishbowl": "Baimendutako editoreak bakarrik",
        "config-profile-private": "Wiki pribatua",
        "config-license": "Copyright eta lizentzia:",
+       "config-license-cc-by": "Creative Commons Aitorpena",
        "config-license-cc-0": "Creative Commons Zero (Jabari Publikoa)",
        "config-license-pd": "Domeinu Askea",
+       "config-license-cc-choose": "Aukeratu Creative Commons lizentzia pertsonalizatua",
        "config-email-settings": "E-posta hobespenak",
+       "config-upload-settings": "Irudi eta fitxategi igoerak",
+       "config-upload-enable": "Fitxategi igoera gaitu",
        "config-logo": "Logo URL:",
+       "config-instantcommons": "Instant Commons gaitu",
+       "config-cc-again": "Berriz aukeratu...",
        "config-advanced-settings": "Konfigurazio aurreratua",
        "config-extensions": "Luzapenak",
        "config-skins": "Itxurak",
        "config-install-step-done": "egina",
+       "config-install-extensions": "Luzapenak barne",
+       "config-install-database": "Datu-basea konfiguratu",
+       "config-install-schema": "Eskema sortu",
+       "config-install-user-alreadyexists": "\"$1\" erabiltzailea badago.",
+       "config-install-tables": "Taulak sortzen",
+       "config-install-interwiki-list": "Ezin izan da <code>interwiki.list</code> fitxategia irakurri.",
+       "config-install-stats": "Estatistikak hasten",
+       "config-install-keys": "Gako sekretuak sortzen",
+       "config-install-sysop": "Administratzaile kontua sortzen",
+       "config-download-localsettings": "Jaitsi <code>LocalSettings.php</code>",
        "config-help": "Laguntza",
+       "config-help-tooltip": "sakatu zabaltzeko",
        "mainpagetext": "'''MediaWiki arrakastaz instalatu da.'''",
        "mainpagedocfooter": "Ikus [//meta.wikimedia.org/wiki/Help:Contents Erabiltzaile Gida] wiki softwarea erabiltzen hasteko informazio gehiagorako.\n\n== Nola hasi ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Konfigurazio balioen zerrenda]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ (Maiz egindako galderak)]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWikiren argitalpenen posta zerrenda]"
 }
index ce15eac..17b5658 100644 (file)
@@ -1,5 +1,9 @@
 {
-       "@metadata": [],
+       "@metadata": {
+               "authors": [
+                       "Snævar"
+               ]
+       },
        "mainpagetext": "'''Uppsetning á MediaWiki heppnaðist.'''",
-       "mainpagedocfooter": "Ráðfærðu þig við [//meta.wikimedia.org/wiki/Help:Contents Notandahandbókina] fyrir frekari upplýsingar um notkun wiki-hugbúnaðarins.\n\n== Fyrir byrjendur ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Listi yfir uppsetningarstillingar]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki Algengar spurningar MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Póstlisti MediaWiki-útgáfa]"
+       "mainpagedocfooter": "Ráðfærðu þig við [//meta.wikimedia.org/wiki/Help:Contents Notandahandbókina] fyrir frekari upplýsingar um notkun wiki-hugbúnaðarins.\n\n== Fyrir byrjendur ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Listi yfir uppsetningarstillingar]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki Algengar spurningar MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Póstlisti MediaWiki-útgáfa]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Læra hvernig á að berjast við amapóst á þínum wiki]"
 }
index a8cd93e..7ed7067 100644 (file)
        "config-upload-deleted": "Directory per i file cancellati:",
        "config-upload-deleted-help": "Scegli una directory in cui archiviare i file cancellati.\nIdealmente, questa non dovrebbe essere accessibile dal web.",
        "config-logo": "URL del logo:",
-       "config-logo-help": "La skin predefinita di MediaWiki include lo spazio per un logo di 135 x 160 pixel sopra il menu laterale.\nCarica un'immagine di dimensioni appropriate e inserisci l'URL qui.\n\nÈ possibile utilizzare <code>$wgStylePath</code> o <code>$wgScriptPath</code> se il logo è relativo a tali percorsi.\n\nSe non si desidera un logo, lascia vuota questa casella.",
+       "config-logo-help": "Il tema predefinito di MediaWiki include lo spazio per un logo di 135 x 160 pixel sopra il menu laterale.\nCarica un'immagine di dimensioni appropriate e inserisci l'URL qui.\n\nÈ possibile utilizzare <code>$wgStylePath</code> o <code>$wgScriptPath</code> se il logo è relativo a tali percorsi.\n\nSe non si desidera un logo, lascia vuota questa casella.",
        "config-instantcommons": "Abilita Instant Commons",
        "config-instantcommons-help": "[//www.mediawiki.org/wiki/InstantCommons Instant Commons] è una funzionalità che consente ai wiki di usare immagini, suoni e altri file multimediali che trovate sul sito [//commons.wikimedia.org/ Wikimedia Commons].\nPer fare questo, MediaWiki richiede l'accesso a Internet.\n\nPer ulteriori informazioni su questa funzionalità, incluse le istruzioni su come configurarlo per wiki diversi da Wikimedia Commons, consultare [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos il manuale].",
        "config-cc-error": "Il selettore di licenze Creative Commons non ha dato alcun risultato.\nInserisci manualmente il nome della licenza.",
        "config-memcache-badport": "I numeri di porta per memcached dovrebbero essere tra $1 e $2.",
        "config-extensions": "Estensioni",
        "config-extensions-help": "Le estensioni elencate sopra sono state rilevate nella tua directory <code>./extensions</code>.\n\nQueste potrebbero richiedere ulteriore configurazione, ma è possibile attivarle ora",
-       "config-skins": "Skin",
-       "config-skins-help": "Le skin elencate sopra sono state rilevate nella tua directory <code>./skins</code>. Devi attivarne almeno una e scegliere quella predefinita.",
-       "config-skins-use-as-default": "Usa questa skin come predefinita",
-       "config-skins-missing": "Non è stata trovata alcuna skin, MediaWiki userà una soluzione di ripiego finché non ne installerai una appropriata.",
-       "config-skins-must-enable-some": "Devi scegliere almeno una skin da attivare.",
-       "config-skins-must-enable-default": "La skin scelta come predefinita deve essere attivata.",
+       "config-skins": "Temi",
+       "config-skins-help": "I temi elencati sopra sono stati rilevati nella tua directory <code>./skins</code>. Devi attivarne almeno uno e scegliere quello predefinito.",
+       "config-skins-use-as-default": "Usa questo tema come predefinito",
+       "config-skins-missing": "Non è stato trovato alcun tema, MediaWiki userà una soluzione di ripiego finché non ne installerai uno appropriato.",
+       "config-skins-must-enable-some": "Devi scegliere almeno un tema da attivare.",
+       "config-skins-must-enable-default": "Il tema scelto come predefinito deve essere attivato.",
        "config-install-alreadydone": "'''Attenzione:''' sembra che hai già installato MediaWiki e stai tentando di installarlo nuovamente.\nProcedi alla pagina successiva.",
        "config-install-begin": "Premendo \"{{int:config-continue}}\", si avvierà l'installazione di MediaWiki.\nSe prima desideri apportare altre modifiche, premi \"{{int:config-back}}\".",
        "config-install-step-done": "fatto",
diff --git a/includes/installer/i18n/lki.json b/includes/installer/i18n/lki.json
new file mode 100644 (file)
index 0000000..e104137
--- /dev/null
@@ -0,0 +1,88 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Hosseinblue",
+                       "Arash71",
+                       "Lakzon"
+               ]
+       },
+       "config-desc": "نۀصب کۀر ویکی‌مدیا",
+       "config-title": "نۀصب ویکی‌مدیا $1",
+       "config-information": "اطلاعات",
+       "config-localsettings-upgrade": "یک پرونده <code>LocalSettings.php</code> شناسایی شده‌است.\nبرای ارتقاء این نصب لطفاً مقدار <code>$wgUpgradeKey</code> در جعبه زیر وارد کنید.\nشما می‌توانید آن را در <code>LocalSettings.php</code> پیدا کنید.",
+       "config-localsettings-cli-upgrade": "یک پرونده <code>LocalSettings.php</code> شناسایی شده است.\nبرای ارتقاء این نصب، لطفاً <code>update.php</code> را اجرا کنید.",
+       "config-localsettings-key": ":کلید ارتقا",
+       "config-localsettings-badkey": "کلیدی که شما ارائه کردید نادرست است.",
+       "config-upgrade-key-missing": "نصب موجود مدیاویکی شناسایی شده‌است.\nبرای بروزرسانی این نصب، لطفاً خط زیر را در آخر کد \nقرار دادن به نصب ارتقاء داده شده، به خط زیر لطفاً در پایین خود را <code>LocalSettings.php</code> قرار دهید:\n\n$1",
+       "config-localsettings-incomplete": "وجود <code>LocalSettings.php</code> به نظر ناقص می‌رسد.\nمتغیر $1 تنظیم نشده‌است.\nبرای اینکه این متغیر تنظیم شود لطفاً <code>LocalSettings.php</code> را تغییر دهید، و \"{{int:Config-continue}}\" را کلیک کنید.",
+       "config-localsettings-connection-error": "هنگام اتصال به پایگاه اطلاعاتی که ازتنظیمات مشخص شده در<code>LocalSettings.php</code> استفاده می‌کند، خطایی رخ داد. لطفاً این تنظیمات را نصب کنید و دوباره تلاش کنید.\n$1",
+       "config-session-error": "خطا در شروع جلسه: $1",
+       "config-session-expired": "به نظر می‌رسد اطلاعات جلسهٔ شما منقضی شده‌است.\nجلسات برای مادام العمر $1 پیکربندی شده‌اند.\nشما می‌توانید این پیکربندی را با تنظیم <code>session.gc_maxlifetime</code> در php.ini افزایش دهید.\nروند نصب را دوباره شروع کنید.",
+       "config-no-session": "اطلاعات دورهٔ شما از دست رفته‌ است!\nphp.ini خود را بررسی کنید و مطمئن شوید <code>session.save_path</code> برای یک فهرست مناسب تنظیم شده‌است.",
+       "config-your-language": "زوون هوومۀ",
+       "config-your-language-help": "زوونئ ئۀرا استفاده در طی کار نۀب انتخب کۀن.",
+       "config-wiki-language": "زوون ویکی:",
+       "config-wiki-language-help": "زوونئ انتخاب کۀن  گِ ویکی ویشتر وۀ ئۀؤۀ مۀنیوسِرئ.",
+       "config-back": "→ ئاهۀتن-بازگشت",
+       "config-continue": "ادامه-دؤم گرتن ←",
+       "config-page-language": "زوون",
+       "config-page-welcome": "خؤةش هةتینِ مدیا ویکی!",
+       "config-page-dbconnect": "اتصال به پایگاه داده",
+       "config-page-upgrade": "ارتقای نصب موجود",
+       "config-page-dbsettings": "تنظیمات پایگاه داده",
+       "config-page-name": "نؤم",
+       "config-page-options": "گزینۀل",
+       "config-page-install": "نۀصب",
+       "config-page-complete": "انجؤم دریا-انجؤم هنگت",
+       "config-page-restart": "راه‌اندازی دوواره نصب",
+       "config-page-readme": "بخؤۀن ئۀرانم",
+       "config-page-releasenotes": "یادداشت‌های انتشار",
+       "config-page-copying": "کپی",
+       "config-page-upgradedoc": "ارتقاء",
+       "config-page-existingwiki": "ویکی موجود",
+       "config-help-restart": "آیا می‌خواهید همهٔ اطلاعات ذخیره شده‌ای که وارد کرده‌اید را پاک کنید و دوباره روند نصب را شروع کنید؟",
+       "config-restart": "أرێ، دوواره راه‌اندازی کة",
+       "config-welcome": "===بررسی‌های محیطی===\nبرای فهمیدن اینکه این محیط برای نصب مدیاویکی مناسب است، اکنون بررسی‌های اساسی انجام خواهد‌شد.\nاگر به دنبال پشتیبانی در چگونگی تکمیل نصب هستید،به یاد داشته باشید این اطلاعات را بگنجانید.",
+       "config-copyright": "===حق چاپ و شرایط===\n$1\nاین برنامه، یک نرم‌افزاری آزاد است. شما می‌توانید آن را بازتوزیع کرده و/یا با شرایط نگارش ۲ یا (با نظر خودتان) هر نگارش جدیدتری از پروانه جامع همگانی گنو که توسط بنیاد نرم‌افزار آزاد منتشر شده، تغییر دهید.\n\nاین برنامه با امید این که مفید واقع‌ شود توزیع شده‌است،اما '''بدون هیچ ضمانتی'''; حتی بدون اشارهٔ ضمانتی از '''قابلیت عرضه''' یا ''' صلاحیت برای یک هدف خاص'''.\nبرای جزئیات بیش‌تر پروانه جامع همگانی گنو را مشاهده کنید.\n\nشما باید <doclink href=Copying> یک نگارش ازمجوز عمومی کلی </doclink> همراه این برنامه دریافت کرده باشید. در غیر این صورت با بنیاد نرم‌افزار آزاد، ایالات متحده امریکا، بوستون، خیابان فرانکلین، پلاک ۵۱، طبقه پنجم، صندوق پستی MA۰۲۱۱۰-۱۳۰ مکاتبه کنید، یا [http://www.gnu.org/copyleft/gpl.html در این‌جا به صورت برخط بخوانید].",
+       "config-sidebar": "* [//www.mediawiki.org وةڵگة اصلی مدیاویکی]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents راهنمای کاربر]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents راهنمای مدیر]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ پرسش‌های رایج]\n----\n* <doclink href=Readme>مرا بخوان</doclink>\n* <doclink href=ReleaseNotes>یادداشت‌های انتشار</doclink>\n* <doclink href=Copying>نسخه برداری</doclink>\n* <doclink href=UpgradeDoc>ارتقا</doclink>",
+       "config-env-good": "محیط بررسی شده‌است.\nشما می‌توانید مدیاویکی را نصب کنید.",
+       "config-env-bad": "محیط بررسی شده‌است.\nشما نمی‌توانید مدیاویکی را نصب کنید.",
+       "config-env-php": "پی‌اچ‌پی $1 نصب شده‌است.",
+       "config-env-hhvm": "HHVM $1 نصب شده‌است.",
+       "config-unicode-using-intl": "برای یونیکد عادی از [http://pecl.php.net/intl intl PECL extension] استفاده کنید.",
+       "config-unicode-pure-php-warning": "'''هشدار:''' [http://pecl.php.net/intl intl PECL extension] برای کنترل یونیکد عادی در دسترس نیست،اجرای کاملاً آهسته به تعویق می‌افتد.\nاگر شما یک سایت پر‌ ترافیک را اجرا می‌کنید، باید کمی [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization] را بخوانید.",
+       "config-unicode-update-warning": "'''هشدار:''' نسخهٔ نصب شدهٔ پوشهٔ یونیکد عادی از ورژن قدیمی‌تر کتابخانه [http://site.icu-project.org/ the ICU project's] استفاده می‌کند.\nاگر کلاً علاقه‌مند به استفاده از یونیکد هستید باید [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations upgrade].",
+       "config-no-db": "درایور پایگاه اطلاعاتی مناسب پیدا نشد! شما لازم دارید یک درایور پایگاه اطلاعاتی  برای پی‌اچ‌پی نصب کنید.انواع پایگاه اطلاعاتی زیر پشتیبانی شده‌اند:$1.\nاگر شما در گروه اشتراک‌گذاری هستید، از تهیه کنندهٔ گروه خود برای نصب یک درایور پایگاه اطلاعاتی مناسب {{PLURAL:$2|سوأل کنید.|پرسش کنید.}}\nاگر خود، پی‌اچ‌پی را تهیه کرده‌اید، با یک پردازشگر فعال دوباره پیکربندی کنید، برای مثال از <code>./configure --with-mysql</code> استفاده کنید.\nاگر پی‌اچ‌پی را از یک بستهٔ دبیان یا آبونتو نصب کرده‌اید، بنابراین لازم دارید بخش php5-mysql را نصب کنید.",
+       "config-outdated-sqlite": "''' هشدار:''' شما اس‌کیولایت $1 دارید، که پایین‌تر از حداقل نسخهٔ $2 مورد نیاز است.اس‌کیولایت در دسترس نخواهد بود.",
+       "config-no-fts3": "'''هشدار:''' اس‌کیولایت بدون [//sqlite.org/fts3.html FTS3 module] تهیه شده‌است ، جستجوی ویژگی‌ها در این بخش پیشین در دسترس نخواهد‌بود.",
+       "config-register-globals-error": "<strong>خطا:  پی‌اچ‌پی<code>[http://php.net/register_globals register_globals]</code> گزینه فعال است.\nبرای ادامه نصب باید غیر فعال باشد.</strong>\n[Https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] را برای کمک در مورد نحوه انجام این کار ببینید.",
+       "config-magic-quotes-gpc": "<strong>هشدار مهم: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc] فعال شده‌است!</strong>\nاین گزینه اطلاعات داده شده به رایانه را به طور غیر‌قابل پیش‌بینی از بین می‌برد.\nشما نمی‌توانید مدیاویکی را نصب یا استفاده کنید مگر اینکه این گزینه غیر‌فعال باشد.",
+       "config-magic-quotes-runtime": "'''مخرب: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime] فعال است.\nاین گزینه اطلاعات داده شده به رایانه را به طور غیر‌قابل پیش‌بینی از بین می‌برد.\nشما نمی‌توانید مدیاویکی را نصب یا استفاده کنید مگر اینکه این گزینه غیر‌فعال باشد.",
+       "config-magic-quotes-sybase": "<strong>هشدار مهم: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc] فعال شده‌است!</strong>\nاین گزینه اطلاعات داده شده به رایانه را به طور غیر‌قابل پیش‌بینی از بین می‌برد.\nشما نمی‌توانید مدیاویکی را نصب یا استفاده کنید مگر اینکه این گزینه غیر‌فعال باشد.",
+       "config-mbstring": "''' مخرب:[http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload] فعال است.\nاین گزینه باعث ایجاد خطا می‌شود و ممکن است اطلاعات را به طور غیر‌قابل پیش‌بینی از بین ببرد.\nشما نمی‌توانید مدیاویکی را نصب یا استفاده کنید مگر اینکه این گزینه غیر‌فعال باشد.",
+       "config-safe-mode": "'''هشدار:'''  PHP's [http://www.php.net/features.safe-mode safe mode] فعال است.\nممکن است باعث ایجاد مشکلاتی شود، مخصوصاً اگر از ارسال پرونده استفاده شود و <code>math</code> پشتیبانی شود.",
+       "config-xml-bad": "ماژول اکس‌ام‌ال پی‌اچ‌پی کار نمی‌کند.\nمدیاویکی نیازمند عملیاتی در این ماژول است و در این پیکربندی کار نخواهد‌کرد.\nشاید نیاز باشد که بستهٔ نرم افزاریِ آرپی‌ام پی‌اچ‌پی-ایکس‌ام‌ال را نصب کنید.",
+       "config-pcre-old": "''' خطای اساسی:'' ' PCRE  $1  یا بعدا مورد نیاز است.\nکد باینری پی‌اچ‌پی‌تان با PCRE  $2 پیوند دارد.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE اطلاعات بیشتر].",
+       "config-pcre-no-utf8": "'''مخرب:''' به‌ نظر می‌رسد ماژول پی‌سی‌آرایی پی‌اچ‌پی بدون پشتیبانی پی‌سی‌آرایی_یو‌تی‌اف۸ تهیه شده‌است.\nمدیاویکی برای درست عمل کردن نیازمند پشتیبانی یوتی‌اف-۸ است.",
+       "config-memory-raised": "PHP's <code>memory_limit</code>, نسخهٔ $1 است، به نسخهٔ $2 ارتقاء داده شده‌است.",
+       "config-memory-bad": "'''هشدار:''' PHP's <code>memory_limit</code> نسخهٔ $1 است.\nاین ممکن است خیلی پایین باشد.\nممکن است نصب با مشکل رو‌به‌رو شود.",
+       "config-ctype": "'''مخرب:''' پی‌اچ‌پی باید با پشتیبانی برای [http://www.php.net/manual/en/ctype.installation.php Ctype extension] تهیه شده‌باشد.",
+       "config-db-type": "نوع پایگاه اطلاعات:",
+       "config-db-host": "میزبان پایگاه اطلاعات:",
+       "config-db-host-oracle": "ای ویکیۀ  شناسایی کۀ.",
+       "config-db-name": "نام پایگاه اطلاعات:",
+       "config-upgrade-done": "تکمیل ارتقاء.\nاکنون شما می‌توانید [$1 start using your wiki].\nاگر می‌خواهید پوشهٔ <code>LocalSettings.php</code> را احیا کنید،دکمهٔ زیر را کلیک کنید.\nاین ''' توصیه نمی‌شود ''' مگر اینکه با ویکی خود مشکل داشته باشید.",
+       "config-site-name-blank": "نام سایتئ وارد کۀن.",
+       "config-ns-generic": "پروژۀ",
+       "config-admin-box": "حساوو مدیر سامانه",
+       "config-admin-name": "نام کاربری هؤمۀ:",
+       "config-admin-password": ":رمز",
+       "config-admin-password-confirm": "رمز دووآرۀ:",
+       "config-admin-email": ":نیشانی رایانامۀ",
+       "config-optional-continue": "پرسشۀلی تریژ بپر إژ مِ",
+       "config-profile-wiki": "واز کردن ویکی",
+       "config-email-user-help": "به همهٔ کاربرانی که ارسال ایمیل را در ترجیحات خود فعال کرده‌اند، اجازه داده خواهد شد که به یکدیگر ایمیل ارسال کنند.",
+       "config-email-usertalk-help": "به همهٔ کاربرانی که دریافت اطلاعیه را در اولویت‌های خود فعال کرده‌اند،اجازه خواهد داده‌شد که اطلاعیه‌ها را در صفحهٔ تغییر گفت‌وگوی کاربر دریافت کنند.",
+       "config-email-watchlist-help": "به همهٔ کاربرانی که مشاهدهٔ صفحه را در اولویت‌های خود فعال کرده‌اند،اجازه خواهد داده‌شد که اطلاعیه‌های در رابطه با صفحات مشاهده شده را دریافت کنند.",
+       "config-install-step-done": "انجؤم بی"
+}
index b7187e2..5d4c5d7 100644 (file)
        "config-upload-deleted": "Папка за избришаните податотеки:",
        "config-upload-deleted-help": "Одберете во која папка да се архивираат избришаните податотеки.\nНајдобро би било ако таа не е достапна преку семрежјето.",
        "config-logo": "URL за логото:",
-       "config-logo-help": "Ð\9cаÑ\82иÑ\87ноÑ\82о Ñ\80Ñ\83во Ð½Ð° Ð\9cедиÑ\98аÐ\92ики Ð¸Ð¼Ð° Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ð·Ð° Ð»Ð¾Ð³Ð¾ Ð¾Ð´ 135x160 Ð¿Ð¸ÐºÑ\81ели Ð½Ð°Ð´ Ñ\81Ñ\82Ñ\80аниÑ\87наÑ\82а Ð»ÐµÐ½Ñ\82а.\n\nМожете да употребите <code>$wgStylePath</code> или <code>$wgScriptPath</code> ако вашето лого е релативно на тие патеки.\n\nАко не сакате да имате лого, тогаш оставете го ова поле празно.",
+       "config-logo-help": "Ð\9cаÑ\82иÑ\87ноÑ\82о Ñ\80Ñ\83во Ð½Ð° Ð\9cедиÑ\98аÐ\92ики Ð¸Ð¼Ð° Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ð·Ð° Ð»Ð¾Ð³Ð¾ Ð¾Ð´ 135x160 Ð¿Ð¸ÐºÑ\81ели Ð½Ð°Ð´ Ñ\81Ñ\82Ñ\80аниÑ\87никоÑ\82.\n\nМожете да употребите <code>$wgStylePath</code> или <code>$wgScriptPath</code> ако вашето лого е релативно на тие патеки.\n\nАко не сакате да имате лого, тогаш оставете го ова поле празно.",
        "config-instantcommons": "Овозможи Instant Commons",
        "config-instantcommons-help": "[//www.mediawiki.org/wiki/InstantCommons Instant Commons] е функција која им овозможува на викијата да користат слики, звучни записи и други мултимедијални содржини од [//commons.wikimedia.org/ Ризницата].\nЗа да може ова да работи, МедијаВики бара пристап до семрежјето.\n\nЗа повеќе информации за оваа функција и напатствија за нејзино поставување на вики (сите други освен Ризницата), коносултирајте го [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos прирачникот].",
        "config-cc-error": "Изборникот на лиценци од Криејтив комонс не даде резултати.\nВнесете го името на лиценцата рачно.",
index 76d8ac1..1157aa8 100644 (file)
@@ -5,40 +5,92 @@
                        "Suyog"
                ]
        },
+       "config-desc": "मिडियाविकि करीता उभारक(ईन्स्टॉलर)",
+       "config-title": "मिडियाविकि $1 उभारणी",
        "config-information": "माहिती",
+       "config-localsettings-upgrade": "<code>LocalSettings.php</code>ही संचिका संसुचित झाली.या उभारणीची दर्जोन्नती करण्यास,खालील पेटीत कृपया <code>$wgUpgradeKey</code> ची किंमत टाका. ती आपणास<code>LocalSettings.php</code>मध्ये सापडेल.",
+       "config-localsettings-cli-upgrade": "<code>LocalSettings.php</code>ही संचिका संसुचित झाली.या उभारणीची दर्जोन्नती करण्यास त्याऐवजी,कृपया<code>update.php</code>चालवा",
        "config-localsettings-key": "दर्जोन्नती कळ:",
        "config-localsettings-badkey": "आपण दिलेली कळ चुकीची आहे.",
+       "config-upgrade-key-missing": "मिडियाविकिचे अस्तित्वात असलेली उभारणी संसुचित झाली आहे.या उभारणीची दर्जोन्नती करण्यास,आपल्या <code>LocalSettings.php</code>च्या खाली असलेल्या ओळीत खालील टाका:\n\n$1",
+       "config-localsettings-incomplete": "अस्तित्वात असलेला <code>LocalSettings.php</code>अपूर्ण दिसत आहे.\n$1 हे चल स्थापिलेले नाही.<code>LocalSettings.php</code> कृपया बदला ज्याने,हे चल स्थापिले जाईल व त्यानंतर \"{{int:Config-continue}}\" टिचका.",
+       "config-localsettings-connection-error": "<code>LocalSettings.php</code> मधील नमूद मांडण्या वापरुन विदागाराशी अनुबंध करतांना एक त्रुटी उद्भवली.\nकृपया या मांडण्या सुधरवुन पुन्हा प्रयत्न करा.\n\n$1",
        "config-session-error": "सत्र सुरू करण्यात त्रुटी:$1",
+       "config-session-expired": "आपला सत्र डाटा कालबाह्य झाला आहे असे दिसते.\n$1 या हयातवेळेशी सत्र रचित असते.\nphp.ini मधिल <code>session.gc_maxlifetime</code> द्वारे आपण त्या वेळेस वाढवु शकता.\nउभारणीची प्रक्रिया पुन्हा सुरू करा.",
+       "config-no-session": "आपला सत्र डाटा हरविला आहे!\nआपली php.ini तपासा व याची खात्री करा कि <code>session.save_path</code> हा योग्य डिरेक्टरीत स्थापिला आहे.",
        "config-your-language": "आपली भाषा:",
        "config-your-language-help": "उभारणी प्रक्रियेत वापरावयाची भाषा निवडा.",
        "config-wiki-language": "विकी भाषा:",
-       "config-wiki-language-help": "तà¥\81मà¤\9aà¥\80 à¤²à¥\87à¤\96न à¤­à¤¾à¤·à¤¾ à¤¨à¤¿à¤µà¤¡à¤¾",
+       "config-wiki-language-help": "à¤\9cà¥\8dयात à¤µà¤¿à¤\95ि à¤ªà¥\8dरबळरितà¥\8dया à¤²à¤¿à¤¹à¥\80ला à¤\9cाà¤\88ल à¤\85शà¥\80 à¤¤à¥\81मà¤\9aà¥\80 à¤²à¥\87à¤\96न à¤­à¤¾à¤·à¤¾ à¤¨à¤¿à¤µà¤¡à¤¾.",
        "config-back": "← परत",
        "config-continue": "चालू ठेवा →",
        "config-page-language": "भाषा",
        "config-page-welcome": "मिडियाविकीवर स्वागत आहे!",
+       "config-page-dbconnect": "डाटाबेसशी अनुबंध करा",
        "config-page-upgrade": "सध्याच्या उभारणीची(इन्स्टॉलेशन) दर्जोन्नती करा",
+       "config-page-dbsettings": "डाटाबेसच्या मांडण्या",
        "config-page-name": "नाव",
        "config-page-options": "पर्याय",
        "config-page-install": "स्थापित करा(इन्स्टॉल)",
        "config-page-complete": "पूर्ण!",
+       "config-page-restart": "उभारणीस पुन्हा सुरू करा",
        "config-page-readme": "हे वाचा",
        "config-page-releasenotes": "विमोचन टिप्पण्या",
-       "config-page-existingwiki": "साध्याचा विकि",
-       "config-restart": "हो, परत चालू करा",
+       "config-page-copying": "नकलवित आहे",
+       "config-page-upgradedoc": "दर्जोन्नती करीत आहे",
+       "config-page-existingwiki": "सध्याचा विकि",
+       "config-help-restart": "आपण टाकून जतन केलेला सर्व डाटा आपणास साफ करावयाचा व उभारणीची प्रक्रिया पुन्हा सुरू करावयाची आहे काय?",
+       "config-restart": "होय, परत चालू करा",
+       "config-welcome": "=== पारिसरीक तपासण्या ===\nमिडियाविकिच्या उभारणीस हा परिसर योग्य आहे काय याच्या मूळ तपासण्या आता केल्या जातील.\nजर आपणास पुढे याची उभारणी करण्याबद्दल साहाय्य लागल्यास, याचा अंतर्भाव करणे लक्षात ठेवा.",
+       "config-copyright": "=== प्रताधिकार व अटी ===\n\n$1\nहा कार्यसंच,हे एक मुक्त संचेतन आहे;आपण त्यास पुनर्वितरीत व/किंवा त्यास फ्री सॉफ्टवेअर फाऊंडेशन द्वारे प्रकाशित, GNU जनरल पब्लिक लायसन्स अंतर्गत बदलु शकता;या परवान्याची आवृत्ती २ किंवा (आपल्या इच्छेनुसार)त्यानंतरची आवृत्ती.\n\nहा कार्यसंचाचे वितरण,पण, <strong>कोणत्याही हमीशिवाय</strong>; याशिवाय <strong>व्यापारीकरणाच्या</strong> कोणत्याही अभिप्रेत आश्वासनाशिवाय किंवा <strong>एखाद्या विशिष्ट कार्यासाठीच्या अर्हतेशिवाय</strong>ही आशा ठेऊन केले आहे कि, तो उपयोगी असेल.\nअधिक माहितीसाठी GNU जनरल पब्लिक लायसन्स बघा.\nआपणास या कार्यसंचासमवेत <doclink href=Copying>GNU जनरल पब्लिक लायसन्सची प्रत मिळाली असेल,</doclink>नसल्यास,फ्री सॉफ्टवेअर फाऊंडेशनला या पत्त्यावर लिहा.Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. किंवा त्यास [http://www.gnu.org/copyleft/gpl.html ऑनलाईन वाचा].",
+       "config-sidebar": "* [//www.mediawiki.org मिडियाविकि गृह]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents सदस्य मार्गदर्शिका]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents प्रशासकाची मार्गदर्शिका]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ]\n----\n* <doclink href=Readme>Read me</doclink>\n* <doclink href=ReleaseNotes>विमोचन टिप्पण्या</doclink>\n* <doclink href=Copying>नकलविणे</doclink>\n* <doclink href=UpgradeDoc>दर्जोन्नती करणे</doclink>",
+       "config-env-good": "पारिसरीक तपासणी झाली आहे.\nआपण मिडियाविकि उभारू शकता.",
+       "config-env-bad": "पारिसरीक तपासणी झाली आहे.\nआपण मिडियाविकि उभारू शकत नाही.",
+       "config-env-php": "PHP $1 उभारल्या गेली.",
+       "config-env-hhvm": "HHVM $1 उभारल्या गेली.",
+       "config-unicode-using-intl": "यूनिकोड सामान्यिकरणासाठी [http://pecl.php.net/intl intl PECL विस्तारक] वापरत आहे.",
+       "config-outdated-sqlite": "<strong>इशारा:</strong> आपणापाशी SQLite $1 आहे, जी किमान आवश्यक आवृत्ती $2 पेक्षा, निम्न आहे. SQLite अनुपलब्ध राहील.",
+       "config-register-globals-error": "<strong>त्रुटी: PHP's <code>[http://php.net/register_globals वैश्विकांची नोंद करा]</code> पर्याय सक्षम केला आहे. उभारणी सुरू ठेवण्यास तो अक्षम केल्या जावयास हवा.</strong>ते कसे करावयाचे याच्या साहाय्यासाठी\n[https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] बघा.",
+       "config-magic-quotes-gpc": "<strong>घातक: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc] सक्रिय आहे!</strong>\nहा पर्याय, अंदाज येऊ न देता, डाटा इनपुटला भ्रष्ट करते.\nआपण हा पर्यास अक्षम केल्याशिवाय मिडियाविकिची उभारणी किंवा वापर करु शकत नाही.",
+       "config-magic-quotes-runtime": "<strong>घातक: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime] सक्रिय आहे!</strong>\nहा पर्याय, अंदाज येऊ न देता, डाटा इनपुटला भ्रष्ट करते.\nआपण हा पर्यास अक्षम केल्याशिवाय मिडियाविकिची उभारणी किंवा वापर करु शकत नाही.",
+       "config-magic-quotes-sybase": "<strong>घातक: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase] सक्रिय आहे!</strong>\nहा पर्याय, अंदाज येऊ न देता, डाटा इनपुटला भ्रष्ट करते.\nआपण हा पर्यास अक्षम केल्याशिवाय मिडियाविकिची उभारणी किंवा वापर करु शकत नाही.",
+       "config-memory-raised": "पीएचपीची <code>memory_limit</code> ही $1 आहे, त्यास $2 ला वाढविली.",
+       "config-memory-bad": "पीएचपीची <code>memory_limit</code> ही $1 आहे.\nही बरीच खालच्या स्तरावरची आहे.\nउभारणी अयशस्वी होऊ शकते!",
+       "config-ctype": "<strong>घातक:</strong> पीएचपीचे [http://www.php.net/manual/en/ctype.installation.php Ctype या विस्तारकाशी] साहाय्य करण्यास संकलन करावे लागेल.",
+       "config-iconv": "<strong>घातक:</strong> पीएचपीचे [http://www.php.net/manual/en/iconv.installation.php iconv या विस्तारकाशी]साहाय्य करण्यास संकलन करावे लागेल.",
+       "config-xcache": "[http://xcache.lighttpd.net/ XCache] उभारली",
+       "config-apc": "[http://www.php.net/apc APC] उभारली आहे",
+       "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] उभारली आहे",
+       "config-no-cache": "<strong>इशारा:</strong>  [http://www.php.net/apc APC], [http://xcache.lighttpd.net/ XCache] किंवा [http://www.iis.net/download/WinCacheForPhp WinCache] सापडली नाही.\nउद्दीष्टाचे कॅश करणे सक्षम नाही.",
+       "config-diff3-bad": "GNU diff3 सापडली नाही.",
+       "config-git-bad": "गीट आवृत्ती नियमन संचेतन सापडली नाही.",
+       "config-db-type": "डाटाबेसचा प्रकार:",
+       "config-db-host": "डाटाबेसचा यजमान:",
+       "config-db-name": "डाटाबेसचे नाव:",
+       "config-db-name-oracle": "डाटाबेस आकृतीबंध:",
+       "config-db-install-account": "उभारणीसाठी सदस्य खाते",
+       "config-db-username": "डाटाबेसवरील सदस्यनाव:",
+       "config-db-password": "डाटाबेसवरील परवलीचा शब्द:",
+       "config-db-prefix": "डाटाबेस सारणी उपसर्ग:",
+       "config-db-port": "डाटाबेस द्वार:",
        "config-pg-test-error": "विदागाराशी अनुबंधन करता येत नाही <strong>$1</strong>: $2",
        "config-type-mssql": "मायक्रोसॉफ्ट एसक्युएल सर्व्हर",
        "config-header-mssql": "मायक्रोसॉफ्ट एसक्युएल सर्व्हर मांडणावळ",
+       "config-invalid-db-type": "डाटाबेसचा अवैध प्रकार.",
+       "config-connection-error": "$1.\n\nयजमान,सदस्यनाव व परवलीचा शब्द तपासा व पुन्हा प्रयत्न करा.",
        "config-mssql-old": "मायक्रोसॉफ्ट एसक्युएल सर्व्हर $1 किंवा त्यानंतरची आवृत्ती हवी. आपणापाशी $2 आहे.",
+       "config-upgrade-done-no-regenerate": "दर्जोन्नती पूर्ण.\n\nआपण आता [$1 आपला विकिचा वापर करु शकता].",
        "config-mssql-auth": "अधिप्रमाणन प्रकार:",
        "config-mssql-install-auth": "उभारणीच्या(इन्स्टॉलेशन) प्रक्रियेदरम्यान,'अधिप्रमाणन प्रकार'( ऑथेंटीकेशन टाईप) निवडा, ज्याचा वापर डाटाबेसशी अनुबंधनात करण्यात येईल.जर आपण \"{{int:config-mssql-windowsauth}} निवडले तर,ज्याकोणत्याही सदस्याची अधिकारपत्रे(क्रेडेंटियल्स) वेबसर्व्हरवर सुरू असतील,तशीच वापरल्या जातील.",
        "config-mssql-web-auth": "'अधिप्रमाणन प्रकार'( ऑथेंटीकेशन टाईप) निवडा, ज्यास,या विकिचे सामान्य चालनादरम्यान, वेब सर्व्हर हा डाटाबेसशी अनुबंधन करण्यास वापरेल.जर आपण\"{{int:config-mssql-windowsauth}}\" निवडले तर,ज्याकोणत्याही सदस्याची अधिकारपत्रे(क्रेडेंटियल्स) वेबसर्व्हरवर सुरू असतील,तशीच वापरल्या जातील.",
        "config-mssql-sqlauth": "एसक्युएल सर्व्हर अधिप्रमाणन",
        "config-mssql-windowsauth": "विंडोजचे अधिप्रमाणन",
        "config-site-name": "विकिचे नाव:",
+       "config-site-name-help": "हे न्याहाळकाच्या शीर्षक पट्टीत व इतर ठिकाणीही दिसेल .",
        "config-site-name-blank": "संकेतस्थळाचे नाव टाका.",
        "config-project-namespace": "प्रकल्प नामविश्व:",
        "config-ns-generic": "प्रकल्प",
+       "config-ns-site-name": "विकि नावाप्रमाणेच: $1",
        "config-admin-name": "आपले सदस्यनाव:",
        "config-admin-password": "परवलीचा शब्द:",
        "config-admin-password-confirm": "परवलीचा शब्द पुन्हा टाका:",
        "config-install-tables-failed": "<strong>त्रुटी:</strong>खालील त्रुटीमुळे सारणी बनविणे अयशस्वी:$1",
        "config-help": "साहाय्य",
        "mainpagetext": "'''मीडियाविकीचे इन्स्टॉलेशन पूर्ण.'''",
-       "mainpagedocfooter": "विà¤\95à¥\80 à¤¸à¥\89फà¥\8dà¤\9fवà¥\87à¤\85र à¤µà¤¾à¤ªà¤°à¤£à¥\8dयाà¤\95रिता [//meta.wikimedia.org/wiki/Help:Contents à¤¯à¥\82à¤\9cर à¤\97ाà¤\88ड] à¤ªà¤¹à¤¾.\n\n== à¤¸à¥\81रà¥\81वात à¤\95रा ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings à¤°à¤\9aित à¤®à¤¾à¤\82डणà¥\8dयाà¤\9aà¥\80 à¤¯à¤¾à¤¦à¥\80]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95ि FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-मिडियाविà¤\95िà¤\9aà¥\80 à¤®à¥\87लिà¤\82à¤\97 à¤¯à¤¾à¤¦à¥\80à¤\9aà¥\87 à¤µà¤¿à¤®à¥\8bà¤\9aनाà¤\9aà¥\80 à¤\89दà¥\8dà¤\98à¥\8bषणाannounce MediaWiki release mailing list]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources à¤\86पलà¥\8dया à¤­à¤¾à¤·à¥\87साठà¥\80 à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95िà¤\9aà¥\87 à¤¸à¥\8dथानिà¤\95िà¤\95रण à¤\95रा]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam à¤\86पलà¥\8dया à¤µà¤¿à¤\95िवर à¤¸à¥\8dपà¥\85मशà¥\80 à¤¦à¥\8bन à¤¹à¤¾à¤¤ à¤\95शे करावे ते शिका]"
+       "mainpagedocfooter": "विà¤\95à¥\80 à¤¸à¥\89फà¥\8dà¤\9fवà¥\87à¤\85र à¤µà¤¾à¤ªà¤°à¤£à¥\8dयाà¤\95रिता [//meta.wikimedia.org/wiki/Help:Contents à¤µà¤¾à¤ªà¤°à¤\95रà¥\8dता à¤®à¤¾à¤°à¥\8dà¤\97दरà¥\8dशिà¤\95ा] à¤ªà¤¹à¤¾.\n\n== à¤¸à¥\81रà¥\81वात à¤\95रा ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings à¤°à¤\9aित à¤®à¤¾à¤\82डणà¥\8dयाà¤\9aà¥\80 à¤¯à¤¾à¤¦à¥\80]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95ि FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-मिडियाविà¤\95िà¤\9aà¥\80 à¤®à¥\87लिà¤\82à¤\97 à¤¯à¤¾à¤¦à¥\80à¤\9aà¥\87 à¤µà¤¿à¤®à¥\8bà¤\9aनाà¤\9aà¥\80 à¤\89दà¥\8dà¤\98à¥\8bषणा]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources à¤\86पलà¥\8dया à¤­à¤¾à¤·à¥\87साठà¥\80 à¤®à¤¿à¤¡à¤¿à¤¯à¤¾à¤µà¤¿à¤\95िà¤\9aà¥\87 à¤¸à¥\8dथानिà¤\95िà¤\95रण à¤\95रा]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam à¤\86पलà¥\8dया à¤µà¤¿à¤\95िवर à¤¸à¥\8dपà¥\85मशà¥\80 à¤¦à¥\8bन à¤¹à¤¾à¤¤ à¤\95से करावे ते शिका]"
 }
index c4ccec6..c987980 100644 (file)
        "config-nofile": "Файл \"$1\" не удается найти. Он был удален?",
        "config-extension-link": "Знаете ли вы, что ваш вики-проект поддерживает [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions расширения]?\n\nВы можете просмотреть [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category расширения по категориям] или [//www.mediawiki.org/wiki/Extension_Matrix матрицу расширений], чтобы увидеть их полный список.",
        "mainpagetext": "'''Вики-движок «MediaWiki» успешно установлен.'''",
-       "mainpagedocfooter": "Информацию по работе с этой вики можно найти в [//meta.wikimedia.org/wiki/Help:Contents/ru справочном руководстве].\n\n== Некоторые полезные ресурсы ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список возможных настроек];\n* [//www.mediawiki.org/wiki/Manual:FAQ/ru Часто задаваемые вопросы и ответы по MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Перевод MediaWiki на свой язык]"
+       "mainpagedocfooter": "Информацию по работе с этой вики можно найти в [//meta.wikimedia.org/wiki/Help:Contents/ru справочном руководстве].\n\n== Некоторые полезные ресурсы ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список возможных настроек];\n* [//www.mediawiki.org/wiki/Manual:FAQ/ru Часто задаваемые вопросы и ответы по MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Перевод MediaWiki на свой язык]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Узнайте, как бороться со спамом в вашей вики]"
 }
index 69a3def..89948f4 100644 (file)
@@ -688,17 +688,6 @@ abstract class JobQueue {
                $stats->updateCount( "jobqueue.{$key}.all", $delta );
                $stats->updateCount( "jobqueue.{$key}.{$type}", $delta );
        }
-
-       /**
-        * Namespace the queue with a key to isolate it for testing
-        *
-        * @param string $key
-        * @return void
-        * @throws MWException
-        */
-       public function setTestingPrefix( $key ) {
-               throw new MWException( "Queue namespacing not supported for this queue type." );
-       }
 }
 
 /**
index 109ca01..07f2c93 100644 (file)
@@ -497,11 +497,4 @@ class JobQueueFederated extends JobQueue {
                        throw new JobQueueError( 'No queue partitions available.' );
                }
        }
-
-       public function setTestingPrefix( $key ) {
-               /** @var JobQueue $queue */
-               foreach ( $this->partitionQueues as $queue ) {
-                       $queue->setTestingPrefix( $key );
-               }
-       }
 }
index 78d2a36..546093f 100644 (file)
@@ -26,8 +26,9 @@
  *
  * This is a faster and less resource-intensive job queue than JobQueueDB.
  * All data for a queue using this class is placed into one redis server.
+ * The mediawiki/services/jobrunner background service must be set up and running.
  *
- * There are eight main redis keys used to track jobs:
+ * There are eight main redis keys (per queue) used to track jobs:
  *   - l-unclaimed  : A list of job IDs used for ready unclaimed jobs
  *   - z-claimed    : A sorted set of (job ID, UNIX timestamp as score) used for job retries
  *   - z-abandoned  : A sorted set of (job ID, UNIX timestamp as score) used for broken jobs
  * entry and every h-sha1ById must refer to an ID that is l-unclaimed. If a job has its
  * ID in z-claimed or z-abandoned, then it must also have an h-attempts entry for its ID.
  *
+ * The following keys are used to track queue states:
+ *   - s-queuesWithJobs : A set of all queues with non-abandoned jobs
+ *
+ * The background service takes care of undelaying, recycling, and pruning jobs as well as
+ * removing s-queuesWithJobs entries as queues empty.
+ *
  * Additionally, "rootjob:* keys track "root jobs" used for additional de-duplication.
  * Aside from root job keys, all keys have no expiry, and are only removed when jobs are run.
  * All the keys are prefixed with the relevant wiki ID information.
@@ -239,7 +246,8 @@ class JobQueueRedis extends JobQueue {
         * @throws RedisException
         */
        protected function pushBlobs( RedisConnRef $conn, array $items ) {
-               $args = array(); // ([id, sha1, rtime, blob [, id, sha1, rtime, blob ... ] ] )
+               $args = array( $this->encodeQueueName() );
+               // Next args come in 4s ([id, sha1, rtime, blob [, id, sha1, rtime, blob ... ] ] )
                foreach ( $items as $item ) {
                        $args[] = (string)$item['uuid'];
                        $args[] = (string)$item['sha1'];
@@ -248,10 +256,17 @@ class JobQueueRedis extends JobQueue {
                }
                static $script =
 <<<LUA
-               local kUnclaimed, kSha1ById, kIdBySha1, kDelayed, kData = unpack(KEYS)
-               if #ARGV % 4 ~= 0 then return redis.error_reply('Unmatched arguments') end
+               local kUnclaimed, kSha1ById, kIdBySha1, kDelayed, kData, kQwJobs = unpack(KEYS)
+               -- First argument is the queue ID
+               local queueId = ARGV[1]
+               -- Next arguments all come in 4s (one per job)
+               local variadicArgCount = #ARGV - 1
+               if variadicArgCount % 4 ~= 0 then
+                       return redis.error_reply('Unmatched arguments')
+               end
+               -- Insert each job into this queue as needed
                local pushed = 0
-               for i = 1,#ARGV,4 do
+               for i = 2,#ARGV,4 do
                        local id,sha1,rtimestamp,blob = ARGV[i],ARGV[i+1],ARGV[i+2],ARGV[i+3]
                        if sha1 == '' or redis.call('hExists',kIdBySha1,sha1) == 0 then
                                if 1*rtimestamp > 0 then
@@ -269,6 +284,8 @@ class JobQueueRedis extends JobQueue {
                                pushed = pushed + 1
                        end
                end
+               -- Mark this queue as having jobs
+               redis.call('sAdd',kQwJobs,queueId)
                return pushed
 LUA;
                return $conn->luaEval( $script,
@@ -279,10 +296,11 @@ LUA;
                                        $this->getQueueKey( 'h-idBySha1' ), # KEYS[3]
                                        $this->getQueueKey( 'z-delayed' ), # KEYS[4]
                                        $this->getQueueKey( 'h-data' ), # KEYS[5]
+                                       $this->getGlobalKey( 's-queuesWithJobs' ), # KEYS[6]
                                ),
                                $args
                        ),
-                       5 # number of first argument(s) that are keys
+                       6 # number of first argument(s) that are keys
                );
        }
 
@@ -328,15 +346,18 @@ LUA;
                static $script =
 <<<LUA
                local kUnclaimed, kSha1ById, kIdBySha1, kClaimed, kAttempts, kData = unpack(KEYS)
+               local rTime = unpack(ARGV)
                -- Pop an item off the queue
                local id = redis.call('rPop',kUnclaimed)
-               if not id then return false end
+               if not id then
+                       return false
+               end
                -- Allow new duplicates of this job
                local sha1 = redis.call('hGet',kSha1ById,id)
                if sha1 then redis.call('hDel',kIdBySha1,sha1) end
                redis.call('hDel',kSha1ById,id)
                -- Mark the jobs as claimed and return it
-               redis.call('zAdd',kClaimed,ARGV[1],id)
+               redis.call('zAdd',kClaimed,rTime,id)
                redis.call('hIncrBy',kAttempts,id,1)
                return redis.call('hGet',kData,id)
 LUA;
@@ -372,11 +393,12 @@ LUA;
                        static $script =
 <<<LUA
                        local kClaimed, kAttempts, kData = unpack(KEYS)
+                       local uuid = unpack(ARGV)
                        -- Unmark the job as claimed
-                       redis.call('zRem',kClaimed,ARGV[1])
-                       redis.call('hDel',kAttempts,ARGV[1])
+                       redis.call('zRem',kClaimed,uuid)
+                       redis.call('hDel',kAttempts,uuid)
                        -- Delete the job data itself
-                       return redis.call('hDel',kData,ARGV[1])
+                       return redis.call('hDel',kData,uuid)
 LUA;
                        $res = $conn->luaEval( $script,
                                array(
@@ -472,7 +494,10 @@ LUA;
                                $keys[] = $this->getQueueKey( $prop );
                        }
 
-                       return ( $conn->delete( $keys ) !== false );
+                       $ok = ( $conn->delete( $keys ) !== false );
+                       $conn->sRem( $this->getGlobalKey( 's-queuesWithJobs' ), $this->encodeQueueName() );
+
+                       return $ok;
                } catch ( RedisException $e ) {
                        $this->throwRedisException( $conn, $e );
                }
@@ -623,6 +648,27 @@ LUA;
                }
        }
 
+       /**
+        * @return array List of (wiki,type) tuples for queues with non-abandoned jobs
+        * @throws JobQueueConnectionError
+        * @throws JobQueueError
+        */
+       public function getServerQueuesWithJobs() {
+               $queues = array();
+
+               $conn = $this->getConnection();
+               try {
+                       $set = $conn->sMembers( $this->getGlobalKey( 's-queuesWithJobs' ) );
+                       foreach ( $set as $queue ) {
+                               $queues[] = $this->decodeQueueName( $queue );
+                       }
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $conn, $e );
+               }
+
+               return $queues;
+       }
+
        /**
         * @param IJobSpecification $job
         * @return array
@@ -703,7 +749,8 @@ LUA;
        protected function getConnection() {
                $conn = $this->redisPool->getConnection( $this->server );
                if ( !$conn ) {
-                       throw new JobQueueConnectionError( "Unable to connect to redis server." );
+                       throw new JobQueueConnectionError(
+                               "Unable to connect to redis server {$this->server}." );
                }
 
                return $conn;
@@ -720,25 +767,48 @@ LUA;
        }
 
        /**
-        * @param string $prop
-        * @param string|null $type
+        * @return string JSON
+        */
+       private function encodeQueueName() {
+               return json_encode( array( $this->type, $this->wiki ) );
+       }
+
+       /**
+        * @param string $name JSON
+        * @return array (type, wiki)
+        */
+       private function decodeQueueName( $name ) {
+               return json_decode( $name );
+       }
+
+       /**
+        * @param string $name
         * @return string
         */
-       private function getQueueKey( $prop, $type = null ) {
-               $type = is_string( $type ) ? $type : $this->type;
-               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
-               if ( strlen( $this->key ) ) { // namespaced queue (for testing)
-                       return wfForeignMemcKey( $db, $prefix, 'jobqueue', $type, $this->key, $prop );
-               } else {
-                       return wfForeignMemcKey( $db, $prefix, 'jobqueue', $type, $prop );
+       private function getGlobalKey( $name ) {
+               $parts = array( 'global', 'jobqueue', $name );
+               foreach ( $parts as $part ) {
+                   if ( !preg_match( '/[a-zA-Z0-9_-]+/', $part ) ) {
+                       throw new InvalidArgumentException( "Key part characters are out of range." );
+                   }
                }
+
+               return implode( ':', $parts );
        }
 
        /**
-        * @param string $key
-        * @return void
+        * @param string $prop
+        * @param string|null $type Override this for sibling queues
+        * @return string
         */
-       public function setTestingPrefix( $key ) {
-               $this->key = $key;
+       private function getQueueKey( $prop, $type = null ) {
+               $type = is_string( $type ) ? $type : $this->type;
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               $keyspace = $prefix ? "$db-$prefix" : $db;
+
+               $parts = array( $keyspace, 'jobqueue', $type, $prop );
+
+               // Parts are typically ASCII, but encode for sanity to escape ":"
+               return implode( ':', array_map( 'rawurlencode', $parts ) );
        }
 }
index af836bc..2073b0f 100644 (file)
@@ -11,7 +11,7 @@ The data model consist of the following main components:
   background. All jobs subclass the Job object and put the main logic in the
   function called run().
 * The JobQueue object represents a particular queue of jobs of a certain type.
-  For example there may be a queue for email jobs and a queue for squid purge
+  For example there may be a queue for email jobs and a queue for CDN purge
   jobs.
 
 \section jobqueue Job queues
@@ -45,7 +45,7 @@ In-memory queues may lose data when restarted depending on snapshot and journal
 settings (including journal fsync() frequency).  Some queue types may totally remove
 jobs when dequeued while leaving the ack() function as a no-op; if a job is
 dequeued by a job runner, which crashes before completion, the job will be
-lost. Some jobs, like purging squid caches after a template change, may not
+lost. Some jobs, like purging CDN caches after a template change, may not
 require durable queues, whereas other jobs might be more important.
 
 \section aggregator Job queue aggregator
diff --git a/includes/jobqueue/jobs/CategoryMembershipChangeJob.php b/includes/jobqueue/jobs/CategoryMembershipChangeJob.php
new file mode 100644 (file)
index 0000000..c9e20a9
--- /dev/null
@@ -0,0 +1,234 @@
+<?php
+/**
+ * Updater for link tracking tables after a page edit.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Job to add recent change entries mentioning category membership changes
+ *
+ * Parameters include:
+ *   - pageId : page ID
+ *   - revTimestamp : timestamp of the triggering revision
+ *
+ * Category changes will be mentioned for revisions at/after the timestamp for this page
+ *
+ * @since 1.27
+ */
+class CategoryMembershipChangeJob extends Job {
+       const ENQUEUE_FUDGE_SEC = 60;
+
+       public function __construct( Title $title, array $params ) {
+               parent::__construct( 'categoryMembershipChange', $title, $params );
+               // Only need one job per page. Note that ENQUEUE_FUDGE_SEC handles races where an
+               // older revision job gets inserted while the newer revision job is de-duplicated.
+               $this->removeDuplicates = true;
+       }
+
+       public function run() {
+               $page = WikiPage::newFromID( $this->params['pageId'], WikiPage::READ_LATEST );
+               if ( !$page ) {
+                       $this->setLastError( "Could not find page #{$this->params['pageId']}" );
+                       return false; // deleted?
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               // Use a named lock so that jobs for this page see each others' changes
+               $fname = __METHOD__;
+               $lockKey = "CategoryMembershipUpdates:{$page->getId()}";
+               if ( !$dbw->lock( $lockKey, $fname, 10 ) ) {
+                       $this->setLastError( "Could not acquire lock '$lockKey'" );
+                       return false;
+               }
+
+               $unlocker = new ScopedCallback( function () use ( $dbw, $lockKey, $fname ) {
+                       $dbw->unlock( $lockKey, $fname );
+               } );
+
+               // Sanity: clear any DB transaction snapshot
+               $dbw->commit( __METHOD__, 'flush' );
+
+               $cutoffUnix = wfTimestamp( TS_UNIX, $this->params['revTimestamp'] );
+               // Using ENQUEUE_FUDGE_SEC handles jobs inserted out of revision order due to the delay
+               // between COMMIT and actual enqueueing of the CategoryMembershipChangeJob job.
+               $cutoffUnix -= self::ENQUEUE_FUDGE_SEC;
+
+               // Get the newest revision that has a SRC_CATEGORIZE row...
+               $row = $dbw->selectRow(
+                       array( 'revision', 'recentchanges' ),
+                       array( 'rev_timestamp', 'rev_id' ),
+                       array(
+                               'rev_page' => $page->getId(),
+                               'rev_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $cutoffUnix ) )
+                       ),
+                       __METHOD__,
+                       array( 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ),
+                       array(
+                               'recentchanges' => array(
+                                       'INNER JOIN',
+                                       array(
+                                               'rc_this_oldid = rev_id',
+                                               'rc_source' => RecentChange::SRC_CATEGORIZE,
+                                               // Allow rc_cur_id or rc_timestamp index usage
+                                               'rc_cur_id = rev_page',
+                                               'rc_timestamp >= rev_timestamp'
+                                       )
+                               )
+                       )
+               );
+               // Only consider revisions newer than any such revision
+               if ( $row ) {
+                       $cutoffUnix = wfTimestamp( TS_UNIX, $row->rev_timestamp );
+                       $lastRevId = (int)$row->rev_id;
+               } else {
+                       $lastRevId = 0;
+               }
+
+               // Find revisions to this page made around and after this revision which lack category
+               // notifications in recent changes. This lets jobs pick up were the last one left off.
+               $encCutoff = $dbw->addQuotes( $dbw->timestamp( $cutoffUnix ) );
+               $res = $dbw->select(
+                       'revision',
+                       Revision::selectFields(),
+                       array(
+                               'rev_page' => $page->getId(),
+                               "rev_timestamp > $encCutoff" .
+                                       " OR (rev_timestamp = $encCutoff AND rev_id > $lastRevId)"
+                       ),
+                       __METHOD__,
+                       array( 'ORDER BY' => 'rev_timestamp ASC, rev_id ASC' )
+               );
+
+               // Apply all category updates in revision timestamp order
+               foreach ( $res as $row ) {
+                       $this->notifyUpdatesForRevision( $page, Revision::newFromRow( $row ) );
+               }
+
+               ScopedCallback::consume( $unlocker );
+
+               return true;
+       }
+
+       /**
+        * @param WikiPage $page
+        * @param Revision $newRev
+        * @throws MWException
+        */
+       protected function notifyUpdatesForRevision( WikiPage $page, Revision $newRev ) {
+               $config = RequestContext::getMain()->getConfig();
+               $title = $page->getTitle();
+
+               // Get the new revision
+               if ( !$newRev->getContent() ) {
+                       return; // deleted?
+               }
+
+               // Get the prior revision (the same for null edits)
+               if ( $newRev->getParentId() ) {
+                       $oldRev = Revision::newFromId( $newRev->getParentId(), Revision::READ_LATEST );
+                       if ( !$oldRev->getContent() ) {
+                               return; // deleted?
+                       }
+               } else {
+                       $oldRev = null;
+               }
+
+               // Parse the new revision and get the categories
+               $categoryChanges = $this->getExplicitCategoriesChanges( $title, $newRev, $oldRev );
+               list( $categoryInserts, $categoryDeletes ) = $categoryChanges;
+               if ( !$categoryInserts && !$categoryDeletes ) {
+                       return; // nothing to do
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $catMembChange = new CategoryMembershipChange( $title, $newRev );
+               $catMembChange->checkTemplateLinks();
+
+               $batchSize = $config->get( 'UpdateRowsPerQuery' );
+               $insertCount = 0;
+
+               foreach ( $categoryInserts as $categoryName ) {
+                       $categoryTitle = Title::makeTitle( NS_CATEGORY, $categoryName );
+                       $catMembChange->triggerCategoryAddedNotification( $categoryTitle );
+                       if ( $insertCount++ && ( $insertCount % $batchSize ) == 0 ) {
+                               $dbw->commit( __METHOD__, 'flush' );
+                               wfWaitForSlaves();
+                       }
+               }
+
+               foreach ( $categoryDeletes as $categoryName ) {
+                       $categoryTitle = Title::makeTitle( NS_CATEGORY, $categoryName );
+                       $catMembChange->triggerCategoryRemovedNotification( $categoryTitle );
+                       if ( $insertCount++ && ( $insertCount++ % $batchSize ) == 0 ) {
+                               $dbw->commit( __METHOD__, 'flush' );
+                               wfWaitForSlaves();
+                       }
+               }
+       }
+
+       private function getExplicitCategoriesChanges(
+               Title $title, Revision $newRev, Revision $oldRev = null
+       ) {
+               // Inject the same timestamp for both revision parses to avoid seeing category changes
+               // due to time-based parser functions. Inject the same page title for the parses too.
+               // Note that REPEATABLE-READ makes template/file pages appear unchanged between parses.
+               $parseTimestamp = $newRev->getTimestamp();
+               // Parse the old rev and get the categories. Do not use link tables as that
+               // assumes these updates are perfectly FIFO and that link tables are always
+               // up to date, neither of which are true.
+               $oldCategories = $oldRev
+                       ? $this->getCategoriesAtRev( $title, $oldRev, $parseTimestamp )
+                       : array();
+               // Parse the new revision and get the categories
+               $newCategories = $this->getCategoriesAtRev( $title, $newRev, $parseTimestamp );
+
+               $categoryInserts = array_values( array_diff( $newCategories, $oldCategories ) );
+               $categoryDeletes = array_values( array_diff( $oldCategories, $newCategories ) );
+
+               return array( $categoryInserts, $categoryDeletes );
+       }
+
+       /**
+        * @param Title $title
+        * @param Revision $rev
+        * @param string $parseTimestamp TS_MW
+        *
+        * @return string[] category names
+        */
+       private function getCategoriesAtRev( Title $title, Revision $rev, $parseTimestamp ) {
+               $content = $rev->getContent();
+               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $options->setTimestamp( $parseTimestamp );
+               // This could possibly use the parser cache if it checked the revision ID,
+               // but that's more complicated than it's worth.
+               $output = $content->getParserOutput( $title, $rev->getId(), $options );
+
+               // array keys will cast numeric category names to ints
+               // so we need to cast them back to strings to avoid breaking things!
+               return array_map( 'strval', array_keys( $output->getCategories() ) );
+       }
+
+       public function getDeduplicationInfo() {
+               $info = parent::getDeduplicationInfo();
+               unset( $info['params']['revTimestamp'] ); // first job wins
+
+               return $info;
+       }
+}
diff --git a/includes/jobqueue/jobs/CdnPurgeJob.php b/includes/jobqueue/jobs/CdnPurgeJob.php
new file mode 100644 (file)
index 0000000..356eeba
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Job to purge a set of URLs from CDN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup JobQueue
+ */
+
+/**
+ * Job to purge a set of URLs from CDN
+ *
+ * @ingroup JobQueue
+ * @since 1.27
+ */
+class CdnPurgeJob extends Job {
+       /**
+        * @param Title $title
+        * @param array $params Job parameters (urls)
+        */
+       function __construct( Title $title, array $params ) {
+               parent::__construct( 'cdnPurge', $title, $params );
+               $this->removeDuplicates = false; // delay semantics are critical
+       }
+
+       public function run() {
+               // Use purge() directly to avoid infinite recursion
+               CdnCacheUpdate::purge( $this->params['urls'] );
+
+               return true;
+       }
+}
index 6b1a1e3..df0a66e 100644 (file)
@@ -29,7 +29,7 @@
  *   - a) Recursive jobs to purge caches for backlink pages for a given title.
  *        These jobs have (recursive:true,table:<table>) set.
  *   - b) Jobs to purge caches for a set of titles (the job title is ignored).
- *           These jobs have (pages:(<page ID>:(<namespace>,<title>),...) set.
+ *        These jobs have (pages:(<page ID>:(<namespace>,<title>),...) set.
  *
  * @ingroup JobQueue
  */
@@ -40,6 +40,23 @@ class HTMLCacheUpdateJob extends Job {
                $this->removeDuplicates = ( !isset( $params['range'] ) && !isset( $params['pages'] ) );
        }
 
+       /**
+        * @param Title $title Title to purge backlink pages from
+        * @param string $table Backlink table name
+        * @return HTMLCacheUpdateJob
+        */
+       public static function newForBacklinks( Title $title, $table ) {
+               return new self(
+                       $title,
+                       array(
+                               'table' => $table,
+                               'recursive' => true
+                       ) + Job::newRootJobParams( // "overall" refresh links job info
+                               "htmlCacheUpdate:{$table}:{$title->getPrefixedText()}"
+                       )
+               );
+       }
+
        function run() {
                global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery;
 
@@ -77,7 +94,7 @@ class HTMLCacheUpdateJob extends Job {
         * @param array $pages Map of (page ID => (namespace, DB key)) entries
         */
        protected function invalidateTitles( array $pages ) {
-               global $wgUpdateRowsPerQuery, $wgUseFileCache, $wgUseSquid;
+               global $wgUpdateRowsPerQuery, $wgUseFileCache;
 
                // Get all page IDs in this query into an array
                $pageIds = array_keys( $pages );
@@ -122,11 +139,9 @@ class HTMLCacheUpdateJob extends Job {
                        __METHOD__
                ) );
 
-               // Update squid
-               if ( $wgUseSquid ) {
-                       $u = SquidUpdate::newFromTitles( $titleArray );
-                       $u->doUpdate();
-               }
+               // Update CDN
+               $u = CdnCacheUpdate::newFromTitles( $titleArray );
+               $u->doUpdate();
 
                // Update file cache
                if ( $wgUseFileCache ) {
index fa3278d..183c1ee 100644 (file)
  * @ingroup JobQueue
  */
 class RefreshLinksJob extends Job {
+       /** @var float Cache parser output when it takes this long to render */
        const PARSE_THRESHOLD_SEC = 1.0;
-
+       /** @var integer Lag safety margin when comparing root job times to last-refresh times */
        const CLOCK_FUDGE = 10;
 
        function __construct( Title $title, array $params ) {
                parent::__construct( 'refreshLinks', $title, $params );
-               // Base backlink update jobs and per-title update jobs can be de-duplicated.
-               // If template A changes twice before any jobs run, a clean queue will have:
-               //              (A base, A base)
-               // The second job is ignored by the queue on insertion.
-               // Suppose, many pages use template A, and that template itself uses template B.
-               // An edit to both will first create two base jobs. A clean FIFO queue will have:
-               //              (A base, B base)
-               // When these jobs run, the queue will have per-title and remnant partition jobs:
-               //              (titleX,titleY,titleZ,...,A remnant,titleM,titleN,titleO,...,B remnant)
-               // Some these jobs will be the same, and will automatically be ignored by
-               // the queue upon insertion. Some title jobs will run before the duplicate is
-               // inserted, so the work will still be done twice in those cases. More titles
-               // can be de-duplicated as the remnant jobs continue to be broken down. This
-               // works best when $wgUpdateRowsPerJob, and either the pages have few backlinks
-               // and/or the backlink sets for pages A and B are almost identical.
-               $this->removeDuplicates = !isset( $params['range'] )
-                       && ( !isset( $params['pages'] ) || count( $params['pages'] ) == 1 );
+               // Avoid the overhead of de-duplication when it would be pointless
+               $this->removeDuplicates = (
+                       // Master positions won't match
+                       !isset( $params['masterPos'] ) &&
+                       // Ranges rarely will line up
+                       !isset( $params['range'] ) &&
+                       // Multiple pages per job make matches unlikely
+                       !( isset( $params['pages'] ) && count( $params['pages'] ) != 1 )
+               );
        }
 
        /**
@@ -229,30 +222,6 @@ class RefreshLinksJob extends Job {
                        $parserOutput
                );
 
-               foreach ( $updates as $key => $update ) {
-                       // FIXME: move category change RC stuff to a separate update.
-                       // RC entry addition aborts if edits where since made, which is not necessary.
-                       // It's also an SoC violation for links update code to care about RC.
-                       if ( $update instanceof LinksUpdate ) {
-                               if ( !empty( $this->params['triggeredRecursive'] ) ) {
-                                       $update->setTriggeredRecursive();
-                               }
-                               if ( !empty( $this->params['triggeringUser'] ) ) {
-                                       $userInfo = $this->params['triggeringUser'];
-                                       if ( $userInfo['userId'] ) {
-                                               $user = User::newFromId( $userInfo['userId'] );
-                                       } else {
-                                               // Anonymous, use the username
-                                               $user = User::newFromName( $userInfo['userName'], false );
-                                       }
-                                       $update->setTriggeringUser( $user );
-                               }
-                               if ( !empty( $this->params['triggeringRevisionId'] ) ) {
-                                       $update->setRevision( $revision );
-                               }
-                       }
-               }
-
                $latestNow = $page->lockAndGetLatest();
                if ( !$latestNow || $revision->getId() != $latestNow ) {
                        // Do not clobber over newer updates with older ones. If all jobs where FIFO and
@@ -273,8 +242,6 @@ class RefreshLinksJob extends Job {
        public function getDeduplicationInfo() {
                $info = parent::getDeduplicationInfo();
                if ( is_array( $info['params'] ) ) {
-                       // Don't let highly unique "masterPos" values ruin duplicate detection
-                       unset( $info['params']['masterPos'] );
                        // For per-pages jobs, the job title is that of the template that changed
                        // (or similar), so remove that since it ruins duplicate detection
                        if ( isset( $info['pages'] ) ) {
index c8e5df6..1770ac7 100644 (file)
 /**
  * Class with Backlink related Job helper methods
  *
+ * When an asset changes, a base job can be inserted to update all assets that depend on it.
+ * The base job splits into per-title "leaf" jobs and a "remnant" job to handle the remaining
+ * range of backlinks. This recurs until the remnant job's backlink range is small enough that
+ * only leaf jobs are created from it.
+ *
+ * For example, if templates A and B are edited (at the same time) the queue will have:
+ *     (A base, B base)
+ * When these jobs run, the queue will have per-title and remnant partition jobs:
+ *        (titleX,titleY,titleZ,...,A remnant,titleM,titleN,titleO,...,B remnant)
+ *
+ * This works best when the queue is FIFO, for several reasons:
+ *   - a) Since the remnant jobs are enqueued after the leaf jobs, the slower leaf jobs have to
+ *        get popped prior to the fast remnant jobs. This avoids flooding the queue with leaf jobs
+ *        for every single backlink of widely used assets (which can be millions).
+ *   - b) Other jobs going in the queue still get a chance to run after a widely used asset changes.
+ *        This is due to the large remnant job pushing to the end of the queue with each division.
+ *
+ * The size of the queues used in this manner depend on the number of assets changes and the
+ * number of workers. Also, with FIFO-per-partition queues, the queue size can be somewhat larger,
+ * depending on the number of queue partitions.
+ *
  * @ingroup JobQueue
  * @since 1.23
  */
@@ -71,6 +92,7 @@ class BacklinkJobUtils {
 
                if ( isset( $params['pages'] ) || empty( $params['recursive'] ) ) {
                        $ranges = array(); // sanity; this is a leaf node
+                       $realBSize = 0;
                        wfWarn( __METHOD__ . " called on {$job->getType()} leaf job (explosive recursion)." );
                } elseif ( isset( $params['range'] ) ) {
                        // This is a range job to trigger the insertion of partitioned/title jobs...
@@ -88,8 +110,10 @@ class BacklinkJobUtils {
                // Combine the first range (of size $bSize) backlinks into leaf jobs
                if ( isset( $ranges[0] ) ) {
                        list( $start, $end ) = $ranges[0];
-                       $titles = $title->getBacklinkCache()->getLinks( $params['table'], $start, $end );
-                       foreach ( array_chunk( iterator_to_array( $titles ), $cSize ) as $titleBatch ) {
+                       $iter = $title->getBacklinkCache()->getLinks( $params['table'], $start, $end );
+                       $titles = iterator_to_array( $iter );
+                       /** @var Title[] $titleBatch */
+                       foreach ( array_chunk( $titles, $cSize ) as $titleBatch ) {
                                $pages = array();
                                foreach ( $titleBatch as $tl ) {
                                        $pages[$tl->getArticleId()] = array( $tl->getNamespace(), $tl->getDBKey() );
index 8abaa68..f77b211 100644 (file)
@@ -49,10 +49,15 @@ class SamplingStatsdClient extends StatsdClient {
                return $data;
        }
 
-       /**
+       /*
+        * Send the metrics over UDP
         * Sample the metrics according to their sample rate and send the remaining ones.
         *
-        * {@inheritDoc}
+        * @param StatsdDataInterface|StatsdDataInterface[] $data message(s) to sent
+        *        strings are not allowed here as sampleData requires a StatsdDataInterface
+        * @param int $sampleRate
+        *
+        * @return integer the data sent in bytes
         */
        public function send( $data, $sampleRate = 1 ) {
                if ( !is_array( $data ) ) {
@@ -74,12 +79,13 @@ class SamplingStatsdClient extends StatsdClient {
                }
                $data = $this->sampleData( $data );
 
-               $messages = array_map( 'strval', $data );
+               $data = array_map( 'strval', $data );
 
                // reduce number of packets
                if ( $this->getReducePacket() ) {
                        $data = $this->reduceCount( $data );
                }
+
                // failures in any of this should be silently ignored if ..
                $written = 0;
                try {
@@ -87,7 +93,7 @@ class SamplingStatsdClient extends StatsdClient {
                        if ( !$fp ) {
                                return;
                        }
-                       foreach ( $messages as $message ) {
+                       foreach ( $data as $message ) {
                                $written += $this->getSender()->write( $fp, $message );
                        }
                        $this->getSender()->close( $fp );
index 3c2dd40..35de084 100644 (file)
@@ -181,7 +181,7 @@ class StatusValue {
        /**
         * Merge another status object into this one
         *
-        * @param Status $other Other Status object
+        * @param StatusValue $other Other StatusValue object
         * @param bool $overwriteValue Whether to override the "value" member
         */
        public function merge( $other, $overwriteValue = false ) {
index 653227e..00ceda3 100644 (file)
  * @file
  */
 
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
 /**
  * An interface to help developers measure the performance of their applications.
  * This interface closely matches the W3C's User Timing specification.
  *
  * @since 1.27
  */
-class Timing {
+class Timing implements LoggerAwareInterface {
 
        /** @var array[] */
        private $entries = array();
 
-       public function __construct() {
+       /** @var LoggerInterface */
+       protected $logger;
+
+       public function __construct( array $params = array() ) {
                $this->clearMarks();
+               $this->setLogger( isset( $params['logger'] ) ? $params['logger'] : new NullLogger() );
+       }
+
+       /**
+        * Sets a logger instance on the object.
+        *
+        * @param LoggerInterface $logger
+        * @return null
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
        }
 
        /**
@@ -102,14 +120,23 @@ class Timing {
         * @param string $measureName
         * @param string $startMark
         * @param string $endMark
-        * @return array The measure that has been created.
+        * @return array|bool The measure that has been created, or false if either
+        *  the start mark or the end mark do not exist.
         */
        public function measure( $measureName, $startMark = 'requestStart', $endMark = null ) {
                $start = $this->getEntryByName( $startMark );
+               if ( $start === null ) {
+                       $this->logger->error( __METHOD__ . ": The mark '$startMark' does not exist" );
+                       return false;
+               }
                $startTime = $start['startTime'];
 
                if ( $endMark ) {
                        $end = $this->getEntryByName( $endMark );
+                       if ( $end === null ) {
+                               $this->logger->error( __METHOD__ . ": The mark '$endMark' does not exist" );
+                               return false;
+                       }
                        $endTime = $end['startTime'];
                } else {
                        $endTime = microtime( true );
index 16e894e..01f8ccc 100644 (file)
@@ -115,6 +115,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        const FLD_TTL = 2;
        const FLD_TIME = 3;
        const FLD_FLAGS = 4;
+       const FLD_HOLDOFF = 5;
 
        /** @var integer Treat this value as expired-on-arrival */
        const FLG_STALE = 1;
@@ -232,31 +233,32 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                $vPrefixLen = strlen( self::VALUE_KEY_PREFIX );
                $valueKeys = self::prefixCacheKeys( $keys, self::VALUE_KEY_PREFIX );
 
-               $checksForAll = array();
-               $checksByKey = array();
+               $checkKeysForAll = array();
+               $checkKeysByKey = array();
                $checkKeysFlat = array();
                foreach ( $checkKeys as $i => $keys ) {
                        $prefixed = self::prefixCacheKeys( (array)$keys, self::TIME_KEY_PREFIX );
                        $checkKeysFlat = array_merge( $checkKeysFlat, $prefixed );
                        // Is this check keys for a specific cache key, or for all keys being fetched?
                        if ( is_int( $i ) ) {
-                               $checksForAll = array_merge( $checksForAll, $prefixed );
+                               $checkKeysForAll = array_merge( $checkKeysForAll, $prefixed );
                        } else {
-                               $checksByKey[$i] = isset( $checksByKey[$i] )
-                                       ? array_merge( $checksByKey[$i], $prefixed )
+                               $checkKeysByKey[$i] = isset( $checkKeysByKey[$i] )
+                                       ? array_merge( $checkKeysByKey[$i], $prefixed )
                                        : $prefixed;
                        }
                }
 
                // Fetch all of the raw values
                $wrappedValues = $this->cache->getMulti( array_merge( $valueKeys, $checkKeysFlat ) );
+               // Time used to compare/init "check" keys (derived after getMulti() to be pessimistic)
                $now = microtime( true );
 
                // Collect timestamps from all "check" keys
-               $checkKeyTimesForAll = $this->processCheckKeys( $checksForAll, $wrappedValues, $now );
-               $checkKeyTimesByKey = array();
-               foreach ( $checksByKey as $cacheKey => $checks ) {
-                       $checkKeyTimesByKey[$cacheKey] =
+               $purgeValuesForAll = $this->processCheckKeys( $checkKeysForAll, $wrappedValues, $now );
+               $purgeValuesByKey = array();
+               foreach ( $checkKeysByKey as $cacheKey => $checks ) {
+                       $purgeValuesByKey[$cacheKey] =
                                $this->processCheckKeys( $checks, $wrappedValues, $now );
                }
 
@@ -274,14 +276,17 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                                // Force dependant keys to be invalid for a while after purging
                                // to reduce race conditions involving stale data getting cached
-                               $checkKeyTimes = $checkKeyTimesForAll;
-                               if ( isset( $checkKeyTimesByKey[$key] ) ) {
-                                       $checkKeyTimes = array_merge( $checkKeyTimes, $checkKeyTimesByKey[$key] );
+                               $purgeValues = $purgeValuesForAll;
+                               if ( isset( $purgeValuesByKey[$key] ) ) {
+                                       $purgeValues = array_merge( $purgeValues, $purgeValuesByKey[$key] );
                                }
-                               foreach ( $checkKeyTimes as $checkKeyTime ) {
-                                       $safeTimestamp = $checkKeyTime + self::HOLDOFF_TTL;
+                               foreach ( $purgeValues as $purge ) {
+                                       $safeTimestamp = $purge[self::FLD_TIME] + $purge[self::FLD_HOLDOFF];
                                        if ( $safeTimestamp >= $wrappedValues[$vKey][self::FLD_TIME] ) {
-                                               $curTTL = min( $curTTL, $checkKeyTime - $now );
+                                               // How long ago this value was expired by *this* check key
+                                               $ago = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
+                                               // How long ago this value was expired by *any* known check key
+                                               $curTTL = min( $curTTL, $ago );
                                        }
                                }
                        }
@@ -296,22 +301,23 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param array $timeKeys List of prefixed time check keys
         * @param array $wrappedValues
         * @param float $now
-        * @return array List of timestamps
+        * @return array List of purge value arrays
         */
        private function processCheckKeys( array $timeKeys, array $wrappedValues, $now ) {
-               $times = array();
+               $purgeValues = array();
                foreach ( $timeKeys as $timeKey ) {
-                       $timestamp = isset( $wrappedValues[$timeKey] )
+                       $purge = isset( $wrappedValues[$timeKey] )
                                ? self::parsePurgeValue( $wrappedValues[$timeKey] )
                                : false;
-                       if ( !is_float( $timestamp ) ) {
+                       if ( $purge === false ) {
                                // Key is not set or invalid; regenerate
-                               $this->cache->add( $timeKey, self::PURGE_VAL_PREFIX . $now, self::CHECK_KEY_TTL );
-                               $timestamp = $now;
+                               $newVal = $this->makePurgeValue( $now, self::HOLDOFF_TTL );
+                               $this->cache->add( $timeKey, $newVal, self::CHECK_KEY_TTL );
+                               $purge = self::parsePurgeValue( $newVal );
                        }
-                       $times[] = $timestamp;
+                       $purgeValues[] = $purge;
                }
-               return $times;
+               return $purgeValues;
        }
 
        /**
@@ -378,7 +384,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                $wrapExtra = array(); // additional wrapped value fields
                // Check if there's a risk of writing stale data after the purge tombstone expired
-               if ( ( $lag + $age ) > self::MAX_READ_LAG ) {
+               if ( $lag === false || ( $lag + $age ) > self::MAX_READ_LAG ) {
                        // Case A: read lag with "lockTSE"; save but record value as stale
                        if ( $lockTSE >= 0 ) {
                                $ttl = max( 1, (int)$lockTSE ); // set() expects seconds
@@ -389,7 +395,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                                return true; // no-op the write for being unsafe
                        // Case C: high replication lag; lower TTL instead of ignoring all set()s
-                       } elseif ( $lag > self::MAX_READ_LAG ) {
+                       } elseif ( $lag === false || $lag > self::MAX_READ_LAG ) {
                                $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED;
                                $this->logger->warning( "Lowered set() TTL for $key due to replication lag." );
                        // Case D: medium length request with medium replication lag; ignore this set()
@@ -479,9 +485,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        $ok = $this->relayDelete( $key ) && $ok;
                } else {
                        // Update the local datacenter immediately
-                       $ok = $this->cache->set( $key, self::PURGE_VAL_PREFIX . microtime( true ), $ttl );
+                       $ok = $this->cache->set( $key,
+                               $this->makePurgeValue( microtime( true ), self::HOLDOFF_NONE ),
+                               $ttl
+                       );
                        // Publish the purge to all datacenters
-                       $ok = $this->relayPurge( $key, $ttl ) && $ok;
+                       $ok = $this->relayPurge( $key, $ttl, self::HOLDOFF_NONE ) && $ok;
                }
 
                return $ok;
@@ -504,17 +513,22 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * Note that "check" keys won't collide with other regular keys.
         *
         * @param string $key
-        * @return float UNIX timestamp of the key
+        * @return float UNIX timestamp of the check key
         */
        final public function getCheckKeyTime( $key ) {
                $key = self::TIME_KEY_PREFIX . $key;
 
-               $time = self::parsePurgeValue( $this->cache->get( $key ) );
-               if ( $time === false ) {
+               $purge = self::parsePurgeValue( $this->cache->get( $key ) );
+               if ( $purge !== false ) {
+                       $time = $purge[self::FLD_TIME];
+               } else {
                        // Casting assures identical floats for the next getCheckKeyTime() calls
-                       $time = (string)microtime( true );
-                       $this->cache->add( $key, self::PURGE_VAL_PREFIX . $time, self::CHECK_KEY_TTL );
-                       $time = (float)$time;
+                       $now = (string)microtime( true );
+                       $this->cache->add( $key,
+                               $this->makePurgeValue( $now, self::HOLDOFF_TTL ),
+                               self::CHECK_KEY_TTL
+                       );
+                       $time = (float)$now;
                }
 
                return $time;
@@ -548,15 +562,18 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @see WANObjectCache::resetCheckKey()
         *
         * @param string $key Cache key
+        * @param int $holdoff HOLDOFF_TTL or HOLDOFF_NONE constant
         * @return bool True if the item was purged or not found, false on failure
         */
-       final public function touchCheckKey( $key ) {
+       final public function touchCheckKey( $key, $holdoff = self::HOLDOFF_TTL ) {
                $key = self::TIME_KEY_PREFIX . $key;
                // Update the local datacenter immediately
                $ok = $this->cache->set( $key,
-                       self::PURGE_VAL_PREFIX . microtime( true ), self::CHECK_KEY_TTL );
+                       $this->makePurgeValue( microtime( true ), $holdoff ),
+                       self::CHECK_KEY_TTL
+               );
                // Publish the purge to all datacenters
-               return $this->relayPurge( $key, self::CHECK_KEY_TTL ) && $ok;
+               return $this->relayPurge( $key, self::CHECK_KEY_TTL, $holdoff ) && $ok;
        }
 
        /**
@@ -904,17 +921,18 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /**
         * Do the actual async bus purge of a key
         *
-        * This must set the key to "PURGED:<UNIX timestamp>"
+        * This must set the key to "PURGED:<UNIX timestamp>:<holdoff>"
         *
         * @param string $key Cache key
         * @param integer $ttl How long to keep the tombstone [seconds]
+        * @param integer $holdoff HOLDOFF_* constant controlling how long to ignore sets for this key
         * @return bool Success
         */
-       protected function relayPurge( $key, $ttl ) {
+       protected function relayPurge( $key, $ttl, $holdoff ) {
                $event = $this->cache->modifySimpleRelayEvent( array(
                        'cmd' => 'set',
                        'key' => $key,
-                       'val' => 'PURGED:$UNIXTIME$',
+                       'val' => 'PURGED:$UNIXTIME$:' . (int)$holdoff,
                        'ttl' => max( $ttl, 1 ),
                        'sbt' => true, // substitute $UNIXTIME$ with actual microtime
                ) );
@@ -996,10 +1014,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         */
        protected function unwrap( $wrapped, $now ) {
                // Check if the value is a tombstone
-               $purgeTimestamp = self::parsePurgeValue( $wrapped );
-               if ( is_float( $purgeTimestamp ) ) {
+               $purge = self::parsePurgeValue( $wrapped );
+               if ( $purge !== false ) {
                        // Purged values should always have a negative current $ttl
-                       $curTTL = min( $purgeTimestamp - $now, self::TINY_NEGATIVE );
+                       $curTTL = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
                        return array( false, $curTTL );
                }
 
@@ -1042,17 +1060,36 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        }
 
        /**
-        * @param string $value String like "PURGED:<timestamp>"
-        * @return float|bool UNIX timestamp or false on failure
+        * @param string $value Wrapped value like "PURGED:<timestamp>:<holdoff>"
+        * @return array|bool Array containing a UNIX timestamp (float) and holdoff period (integer),
+        *  or false if value isn't a valid purge value
         */
        protected static function parsePurgeValue( $value ) {
-               $m = array();
-               if ( is_string( $value ) &&
-                       preg_match( '/^' . self::PURGE_VAL_PREFIX . '([^:]+)$/', $value, $m )
+               if ( !is_string( $value ) ) {
+                       return false;
+               }
+               $segments = explode( ':', $value, 3 );
+               if ( !isset( $segments[0] ) || !isset( $segments[1] )
+                       || "{$segments[0]}:" !== self::PURGE_VAL_PREFIX
                ) {
-                       return (float)$m[1];
-               } else {
                        return false;
                }
+               if ( !isset( $segments[2] ) ) {
+                       // Back-compat with old purge values without holdoff
+                       $segments[2] = self::HOLDOFF_TTL;
+               }
+               return array(
+                       self::FLD_TIME => (float)$segments[1],
+                       self::FLD_HOLDOFF => (int)$segments[2],
+               );
+       }
+
+       /**
+        * @param float $timestamp
+        * @param int $holdoff In seconds
+        * @return string Wrapped purge value
+        */
+       protected function makePurgeValue( $timestamp, $holdoff ) {
+               return self::PURGE_VAL_PREFIX . (float)$timestamp . ':' . (int)$holdoff;
        }
 }
index df37610..dcd7a45 100644 (file)
@@ -114,7 +114,7 @@ class LogEventsList extends ContextSource {
                }
 
                // Submit button
-               $html .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() );
+               $html .= Xml::submitButton( $this->msg( 'logeventslist-submit' )->text() );
 
                // Fieldset
                $html = Xml::fieldset( $this->msg( 'log' )->text(), $html );
index 25f4806..73eeba6 100644 (file)
@@ -190,8 +190,18 @@ class FormatMetadata extends ContextSource {
 
                                        case 'PhotometricInterpretation':
                                                switch ( $val ) {
+                                                       case 0:
+                                                       case 1:
                                                        case 2:
+                                                       case 3:
+                                                       case 4:
+                                                       case 5:
                                                        case 6:
+                                                       case 8:
+                                                       case 9:
+                                                       case 10:
+                                                       case 32803:
+                                                       case 34892:
                                                                $val = $this->exifMsg( $tag, $val );
                                                                break;
                                                        default:
index b4aecee..90a9f7c 100644 (file)
@@ -44,12 +44,13 @@ use MediaWiki\Logger\LoggerFactory;
  *
  * - ObjectCache::getMainWANInstance()
  *   Purpose: Memory cache.
- *   Stored in the local data-center's main cache (uses different cache keys).
- *   Delete events are broadcasted to other DCs. See WANObjectCache for details.
+ *   Stored in the local data-center's main cache (keyspace different from local-cluster cache).
+ *   Delete events are broadcasted to other DCs main cache. See WANObjectCache for details.
  *
  * - ObjectCache::getLocalServerInstance( $fallbackType )
  *   Purpose: Memory cache for very hot keys.
- *   Stored only on the individual web server (often EmptyBagOStuff in CLI mode).
+ *   Stored only on the individual web server (typically APC for web requests,
+ *   and EmptyBagOStuff in CLI mode).
  *   Not replicated to the other servers.
  *
  * - ObjectCache::getLocalClusterInstance()
@@ -62,7 +63,7 @@ use MediaWiki\Logger\LoggerFactory;
  *   Purpose: Ephemeral global storage.
  *   Stored centrally within the primary data-center.
  *   Changes are applied there first and replicated to other DCs (best-effort).
- *   To retrieve the latest value (e.g. not from a slave), use BagOStuff:READ_LATEST.
+ *   To retrieve the latest value (e.g. not from a slave), use BagOStuff::READ_LATEST.
  *   This store may be subject to LRU style evictions.
  *
  * - ObjectCache::getInstance( $cacheType )
index 5d6435e..35621a4 100644 (file)
@@ -696,7 +696,7 @@ class Article implements Page {
 
                                        # Don't cache a dirty ParserOutput object
                                        if ( $poolArticleView->getIsDirty() ) {
-                                               $outputPage->setSquidMaxage( 0 );
+                                               $outputPage->setCdnMaxage( 0 );
                                                $outputPage->addHTML( "<!-- parser cache is expired, " .
                                                        "sending anyway due to pool overload-->\n" );
                                        }
index 98bca05..f290db8 100644 (file)
@@ -881,7 +881,8 @@ class WikiPage implements Page, IDBAccessObject {
                if ( $row && !is_null( $row->rd_fragment ) && !is_null( $row->rd_interwiki ) ) {
                        $this->mRedirectTarget = Title::makeTitle(
                                $row->rd_namespace, $row->rd_title,
-                               $row->rd_fragment, $row->rd_interwiki );
+                               $row->rd_fragment, $row->rd_interwiki
+                       );
                        return $this->mRedirectTarget;
                }
 
@@ -891,39 +892,54 @@ class WikiPage implements Page, IDBAccessObject {
        }
 
        /**
-        * Insert an entry for this page into the redirect table.
+        * Insert an entry for this page into the redirect table if the content is a redirect
+        *
+        * The database update will be deferred via DeferredUpdates
         *
         * Don't call this function directly unless you know what you're doing.
         * @return Title|null Title object or null if not a redirect
         */
        public function insertRedirect() {
-               // recurse through to only get the final target
                $content = $this->getContent();
                $retval = $content ? $content->getUltimateRedirectTarget() : null;
                if ( !$retval ) {
                        return null;
                }
-               $this->insertRedirectEntry( $retval );
+
+               // Update the DB post-send if the page has not cached since now
+               $that = $this;
+               $latest = $this->getLatest();
+               DeferredUpdates::addCallableUpdate( function() use ( $that, $retval, $latest ) {
+                       $that->insertRedirectEntry( $retval, $latest );
+               } );
+
                return $retval;
        }
 
        /**
-        * Insert or update the redirect table entry for this page to indicate
-        * it redirects to $rt .
+        * Insert or update the redirect table entry for this page to indicate it redirects to $rt
         * @param Title $rt Redirect target
+        * @param int|null $oldLatest Prior page_latest for check and set
         */
-       public function insertRedirectEntry( $rt ) {
+       public function insertRedirectEntry( Title $rt, $oldLatest = null ) {
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->replace( 'redirect', array( 'rd_from' ),
-                       array(
-                               'rd_from' => $this->getId(),
-                               'rd_namespace' => $rt->getNamespace(),
-                               'rd_title' => $rt->getDBkey(),
-                               'rd_fragment' => $rt->getFragment(),
-                               'rd_interwiki' => $rt->getInterwiki(),
-                       ),
-                       __METHOD__
-               );
+               $dbw->startAtomic( __METHOD__ );
+
+               if ( !$oldLatest || $oldLatest == $this->lockAndGetLatest() ) {
+                       $dbw->replace( 'redirect',
+                               array( 'rd_from' ),
+                               array(
+                                       'rd_from' => $this->getId(),
+                                       'rd_namespace' => $rt->getNamespace(),
+                                       'rd_title' => $rt->getDBkey(),
+                                       'rd_fragment' => $rt->getFragment(),
+                                       'rd_interwiki' => $rt->getInterwiki(),
+                               ),
+                               __METHOD__
+                       );
+               }
+
+               $dbw->endAtomic( __METHOD__ );
        }
 
        /**
@@ -1027,55 +1043,6 @@ class WikiPage implements Page, IDBAccessObject {
                return new UserArrayFromResult( $res );
        }
 
-       /**
-        * Get the last N authors
-        * @param int $num Number of revisions to get
-        * @param int|string $revLatest The latest rev_id, selected from the master (optional)
-        * @return array Array of authors, duplicates not removed
-        */
-       public function getLastNAuthors( $num, $revLatest = 0 ) {
-               // First try the slave
-               // If that doesn't have the latest revision, try the master
-               $continue = 2;
-               $db = wfGetDB( DB_SLAVE );
-
-               do {
-                       $res = $db->select( array( 'page', 'revision' ),
-                               array( 'rev_id', 'rev_user_text' ),
-                               array(
-                                       'page_namespace' => $this->mTitle->getNamespace(),
-                                       'page_title' => $this->mTitle->getDBkey(),
-                                       'rev_page = page_id'
-                               ), __METHOD__,
-                               array(
-                                       'ORDER BY' => 'rev_timestamp DESC',
-                                       'LIMIT' => $num
-                               )
-                       );
-
-                       if ( !$res ) {
-                               return array();
-                       }
-
-                       $row = $db->fetchObject( $res );
-
-                       if ( $continue == 2 && $revLatest && $row->rev_id != $revLatest ) {
-                               $db = wfGetDB( DB_MASTER );
-                               $continue--;
-                       } else {
-                               $continue = 0;
-                       }
-               } while ( $continue );
-
-               $authors = array( $row->rev_user_text );
-
-               foreach ( $res as $row ) {
-                       $authors[] = $row->rev_user_text;
-               }
-
-               return $authors;
-       }
-
        /**
         * Should the parser cache be used?
         *
@@ -1160,16 +1127,16 @@ class WikiPage implements Page, IDBAccessObject {
 
                $title = $this->mTitle;
                wfGetDB( DB_MASTER )->onTransactionIdle( function() use ( $title ) {
-                       global $wgUseSquid;
                        // Invalidate the cache in auto-commit mode
                        $title->invalidateCache();
-                       if ( $wgUseSquid ) {
-                               // Send purge now that page_touched update was committed above
-                               $update = new SquidUpdate( $title->getSquidURLs() );
-                               $update->doUpdate();
-                       }
                } );
 
+               // Send purge after above page_touched update was committed
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( $title->getCdnUrls() ),
+                       DeferredUpdates::PRESEND
+               );
+
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
                        // @todo move this logic to MessageCache
                        if ( $this->exists() ) {
@@ -1696,209 +1663,170 @@ class WikiPage implements Page, IDBAccessObject {
         * @since 1.21
         * @throws MWException
         */
-       public function doEditContent( Content $content, $summary, $flags = 0, $baseRevId = false,
+       public function doEditContent(
+               Content $content, $summary, $flags = 0, $baseRevId = false,
                User $user = null, $serialFormat = null
        ) {
-               global $wgUser, $wgUseAutomaticEditSummaries, $wgUseRCPatrol, $wgUseNPPatrol;
+               global $wgUser, $wgUseAutomaticEditSummaries;
 
                // Low-level sanity check
                if ( $this->mTitle->getText() === '' ) {
                        throw new MWException( 'Something is trying to edit an article with an empty title' );
                }
-
-               if ( !$content->getContentHandler()->canBeUsedOn( $this->getTitle() ) ) {
+               // Make sure the given content type is allowed for this page
+               if ( !$content->getContentHandler()->canBeUsedOn( $this->mTitle ) ) {
                        return Status::newFatal( 'content-not-allowed-here',
                                ContentHandler::getLocalizedName( $content->getModel() ),
-                               $this->getTitle()->getPrefixedText() );
+                               $this->mTitle->getPrefixedText()
+                       );
                }
 
-               $user = is_null( $user ) ? $wgUser : $user;
-               $status = Status::newGood( array() );
-
                // Load the data from the master database if needed.
                // The caller may already loaded it from the master or even loaded it using
                // SELECT FOR UPDATE, so do not override that using clear().
                $this->loadPageData( 'fromdbmaster' );
 
+               $user = $user ?: $wgUser;
                $flags = $this->checkFlags( $flags );
 
-               // handle hook
+               // Trigger pre-save hook (using provided edit summary)
+               $hookStatus = Status::newGood( array() );
                $hook_args = array( &$this, &$user, &$content, &$summary,
-                                                       $flags & EDIT_MINOR, null, null, &$flags, &$status );
-
+                                                       $flags & EDIT_MINOR, null, null, &$flags, &$hookStatus );
+               // Check if the hook rejected the attempted save
                if ( !Hooks::run( 'PageContentSave', $hook_args )
-                       || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args ) ) {
-
-                       wfDebug( __METHOD__ . ": ArticleSave or ArticleSaveContent hook aborted save!\n" );
-
-                       if ( $status->isOK() ) {
-                               $status->fatal( 'edit-hook-aborted' );
+                       || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args )
+               ) {
+                       if ( $hookStatus->isOK() ) {
+                               // Hook returned false but didn't call fatal(); use generic message
+                               $hookStatus->fatal( 'edit-hook-aborted' );
                        }
 
-                       return $status;
+                       return $hookStatus;
                }
 
-               // Silently ignore EDIT_MINOR if not allowed
-               $isminor = ( $flags & EDIT_MINOR ) && $user->isAllowed( 'minoredit' );
-               $bot = $flags & EDIT_FORCE_BOT;
-
+               $old_revision = $this->getRevision(); // current revision
                $old_content = $this->getContent( Revision::RAW ); // current revision's content
 
-               $oldsize = $old_content ? $old_content->getSize() : 0;
-               $oldid = $this->getLatest();
-               $oldIsRedirect = $this->isRedirect();
-               $oldcountable = $this->isCountable();
-
-               $handler = $content->getContentHandler();
-
-               // Provide autosummaries if one is not provided and autosummaries are enabled.
-               if ( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '' ) {
-                       if ( !$old_content ) {
-                               $old_content = null;
-                       }
+               // Provide autosummaries if one is not provided and autosummaries are enabled
+               if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) {
+                       $handler = $content->getContentHandler();
                        $summary = $handler->getAutosummary( $old_content, $content, $flags );
                }
 
+               // Get the pre-save transform content and final parser output
                $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat );
-               $serialized = $editInfo->pst;
-
-               /**
-                * @var Content $content
-                */
-               $content = $editInfo->pstContent;
-               $newsize = $content->getSize();
-
-               $dbw = wfGetDB( DB_MASTER );
-               $now = wfTimestampNow();
+               $pstContent = $editInfo->pstContent; // Content object
+               $meta = array(
+                       'bot' => ( $flags & EDIT_FORCE_BOT ),
+                       'minor' => ( $flags & EDIT_MINOR ) && $user->isAllowed( 'minoredit' ),
+                       'serialized' => $editInfo->pst,
+                       'serialFormat' => $serialFormat,
+                       'baseRevId' => $baseRevId,
+                       'oldRevision' => $old_revision,
+                       'oldContent' => $old_content,
+                       'oldId' => $this->getLatest(),
+                       'oldIsRedirect' => $this->isRedirect(),
+                       'oldCountable' => $this->isCountable()
+               );
 
+               // Actually create the revision and create/update the page
                if ( $flags & EDIT_UPDATE ) {
-                       // Update article, but only if changed.
-                       $status->value['new'] = false;
-
-                       if ( !$oldid ) {
-                               // Article gone missing
-                               wfDebug( __METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n" );
-                               $status->fatal( 'edit-gone-missing' );
-
-                               return $status;
-                       } elseif ( !$old_content ) {
-                               // Sanity check for bug 37225
-                               throw new MWException( "Could not find text for current revision {$oldid}." );
-                       }
-
-                       $revision = new Revision( array(
-                               'page'       => $this->getId(),
-                               'title'      => $this->getTitle(), // for determining the default content model
-                               'comment'    => $summary,
-                               'minor_edit' => $isminor,
-                               'text'       => $serialized,
-                               'len'        => $newsize,
-                               'parent_id'  => $oldid,
-                               'user'       => $user->getId(),
-                               'user_text'  => $user->getName(),
-                               'timestamp'  => $now,
-                               'content_model' => $content->getModel(),
-                               'content_format' => $serialFormat,
-                       ) ); // XXX: pass content object?!
-
-                       $changed = !$content->equals( $old_content );
-
-                       if ( $changed ) {
-                               $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
-                               $status->merge( $prepStatus );
-
-                               if ( !$status->isOK() ) {
-                                       return $status;
-                               }
+                       $status = $this->doModify( $pstContent, $flags, $user, $summary, $meta );
+               } else {
+                       $status = $this->doCreate( $pstContent, $flags, $user, $summary, $meta );
+               }
 
-                               $dbw->begin( __METHOD__ );
-                               // Get the latest page_latest value while locking it.
-                               // Do a CAS style check to see if it's the same as when this method
-                               // started. If it changed then bail out before touching the DB.
-                               $latestNow = $this->lockAndGetLatest();
-                               if ( $latestNow != $oldid ) {
-                                       $dbw->commit( __METHOD__ );
-                                       // Page updated or deleted in the mean time
-                                       $status->fatal( 'edit-conflict' );
-
-                                       return $status;
-                               }
+               // Trigger post-save hook
+               $revision = $status->value['revision']; // new revision
+               $hook_args = array( &$this, &$user, $pstContent, $summary,
+                       $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
+               ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
+               Hooks::run( 'PageContentSaveComplete', $hook_args );
 
-                               // At this point we are now comitted to returning an OK
-                               // status unless some DB query error or other exception comes up.
-                               // This way callers don't have to call rollback() if $status is bad
-                               // unless they actually try to catch exceptions (which is rare).
+               // Promote user to any groups they meet the criteria for
+               DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                       $user->addAutopromoteOnceGroups( 'onEdit' );
+                       $user->addAutopromoteOnceGroups( 'onView' ); // b/c
+               } );
 
-                               $revisionId = $revision->insertOn( $dbw );
+               return $status;
+       }
 
-                               // Update page_latest and friends to reflect the new revision
-                               if ( !$this->updateRevisionOn( $dbw, $revision, null, $oldIsRedirect ) ) {
-                                       $dbw->rollback( __METHOD__ );
-                                       throw new MWException( "Failed to update page row to use new revision." );
-                               }
+       /**
+        * @param Content $content Pre-save transform content
+        * @param integer $flags
+        * @param User $user
+        * @param string $summary
+        * @param array $meta
+        * @return Status
+        * @throws DBUnexpectedError
+        * @throws Exception
+        * @throws FatalError
+        * @throws MWException
+        */
+       private function doModify(
+               Content $content, $flags, User $user, $summary, array $meta
+       ) {
+               global $wgUseRCPatrol;
 
-                               Hooks::run( 'NewRevisionFromEditComplete',
-                                       array( $this, $revision, $baseRevId, $user ) );
+               // Update article, but only if changed.
+               $status = Status::newGood( array( 'new' => false, 'revision' => null ) );
 
-                               // Update recentchanges
-                               if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
-                                       // Mark as patrolled if the user can do so
-                                       $patrolled = $wgUseRCPatrol && !count(
-                                               $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
-                                       // Add RC row to the DB
-                                       RecentChange::notifyEdit(
-                                               $now, $this->mTitle, $isminor, $user, $summary,
-                                               $oldid, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
-                                               $revisionId, $patrolled
-                                       );
-                               }
+               // Convenience variables
+               $now = wfTimestampNow();
+               $oldid = $meta['oldId'];
+               /** @var $oldContent Content|null */
+               $oldContent = $meta['oldContent'];
+               $newsize = $content->getSize();
 
-                               $user->incEditCount();
+               if ( !$oldid ) {
+                       // Article gone missing
+                       $status->fatal( 'edit-gone-missing' );
 
-                               $dbw->commit( __METHOD__ );
-                               $this->mTimestamp = $now;
-                       } else {
-                               // Bug 32948: revision ID must be set to page {{REVISIONID}} and
-                               // related variables correctly
-                               $revision->setId( $this->getLatest() );
-                       }
+                       return $status;
+               } elseif ( !$oldContent ) {
+                       // Sanity check for bug 37225
+                       throw new MWException( "Could not find text for current revision {$oldid}." );
+               }
 
-                       // Update links tables, site stats, etc.
-                       $this->doEditUpdates(
-                               $revision,
-                               $user,
-                               array(
-                                       'changed' => $changed,
-                                       'oldcountable' => $oldcountable
-                               )
-                       );
+               // @TODO: pass content object?!
+               $revision = new Revision( array(
+                       'page'       => $this->getId(),
+                       'title'      => $this->mTitle, // for determining the default content model
+                       'comment'    => $summary,
+                       'minor_edit' => $meta['minor'],
+                       'text'       => $meta['serialized'],
+                       'len'        => $newsize,
+                       'parent_id'  => $oldid,
+                       'user'       => $user->getId(),
+                       'user_text'  => $user->getName(),
+                       'timestamp'  => $now,
+                       'content_model' => $content->getModel(),
+                       'content_format' => $meta['serialFormat'],
+               ) );
 
-                       if ( !$changed ) {
-                               $status->warning( 'edit-no-change' );
-                               $revision = null;
-                               // Update page_touched, this is usually implicit in the page update
-                               // Other cache updates are done in onArticleEdit()
-                               $this->mTitle->invalidateCache( $now );
-                       }
-               } else {
-                       // Create new article
-                       $status->value['new'] = true;
+               $changed = !$content->equals( $oldContent );
 
+               if ( $changed ) {
                        $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
                        $status->merge( $prepStatus );
                        if ( !$status->isOK() ) {
                                return $status;
                        }
 
+                       $dbw = wfGetDB( DB_MASTER );
                        $dbw->begin( __METHOD__ );
+                       // Get the latest page_latest value while locking it.
+                       // Do a CAS style check to see if it's the same as when this method
+                       // started. If it changed then bail out before touching the DB.
+                       $latestNow = $this->lockAndGetLatest();
+                       if ( $latestNow != $oldid ) {
+                               $dbw->commit( __METHOD__ );
+                               // Page updated or deleted in the mean time
+                               $status->fatal( 'edit-conflict' );
 
-                       // Add the page record unless one already exists for the title
-                       $newid = $this->insertOn( $dbw );
-                       if ( $newid === false ) {
-                               $dbw->commit( __METHOD__ ); // nothing inserted
-                               $status->fatal( 'edit-already-exists' );
-
-                               return $status; // nothing done
+                               return $status;
                        }
 
                        // At this point we are now comitted to returning an OK
@@ -1906,46 +1834,37 @@ class WikiPage implements Page, IDBAccessObject {
                        // This way callers don't have to call rollback() if $status is bad
                        // unless they actually try to catch exceptions (which is rare).
 
-                       // Save the revision text...
-                       $revision = new Revision( array(
-                               'page'       => $newid,
-                               'title'      => $this->getTitle(), // for determining the default content model
-                               'comment'    => $summary,
-                               'minor_edit' => $isminor,
-                               'text'       => $serialized,
-                               'len'        => $newsize,
-                               'user'       => $user->getId(),
-                               'user_text'  => $user->getName(),
-                               'timestamp'  => $now,
-                               'content_model' => $content->getModel(),
-                               'content_format' => $serialFormat,
-                       ) );
+                       // Save the revision text
                        $revisionId = $revision->insertOn( $dbw );
-
-                       // Bug 37225: use accessor to get the text as Revision may trim it
-                       $content = $revision->getContent(); // sanity; get normalized version
-
-                       if ( $content ) {
-                               $newsize = $content->getSize();
-                       }
-
-                       // Update the page record with revision data
-                       if ( !$this->updateRevisionOn( $dbw, $revision, 0 ) ) {
+                       // Update page_latest and friends to reflect the new revision
+                       if ( !$this->updateRevisionOn( $dbw, $revision, null, $meta['oldIsRedirect'] ) ) {
                                $dbw->rollback( __METHOD__ );
                                throw new MWException( "Failed to update page row to use new revision." );
                        }
 
-                       Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
+                       Hooks::run( 'NewRevisionFromEditComplete',
+                               array( $this, $revision, $meta['baseRevId'], $user ) );
 
                        // Update recentchanges
                        if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
                                // Mark as patrolled if the user can do so
-                               $patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) && !count(
-                                       $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
+                               $patrolled = $wgUseRCPatrol && !count(
+                                               $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
                                // Add RC row to the DB
-                               RecentChange::notifyNew(
-                                       $now, $this->mTitle, $isminor, $user, $summary, $bot,
-                                       '', $newsize, $revisionId, $patrolled
+                               RecentChange::notifyEdit(
+                                       $now,
+                                       $this->mTitle,
+                                       $revision->isMinor(),
+                                       $user,
+                                       $summary,
+                                       $oldid,
+                                       $this->getTimestamp(),
+                                       $meta['bot'],
+                                       '',
+                                       $oldContent ? $oldContent->getSize() : 0,
+                                       $newsize,
+                                       $revisionId,
+                                       $patrolled
                                );
                        }
 
@@ -1953,31 +1872,140 @@ class WikiPage implements Page, IDBAccessObject {
 
                        $dbw->commit( __METHOD__ );
                        $this->mTimestamp = $now;
+               } else {
+                       // Bug 32948: revision ID must be set to page {{REVISIONID}} and
+                       // related variables correctly
+                       $revision->setId( $this->getLatest() );
+               }
 
-                       // Update links, etc.
-                       $this->doEditUpdates( $revision, $user, array( 'created' => true ) );
+               // Update links tables, site stats, etc.
+               $this->doEditUpdates(
+                       $revision,
+                       $user,
+                       array(
+                               'changed' => $changed,
+                               'oldcountable' => $meta['oldCountable'],
+                               'oldrevision' => $meta['oldRevision']
+                       )
+               );
+
+               if ( $changed ) {
+                       // Return the new revision to the caller
+                       $status->value['revision'] = $revision;
+               } else {
+                       $status->warning( 'edit-no-change' );
+                       // Update page_touched as updateRevisionOn() was not called.
+                       // Other cache updates are managed in onArticleEdit() via doEditUpdates().
+                       $this->mTitle->invalidateCache( $now );
+               }
 
-                       $hook_args = array( &$this, &$user, $content, $summary,
-                                                               $flags & EDIT_MINOR, null, null, &$flags, $revision );
+               return $status;
+       }
 
-                       ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
-                       Hooks::run( 'PageContentInsertComplete', $hook_args );
+       /**
+        * @param Content $content Pre-save transform content
+        * @param integer $flags
+        * @param User $user
+        * @param string $summary
+        * @param array $meta
+        * @return Status
+        * @throws DBUnexpectedError
+        * @throws Exception
+        * @throws FatalError
+        * @throws MWException
+        */
+       private function doCreate(
+               Content $content, $flags, User $user, $summary, array $meta
+       ) {
+               global $wgUseRCPatrol, $wgUseNPPatrol;
+
+               $status = Status::newGood( array( 'new' => true, 'revision' => null ) );
+
+               $now = wfTimestampNow();
+               $newsize = $content->getSize();
+               $prepStatus = $content->prepareSave( $this, $flags, $meta['oldId'], $user );
+               $status->merge( $prepStatus );
+               if ( !$status->isOK() ) {
+                       return $status;
                }
 
-               // Return the new revision (or null) to the caller
-               $status->value['revision'] = $revision;
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->begin( __METHOD__ );
 
-               $hook_args = array( &$this, &$user, $content, $summary,
-                       $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
+               // Add the page record unless one already exists for the title
+               $newid = $this->insertOn( $dbw );
+               if ( $newid === false ) {
+                       $dbw->commit( __METHOD__ ); // nothing inserted
+                       $status->fatal( 'edit-already-exists' );
 
-               ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
-               Hooks::run( 'PageContentSaveComplete', $hook_args );
+                       return $status; // nothing done
+               }
 
-               // Promote user to any groups they meet the criteria for
-               DeferredUpdates::addCallableUpdate( function () use ( $user ) {
-                       $user->addAutopromoteOnceGroups( 'onEdit' );
-                       $user->addAutopromoteOnceGroups( 'onView' ); // b/c
-               } );
+               // At this point we are now comitted to returning an OK
+               // status unless some DB query error or other exception comes up.
+               // This way callers don't have to call rollback() if $status is bad
+               // unless they actually try to catch exceptions (which is rare).
+
+               // @TODO: pass content object?!
+               $revision = new Revision( array(
+                       'page'       => $newid,
+                       'title'      => $this->mTitle, // for determining the default content model
+                       'comment'    => $summary,
+                       'minor_edit' => $meta['minor'],
+                       'text'       => $meta['serialized'],
+                       'len'        => $newsize,
+                       'user'       => $user->getId(),
+                       'user_text'  => $user->getName(),
+                       'timestamp'  => $now,
+                       'content_model' => $content->getModel(),
+                       'content_format' => $meta['serialFormat'],
+               ) );
+
+               // Save the revision text...
+               $revisionId = $revision->insertOn( $dbw );
+               // Update the page record with revision data
+               if ( !$this->updateRevisionOn( $dbw, $revision, 0 ) ) {
+                       $dbw->rollback( __METHOD__ );
+                       throw new MWException( "Failed to update page row to use new revision." );
+               }
+
+               Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
+
+               // Update recentchanges
+               if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
+                       // Mark as patrolled if the user can do so
+                       $patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) &&
+                               !count( $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
+                       // Add RC row to the DB
+                       RecentChange::notifyNew(
+                               $now,
+                               $this->mTitle,
+                               $revision->isMinor(),
+                               $user,
+                               $summary,
+                               $meta['bot'],
+                               '',
+                               $newsize,
+                               $revisionId,
+                               $patrolled
+                       );
+               }
+
+               $user->incEditCount();
+
+               $dbw->commit( __METHOD__ );
+               $this->mTimestamp = $now;
+
+               // Update links, etc.
+               $this->doEditUpdates( $revision, $user, array( 'created' => true ) );
+
+               $hook_args = array( &$this, &$user, $content, $summary,
+                       $flags & EDIT_MINOR, null, null, &$flags, $revision );
+               ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
+               Hooks::run( 'PageContentInsertComplete', $hook_args );
+
+               // Return the new revision to the caller
+               $status->value['revision'] = $revision;
 
                return $status;
        }
@@ -2156,6 +2184,8 @@ class WikiPage implements Page, IDBAccessObject {
         * - changed: boolean, whether the revision changed the content (default true)
         * - created: boolean, whether the revision created the page (default false)
         * - moved: boolean, whether the page was moved (default false)
+        * - restored: boolean, whether the page was undeleted (default false)
+        * - oldrevision: Revision object for the pre-update revision (default null)
         * - oldcountable: boolean, null, or string 'no-change' (default null):
         *   - boolean: whether the page was counted as an article before that
         *     revision, only used in changed is true and created is false
@@ -2164,10 +2194,14 @@ class WikiPage implements Page, IDBAccessObject {
         *   - 'no-change': don't update the article count, ever
         */
        public function doEditUpdates( Revision $revision, User $user, array $options = array() ) {
+               global $wgRCWatchCategoryMembership;
+
                $options += array(
                        'changed' => true,
                        'created' => false,
                        'moved' => false,
+                       'restored' => false,
+                       'oldrevision' => null,
                        'oldcountable' => null
                );
                $content = $revision->getContent();
@@ -2194,7 +2228,8 @@ class WikiPage implements Page, IDBAccessObject {
                if ( $content ) {
                        $recursive = $options['changed']; // bug 50785
                        $updates = $content->getSecondaryDataUpdates(
-                               $this->getTitle(), null, $recursive, $editInfo->output );
+                               $this->getTitle(), null, $recursive, $editInfo->output
+                       );
                        foreach ( $updates as $update ) {
                                if ( $update instanceof LinksUpdate ) {
                                        $update->setRevision( $revision );
@@ -2202,6 +2237,21 @@ class WikiPage implements Page, IDBAccessObject {
                                }
                                DeferredUpdates::addUpdate( $update );
                        }
+                       if ( $wgRCWatchCategoryMembership
+                               && ( $options['changed'] || $options['created'] )
+                               && !$options['restored']
+                       ) {
+                               // Note: jobs are pushed after deferred updates, so the job should be able to see
+                               // the recent change entry (also done via deferred updates) and carry over any
+                               // bot/deletion/IP flags, ect.
+                               JobQueueGroup::singleton()->lazyPush( new CategoryMembershipChangeJob(
+                                       $this->getTitle(),
+                                       array(
+                                               'pageId' => $this->getId(),
+                                               'revTimestamp' => $revision->getTimestamp()
+                                       )
+                               ) );
+                       }
                }
 
                Hooks::run( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
@@ -3267,7 +3317,7 @@ class WikiPage implements Page, IDBAccessObject {
                // Invalidate the caches of all pages which redirect here
                DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'redirect' ) );
 
-               // Purge squid for this page only
+               // Purge CDN for this page only
                $title->purgeSquid();
                // Clear file cache for this page only
                HTMLFileCache::clearFileCache( $title );
index 42091a0..d25d11a 100644 (file)
@@ -46,7 +46,7 @@ class CoreParserFunctions {
                        'numberofarticles', 'numberoffiles', 'numberofadmins',
                        'numberingroup', 'numberofedits', 'language',
                        'padleft', 'padright', 'anchorencode', 'defaultsort', 'filepath',
-                       'pagesincategory', 'pagesize', 'protectionlevel',
+                       'pagesincategory', 'pagesize', 'protectionlevel', 'protectionexpiry',
                        'namespacee', 'namespacenumber', 'talkspace', 'talkspacee',
                        'subjectspace', 'subjectspacee', 'pagename', 'pagenamee',
                        'fullpagename', 'fullpagenamee', 'rootpagename', 'rootpagenamee',
@@ -772,8 +772,8 @@ class CoreParserFunctions {
        /**
         * Returns the requested protection level for the current page. This
         * is an expensive parser function and can't be called too many times
-        * per page, unless the protection levels for the given title have
-        * already been retrieved
+        * per page, unless the protection levels/expiries for the given title
+        * have already been retrieved
         *
         * @param Parser $parser
         * @param string $type
@@ -795,6 +795,35 @@ class CoreParserFunctions {
                return '';
        }
 
+       /**
+        * Returns the requested protection expiry for the current page. This
+        * is an expensive parser function and can't be called too many times
+        * per page, unless the protection levels/expiries for the given title
+        * have already been retrieved
+        *
+        * @param Parser $parser
+        * @param string $type
+        * @param string $title
+        *
+        * @return string
+        */
+       public static function protectionexpiry( $parser, $type = '', $title = '' ) {
+               $titleObject = Title::newFromText( $title );
+               if ( !( $titleObject instanceof Title ) ) {
+                       $titleObject = $parser->mTitle;
+               }
+               if ( $titleObject->areRestrictionsLoaded() || $parser->incrementExpensiveFunctionCount() ) {
+                       $expiry = $parser->mTitle->getRestrictionExpiry( strtolower( $type ) );
+                       // getRestrictionExpiry() returns false on invalid type; trying to
+                       // match protectionlevel() function that returns empty string instead
+                       if ( $expiry === false ) {
+                               $expiry = '';
+                       }
+                       return $expiry;
+               }
+               return '';
+       }
+
        /**
         * Gives language names.
         * @param Parser $parser
index eb4a958..b1098f5 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use \Cdb\Reader as CdbReader;
+
 /**
  * Functions to check passwords against a policy requirement
  * @since 1.26
@@ -112,4 +114,50 @@ class PasswordPolicyChecks {
                return $status;
        }
 
+       /**
+        * Ensure that password isn't in top X most popular passwords
+        *
+        * @param $policyVal int Cut off to use. Will automatically shrink to the max
+        *   supported for error messages if set to more than max number of passwords on file,
+        *   so you can use the PHP_INT_MAX constant here safely.
+        * @param $user User
+        * @param $password String
+        * @since 1.27
+        * @return Status
+        */
+       public static function checkPopularPasswordBlacklist( $policyVal, User $user, $password ) {
+               global $wgPopularPasswordFile, $wgSitename;
+               $status = Status::newGood();
+               if ( $policyVal > 0 ) {
+                       $langEn = Language::factory( 'en' );
+                       $passwordKey = $langEn->lc( trim( $password ) );
+
+                       // People often use the name of the current site, which won't be
+                       // in the common password file. Also check '' for people who use
+                       // just whitespace.
+                       $sitename = $langEn->lc( trim( $wgSitename ) );
+                       $hardcodedCommonPasswords = array( '', 'wiki', 'mediawiki', $sitename );
+                       if ( in_array( $passwordKey, $hardcodedCommonPasswords ) ) {
+                               $status->error( 'passwordtoopopular' );
+                               return $status;
+                       }
+
+                       // This could throw an exception, but there's not a good way
+                       // of failing gracefully, if say the file is missing, so just
+                       // let the exception fall through.
+                       // Format of cdb file is mapping password => popularity rank.
+                       // See maintenance/createCommonPasswordCdb.php
+                       $db = CdbReader::open( $wgPopularPasswordFile );
+
+                       $res = $db->get( $passwordKey );
+                       if ( $res && (int)$res <= $policyVal ) {
+                               // Note: If you want to find the true number of common
+                               // passwords stored (for reporting the error), you have to take
+                               // the max of the policyVal and $db->get( '_TOTALENTRIES' ).
+                               $status->error( 'passwordtoopopular' );
+                       }
+               }
+               return $status;
+       }
+
 }
index 76d62d2..5efb3ab 100644 (file)
@@ -33,13 +33,10 @@ class ProfilerOutputDb extends ProfilerOutput {
 
        public function __construct( Profiler $collector, array $params ) {
                parent::__construct( $collector, $params );
-               global $wgProfilePerHost;
 
                // Initialize per-host profiling from config, back-compat if available
                if ( isset( $this->params['perHost'] ) ) {
                        $this->perHost = $this->params['perHost'];
-               } elseif ( $wgProfilePerHost ) {
-                       $this->perHost = $wgProfilePerHost;
                }
        }
 
index 414f8e2..1f3085a 100644 (file)
@@ -101,11 +101,11 @@ class ResourceLoader implements LoggerAwareInterface {
         * requests its own information. This sacrifice of modularity yields a substantial
         * performance improvement.
         *
-        * @param array $modules List of module names to preload information for
+        * @param array $moduleNames List of module names to preload information for
         * @param ResourceLoaderContext $context Context to load the information within
         */
-       public function preloadModuleInfo( array $modules, ResourceLoaderContext $context ) {
-               if ( !count( $modules ) ) {
+       public function preloadModuleInfo( array $moduleNames, ResourceLoaderContext $context ) {
+               if ( !$moduleNames ) {
                        // Or else Database*::select() will explode, plus it's cheaper!
                        return;
                }
@@ -116,11 +116,12 @@ class ResourceLoader implements LoggerAwareInterface {
                // Batched version of ResourceLoaderModule::getFileDependencies
                $vary = "$skin|$lang";
                $res = $dbr->select( 'module_deps', array( 'md_module', 'md_deps' ), array(
-                               'md_module' => $modules,
+                               'md_module' => $moduleNames,
                                'md_skin' => $vary,
                        ), __METHOD__
                );
-               // Prime in-object cache values for each module
+
+               // Prime in-object cache for file dependencies
                $modulesWithDeps = array();
                foreach ( $res as $row ) {
                        $module = $this->getModule( $row->md_module );
@@ -132,41 +133,25 @@ class ResourceLoader implements LoggerAwareInterface {
                        }
                }
                // Register the absence of a dependency row too
-               foreach ( array_diff( $modules, $modulesWithDeps ) as $name ) {
+               foreach ( array_diff( $moduleNames, $modulesWithDeps ) as $name ) {
                        $module = $this->getModule( $name );
                        if ( $module ) {
                                $this->getModule( $name )->setFileDependencies( $context, array() );
                        }
                }
 
-               // Get message blob mtimes. Only do this for modules with messages
-               $modulesWithMessages = array();
-               foreach ( $modules as $name ) {
+               // Prime in-object cache for message blobs for modules with messages
+               $modules = array();
+               foreach ( $moduleNames as $name ) {
                        $module = $this->getModule( $name );
-                       if ( $module && count( $module->getMessages() ) ) {
-                               $modulesWithMessages[] = $name;
-                       }
-               }
-               $modulesWithoutMessages = array_flip( $modules ); // Will be trimmed down by the loop below
-               if ( count( $modulesWithMessages ) ) {
-                       $res = $dbr->select( 'msg_resource', array( 'mr_resource', 'mr_timestamp' ), array(
-                                       'mr_resource' => $modulesWithMessages,
-                                       'mr_lang' => $lang
-                               ), __METHOD__
-                       );
-                       foreach ( $res as $row ) {
-                               $module = $this->getModule( $row->mr_resource );
-                               if ( $module ) {
-                                       $module->setMsgBlobMtime( $lang, wfTimestamp( TS_UNIX, $row->mr_timestamp ) );
-                                       unset( $modulesWithoutMessages[$row->mr_resource] );
-                               }
+                       if ( $module && $module->getMessages() ) {
+                               $modules[$name] = $module;
                        }
                }
-               foreach ( array_keys( $modulesWithoutMessages ) as $name ) {
-                       $module = $this->getModule( $name );
-                       if ( $module ) {
-                               $module->setMsgBlobMtime( $lang, 1 );
-                       }
+               $store = $this->getMessageBlobStore();
+               $blobs = $store->getBlobs( $modules, $lang );
+               foreach ( $blobs as $name => $blob ) {
+                       $modules[$name]->setMessageBlob( $blob, $lang );
                }
        }
 
@@ -241,15 +226,13 @@ class ResourceLoader implements LoggerAwareInterface {
 
        /**
         * Register core modules and runs registration hooks.
-        * @param Config|null $config
+        * @param Config $config [optional]
+        * @param LoggerInterface $logger [optional]
         */
        public function __construct( Config $config = null, LoggerInterface $logger = null ) {
                global $IP;
 
-               if ( !$logger ) {
-                       $logger = new NullLogger();
-               }
-               $this->setLogger( $logger );
+               $this->logger = $logger ?: new NullLogger();
 
                if ( !$config ) {
                        $this->logger->debug( __METHOD__ . ' was called without providing a Config instance' );
@@ -274,7 +257,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        $this->registerTestModules();
                }
 
-               $this->setMessageBlobStore( new MessageBlobStore( $this ) );
+               $this->setMessageBlobStore( new MessageBlobStore( $this, $this->logger ) );
        }
 
        /**
@@ -284,10 +267,22 @@ class ResourceLoader implements LoggerAwareInterface {
                return $this->config;
        }
 
+       /**
+        * @since 1.26
+        * @param LoggerInterface $logger
+        */
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
        }
 
+       /**
+        * @since 1.27
+        * @return LoggerInterface
+        */
+       public function getLogger() {
+               return $this->logger;
+       }
+
        /**
         * @since 1.26
         * @return MessageBlobStore
@@ -548,6 +543,7 @@ class ResourceLoader implements LoggerAwareInterface {
                                /** @var ResourceLoaderModule $object */
                                $object = new $class( $info );
                                $object->setConfig( $this->getConfig() );
+                               $object->setLogger( $this->logger );
                        }
                        $object->setName( $name );
                        $this->modules[$name] = $object;
@@ -666,7 +662,7 @@ class ResourceLoader implements LoggerAwareInterface {
                }
 
                try {
-                       // Preload for getCombinedVersion()
+                       // Preload for getCombinedVersion() and for batch makeModuleResponse()
                        $this->preloadModuleInfo( array_keys( $modules ), $context );
                } catch ( Exception $e ) {
                        MWExceptionHandler::logException( $e );
@@ -966,19 +962,6 @@ MESSAGE;
                        return $data;
                }
 
-               // Pre-fetch blobs
-               if ( $context->shouldIncludeMessages() ) {
-                       try {
-                               $this->blobStore->get( $this, $modules, $context->getLanguage() );
-                       } catch ( Exception $e ) {
-                               MWExceptionHandler::logException( $e );
-                               $this->logger->warning( 'Prefetching MessageBlobStore failed: {exception}', array(
-                                       'exception' => $e
-                               ) );
-                               $this->errors[] = self::formatExceptionNoComment( $e );
-                       }
-               }
-
                foreach ( $missing as $name ) {
                        $states[$name] = 'missing';
                }
index ff0e449..78bf69d 100644 (file)
@@ -29,10 +29,9 @@ use MediaWiki\Logger\LoggerFactory;
  * of a specific loader request
  */
 class ResourceLoaderContext {
-       /* Protected Members */
-
        protected $resourceLoader;
        protected $request;
+       protected $logger;
 
        // Module content vary
        protected $skin;
@@ -54,8 +53,6 @@ class ResourceLoaderContext {
        protected $userObj;
        protected $imageObj;
 
-       /* Methods */
-
        /**
         * @param ResourceLoader $resourceLoader
         * @param WebRequest $request
@@ -63,6 +60,7 @@ class ResourceLoaderContext {
        public function __construct( ResourceLoader $resourceLoader, WebRequest $request ) {
                $this->resourceLoader = $resourceLoader;
                $this->request = $request;
+               $this->logger = $resourceLoader->getLogger();
 
                // List of modules
                $modules = $request->getVal( 'modules' );
@@ -151,6 +149,14 @@ class ResourceLoaderContext {
                return $this->request;
        }
 
+       /**
+        * @since 1.27
+        * @return \Psr\Log\LoggerInterface
+        */
+       public function getLogger() {
+               return $this->logger;
+       }
+
        /**
         * @return array
         */
index 1421b10..f5b3bad 100644 (file)
@@ -445,7 +445,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
 
        /**
         * Gets list of names of modules this module depends on.
-        * @param ResourceLoaderContext context
+        * @param ResourceLoaderContext|null $context
         * @return array List of module names
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
@@ -583,7 +583,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                $summary[] = array(
                        'options' => $options,
                        'fileHashes' => $this->getFileHashes( $context ),
-                       'msgBlobMtime' => $this->getMsgBlobMtime( $context->getLanguage() ),
+                       'messageBlob' => $this->getMessageBlob( $context ),
                );
                return $summary;
        }
index fcda87b..113fc84 100644 (file)
  * @author Roan Kattouw
  */
 
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
 /**
  * Abstraction for ResourceLoader modules, with name registration and maxage functionality.
  */
-abstract class ResourceLoaderModule {
+abstract class ResourceLoaderModule implements LoggerAwareInterface {
        # Type of resource
        const TYPE_SCRIPTS = 'scripts';
        const TYPE_STYLES = 'styles';
@@ -60,8 +64,8 @@ abstract class ResourceLoaderModule {
 
        // In-object cache for file dependencies
        protected $fileDeps = array();
-       // In-object cache for message blob mtime
-       protected $msgBlobMtime = array();
+       // In-object cache for message blob (keyed by language)
+       protected $msgBlobs = array();
        // In-object cache for version hash
        protected $versionHash = array();
        // In-object cache for module content
@@ -72,6 +76,11 @@ abstract class ResourceLoaderModule {
         */
        protected $config;
 
+       /**
+        * @var LoggerInterface
+        */
+       protected $logger;
+
        /* Methods */
 
        /**
@@ -168,6 +177,25 @@ abstract class ResourceLoaderModule {
                $this->config = $config;
        }
 
+       /**
+        * @since 1.27
+        * @param LoggerInterface $logger
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * @since 1.27
+        * @return LoggerInterface
+        */
+       protected function getLogger() {
+               if ( !$this->logger ) {
+                       $this->logger = new NullLogger();
+               }
+               return $this->logger;
+       }
+
        /**
         * Get the URL or URLs to load for this module's JS in debug mode.
         * The default behavior is to return a load.php?only=scripts URL for
@@ -453,45 +481,40 @@ abstract class ResourceLoaderModule {
        }
 
        /**
-        * Get the last modification timestamp of the messages in this module for a given language.
-        * @param string $lang Language code
-        * @return int UNIX timestamp
+        * Get the hash of the message blob.
+        *
+        * @since 1.27
+        * @param ResourceLoaderContext $context
+        * @return string|null JSON blob or null if module has no messages
         */
-       public function getMsgBlobMtime( $lang ) {
-               if ( !isset( $this->msgBlobMtime[$lang] ) ) {
-                       if ( !count( $this->getMessages() ) ) {
-                               return 1;
-                       }
-
-                       $dbr = wfGetDB( DB_SLAVE );
-                       $msgBlobMtime = $dbr->selectField( 'msg_resource',
-                               'mr_timestamp',
-                               array(
-                                       'mr_resource' => $this->getName(),
-                                       'mr_lang' => $lang
-                               ),
-                               __METHOD__
-                       );
-                       // If no blob was found, but the module does have messages, that means we need
-                       // to regenerate it. Return NOW
-                       if ( $msgBlobMtime === false ) {
-                               $msgBlobMtime = wfTimestampNow();
-                       }
-                       $this->msgBlobMtime[$lang] = wfTimestamp( TS_UNIX, $msgBlobMtime );
+       protected function getMessageBlob( ResourceLoaderContext $context ) {
+               if ( !$this->getMessages() ) {
+                       // Don't bother consulting MessageBlobStore
+                       return null;
                }
-               return $this->msgBlobMtime[$lang];
+               // Message blobs may only vary language, not by context keys
+               $lang = $context->getLanguage();
+               if ( !isset( $this->msgBlobs[$lang] ) ) {
+                       $this->getLogger()->warning( 'Message blob for {module} should have been preloaded', array(
+                               'module' => $this->getName(),
+                       ) );
+                       $store = $context->getResourceLoader()->getMessageBlobStore();
+                       $this->msgBlobs[$lang] = $store->getBlob( $this, $lang );
+               }
+               return $this->msgBlobs[$lang];
        }
 
        /**
-        * Set in-object cache for message blob time.
+        * Set in-object cache for message blobs.
         *
-        * This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
+        * Used to allow fetching of message blobs in batches. See ResourceLoader::preloadModuleInfo().
         *
+        * @since 1.27
+        * @param string|null $blob JSON blob or null
         * @param string $lang Language code
-        * @param int $mtime UNIX timestamp
         */
-       public function setMsgBlobMtime( $lang, $mtime ) {
-               $this->msgBlobMtime[$lang] = $mtime;
+       public function setMessageBlob( $blob, $lang ) {
+               $this->msgBlobs[$lang] = $blob;
        }
 
        /**
@@ -607,13 +630,9 @@ abstract class ResourceLoaderModule {
                }
 
                // Messages
-               $blobs = $rl->getMessageBlobStore()->get(
-                       $rl,
-                       array( $this->getName() => $this ),
-                       $context->getLanguage()
-               );
-               if ( isset( $blobs[$this->getName()] ) ) {
-                       $content['messagesBlob'] = $blobs[$this->getName()];
+               $blob = $this->getMessageBlob( $context );
+               if ( $blob ) {
+                       $content['messagesBlob'] = $blob;
                }
 
                $templates = $this->getTemplates();
@@ -746,7 +765,7 @@ abstract class ResourceLoaderModule {
         * A number of utility methods are available to help you gather data. These are not
         * called by default and must be included by the subclass' getDefinitionSummary().
         *
-        * - getMsgBlobMtime()
+        * - getMessageBlob()
         *
         * @since 1.23
         * @param ResourceLoaderContext $context
index 9e840d5..39e4e0b 100644 (file)
@@ -211,6 +211,13 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                        $versionHash = $module->getVersionHash( $context );
                        if ( strlen( $versionHash ) !== 8 ) {
+                               $context->getLogger()->warning(
+                                       "Module '{module}' produced an invalid version hash: '{version}'.",
+                                       array(
+                                               'module' => $name,
+                                               'version' => $versionHash,
+                                       )
+                               );
                                // Module implementation either broken or deviated from ResourceLoader::makeHash
                                // Asserted by tests/phpunit/structure/ResourcesTest.
                                $versionHash = ResourceLoader::makeHash( $versionHash );
index 2295eaa..c8276fc 100644 (file)
@@ -108,16 +108,18 @@ class RevDelFileList extends RevDelList {
                $file = wfLocalFile( $this->title );
                $file->purgeCache();
                $file->purgeDescription();
+
+               // Purge full images from cache
                $purgeUrls = array();
                foreach ( $this->ids as $timestamp ) {
                        $archiveName = $timestamp . '!' . $this->title->getDBkey();
                        $file->purgeOldThumbnails( $archiveName );
                        $purgeUrls[] = $file->getArchiveUrl( $archiveName );
                }
-               if ( $this->getConfig()->get( 'UseSquid' ) ) {
-                       // purge full images from cache
-                       SquidUpdate::purge( $purgeUrls );
-               }
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( $purgeUrls ),
+                       DeferredUpdates::PRESEND
+               );
 
                return Status::newGood();
        }
index db2bc6a..d68ef45 100644 (file)
@@ -85,7 +85,8 @@ class RevisionDeleter {
                if ( !$typeName ) {
                        throw new MWException( __METHOD__ . ": Unknown RevDel type '$typeName'" );
                }
-               return new self::$allowedTypes[$typeName]( $context, $title, $ids );
+               $class = self::$allowedTypes[$typeName];
+               return new $class( $context, $title, $ids );
        }
 
        /**
diff --git a/includes/search/SearchExactMatchRescorer.php b/includes/search/SearchExactMatchRescorer.php
new file mode 100644 (file)
index 0000000..0ff628d
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Rescores results from a prefix search/opensearch to make sure the
+ * exact match is the first result.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * An utility class to rescore search results by looking for an exact match
+ * in the db and add the page found to the first position.
+ *
+ * NOTE: extracted from TitlePrefixSearch
+ * @ingroup Search
+ */
+class SearchExactMatchRescorer {
+       /**
+        * Default search backend does proper prefix searching, but custom backends
+        * may sort based on other algorithms that may cause the exact title match
+        * to not be in the results or be lower down the list.
+        * @param string $search the query
+        * @param int[] $namespaces the namespaces
+        * @param int $limit the max number of results to return
+        * @param string[] $srchres results
+        * @return string[] munged results
+        */
+       public function rescore( $search, $namespaces, $srchres, $limit ) {
+               // Pick namespace (based on PrefixSearch::defaultSearchBackend)
+               $ns = in_array( NS_MAIN, $namespaces ) ? NS_MAIN : $namespaces[0];
+               $t = Title::newFromText( $search, $ns );
+               if ( !$t || !$t->exists() ) {
+                       // No exact match so just return the search results
+                       return $srchres;
+               }
+               $string = $t->getPrefixedText();
+               $key = array_search( $string, $srchres );
+               if ( $key !== false ) {
+                       // Exact match was in the results so just move it to the front
+                       return $this->pullFront( $key, $srchres );
+               }
+               // Exact match not in the search results so check for some redirect handling cases
+               if ( $t->isRedirect() ) {
+                       $target = $this->getRedirectTarget( $t );
+                       $key = array_search( $target, $srchres );
+                       if ( $key !== false ) {
+                               // Exact match is a redirect to one of the returned matches so pull the
+                               // returned match to the front.  This might look odd but the alternative
+                               // is to put the redirect in front and drop the match.  The name of the
+                               // found match is often more descriptive/better formed than the name of
+                               // the redirect AND by definition they share a prefix.  Hopefully this
+                               // choice is less confusing and more helpful.  But it might not be.  But
+                               // it is the choice we're going with for now.
+                               return $this->pullFront( $key, $srchres );
+                       }
+                       $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
+                       if ( isset( $redirectTargetsToRedirect[$target] ) ) {
+                               // The exact match and something in the results list are both redirects
+                               // to the same thing!  In this case we'll pull the returned match to the
+                               // top following the same logic above.  Again, it might not be a perfect
+                               // choice but it'll do.
+                               return $this->pullFront( $redirectTargetsToRedirect[$target], $srchres );
+                       }
+               } else {
+                       $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
+                       if ( isset( $redirectTargetsToRedirect[$string] ) ) {
+                               // The exact match is the target of a redirect already in the results list so remove
+                               // the redirect from the results list and push the exact match to the front
+                               array_splice( $srchres, $redirectTargetsToRedirect[$string], 1 );
+                               array_unshift( $srchres, $string );
+                               return $srchres;
+                       }
+               }
+
+               // Exact match is totally unique from the other results so just add it to the front
+               array_unshift( $srchres, $string );
+               // And roll one off the end if the results are too long
+               if ( count( $srchres ) > $limit ) {
+                       array_pop( $srchres );
+               }
+               return $srchres;
+       }
+
+       /**
+        * @param string[] $titles as strings
+        * @return array redirect target prefixedText to index of title in titles
+        *   that is a redirect to it.
+        */
+       private function redirectTargetsToRedirect( $titles ) {
+               $result = array();
+               foreach ( $titles as $key => $titleText ) {
+                       $title = Title::newFromText( $titleText );
+                       if ( !$title || !$title->isRedirect() ) {
+                               continue;
+                       }
+                       $target = $this->getRedirectTarget( $title );
+                       if ( !$target ) {
+                               continue;
+                       }
+                       $result[$target] = $key;
+               }
+               return $result;
+       }
+
+       /**
+        * Returns an array where the element of $array at index $key becomes
+        * the first element.
+        * @param int $key key to pull to the front
+        * @return array $array with the item at $key pulled to the front
+        */
+       private function pullFront( $key, $array ) {
+               $cut = array_splice( $array, $key, 1 );
+               array_unshift( $array, $cut[0] );
+               return $array;
+       }
+
+       /**
+        * Get a redirect's destination from a title
+        * @param Title $title A title to redirect. It may not redirect or even exist
+        * @return null|string If title exists and redirects, get the destination's prefixed name
+        */
+       private function getRedirectTarget( $title ) {
+               $page = WikiPage::factory( $title );
+               if ( !$page->exists() ) {
+                       return null;
+               }
+               $redir = $page->getRedirectTarget();
+               return $redir ? $redir->getPrefixedText() : null;
+       }
+}
index b9f9d3d..dbb7c7f 100644 (file)
@@ -232,7 +232,7 @@ abstract class Skin extends ContextSource {
                $title = $this->getRelevantTitle();
 
                // User/talk link
-               if ( $user->isLoggedIn() || $this->showIPinHeader() ) {
+               if ( $user->isLoggedIn() ) {
                        $titles[] = $user->getUserPage();
                        $titles[] = $user->getTalkPage();
                }
@@ -725,12 +725,12 @@ abstract class Skin extends ContextSource {
        }
 
        /**
-        * Returns true if the IP should be shown in the header
-        * @return bool
+        * @deprecated since 1.27, feature removed
+        * @return bool Always false
         */
        function showIPinHeader() {
-               global $wgShowIPinHeader;
-               return $wgShowIPinHeader && session_id() != '';
+               wfDeprecated( __METHOD__, '1.27' );
+               return false;
        }
 
        /**
@@ -1445,8 +1445,8 @@ abstract class Skin extends ContextSource {
                                )->numParams( $plural );
                        }
                        $newMessagesAlert = $newMessagesAlert->text();
-                       # Disable Squid cache
-                       $out->setSquidMaxage( 0 );
+                       # Disable CDN cache
+                       $out->setCdnMaxage( 0 );
                } elseif ( count( $newtalks ) ) {
                        $sep = $this->msg( 'newtalkseparator' )->escaped();
                        $msgs = array();
@@ -1459,7 +1459,7 @@ abstract class Skin extends ContextSource {
                        }
                        $parts = implode( $sep, $msgs );
                        $newMessagesAlert = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped();
-                       $out->setSquidMaxage( 0 );
+                       $out->setCdnMaxage( 0 );
                }
 
                return $newMessagesAlert;
index 4d7c03a..163f3d5 100644 (file)
@@ -207,7 +207,7 @@ class SkinTemplate extends Skin {
                $this->loggedin = $user->isLoggedIn();
                $this->username = $user->getName();
 
-               if ( $this->loggedin || $this->showIPinHeader() ) {
+               if ( $this->loggedin ) {
                        $this->userpageUrlDetails = self::makeUrlDetails( $this->userpage );
                } else {
                        # This won't be used in the standard skins, but we define it to preserve the interface
@@ -660,21 +660,28 @@ class SkinTemplate extends Skin {
                                'active' => $title->isSpecial( 'Userlogin' ) && $is_signup,
                        );
 
-                       if ( $this->showIPinHeader() ) {
-                               $href = &$this->userpageUrlDetails['href'];
+                       // No need to show Talk and Contributions to anons if they can't contribute!
+                       if ( User::groupHasPermission( '*', 'edit' ) ) {
+                               // Show the text "Not logged in"
                                $personal_urls['anonuserpage'] = array(
-                                       'text' => $this->username,
-                                       'href' => $href,
-                                       'class' => $this->userpageUrlDetails['exists'] ? false : 'new',
-                                       'active' => ( $pageurl == $href )
+                                       'text' => $this->msg( 'notloggedin' )->text()
                                );
-                               $usertalkUrlDetails = $this->makeTalkUrlDetails( $this->userpage );
-                               $href = &$usertalkUrlDetails['href'];
+
+                               // Because of caching, we can't link directly to the IP talk and
+                               // contributions pages. Instead we use the special page shortcuts
+                               // (which work correctly regardless of caching). This means we can't
+                               // determine whether these links are active or not, but since major
+                               // skins (MonoBook, Vector) don't use this information, it's not a
+                               // huge loss.
                                $personal_urls['anontalk'] = array(
                                        'text' => $this->msg( 'anontalk' )->text(),
-                                       'href' => $href,
-                                       'class' => $usertalkUrlDetails['exists'] ? false : 'new',
-                                       'active' => ( $pageurl == $href )
+                                       'href' => self::makeSpecialUrlSubpage( 'Mytalk', false ),
+                                       'active' => false
+                               );
+                               $personal_urls['anoncontribs'] = array(
+                                       'text' => $this->msg( 'anoncontribs' )->text(),
+                                       'href' => self::makeSpecialUrlSubpage( 'Mycontributions', false ),
+                                       'active' => false
                                );
                        }
 
index bfb29ae..9755e8e 100644 (file)
@@ -473,12 +473,37 @@ abstract class QueryPage extends SpecialPage {
         * Returns limit and offset, as returned by $this->getRequest()->getLimitOffset().
         * Subclasses may override this to further restrict or modify limit and offset.
         *
+        * @note Restricts the offset parameter, as most query pages have inefficient paging
         * @since 1.26
         *
         * @return int[] list( $limit, $offset )
         */
        protected function getLimitOffset() {
-               return $this->getRequest()->getLimitOffset();
+               list( $limit, $offset ) = $this->getRequest()->getLimitOffset();
+               if ( !$this->getConfig()->get( 'MiserMode' ) ) {
+                       $maxResults = $this->getMaxResults();
+                       // Can't display more than max results on a page
+                       $limit = min( $limit, $maxResults );
+                       // Can't skip over more than $maxResults
+                       $offset = min( $offset, $maxResults );
+                       // Can't let $offset + $limit > $maxResults
+                       $limit = min( $limit, $maxResults - $offset );
+               }
+               return array( $limit, $offset );
+       }
+
+       /**
+        * Get max number of results we can return in miser mode.
+        *
+        * Most QueryPage subclasses use inefficient paging, so limit the max amount we return
+        * This matters for uncached query pages that might otherwise accept an offset of 3 million
+        *
+        * @since 1.27
+        * @return int
+        */
+       protected function getMaxResults() {
+               // Max of 10000, unless we store more than 5000 in query cache.
+               return max( $this->getConfig()->get( 'QueryCacheLimit' ), 10000 );
        }
 
        /**
@@ -562,8 +587,10 @@ abstract class QueryPage extends SpecialPage {
                                        min( $this->numRows, $this->limit ), # do not show the one extra row, if exist
                                        $this->offset + 1, ( min( $this->numRows, $this->limit ) + $this->offset ) )->parseAsBlock() );
                                # Disable the "next" link when we reach the end
+                               $atEnd = ( $this->numRows <= $this->limit )
+                                       || ( $this->offset + $this-> limit  >= $this->getMaxResults() );
                                $paging = $this->getLanguage()->viewPrevNext( $this->getPageTitle( $par ), $this->offset,
-                                       $this->limit, $this->linkParameters(), ( $this->numRows <= $this->limit ) );
+                                       $this->limit, $this->linkParameters(), $atEnd );
                                $out->addHTML( '<p>' . $paging . '</p>' );
                        } else {
                                # No results to show, so don't bother with "showing X of Y" etc.
index 047e941..70c7a8b 100644 (file)
@@ -212,10 +212,20 @@ class ActiveUsersPager extends UsersPager {
                $out .= Xml::fieldset( $this->msg( 'activeusers' )->text() ) . "\n";
                $out .= Html::hidden( 'title', $self->getPrefixedDBkey() ) . $limit . "\n";
 
-               # Username field
-               $out .= Xml::inputLabel( $this->msg( 'activeusers-from' )->text(),
-                       'username', 'offset', 20, $this->requestedUser,
-                       array( 'class' => 'mw-ui-input-inline', 'tabindex' => 1 ) ) . '<br />';
+               # Username field (with autocompletion support)
+               $this->getOutput()->addModules( 'mediawiki.userSuggest' );
+               $out .= Xml::inputLabel(
+                       $this->msg( 'activeusers-from' )->text(),
+                       'username',
+                       'offset',
+                       20,
+                       $this->requestedUser,
+                       array(
+                               'class' => 'mw-ui-input-inline mw-autocomplete-user',
+                               'tabindex' => 1,
+                               'autofocus' => $this->requestedUser === '',
+                       )
+               ) . '<br />';
 
                $out .= Xml::checkLabel( $this->msg( 'activeusers-hidebots' )->text(),
                        'hidebots', 'hidebots', $this->opts->getValue( 'hidebots' ), array( 'tabindex' => 2 ) );
@@ -230,7 +240,7 @@ class ActiveUsersPager extends UsersPager {
 
                # Submit button and form bottom
                $out .= Xml::submitButton(
-                       $this->msg( 'allpagessubmit' )->text(),
+                       $this->msg( 'activeusers-submit' )->text(),
                        array( 'tabindex' => 4 )
                ) . "\n";
                $out .= Xml::closeElement( 'fieldset' );
@@ -308,3 +318,5 @@ class SpecialActiveUsers extends SpecialPage {
                return 'users';
        }
 }
+
+
index 190fe8f..9e75522 100644 (file)
@@ -356,6 +356,26 @@ class SpecialAllPages extends IncludableSpecialPage {
                }
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
        protected function getGroupName() {
                return 'pages';
        }
index cea6ceb..564579a 100644 (file)
@@ -191,7 +191,7 @@ class CategoryPager extends AlphabeticPager {
                                                'from', 'from', 20, $from, array( 'class' => 'mw-ui-input-inline' ) ) .
                                                ' ' .
                                                Html::submitButton(
-                                                       $this->msg( 'allpagessubmit' )->text(),
+                                                       $this->msg( 'categories-submit' )->text(),
                                                        array(), array( 'mw-ui-progressive' )
                                                )
                                )
index b0def59..4812c9d 100644 (file)
@@ -220,4 +220,28 @@ class SpecialChangeContentModel extends FormSpecialPage {
                $out->setPageTitle( $this->msg( 'changecontentmodel-success-title' ) );
                $out->addWikiMsg( 'changecontentmodel-success-text', $this->title );
        }
+
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
+       protected function getGroupName() {
+               return 'pagetools';
+       }
 }
index 5f7c587..b1908c2 100644 (file)
@@ -465,7 +465,8 @@ class SpecialContributions extends IncludableSpecialPage {
                        'month',
                        'topOnly',
                        'newOnly',
-                       'associated'
+                       'associated',
+                       'tagfilter'
                );
 
                foreach ( $this->opts as $name => $value ) {
@@ -481,7 +482,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        $filterSelection = Html::rawElement(
                                'td',
                                array(),
-                               array_shift( $tagFilter ) . implode( '&#160', $tagFilter )
+                               implode( '&#160', $tagFilter )
                        );
                } else {
                        $filterSelection = Html::rawElement( 'td', array( 'colspan' => 2 ), '' );
index 6b0d1ec..3b31530 100644 (file)
@@ -260,6 +260,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         * @return string Form asking for user name.
         */
        protected function userForm( $name ) {
+               $this->getOutput()->addModules( 'mediawiki.userSuggest' );
                $string = Xml::openElement(
                        'form',
                        array( 'method' => 'get', 'action' => wfScript(), 'id' => 'askusername' )
@@ -272,7 +273,11 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                                'target',
                                'emailusertarget',
                                30,
-                               $name
+                               $name,
+                               array(
+                                       'class' => 'mw-autocomplete-user',  // used by mediawiki.userSuggest
+                                       'autofocus' => true,
+                               )
                        ) .
                        ' ' .
                        Xml::submitButton( $this->msg( 'emailusernamesubmit' )->text() ) .
index 642ea69..91fef03 100644 (file)
@@ -65,7 +65,10 @@ class SpecialExport extends SpecialPage {
                                         */
                                        $catpages = $this->getPagesFromCategory( $t );
                                        if ( $catpages ) {
-                                               $page .= "\n" . implode( "\n", $catpages );
+                                               if ( $page !== '' ) {
+                                                       $page .= "\n";
+                                               }
+                                               $page .= implode( "\n", $catpages );
                                        }
                                }
                        }
index 8c9a76b..bb57ee0 100644 (file)
@@ -232,6 +232,30 @@ class FileDuplicateSearchPage extends QueryPage {
                return "$plink . . $user . . $time";
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || $title->getNamespace() !== NS_FILE ) {
+                       // No prefix suggestion outside of file namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search, but just for files
+               $prefixSearcher = new TitlePrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array( NS_FILE ), $offset );
+
+               return array_map( function ( Title $t ) {
+                       // Remove namespace in search suggestion
+                       return $t->getText();
+               }, $result );
+       }
+
        protected function getGroupName() {
                return 'media';
        }
index 3ea56c6..8de4e2f 100644 (file)
@@ -108,7 +108,7 @@ class ImageListPager extends TablePager {
 
                if ( $search !== '' && !$this->getConfig()->get( 'MiserMode' ) ) {
                        $this->mSearch = $search;
-                       $nt = Title::newFromURL( $this->mSearch );
+                       $nt = Title::newFromText( $this->mSearch );
 
                        if ( $nt ) {
                                $dbr = wfGetDB( DB_SLAVE );
@@ -147,7 +147,7 @@ class ImageListPager extends TablePager {
                }
 
                if ( $this->mSearch !== '' ) {
-                       $nt = Title::newFromURL( $this->mSearch );
+                       $nt = Title::newFromText( $this->mSearch );
                        if ( $nt ) {
                                $dbr = wfGetDB( DB_SLAVE );
                                $conds[] = 'LOWER(' . $prefix . '_name)' .
index 274a95a..d43a263 100644 (file)
@@ -322,7 +322,7 @@ class UsersPager extends AlphabeticPager {
 
                # Submit button and form bottom
                $out .= Html::hidden( 'limit', $this->mLimit );
-               $out .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() );
+               $out .= Xml::submitButton( $this->msg( 'listusers-submit' )->text() );
                Hooks::run( 'SpecialListusersHeader', array( $this, &$out ) );
                $out .= Xml::closeElement( 'fieldset' ) .
                        Xml::closeElement( 'form' );
index ef1fd73..f11ed9a 100644 (file)
@@ -91,8 +91,8 @@ class SpecialMergeHistory extends SpecialPage {
 
                // target page
                if ( $this->mSubmitted ) {
-                       $this->mTargetObj = Title::newFromURL( $this->mTarget );
-                       $this->mDestObj = Title::newFromURL( $this->mDest );
+                       $this->mTargetObj = Title::newFromText( $this->mTarget );
+                       $this->mDestObj = Title::newFromText( $this->mDest );
                } else {
                        $this->mTargetObj = null;
                        $this->mDestObj = null;
index e9fb75b..a1bd2fa 100644 (file)
@@ -793,6 +793,26 @@ class MovePageForm extends UnlistedSpecialPage {
                $out->addHTML( "</ul>\n" );
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
        protected function getGroupName() {
                return 'pagetools';
        }
index 00c8e05..6b7c038 100644 (file)
@@ -113,7 +113,7 @@ class NewFilesPager extends ReverseChronologicalPager {
 
                if ( !$this->getConfig()->get( 'MiserMode' ) && $this->like !== null ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $likeObj = Title::newFromURL( $this->like );
+                       $likeObj = Title::newFromText( $this->like );
                        if ( $likeObj instanceof Title ) {
                                $like = $dbr->buildLike(
                                        $dbr->anyString(),
index 0fa4857..5d3700d 100644 (file)
@@ -254,7 +254,7 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                $htmlForm = new HTMLForm( $form, $this->getContext() );
 
-               $htmlForm->setSubmitText( $this->msg( 'allpagessubmit' )->text() );
+               $htmlForm->setSubmitText( $this->msg( 'newpages-submit' )->text() );
                $htmlForm->setSubmitProgressive();
                // The form should be visible on each request (inclusive requests with submitted forms), so
                // return always false here.
index 177c19b..02fca3a 100644 (file)
@@ -198,6 +198,26 @@ class SpecialPageLanguage extends FormSpecialPage {
                return $out1 . $out2;
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
        protected function getGroupName() {
                return 'pagetools';
        }
index 53e1d1b..292b575 100644 (file)
@@ -42,6 +42,11 @@ class SpecialPasswordReset extends FormSpecialPage {
         */
        private $result;
 
+       /**
+        * @var string $method Identifies which password reset field was specified by the user.
+        */
+       private $method;
+
        public function __construct() {
                parent::__construct( 'PasswordReset', 'editmyprivateinfo' );
        }
@@ -196,6 +201,8 @@ class SpecialPasswordReset extends FormSpecialPage {
                        return array( $error );
                }
 
+               $this->method = $method;
+
                if ( count( $users ) == 0 ) {
                        if ( $method == 'email' ) {
                                // Don't reveal whether or not an email address is in use
@@ -310,7 +317,12 @@ class SpecialPasswordReset extends FormSpecialPage {
                        $this->getOutput()->addHTML( Html::rawElement( 'pre', array(), $this->email->escaped() ) );
                }
 
-               $this->getOutput()->addWikiMsg( 'passwordreset-emailsent' );
+               if ( $this->method === 'email' ) {
+                       $this->getOutput()->addWikiMsg( 'passwordreset-emailsentemail' );
+               } else {
+                       $this->getOutput()->addWikiMsg( 'passwordreset-emailsentusername' );
+               }
+
                $this->getOutput()->returnToMain();
        }
 
index f10a979..a6c0423 100644 (file)
@@ -138,7 +138,7 @@ class SpecialPrefixindex extends SpecialAllPages {
                                'stripprefix',
                                $this->stripPrefix
                        ) . ' ' .
-                       Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) .
+                       Xml::submitButton( $this->msg( 'prefixindex-submit' )->text() ) .
                        "</td>
                        </tr>";
                $out .= Xml::closeElement( 'table' );
@@ -294,6 +294,26 @@ class SpecialPrefixindex extends SpecialAllPages {
                $output->addHTML( $topOut . $out );
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
        protected function getGroupName() {
                return 'pages';
        }
index 6859310..7a82cd8 100644 (file)
@@ -109,7 +109,7 @@ class SpecialProtectedpages extends SpecialPage {
                        $this->getRedirectCheck( $noRedirect ) . "\n" .
                        "<br />\n" .
                        $this->getSizeLimit( $sizetype, $size ) . "\n" .
-                       Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" .
+                       Xml::submitButton( $this->msg( 'protectedpages-submit' )->text() ) . "\n" .
                        Xml::closeElement( 'fieldset' ) .
                        Xml::closeElement( 'form' );
        }
@@ -228,7 +228,7 @@ class SpecialProtectedpages extends SpecialPage {
                }
 
                return '<span class="mw-input-with-label">' .
-                       Xml::label( $this->msg( 'restriction-type' )->text(), $this->IdType ) . '&#160;' .
+                       Xml::label( $this->msg( 'restriction-type' )->text(), $this->IdType ) . ' ' .
                        Xml::tags( 'select',
                                array( 'id' => $this->IdType, 'name' => $this->IdType ),
                                implode( "\n", $options ) ) . "</span>";
index 85ce78f..2c79fec 100644 (file)
@@ -126,7 +126,7 @@ class SpecialProtectedtitles extends SpecialPage {
                        Html::hidden( 'title', $special ) . "&#160;\n" .
                        $this->getNamespaceMenu( $namespace ) . "&#160;\n" .
                        $this->getLevelMenu( $level ) . "&#160;\n" .
-                       "&#160;" . Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" .
+                       "&#160;" . Xml::submitButton( $this->msg( 'protectedtitles-submit' )->text() ) . "\n" .
                        "</fieldset></form>";
        }
 
index 44c9987..4848d01 100644 (file)
@@ -50,7 +50,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                }
 
                // 10 seconds server-side caching max
-               $this->getOutput()->setSquidMaxage( 10 );
+               $this->getOutput()->setCdnMaxage( 10 );
                // Check if the client has a cached version
                $lastmod = $this->checkLastModified();
                if ( $lastmod === false ) {
@@ -403,7 +403,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $extraOpts = $this->getExtraOptions( $opts );
                $extraOptsCount = count( $extraOpts );
                $count = 0;
-               $submit = ' ' . Xml::submitbutton( $this->msg( 'allpagessubmit' )->text() );
+               $submit = ' ' . Xml::submitbutton( $this->msg( 'recentchanges-submit' )->text() );
 
                $out = Xml::openElement( 'table', array( 'class' => 'mw-recentchanges-table' ) );
                foreach ( $extraOpts as $name => $optionRow ) {
index 3c403fe..8db8f24 100644 (file)
@@ -55,7 +55,7 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
                        return false;
                }
                $outputPage = $this->getOutput();
-               $title = Title::newFromURL( $target );
+               $title = Title::newFromText( $target );
                if ( !$title || $title->isExternal() ) {
                        $outputPage->addHtml( '<div class="errorbox">' . $this->msg( 'allpagesbadtitle' )
                                        ->parse() . '</div>' );
@@ -263,4 +263,24 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
 
                return $this->rclTargetTitle;
        }
+
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
 }
index 65cb8e5..5ed0483 100644 (file)
@@ -329,10 +329,10 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        return;
                }
                $this->getOutput()->disable();
-               # We mustn't allow the output to be Squid cached, otherwise
+               # We mustn't allow the output to be CDN cached, otherwise
                # if an admin previews a deleted image, and it's cached, then
                # a user without appropriate permissions can toddle off and
-               # nab the image, and Squid will serve it
+               # nab the image, and CDN will serve it
                $this->getRequest()->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
                $this->getRequest()->response()->header(
                        'Cache-Control: no-cache, no-store, max-age=0, must-revalidate'
index e06bae0..a989aac 100644 (file)
@@ -114,16 +114,18 @@ class SpecialStatistics extends SpecialPage {
         * @return string
         */
        private function getPageStats() {
+               $specialAllPagesTitle = SpecialPage::getTitleFor( 'Allpages' );
                $pageStatsHtml = Xml::openElement( 'tr' ) .
                        Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-pages' )
                                ->parse() ) .
                        Xml::closeElement( 'tr' ) .
-                               $this->formatRow( Linker::linkKnown( SpecialPage::getTitleFor( 'Allpages' ),
-                                       $this->msg( 'statistics-articles' )->parse() ),
+                               $this->formatRow( Linker::linkKnown( $specialAllPagesTitle,
+                                       $this->msg( 'statistics-articles' )->parse(), array(), array( 'hideredirects' => 1 ) ),
                                        $this->getLanguage()->formatNum( $this->good ),
                                        array( 'class' => 'mw-statistics-articles' ),
                                        'statistics-articles-desc' ) .
-                               $this->formatRow( $this->msg( 'statistics-pages' )->parse(),
+                               $this->formatRow( Linker::linkKnown( $specialAllPagesTitle,
+                                       $this->msg( 'statistics-pages' )->parse() ),
                                        $this->getLanguage()->formatNum( $this->total ),
                                        array( 'class' => 'mw-statistics-pages' ),
                                        'statistics-pages-desc' );
index 71f387b..c03f811 100644 (file)
@@ -392,7 +392,7 @@ class SpecialTags extends SpecialPage {
                $func = $activate ? 'canActivateTag' : 'canDeactivateTag';
                $result = ChangeTags::$func( $tag, $user );
                if ( !$result->isGood() ) {
-                       $out->wrapWikiMsg( "<div class=\"error\">\n$1" . $result->getWikiText() .
+                       $out->addWikiText( "<div class=\"error\">\n" . $result->getWikiText() .
                                "\n</div>" );
                        if ( !$result->isOK() ) {
                                return;
@@ -451,6 +451,21 @@ class SpecialTags extends SpecialPage {
                }
        }
 
+       /**
+        * Return an array of subpages that this special page will accept.
+        *
+        * @return string[] subpages
+        */
+       public function getSubpagesForPrefixSearch() {
+               // The subpages does not have an own form, so not listing it at the moment
+               return array(
+                       // 'delete',
+                       // 'activate',
+                       // 'deactivate',
+                       // 'create',
+               );
+       }
+
        protected function getGroupName() {
                return 'changes';
        }
index 447c3ef..aada064 100644 (file)
@@ -625,19 +625,21 @@ class PageArchive {
                $wasnew = $article->updateIfNewerOn( $dbw, $revision, $previousRevId );
                if ( $created || $wasnew ) {
                        // Update site stats, link tables, etc
-                       $user = User::newFromName( $revision->getUserText( Revision::RAW ), false );
                        $article->doEditUpdates(
                                $revision,
-                               $user,
-                               array( 'created' => $created, 'oldcountable' => $oldcountable )
+                               User::newFromName( $revision->getUserText( Revision::RAW ), false ),
+                               array(
+                                       'created' => $created,
+                                       'oldcountable' => $oldcountable,
+                                       'restored' => true
+                               )
                        );
                }
 
                Hooks::run( 'ArticleUndelete', array( &$this->title, $created, $comment, $oldPageId ) );
 
                if ( $this->title->getNamespace() == NS_FILE ) {
-                       $update = new HTMLCacheUpdate( $this->title, 'imagelinks' );
-                       $update->doUpdate();
+                       DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->title, 'imagelinks' ) );
                }
 
                return Status::newGood( $restored );
@@ -698,7 +700,7 @@ class SpecialUndelete extends SpecialPage {
                $this->mTargetObj = null;
 
                if ( $this->mTarget !== null && $this->mTarget !== '' ) {
-                       $this->mTargetObj = Title::newFromURL( $this->mTarget );
+                       $this->mTargetObj = Title::newFromText( $this->mTarget );
                }
 
                $this->mSearchPrefix = $request->getText( 'prefix' );
@@ -1195,10 +1197,10 @@ class SpecialUndelete extends SpecialPage {
        private function showFile( $key ) {
                $this->getOutput()->disable();
 
-               # We mustn't allow the output to be Squid cached, otherwise
+               # We mustn't allow the output to be CDN cached, otherwise
                # if an admin previews a deleted image, and it's cached, then
                # a user without appropriate permissions can toddle off and
-               # nab the image, and Squid will serve it
+               # nab the image, and CDN will serve it
                $response = $this->getRequest()->response();
                $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
                $response->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
@@ -1690,6 +1692,26 @@ class SpecialUndelete extends SpecialPage {
                }
        }
 
+       /**
+        * Return an array of subpages beginning with $search that this special page will accept.
+        *
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       public function prefixSearchSubpages( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+               // Autocomplete subpage the same as a normal search
+               $prefixSearcher = new StringPrefixSearch;
+               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
+               return $result;
+       }
+
        protected function getGroupName() {
                return 'pagetools';
        }
index 38d3549..fec1e3a 100644 (file)
@@ -372,6 +372,7 @@ class LoginForm extends SpecialPage {
                        return;
                }
 
+               /** @var User $u */
                $u = $status->getValue();
 
                // Wipe the initial password and mail a temporary one
index a6fe1b5..ea22274 100644 (file)
@@ -117,6 +117,11 @@ class UserrightsPage extends SpecialPage {
                $fetchedStatus = $this->fetchUser( $this->mTarget );
                if ( $fetchedStatus->isOk() ) {
                        $this->mFetchedUser = $fetchedStatus->value;
+                       if ( $this->mFetchedUser instanceof User ) {
+                               // Set the 'relevant user' in the skin, so it displays links like Contributions,
+                               // User logs, UserRights, etc.
+                               $this->getSkin()->setRelevantUser( $this->mFetchedUser );
+                       }
                }
 
                if ( !$this->userCanChangeRights( $user, true ) ) {
@@ -458,8 +463,10 @@ class UserrightsPage extends SpecialPage {
                                30,
                                str_replace( '_', ' ', $this->mTarget ),
                                array(
-                                       'autofocus' => '',
                                        'class' => 'mw-autocomplete-user', // used by mediawiki.userSuggest
+                               ) + (
+                                       // Set autofocus on blank input and error input
+                                       $this->mFetchedUser === null ? array( 'autofocus' => '' ) : array()
                                )
                        ) . ' ' .
                        Xml::submitButton( $this->msg( 'editusergroup' )->text() ) .
index 02a1f73..ca26bb4 100644 (file)
@@ -40,13 +40,8 @@ class WantedPagesPage extends WantedQueryPage {
                $inc = $this->including();
 
                if ( $inc ) {
-                       $parts = explode( '/', $par, 2 );
-                       $this->limit = (int)$parts[0];
-                       // @todo FIXME: nlinks is ignored
-                       // $nlinks = isset( $parts[1] ) && $parts[1] === 'nlinks';
+                       $this->limit = (int)$par;
                        $this->offset = 0;
-               } else {
-                       // $nlinks = true;
                }
                $this->setListoutput( $inc );
                $this->shownavigation = !$inc;
index 32d4552..e22a8e6 100644 (file)
@@ -403,8 +403,15 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         */
        public function doHeader( $opts, $numRows ) {
                $user = $this->getUser();
+               $out = $this->getOutput();
 
-               $this->getOutput()->addSubtitle(
+               // if the user wishes, that the watchlist is reloaded, whenever a filter changes,
+               // add the module for that
+               if ( $user->getBoolOption( 'watchlistreloadautomatically' ) ) {
+                       $out->addModules( array( 'mediawiki.special.watchlist' ) );
+               }
+
+               $out->addSubtitle(
                        $this->msg( 'watchlistfor2', $user->getName() )
                                ->rawParams( SpecialEditWatchlist::buildTools( null ) )
                );
@@ -469,7 +476,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $form .= $this->msg( 'watchlist-hide' ) .
                        $this->msg( 'colon-separator' )->escaped() .
                        implode( ' ', $links );
-               $form .= "\n<hr />\n<p>";
+               $form .= "\n<br />\n";
                $form .= Html::namespaceSelector(
                        array(
                                'selected' => $opts['namespace'],
@@ -495,7 +502,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                        $opts['associated'],
                        array( 'title' => $this->msg( 'tooltip-namespace_association' )->text() )
                ) . "</span>\n";
-               $form .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "</p>\n";
+               $form .= Xml::submitButton( $this->msg( 'watchlist-submit' )->text() ) . "\n";
                foreach ( $hiddenFields as $key => $value ) {
                        $form .= Html::hidden( $key, $value ) . "\n";
                }
@@ -516,13 +523,13 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
                $userWatchlistOption = (string)$this->getUser()->getOption( 'watchlistdays' );
                // add the user preference, if it isn't available already
-               if ( !in_array( $userWatchlistOption, $days ) ) {
+               if ( !in_array( $userWatchlistOption, $days ) && $userWatchlistOption !== '0' ) {
                        $days[] = $userWatchlistOption;
                }
 
                $selected = (string)$options['days'];
                // add the currently selected value, if it isn't available already
-               if ( !in_array( $selected, $days ) ) {
+               if ( !in_array( $selected, $days ) && $selected !== '0' ) {
                        $days[] = $selected;
                }
 
@@ -540,7 +547,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
                // 'all' option
                $name = $this->msg( 'watchlistall2' )->text();
-               $value = 0;
+               $value = '0';
                $select->addOption( $name, $value );
 
                return $select->getHTML() . "\n<br />\n";
index 0e5ffce..47fd972 100644 (file)
@@ -72,7 +72,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                // Bind to member variable
                $this->opts = $opts;
 
-               $this->target = Title::newFromURL( $opts->getValue( 'target' ) );
+               $this->target = Title::newFromText( $opts->getValue( 'target' ) );
                if ( !$this->target ) {
                        if ( !$this->including() ) {
                                $out->addHTML( $this->whatlinkshereForm() );
@@ -496,7 +496,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                $f .= ' ';
 
                # Submit
-               $f .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() );
+               $f .= Xml::submitButton( $this->msg( 'whatlinkshere-submit' )->text() );
 
                # Close
                $f .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' ) . "\n";
@@ -548,7 +548,9 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               if ( $search === '' ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
                        return array();
                }
                // Autocomplete subpage the same as a normal search
index 61fd3e4..06775ef 100644 (file)
@@ -33,8 +33,8 @@ abstract class TidyDriverBase {
        /**
         * Clean up HTML
         *
-        * @param string HTML document fragment to clean up
-        * @param string The corrected HTML output
+        * @param string $text HTML document fragment to clean up
+        * @return string The corrected HTML output
         */
        abstract public function tidy( $text );
 }
diff --git a/includes/user/CentralIdLookup.php b/includes/user/CentralIdLookup.php
new file mode 100644 (file)
index 0000000..638a3e2
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+/**
+ * A central user id lookup service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * The CentralIdLookup service allows for connecting local users with
+ * cluster-wide IDs.
+ */
+abstract class CentralIdLookup implements IDBAccessObject {
+       // Audience options for accessors
+       const AUDIENCE_PUBLIC = 1;
+       const AUDIENCE_RAW = 2;
+
+       /** @var CentralIdLookup[][] */
+       private static $instances = array();
+
+       /** @var string */
+       private $providerId;
+
+       /**
+        * Fetch a CentralIdLookup
+        * @param string|null $providerId Provider ID from $wgCentralIdLookupProviders
+        * @return CentralIdLookup|null
+        */
+       public static function factory( $providerId = null ) {
+               global $wgCentralIdLookupProviders, $wgCentralIdLookupProvider;
+
+               if ( $providerId === null ) {
+                       $providerId = $wgCentralIdLookupProvider;
+               }
+
+               if ( !array_key_exists( $providerId, self::$instances ) ) {
+                       self::$instances[$providerId] = null;
+
+                       if ( isset( $wgCentralIdLookupProviders[$providerId] ) ) {
+                               $provider = ObjectFactory::getObjectFromSpec( $wgCentralIdLookupProviders[$providerId] );
+                               if ( $provider instanceof CentralIdLookup ) {
+                                       $provider->providerId = $providerId;
+                                       self::$instances[$providerId] = $provider;
+                               }
+                       }
+               }
+
+               return self::$instances[$providerId];
+       }
+
+       final public function getProviderId() {
+               return $this->providerId;
+       }
+
+       /**
+        * Check that the "audience" parameter is valid
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @return User|null User to check against, or null if no checks are needed
+        * @throws InvalidArgumentException
+        */
+       protected function checkAudience( $audience ) {
+               if ( $audience instanceof User ) {
+                       return $audience;
+               }
+               if ( $audience === self::AUDIENCE_PUBLIC ) {
+                       return new User;
+               }
+               if ( $audience === self::AUDIENCE_RAW ) {
+                       return null;
+               }
+               throw new InvalidArgumentException( 'Invalid audience' );
+       }
+
+       /**
+        * Check that a User is attached on the specified wiki.
+        *
+        * If unattached local accounts don't exist in your extension, this comes
+        * down to a check whether the central account exists at all and that
+        * $wikiId is using the same central database.
+        *
+        * @param User $user
+        * @param string|null $wikiId Wiki to check attachment status. If null, check the current wiki.
+        * @return bool
+        */
+       abstract public function isAttached( User $user, $wikiId = null );
+
+       /**
+        * Given central user IDs, return the (local) user names
+        * @note There's no requirement that the user names actually exist locally,
+        *  or if they do that they're actually attached to the central account.
+        * @param array $idToName Array with keys being central user IDs
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return array Copy of $idToName with values set to user names (or
+        *  empty-string if the user exists but $audience lacks the rights needed
+        *  to see it). IDs not corresponding to a user are unchanged.
+        */
+       abstract public function lookupCentralIds(
+               array $idToName, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       );
+
+       /**
+        * Given (local) user names, return the central IDs
+        * @note There's no requirement that the user names actually exist locally,
+        *  or if they do that they're actually attached to the central account.
+        * @param array $nameToId Array with keys being canonicalized user names
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return array Copy of $nameToId with values set to central IDs.
+        *  Names not corresponding to a user (or $audience lacks the rights needed
+        *  to see it) are unchanged.
+        */
+       abstract public function lookupUserNames(
+               array $nameToId, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       );
+
+       /**
+        * Given a central user ID, return the (local) user name
+        * @note There's no requirement that the user name actually exists locally,
+        *  or if it does that it's actually attached to the central account.
+        * @param int $id Central user ID
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return string|null User name, or empty string if $audience lacks the
+        *  rights needed to see it, or null if $id doesn't correspond to a user
+        */
+       public function nameFromCentralId(
+               $id, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               $idToName = $this->lookupCentralIds( array( $id => null ), $audience, $flags );
+               return $idToName[$id];
+       }
+
+       /**
+        * Given a (local) user name, return the central ID
+        * @note There's no requirement that the user name actually exists locally,
+        *  or if it does that it's actually attached to the central account.
+        * @param string $name Canonicalized user name
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return int User ID; 0 if the name does not correspond to a user or
+        *  $audience lacks the rights needed to see it.
+        */
+       public function centralIdFromName(
+               $name, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               $nameToId = $this->lookupUserNames( array( $name => 0 ), $audience, $flags );
+               return $nameToId[$name];
+       }
+
+       /**
+        * Given a central user ID, return a local User object
+        * @note Unlike nameFromCentralId(), this does guarantee that the local
+        *  user exists and is attached to the central account.
+        * @param int $id Central user ID
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return User|null Local user, or null if: $id doesn't correspond to a
+        *  user, $audience lacks the rights needed to see the user, the user
+        *  doesn't exist locally, or the user isn't locally attached.
+        */
+       public function localUserFromCentralId(
+               $id, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               $name = $this->nameFromCentralId( $id, $audience, $flags );
+               if ( $name !== null && $name !== '' ) {
+                       $user = User::newFromName( $name );
+                       if ( $user && $user->getId() && $this->isAttached( $user ) ) {
+                               return $user;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Given a local User object, return the central ID
+        * @note Unlike centralIdFromName(), this does guarantee that the local
+        *  user is attached to the central account.
+        * @param User $user Local user
+        * @param int|User $audience One of the audience constants, or a specific user
+        * @param int $flags IDBAccessObject read flags
+        * @return int User ID; 0 if the local user does not correspond to a
+        *  central user, $audience lacks the rights needed to see it, or the
+        *  central user isn't locally attached.
+        */
+       public function centralIdFromLocalUser(
+               User $user, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               return $this->isAttached( $user )
+                       ? $this->centralIdFromName( $user->getName(), $audience, $flags )
+                       : 0;
+       }
+
+}
diff --git a/includes/user/LocalIdLookup.php b/includes/user/LocalIdLookup.php
new file mode 100644 (file)
index 0000000..04c5b90
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/**
+ * A central user id lookup service implementation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * A CentralIdLookup provider that just uses local IDs. Useful if the wiki
+ * isn't part of a cluster or you're using shared user tables.
+ *
+ * @note Shared user table support expects that all wikis involved have
+ *  $wgSharedDB and $wgSharedTables set, and that all wikis involved in the
+ *  sharing are listed in $wgLocalDatabases, and that no wikis not involved in
+ *  the sharing are listed in $wgLocalDatabases.
+ */
+class LocalIdLookup extends CentralIdLookup {
+
+       public function isAttached( User $user, $wikiId = null ) {
+               global $wgSharedDB, $wgSharedTables, $wgLocalDatabases;
+
+               // If the user has no ID, it can't be attached
+               if ( !$user->getId() ) {
+                       return false;
+               }
+
+               // Easy case, we're checking locally
+               if ( $wikiId === null || $wikiId === wfWikiId() ) {
+                       return true;
+               }
+
+               // Assume that shared user tables are set up as described above, if
+               // they're being used at all.
+               return $wgSharedDB !== null &&
+                       in_array( 'user', $wgSharedTables, true ) &&
+                       in_array( $wikiId, $wgLocalDatabases, true );
+       }
+
+       public function lookupCentralIds(
+               array $idToName, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               if ( !$idToName ) {
+                       return array();
+               }
+
+               $audience = $this->checkAudience( $audience );
+               $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+               $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
+                       ? array( 'LOCK IN SHARE MODE' )
+                       : array();
+
+               $tables = array( 'user' );
+               $fields = array( 'user_id', 'user_name' );
+               $where = array(
+                       'user_id' => array_map( 'intval', array_keys( $idToName ) ),
+               );
+               $join = array();
+               if ( $audience && !$audience->isAllowed( 'hideuser' ) ) {
+                       $tables[] = 'ipblocks';
+                       $join['ipblocks'] = array( 'LEFT JOIN', 'ipb_user=user_id' );
+                       $fields[] = 'ipb_deleted';
+               }
+
+               $res = $db->select( $tables, $fields, $where, __METHOD__, $options, $join );
+               foreach ( $res as $row ) {
+                       $idToName[$row->user_id] = empty( $row->ipb_deleted ) ? $row->user_name : '';
+               }
+
+               return $idToName;
+       }
+
+       public function lookupUserNames(
+               array $nameToId, $audience = self::AUDIENCE_PUBLIC, $flags = self::READ_NORMAL
+       ) {
+               if ( !$nameToId ) {
+                       return array();
+               }
+
+               $audience = $this->checkAudience( $audience );
+               $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+               $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
+                       ? array( 'LOCK IN SHARE MODE' )
+                       : array();
+
+               $tables = array( 'user' );
+               $fields = array( 'user_id', 'user_name' );
+               $where = array(
+                       'user_name' => array_map( 'strval', array_keys( $nameToId ) ),
+               );
+               $join = array();
+               if ( $audience && !$audience->isAllowed( 'hideuser' ) ) {
+                       $tables[] = 'ipblocks';
+                       $join['ipblocks'] = array( 'LEFT JOIN', 'ipb_user=user_id' );
+                       $where[] = 'ipb_deleted = 0 OR ipb_deleted IS NULL';
+               }
+
+               $res = $db->select( $tables, $fields, $where, __METHOD__, $options, $join );
+               foreach ( $res as $row ) {
+                       $nameToId[$row->user_name] = (int)$row->user_id;
+               }
+
+               return $nameToId;
+       }
+}
diff --git a/includes/user/User.php b/includes/user/User.php
new file mode 100644 (file)
index 0000000..1de4008
--- /dev/null
@@ -0,0 +1,5334 @@
+<?php
+/**
+ * Implements the User class for the %MediaWiki software.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * String Some punctuation to prevent editing from broken text-mangling proxies.
+ * @ingroup Constants
+ */
+define( 'EDIT_TOKEN_SUFFIX', '+\\' );
+
+/**
+ * The User object encapsulates all of the user-specific settings (user_id,
+ * name, rights, email address, options, last login time). Client
+ * classes use the getXXX() functions to access these fields. These functions
+ * do all the work of determining whether the user is logged in,
+ * whether the requested option can be satisfied from cookies or
+ * whether a database query is needed. Most of the settings needed
+ * for rendering normal pages are set in the cookie to minimize use
+ * of the database.
+ */
+class User implements IDBAccessObject {
+       /**
+        * @const int Number of characters in user_token field.
+        */
+       const TOKEN_LENGTH = 32;
+
+       /**
+        * Global constant made accessible as class constants so that autoloader
+        * magic can be used.
+        */
+       const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
+
+       /**
+        * @const int Serialized record version.
+        */
+       const VERSION = 10;
+
+       /**
+        * Maximum items in $mWatchedItems
+        */
+       const MAX_WATCHED_ITEMS_CACHE = 100;
+
+       /**
+        * Exclude user options that are set to their default value.
+        * @since 1.25
+        */
+       const GETOPTIONS_EXCLUDE_DEFAULTS = 1;
+
+       /**
+        * Array of Strings List of member variables which are saved to the
+        * shared cache (memcached). Any operation which changes the
+        * corresponding database fields must call a cache-clearing function.
+        * @showinitializer
+        */
+       protected static $mCacheVars = array(
+               // user table
+               'mId',
+               'mName',
+               'mRealName',
+               'mEmail',
+               'mTouched',
+               'mToken',
+               'mEmailAuthenticated',
+               'mEmailToken',
+               'mEmailTokenExpires',
+               'mRegistration',
+               'mEditCount',
+               // user_groups table
+               'mGroups',
+               // user_properties table
+               'mOptionOverrides',
+       );
+
+       /**
+        * Array of Strings Core rights.
+        * Each of these should have a corresponding message of the form
+        * "right-$right".
+        * @showinitializer
+        */
+       protected static $mCoreRights = array(
+               'apihighlimits',
+               'applychangetags',
+               'autoconfirmed',
+               'autopatrol',
+               'bigdelete',
+               'block',
+               'blockemail',
+               'bot',
+               'browsearchive',
+               'changetags',
+               'createaccount',
+               'createpage',
+               'createtalk',
+               'delete',
+               'deletedhistory',
+               'deletedtext',
+               'deletelogentry',
+               'deleterevision',
+               'edit',
+               'editcontentmodel',
+               'editinterface',
+               'editprotected',
+               'editmyoptions',
+               'editmyprivateinfo',
+               'editmyusercss',
+               'editmyuserjs',
+               'editmywatchlist',
+               'editsemiprotected',
+               'editusercssjs', # deprecated
+               'editusercss',
+               'edituserjs',
+               'hideuser',
+               'import',
+               'importupload',
+               'ipblock-exempt',
+               'managechangetags',
+               'markbotedits',
+               'mergehistory',
+               'minoredit',
+               'move',
+               'movefile',
+               'move-categorypages',
+               'move-rootuserpages',
+               'move-subpages',
+               'nominornewtalk',
+               'noratelimit',
+               'override-export-depth',
+               'pagelang',
+               'passwordreset',
+               'patrol',
+               'patrolmarks',
+               'protect',
+               'proxyunbannable',
+               'purge',
+               'read',
+               'reupload',
+               'reupload-own',
+               'reupload-shared',
+               'rollback',
+               'sendemail',
+               'siteadmin',
+               'suppressionlog',
+               'suppressredirect',
+               'suppressrevision',
+               'unblockself',
+               'undelete',
+               'unwatchedpages',
+               'upload',
+               'upload_by_url',
+               'userrights',
+               'userrights-interwiki',
+               'viewmyprivateinfo',
+               'viewmywatchlist',
+               'viewsuppressed',
+               'writeapi',
+       );
+
+       /**
+        * String Cached results of getAllRights()
+        */
+       protected static $mAllRights = false;
+
+       /** Cache variables */
+       // @{
+       public $mId;
+       /** @var string */
+       public $mName;
+       /** @var string */
+       public $mRealName;
+
+       /** @var string */
+       public $mEmail;
+       /** @var string TS_MW timestamp from the DB */
+       public $mTouched;
+       /** @var string TS_MW timestamp from cache */
+       protected $mQuickTouched;
+       /** @var string */
+       protected $mToken;
+       /** @var string */
+       public $mEmailAuthenticated;
+       /** @var string */
+       protected $mEmailToken;
+       /** @var string */
+       protected $mEmailTokenExpires;
+       /** @var string */
+       protected $mRegistration;
+       /** @var int */
+       protected $mEditCount;
+       /** @var array */
+       public $mGroups;
+       /** @var array */
+       protected $mOptionOverrides;
+       // @}
+
+       /**
+        * Bool Whether the cache variables have been loaded.
+        */
+       // @{
+       public $mOptionsLoaded;
+
+       /**
+        * Array with already loaded items or true if all items have been loaded.
+        */
+       protected $mLoadedItems = array();
+       // @}
+
+       /**
+        * String Initialization data source if mLoadedItems!==true. May be one of:
+        *  - 'defaults'   anonymous user initialised from class defaults
+        *  - 'name'       initialise from mName
+        *  - 'id'         initialise from mId
+        *  - 'session'    log in from cookies or session if possible
+        *
+        * Use the User::newFrom*() family of functions to set this.
+        */
+       public $mFrom;
+
+       /**
+        * Lazy-initialized variables, invalidated with clearInstanceCache
+        */
+       protected $mNewtalk;
+       /** @var string */
+       protected $mDatePreference;
+       /** @var string */
+       public $mBlockedby;
+       /** @var string */
+       protected $mHash;
+       /** @var array */
+       public $mRights;
+       /** @var string */
+       protected $mBlockreason;
+       /** @var array */
+       protected $mEffectiveGroups;
+       /** @var array */
+       protected $mImplicitGroups;
+       /** @var array */
+       protected $mFormerGroups;
+       /** @var bool */
+       protected $mBlockedGlobally;
+       /** @var bool */
+       protected $mLocked;
+       /** @var bool */
+       public $mHideName;
+       /** @var array */
+       public $mOptions;
+
+       /**
+        * @var WebRequest
+        */
+       private $mRequest;
+
+       /** @var Block */
+       public $mBlock;
+
+       /** @var bool */
+       protected $mAllowUsertalk;
+
+       /** @var Block */
+       private $mBlockedFromCreateAccount = false;
+
+       /** @var array */
+       private $mWatchedItems = array();
+
+       /** @var integer User::READ_* constant bitfield used to load data */
+       protected $queryFlagsUsed = self::READ_NORMAL;
+
+       public static $idCacheByName = array();
+
+       /**
+        * Lightweight constructor for an anonymous user.
+        * Use the User::newFrom* factory functions for other kinds of users.
+        *
+        * @see newFromName()
+        * @see newFromId()
+        * @see newFromConfirmationCode()
+        * @see newFromSession()
+        * @see newFromRow()
+        */
+       public function __construct() {
+               $this->clearInstanceCache( 'defaults' );
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return $this->getName();
+       }
+
+       /**
+        * Load the user table data for this object from the source given by mFrom.
+        *
+        * @param integer $flags User::READ_* constant bitfield
+        */
+       public function load( $flags = self::READ_NORMAL ) {
+               if ( $this->mLoadedItems === true ) {
+                       return;
+               }
+
+               // Set it now to avoid infinite recursion in accessors
+               $this->mLoadedItems = true;
+               $this->queryFlagsUsed = $flags;
+
+               switch ( $this->mFrom ) {
+                       case 'defaults':
+                               $this->loadDefaults();
+                               break;
+                       case 'name':
+                               // Make sure this thread sees its own changes
+                               if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) {
+                                       $flags |= self::READ_LATEST;
+                                       $this->queryFlagsUsed = $flags;
+                               }
+
+                               $this->mId = self::idFromName( $this->mName, $flags );
+                               if ( !$this->mId ) {
+                                       // Nonexistent user placeholder object
+                                       $this->loadDefaults( $this->mName );
+                               } else {
+                                       $this->loadFromId( $flags );
+                               }
+                               break;
+                       case 'id':
+                               $this->loadFromId( $flags );
+                               break;
+                       case 'session':
+                               if ( !$this->loadFromSession() ) {
+                                       // Loading from session failed. Load defaults.
+                                       $this->loadDefaults();
+                               }
+                               Hooks::run( 'UserLoadAfterLoadFromSession', array( $this ) );
+                               break;
+                       default:
+                               throw new UnexpectedValueException(
+                                       "Unrecognised value for User->mFrom: \"{$this->mFrom}\"" );
+               }
+       }
+
+       /**
+        * Load user table data, given mId has already been set.
+        * @param integer $flags User::READ_* constant bitfield
+        * @return bool False if the ID does not exist, true otherwise
+        */
+       public function loadFromId( $flags = self::READ_NORMAL ) {
+               if ( $this->mId == 0 ) {
+                       $this->loadDefaults();
+                       return false;
+               }
+
+               // Try cache (unless this needs data from the master DB).
+               // NOTE: if this thread called saveSettings(), the cache was cleared.
+               $latest = DBAccessObjectUtils::hasFlags( $flags, self::READ_LATEST );
+               if ( $latest || !$this->loadFromCache() ) {
+                       wfDebug( "User: cache miss for user {$this->mId}\n" );
+                       // Load from DB (make sure this thread sees its own changes)
+                       if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) {
+                               $flags |= self::READ_LATEST;
+                       }
+                       if ( !$this->loadFromDatabase( $flags ) ) {
+                               // Can't load from ID, user is anonymous
+                               return false;
+                       }
+                       $this->saveToCache();
+               }
+
+               $this->mLoadedItems = true;
+               $this->queryFlagsUsed = $flags;
+
+               return true;
+       }
+
+       /**
+        * @since 1.27
+        * @param string $wikiId
+        * @param integer $userId
+        */
+       public static function purge( $wikiId, $userId ) {
+               $cache = ObjectCache::getMainWANInstance();
+               $cache->delete( $cache->makeGlobalKey( 'user', 'id', $wikiId, $userId ) );
+       }
+
+       /**
+        * @since 1.27
+        * @param WANObjectCache $cache
+        * @return string
+        */
+       protected function getCacheKey( WANObjectCache $cache ) {
+               return $cache->makeGlobalKey( 'user', 'id', wfWikiID(), $this->mId );
+       }
+
+       /**
+        * Load user data from shared cache, given mId has already been set.
+        *
+        * @return bool false if the ID does not exist or data is invalid, true otherwise
+        * @since 1.25
+        */
+       protected function loadFromCache() {
+               if ( $this->mId == 0 ) {
+                       $this->loadDefaults();
+                       return false;
+               }
+
+               $cache = ObjectCache::getMainWANInstance();
+               $data = $cache->get( $this->getCacheKey( $cache ) );
+               if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
+                       // Object is expired
+                       return false;
+               }
+
+               wfDebug( "User: got user {$this->mId} from cache\n" );
+
+               // Restore from cache
+               foreach ( self::$mCacheVars as $name ) {
+                       $this->$name = $data[$name];
+               }
+
+               return true;
+       }
+
+       /**
+        * Save user data to the shared cache
+        *
+        * This method should not be called outside the User class
+        */
+       public function saveToCache() {
+               $this->load();
+               $this->loadGroups();
+               $this->loadOptions();
+
+               if ( $this->isAnon() ) {
+                       // Anonymous users are uncached
+                       return;
+               }
+
+               $data = array();
+               foreach ( self::$mCacheVars as $name ) {
+                       $data[$name] = $this->$name;
+               }
+               $data['mVersion'] = self::VERSION;
+               $opts = Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+
+               $cache = ObjectCache::getMainWANInstance();
+               $key = $this->getCacheKey( $cache );
+               $cache->set( $key, $data, $cache::TTL_HOUR, $opts );
+       }
+
+       /** @name newFrom*() static factory methods */
+       // @{
+
+       /**
+        * Static factory method for creation from username.
+        *
+        * This is slightly less efficient than newFromId(), so use newFromId() if
+        * you have both an ID and a name handy.
+        *
+        * @param string $name Username, validated by Title::newFromText()
+        * @param string|bool $validate Validate username. Takes the same parameters as
+        *  User::getCanonicalName(), except that true is accepted as an alias
+        *  for 'valid', for BC.
+        *
+        * @return User|bool User object, or false if the username is invalid
+        *  (e.g. if it contains illegal characters or is an IP address). If the
+        *  username is not present in the database, the result will be a user object
+        *  with a name, zero user ID and default settings.
+        */
+       public static function newFromName( $name, $validate = 'valid' ) {
+               if ( $validate === true ) {
+                       $validate = 'valid';
+               }
+               $name = self::getCanonicalName( $name, $validate );
+               if ( $name === false ) {
+                       return false;
+               } else {
+                       // Create unloaded user object
+                       $u = new User;
+                       $u->mName = $name;
+                       $u->mFrom = 'name';
+                       $u->setItemLoaded( 'name' );
+                       return $u;
+               }
+       }
+
+       /**
+        * Static factory method for creation from a given user ID.
+        *
+        * @param int $id Valid user ID
+        * @return User The corresponding User object
+        */
+       public static function newFromId( $id ) {
+               $u = new User;
+               $u->mId = $id;
+               $u->mFrom = 'id';
+               $u->setItemLoaded( 'id' );
+               return $u;
+       }
+
+       /**
+        * Factory method to fetch whichever user has a given email confirmation code.
+        * This code is generated when an account is created or its e-mail address
+        * has changed.
+        *
+        * If the code is invalid or has expired, returns NULL.
+        *
+        * @param string $code Confirmation code
+        * @param int $flags User::READ_* bitfield
+        * @return User|null
+        */
+       public static function newFromConfirmationCode( $code, $flags = 0 ) {
+               $db = ( $flags & self::READ_LATEST ) == self::READ_LATEST
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+
+               $id = $db->selectField(
+                       'user',
+                       'user_id',
+                       array(
+                               'user_email_token' => md5( $code ),
+                               'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ),
+                       )
+               );
+
+               return $id ? User::newFromId( $id ) : null;
+       }
+
+       /**
+        * Create a new user object using data from session or cookies. If the
+        * login credentials are invalid, the result is an anonymous user.
+        *
+        * @param WebRequest|null $request Object to use; $wgRequest will be used if omitted.
+        * @return User
+        */
+       public static function newFromSession( WebRequest $request = null ) {
+               $user = new User;
+               $user->mFrom = 'session';
+               $user->mRequest = $request;
+               return $user;
+       }
+
+       /**
+        * Create a new user object from a user row.
+        * The row should have the following fields from the user table in it:
+        * - either user_name or user_id to load further data if needed (or both)
+        * - user_real_name
+        * - all other fields (email, etc.)
+        * It is useless to provide the remaining fields if either user_id,
+        * user_name and user_real_name are not provided because the whole row
+        * will be loaded once more from the database when accessing them.
+        *
+        * @param stdClass $row A row from the user table
+        * @param array $data Further data to load into the object (see User::loadFromRow for valid keys)
+        * @return User
+        */
+       public static function newFromRow( $row, $data = null ) {
+               $user = new User;
+               $user->loadFromRow( $row, $data );
+               return $user;
+       }
+
+       /**
+        * Static factory method for creation of a "system" user from username.
+        *
+        * A "system" user is an account that's used to attribute logged actions
+        * taken by MediaWiki itself, as opposed to a bot or human user. Examples
+        * might include the 'Maintenance script' or 'Conversion script' accounts
+        * used by various scripts in the maintenance/ directory or accounts such
+        * as 'MediaWiki message delivery' used by the MassMessage extension.
+        *
+        * This can optionally create the user if it doesn't exist, and "steal" the
+        * account if it does exist.
+        *
+        * @param string $name Username
+        * @param array $options Options are:
+        *  - validate: As for User::getCanonicalName(), default 'valid'
+        *  - create: Whether to create the user if it doesn't already exist, default true
+        *  - steal: Whether to reset the account's password and email if it
+        *    already exists, default false
+        * @return User|null
+        */
+       public static function newSystemUser( $name, $options = array() ) {
+               $options += array(
+                       'validate' => 'valid',
+                       'create' => true,
+                       'steal' => false,
+               );
+
+               $name = self::getCanonicalName( $name, $options['validate'] );
+               if ( $name === false ) {
+                       return null;
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $row = $dbw->selectRow(
+                       'user',
+                       array_merge(
+                               self::selectFields(),
+                               array( 'user_password', 'user_newpassword' )
+                       ),
+                       array( 'user_name' => $name ),
+                       __METHOD__
+               );
+               if ( !$row ) {
+                       // No user. Create it?
+                       return $options['create'] ? self::createNew( $name ) : null;
+               }
+               $user = self::newFromRow( $row );
+
+               // A user is considered to exist as a non-system user if it has a
+               // password set, or a temporary password set, or an email set.
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               try {
+                       $password = $passwordFactory->newFromCiphertext( $row->user_password );
+               } catch ( PasswordError $e ) {
+                       wfDebug( 'Invalid password hash found in database.' );
+                       $password = PasswordFactory::newInvalidPassword();
+               }
+               try {
+                       $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
+               } catch ( PasswordError $e ) {
+                       wfDebug( 'Invalid password hash found in database.' );
+                       $newpassword = PasswordFactory::newInvalidPassword();
+               }
+               if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
+                       || $user->mEmail
+               ) {
+                       // User exists. Steal it?
+                       if ( !$options['steal'] ) {
+                               return null;
+                       }
+
+                       $nopass = PasswordFactory::newInvalidPassword()->toString();
+
+                       $dbw->update(
+                               'user',
+                               array(
+                                       'user_password' => $nopass,
+                                       'user_newpassword' => $nopass,
+                                       'user_newpass_time' => null,
+                               ),
+                               array( 'user_id' => $user->getId() ),
+                               __METHOD__
+                       );
+                       $user->invalidateEmail();
+                       $user->saveSettings();
+               }
+
+               return $user;
+       }
+
+       // @}
+
+       /**
+        * Get the username corresponding to a given user ID
+        * @param int $id User ID
+        * @return string|bool The corresponding username
+        */
+       public static function whoIs( $id ) {
+               return UserCache::singleton()->getProp( $id, 'name' );
+       }
+
+       /**
+        * Get the real name of a user given their user ID
+        *
+        * @param int $id User ID
+        * @return string|bool The corresponding user's real name
+        */
+       public static function whoIsReal( $id ) {
+               return UserCache::singleton()->getProp( $id, 'real_name' );
+       }
+
+       /**
+        * Get database id given a user name
+        * @param string $name Username
+        * @param integer $flags User::READ_* constant bitfield
+        * @return int|null The corresponding user's ID, or null if user is nonexistent
+        */
+       public static function idFromName( $name, $flags = self::READ_NORMAL ) {
+               $nt = Title::makeTitleSafe( NS_USER, $name );
+               if ( is_null( $nt ) ) {
+                       // Illegal name
+                       return null;
+               }
+
+               if ( !( $flags & self::READ_LATEST ) && isset( self::$idCacheByName[$name] ) ) {
+                       return self::$idCacheByName[$name];
+               }
+
+               $db = ( $flags & self::READ_LATEST )
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+
+               $s = $db->selectRow(
+                       'user',
+                       array( 'user_id' ),
+                       array( 'user_name' => $nt->getText() ),
+                       __METHOD__
+               );
+
+               if ( $s === false ) {
+                       $result = null;
+               } else {
+                       $result = $s->user_id;
+               }
+
+               self::$idCacheByName[$name] = $result;
+
+               if ( count( self::$idCacheByName ) > 1000 ) {
+                       self::$idCacheByName = array();
+               }
+
+               return $result;
+       }
+
+       /**
+        * Reset the cache used in idFromName(). For use in tests.
+        */
+       public static function resetIdByNameCache() {
+               self::$idCacheByName = array();
+       }
+
+       /**
+        * Does the string match an anonymous IPv4 address?
+        *
+        * This function exists for username validation, in order to reject
+        * usernames which are similar in form to IP addresses. Strings such
+        * as 300.300.300.300 will return true because it looks like an IP
+        * address, despite not being strictly valid.
+        *
+        * We match "\d{1,3}\.\d{1,3}\.\d{1,3}\.xxx" as an anonymous IP
+        * address because the usemod software would "cloak" anonymous IP
+        * addresses like this, if we allowed accounts like this to be created
+        * new users could get the old edits of these anonymous users.
+        *
+        * @param string $name Name to match
+        * @return bool
+        */
+       public static function isIP( $name ) {
+               return preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/', $name )
+                       || IP::isIPv6( $name );
+       }
+
+       /**
+        * Is the input a valid username?
+        *
+        * Checks if the input is a valid username, we don't want an empty string,
+        * an IP address, anything that contains slashes (would mess up subpages),
+        * is longer than the maximum allowed username size or doesn't begin with
+        * a capital letter.
+        *
+        * @param string $name Name to match
+        * @return bool
+        */
+       public static function isValidUserName( $name ) {
+               global $wgContLang, $wgMaxNameChars;
+
+               if ( $name == ''
+                       || User::isIP( $name )
+                       || strpos( $name, '/' ) !== false
+                       || strlen( $name ) > $wgMaxNameChars
+                       || $name != $wgContLang->ucfirst( $name )
+               ) {
+                       wfDebugLog( 'username', __METHOD__ .
+                               ": '$name' invalid due to empty, IP, slash, length, or lowercase" );
+                       return false;
+               }
+
+               // Ensure that the name can't be misresolved as a different title,
+               // such as with extra namespace keys at the start.
+               $parsed = Title::newFromText( $name );
+               if ( is_null( $parsed )
+                       || $parsed->getNamespace()
+                       || strcmp( $name, $parsed->getPrefixedText() ) ) {
+                       wfDebugLog( 'username', __METHOD__ .
+                               ": '$name' invalid due to ambiguous prefixes" );
+                       return false;
+               }
+
+               // Check an additional blacklist of troublemaker characters.
+               // Should these be merged into the title char list?
+               $unicodeBlacklist = '/[' .
+                       '\x{0080}-\x{009f}' . # iso-8859-1 control chars
+                       '\x{00a0}' .          # non-breaking space
+                       '\x{2000}-\x{200f}' . # various whitespace
+                       '\x{2028}-\x{202f}' . # breaks and control chars
+                       '\x{3000}' .          # ideographic space
+                       '\x{e000}-\x{f8ff}' . # private use
+                       ']/u';
+               if ( preg_match( $unicodeBlacklist, $name ) ) {
+                       wfDebugLog( 'username', __METHOD__ .
+                               ": '$name' invalid due to blacklisted characters" );
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Usernames which fail to pass this function will be blocked
+        * from user login and new account registrations, but may be used
+        * internally by batch processes.
+        *
+        * If an account already exists in this form, login will be blocked
+        * by a failure to pass this function.
+        *
+        * @param string $name Name to match
+        * @return bool
+        */
+       public static function isUsableName( $name ) {
+               global $wgReservedUsernames;
+               // Must be a valid username, obviously ;)
+               if ( !self::isValidUserName( $name ) ) {
+                       return false;
+               }
+
+               static $reservedUsernames = false;
+               if ( !$reservedUsernames ) {
+                       $reservedUsernames = $wgReservedUsernames;
+                       Hooks::run( 'UserGetReservedNames', array( &$reservedUsernames ) );
+               }
+
+               // Certain names may be reserved for batch processes.
+               foreach ( $reservedUsernames as $reserved ) {
+                       if ( substr( $reserved, 0, 4 ) == 'msg:' ) {
+                               $reserved = wfMessage( substr( $reserved, 4 ) )->inContentLanguage()->text();
+                       }
+                       if ( $reserved == $name ) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Usernames which fail to pass this function will be blocked
+        * from new account registrations, but may be used internally
+        * either by batch processes or by user accounts which have
+        * already been created.
+        *
+        * Additional blacklisting may be added here rather than in
+        * isValidUserName() to avoid disrupting existing accounts.
+        *
+        * @param string $name String to match
+        * @return bool
+        */
+       public static function isCreatableName( $name ) {
+               global $wgInvalidUsernameCharacters;
+
+               // Ensure that the username isn't longer than 235 bytes, so that
+               // (at least for the builtin skins) user javascript and css files
+               // will work. (bug 23080)
+               if ( strlen( $name ) > 235 ) {
+                       wfDebugLog( 'username', __METHOD__ .
+                               ": '$name' invalid due to length" );
+                       return false;
+               }
+
+               // Preg yells if you try to give it an empty string
+               if ( $wgInvalidUsernameCharacters !== '' ) {
+                       if ( preg_match( '/[' . preg_quote( $wgInvalidUsernameCharacters, '/' ) . ']/', $name ) ) {
+                               wfDebugLog( 'username', __METHOD__ .
+                                       ": '$name' invalid due to wgInvalidUsernameCharacters" );
+                               return false;
+                       }
+               }
+
+               return self::isUsableName( $name );
+       }
+
+       /**
+        * Is the input a valid password for this user?
+        *
+        * @param string $password Desired password
+        * @return bool
+        */
+       public function isValidPassword( $password ) {
+               // simple boolean wrapper for getPasswordValidity
+               return $this->getPasswordValidity( $password ) === true;
+       }
+
+
+       /**
+        * Given unvalidated password input, return error message on failure.
+        *
+        * @param string $password Desired password
+        * @return bool|string|array True on success, string or array of error message on failure
+        */
+       public function getPasswordValidity( $password ) {
+               $result = $this->checkPasswordValidity( $password );
+               if ( $result->isGood() ) {
+                       return true;
+               } else {
+                       $messages = array();
+                       foreach ( $result->getErrorsByType( 'error' ) as $error ) {
+                               $messages[] = $error['message'];
+                       }
+                       foreach ( $result->getErrorsByType( 'warning' ) as $warning ) {
+                               $messages[] = $warning['message'];
+                       }
+                       if ( count( $messages ) === 1 ) {
+                               return $messages[0];
+                       }
+                       return $messages;
+               }
+       }
+
+       /**
+        * Check if this is a valid password for this user
+        *
+        * Create a Status object based on the password's validity.
+        * The Status should be set to fatal if the user should not
+        * be allowed to log in, and should have any errors that
+        * would block changing the password.
+        *
+        * If the return value of this is not OK, the password
+        * should not be checked. If the return value is not Good,
+        * the password can be checked, but the user should not be
+        * able to set their password to this.
+        *
+        * @param string $password Desired password
+        * @param string $purpose one of 'login', 'create', 'reset'
+        * @return Status
+        * @since 1.23
+        */
+       public function checkPasswordValidity( $password, $purpose = 'login' ) {
+               global $wgPasswordPolicy;
+
+               $upp = new UserPasswordPolicy(
+                       $wgPasswordPolicy['policies'],
+                       $wgPasswordPolicy['checks']
+               );
+
+               $status = Status::newGood();
+               $result = false; // init $result to false for the internal checks
+
+               if ( !Hooks::run( 'isValidPassword', array( $password, &$result, $this ) ) ) {
+                       $status->error( $result );
+                       return $status;
+               }
+
+               if ( $result === false ) {
+                       $status->merge( $upp->checkUserPassword( $this, $password, $purpose ) );
+                       return $status;
+               } elseif ( $result === true ) {
+                       return $status;
+               } else {
+                       $status->error( $result );
+                       return $status; // the isValidPassword hook set a string $result and returned true
+               }
+       }
+
+       /**
+        * Given unvalidated user input, return a canonical username, or false if
+        * the username is invalid.
+        * @param string $name User input
+        * @param string|bool $validate Type of validation to use:
+        *   - false        No validation
+        *   - 'valid'      Valid for batch processes
+        *   - 'usable'     Valid for batch processes and login
+        *   - 'creatable'  Valid for batch processes, login and account creation
+        *
+        * @throws InvalidArgumentException
+        * @return bool|string
+        */
+       public static function getCanonicalName( $name, $validate = 'valid' ) {
+               // Force usernames to capital
+               global $wgContLang;
+               $name = $wgContLang->ucfirst( $name );
+
+               # Reject names containing '#'; these will be cleaned up
+               # with title normalisation, but then it's too late to
+               # check elsewhere
+               if ( strpos( $name, '#' ) !== false ) {
+                       return false;
+               }
+
+               // Clean up name according to title rules,
+               // but only when validation is requested (bug 12654)
+               $t = ( $validate !== false ) ?
+                       Title::newFromText( $name ) : Title::makeTitle( NS_USER, $name );
+               // Check for invalid titles
+               if ( is_null( $t ) ) {
+                       return false;
+               }
+
+               // Reject various classes of invalid names
+               global $wgAuth;
+               $name = $wgAuth->getCanonicalName( $t->getText() );
+
+               switch ( $validate ) {
+                       case false:
+                               break;
+                       case 'valid':
+                               if ( !User::isValidUserName( $name ) ) {
+                                       $name = false;
+                               }
+                               break;
+                       case 'usable':
+                               if ( !User::isUsableName( $name ) ) {
+                                       $name = false;
+                               }
+                               break;
+                       case 'creatable':
+                               if ( !User::isCreatableName( $name ) ) {
+                                       $name = false;
+                               }
+                               break;
+                       default:
+                               throw new InvalidArgumentException(
+                                       'Invalid parameter value for $validate in ' . __METHOD__ );
+               }
+               return $name;
+       }
+
+       /**
+        * Count the number of edits of a user
+        *
+        * @param int $uid User ID to check
+        * @return int The user's edit count
+        *
+        * @deprecated since 1.21 in favour of User::getEditCount
+        */
+       public static function edits( $uid ) {
+               wfDeprecated( __METHOD__, '1.21' );
+               $user = self::newFromId( $uid );
+               return $user->getEditCount();
+       }
+
+       /**
+        * Return a random password.
+        *
+        * @deprecated since 1.27, use PasswordFactory::generateRandomPasswordString()
+        * @return string New random password
+        */
+       public static function randomPassword() {
+               global $wgMinimalPasswordLength;
+               return PasswordFactory::generateRandomPasswordString( $wgMinimalPasswordLength );
+       }
+
+       /**
+        * Set cached properties to default.
+        *
+        * @note This no longer clears uncached lazy-initialised properties;
+        *       the constructor does that instead.
+        *
+        * @param string|bool $name
+        */
+       public function loadDefaults( $name = false ) {
+               $this->mId = 0;
+               $this->mName = $name;
+               $this->mRealName = '';
+               $this->mEmail = '';
+               $this->mOptionOverrides = null;
+               $this->mOptionsLoaded = false;
+
+               $loggedOut = $this->getRequest()->getCookie( 'LoggedOut' );
+               if ( $loggedOut !== null ) {
+                       $this->mTouched = wfTimestamp( TS_MW, $loggedOut );
+               } else {
+                       $this->mTouched = '1'; # Allow any pages to be cached
+               }
+
+               $this->mToken = null; // Don't run cryptographic functions till we need a token
+               $this->mEmailAuthenticated = null;
+               $this->mEmailToken = '';
+               $this->mEmailTokenExpires = null;
+               $this->mRegistration = wfTimestamp( TS_MW );
+               $this->mGroups = array();
+
+               Hooks::run( 'UserLoadDefaults', array( $this, $name ) );
+       }
+
+       /**
+        * Return whether an item has been loaded.
+        *
+        * @param string $item Item to check. Current possibilities:
+        *   - id
+        *   - name
+        *   - realname
+        * @param string $all 'all' to check if the whole object has been loaded
+        *   or any other string to check if only the item is available (e.g.
+        *   for optimisation)
+        * @return bool
+        */
+       public function isItemLoaded( $item, $all = 'all' ) {
+               return ( $this->mLoadedItems === true && $all === 'all' ) ||
+                       ( isset( $this->mLoadedItems[$item] ) && $this->mLoadedItems[$item] === true );
+       }
+
+       /**
+        * Set that an item has been loaded
+        *
+        * @param string $item
+        */
+       protected function setItemLoaded( $item ) {
+               if ( is_array( $this->mLoadedItems ) ) {
+                       $this->mLoadedItems[$item] = true;
+               }
+       }
+
+       /**
+        * Load user data from the session or login cookie.
+        *
+        * @return bool True if the user is logged in, false otherwise.
+        */
+       private function loadFromSession() {
+               $result = null;
+               Hooks::run( 'UserLoadFromSession', array( $this, &$result ) );
+               if ( $result !== null ) {
+                       return $result;
+               }
+
+               $request = $this->getRequest();
+
+               $cookieId = $request->getCookie( 'UserID' );
+               $sessId = $request->getSessionData( 'wsUserID' );
+
+               if ( $cookieId !== null ) {
+                       $sId = intval( $cookieId );
+                       if ( $sessId !== null && $cookieId != $sessId ) {
+                               wfDebugLog( 'loginSessions', "Session user ID ($sessId) and
+                                       cookie user ID ($sId) don't match!" );
+                               return false;
+                       }
+                       $request->setSessionData( 'wsUserID', $sId );
+               } elseif ( $sessId !== null && $sessId != 0 ) {
+                       $sId = $sessId;
+               } else {
+                       return false;
+               }
+
+               if ( $request->getSessionData( 'wsUserName' ) !== null ) {
+                       $sName = $request->getSessionData( 'wsUserName' );
+               } elseif ( $request->getCookie( 'UserName' ) !== null ) {
+                       $sName = $request->getCookie( 'UserName' );
+                       $request->setSessionData( 'wsUserName', $sName );
+               } else {
+                       return false;
+               }
+
+               $proposedUser = User::newFromId( $sId );
+               if ( !$proposedUser->isLoggedIn() ) {
+                       // Not a valid ID
+                       return false;
+               }
+
+               global $wgBlockDisablesLogin;
+               if ( $wgBlockDisablesLogin && $proposedUser->isBlocked() ) {
+                       // User blocked and we've disabled blocked user logins
+                       return false;
+               }
+
+               if ( $request->getSessionData( 'wsToken' ) ) {
+                       $passwordCorrect =
+                               ( $proposedUser->getToken( false ) === $request->getSessionData( 'wsToken' ) );
+                       $from = 'session';
+               } elseif ( $request->getCookie( 'Token' ) ) {
+                       # Get the token from DB/cache and clean it up to remove garbage padding.
+                       # This deals with historical problems with bugs and the default column value.
+                       $token = rtrim( $proposedUser->getToken( false ) ); // correct token
+                       // Make comparison in constant time (bug 61346)
+                       $passwordCorrect = strlen( $token )
+                               && hash_equals( $token, $request->getCookie( 'Token' ) );
+                       $from = 'cookie';
+               } else {
+                       // No session or persistent login cookie
+                       return false;
+               }
+
+               if ( ( $sName === $proposedUser->getName() ) && $passwordCorrect ) {
+                       $this->loadFromUserObject( $proposedUser );
+                       $request->setSessionData( 'wsToken', $this->mToken );
+                       wfDebug( "User: logged in from $from\n" );
+                       return true;
+               } else {
+                       // Invalid credentials
+                       wfDebug( "User: can't log in from $from, invalid credentials\n" );
+                       return false;
+               }
+       }
+
+       /**
+        * Load user and user_group data from the database.
+        * $this->mId must be set, this is how the user is identified.
+        *
+        * @param integer $flags User::READ_* constant bitfield
+        * @return bool True if the user exists, false if the user is anonymous
+        */
+       public function loadFromDatabase( $flags = self::READ_LATEST ) {
+               // Paranoia
+               $this->mId = intval( $this->mId );
+
+               // Anonymous user
+               if ( !$this->mId ) {
+                       $this->loadDefaults();
+                       return false;
+               }
+
+               list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
+               $db = wfGetDB( $index );
+
+               $s = $db->selectRow(
+                       'user',
+                       self::selectFields(),
+                       array( 'user_id' => $this->mId ),
+                       __METHOD__,
+                       $options
+               );
+
+               $this->queryFlagsUsed = $flags;
+               Hooks::run( 'UserLoadFromDatabase', array( $this, &$s ) );
+
+               if ( $s !== false ) {
+                       // Initialise user table data
+                       $this->loadFromRow( $s );
+                       $this->mGroups = null; // deferred
+                       $this->getEditCount(); // revalidation for nulls
+                       return true;
+               } else {
+                       // Invalid user_id
+                       $this->mId = 0;
+                       $this->loadDefaults();
+                       return false;
+               }
+       }
+
+       /**
+        * Initialize this object from a row from the user table.
+        *
+        * @param stdClass $row Row from the user table to load.
+        * @param array $data Further user data to load into the object
+        *
+        *      user_groups             Array with groups out of the user_groups table
+        *      user_properties         Array with properties out of the user_properties table
+        */
+       protected function loadFromRow( $row, $data = null ) {
+               $all = true;
+
+               $this->mGroups = null; // deferred
+
+               if ( isset( $row->user_name ) ) {
+                       $this->mName = $row->user_name;
+                       $this->mFrom = 'name';
+                       $this->setItemLoaded( 'name' );
+               } else {
+                       $all = false;
+               }
+
+               if ( isset( $row->user_real_name ) ) {
+                       $this->mRealName = $row->user_real_name;
+                       $this->setItemLoaded( 'realname' );
+               } else {
+                       $all = false;
+               }
+
+               if ( isset( $row->user_id ) ) {
+                       $this->mId = intval( $row->user_id );
+                       $this->mFrom = 'id';
+                       $this->setItemLoaded( 'id' );
+               } else {
+                       $all = false;
+               }
+
+               if ( isset( $row->user_id ) && isset( $row->user_name ) ) {
+                       self::$idCacheByName[$row->user_name] = $row->user_id;
+               }
+
+               if ( isset( $row->user_editcount ) ) {
+                       $this->mEditCount = $row->user_editcount;
+               } else {
+                       $all = false;
+               }
+
+               if ( isset( $row->user_email ) ) {
+                       $this->mEmail = $row->user_email;
+                       $this->mTouched = wfTimestamp( TS_MW, $row->user_touched );
+                       $this->mToken = $row->user_token;
+                       if ( $this->mToken == '' ) {
+                               $this->mToken = null;
+                       }
+                       $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
+                       $this->mEmailToken = $row->user_email_token;
+                       $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
+                       $this->mRegistration = wfTimestampOrNull( TS_MW, $row->user_registration );
+               } else {
+                       $all = false;
+               }
+
+               if ( $all ) {
+                       $this->mLoadedItems = true;
+               }
+
+               if ( is_array( $data ) ) {
+                       if ( isset( $data['user_groups'] ) && is_array( $data['user_groups'] ) ) {
+                               $this->mGroups = $data['user_groups'];
+                       }
+                       if ( isset( $data['user_properties'] ) && is_array( $data['user_properties'] ) ) {
+                               $this->loadOptions( $data['user_properties'] );
+                       }
+               }
+       }
+
+       /**
+        * Load the data for this user object from another user object.
+        *
+        * @param User $user
+        */
+       protected function loadFromUserObject( $user ) {
+               $user->load();
+               $user->loadGroups();
+               $user->loadOptions();
+               foreach ( self::$mCacheVars as $var ) {
+                       $this->$var = $user->$var;
+               }
+       }
+
+       /**
+        * Load the groups from the database if they aren't already loaded.
+        */
+       private function loadGroups() {
+               if ( is_null( $this->mGroups ) ) {
+                       $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+                               ? wfGetDB( DB_MASTER )
+                               : wfGetDB( DB_SLAVE );
+                       $res = $db->select( 'user_groups',
+                               array( 'ug_group' ),
+                               array( 'ug_user' => $this->mId ),
+                               __METHOD__ );
+                       $this->mGroups = array();
+                       foreach ( $res as $row ) {
+                               $this->mGroups[] = $row->ug_group;
+                       }
+               }
+       }
+
+       /**
+        * Add the user to the group if he/she meets given criteria.
+        *
+        * Contrary to autopromotion by \ref $wgAutopromote, the group will be
+        *   possible to remove manually via Special:UserRights. In such case it
+        *   will not be re-added automatically. The user will also not lose the
+        *   group if they no longer meet the criteria.
+        *
+        * @param string $event Key in $wgAutopromoteOnce (each one has groups/criteria)
+        *
+        * @return array Array of groups the user has been promoted to.
+        *
+        * @see $wgAutopromoteOnce
+        */
+       public function addAutopromoteOnceGroups( $event ) {
+               global $wgAutopromoteOnceLogInRC, $wgAuth;
+
+               if ( wfReadOnly() || !$this->getId() ) {
+                       return array();
+               }
+
+               $toPromote = Autopromote::getAutopromoteOnceGroups( $this, $event );
+               if ( !count( $toPromote ) ) {
+                       return array();
+               }
+
+               if ( !$this->checkAndSetTouched() ) {
+                       return array(); // raced out (bug T48834)
+               }
+
+               $oldGroups = $this->getGroups(); // previous groups
+               foreach ( $toPromote as $group ) {
+                       $this->addGroup( $group );
+               }
+               // update groups in external authentication database
+               Hooks::run( 'UserGroupsChanged', array( $this, $toPromote, array(), false ) );
+               $wgAuth->updateExternalDBGroups( $this, $toPromote );
+
+               $newGroups = array_merge( $oldGroups, $toPromote ); // all groups
+
+               $logEntry = new ManualLogEntry( 'rights', 'autopromote' );
+               $logEntry->setPerformer( $this );
+               $logEntry->setTarget( $this->getUserPage() );
+               $logEntry->setParameters( array(
+                       '4::oldgroups' => $oldGroups,
+                       '5::newgroups' => $newGroups,
+               ) );
+               $logid = $logEntry->insert();
+               if ( $wgAutopromoteOnceLogInRC ) {
+                       $logEntry->publish( $logid );
+               }
+
+               return $toPromote;
+       }
+
+       /**
+        * Bump user_touched if it didn't change since this object was loaded
+        *
+        * On success, the mTouched field is updated.
+        * The user serialization cache is always cleared.
+        *
+        * @return bool Whether user_touched was actually updated
+        * @since 1.26
+        */
+       protected function checkAndSetTouched() {
+               $this->load();
+
+               if ( !$this->mId ) {
+                       return false; // anon
+               }
+
+               // Get a new user_touched that is higher than the old one
+               $oldTouched = $this->mTouched;
+               $newTouched = $this->newTouchedTimestamp();
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update( 'user',
+                       array( 'user_touched' => $dbw->timestamp( $newTouched ) ),
+                       array(
+                               'user_id' => $this->mId,
+                               'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
+                       ),
+                       __METHOD__
+               );
+               $success = ( $dbw->affectedRows() > 0 );
+
+               if ( $success ) {
+                       $this->mTouched = $newTouched;
+                       $this->clearSharedCache();
+               } else {
+                       // Clears on failure too since that is desired if the cache is stale
+                       $this->clearSharedCache( 'refresh' );
+               }
+
+               return $success;
+       }
+
+       /**
+        * Clear various cached data stored in this object. The cache of the user table
+        * data (i.e. self::$mCacheVars) is not cleared unless $reloadFrom is given.
+        *
+        * @param bool|string $reloadFrom Reload user and user_groups table data from a
+        *   given source. May be "name", "id", "defaults", "session", or false for no reload.
+        */
+       public function clearInstanceCache( $reloadFrom = false ) {
+               $this->mNewtalk = -1;
+               $this->mDatePreference = null;
+               $this->mBlockedby = -1; # Unset
+               $this->mHash = false;
+               $this->mRights = null;
+               $this->mEffectiveGroups = null;
+               $this->mImplicitGroups = null;
+               $this->mGroups = null;
+               $this->mOptions = null;
+               $this->mOptionsLoaded = false;
+               $this->mEditCount = null;
+
+               if ( $reloadFrom ) {
+                       $this->mLoadedItems = array();
+                       $this->mFrom = $reloadFrom;
+               }
+       }
+
+       /**
+        * Combine the language default options with any site-specific options
+        * and add the default language variants.
+        *
+        * @return array Array of String options
+        */
+       public static function getDefaultOptions() {
+               global $wgNamespacesToBeSearchedDefault, $wgDefaultUserOptions, $wgContLang, $wgDefaultSkin;
+
+               static $defOpt = null;
+               if ( !defined( 'MW_PHPUNIT_TEST' ) && $defOpt !== null ) {
+                       // Disabling this for the unit tests, as they rely on being able to change $wgContLang
+                       // mid-request and see that change reflected in the return value of this function.
+                       // Which is insane and would never happen during normal MW operation
+                       return $defOpt;
+               }
+
+               $defOpt = $wgDefaultUserOptions;
+               // Default language setting
+               $defOpt['language'] = $wgContLang->getCode();
+               foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
+                       $defOpt[$langCode == $wgContLang->getCode() ? 'variant' : "variant-$langCode"] = $langCode;
+               }
+               foreach ( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
+                       $defOpt['searchNs' . $nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
+               }
+               $defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
+
+               Hooks::run( 'UserGetDefaultOptions', array( &$defOpt ) );
+
+               return $defOpt;
+       }
+
+       /**
+        * Get a given default option value.
+        *
+        * @param string $opt Name of option to retrieve
+        * @return string Default option value
+        */
+       public static function getDefaultOption( $opt ) {
+               $defOpts = self::getDefaultOptions();
+               if ( isset( $defOpts[$opt] ) ) {
+                       return $defOpts[$opt];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Get blocking information
+        * @param bool $bFromSlave Whether to check the slave database first.
+        *   To improve performance, non-critical checks are done against slaves.
+        *   Check when actually saving should be done against master.
+        */
+       private function getBlockedStatus( $bFromSlave = true ) {
+               global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff;
+
+               if ( -1 != $this->mBlockedby ) {
+                       return;
+               }
+
+               wfDebug( __METHOD__ . ": checking...\n" );
+
+               // Initialize data...
+               // Otherwise something ends up stomping on $this->mBlockedby when
+               // things get lazy-loaded later, causing false positive block hits
+               // due to -1 !== 0. Probably session-related... Nothing should be
+               // overwriting mBlockedby, surely?
+               $this->load();
+
+               # We only need to worry about passing the IP address to the Block generator if the
+               # user is not immune to autoblocks/hardblocks, and they are the current user so we
+               # know which IP address they're actually coming from
+               if ( !$this->isAllowed( 'ipblock-exempt' ) && $this->equals( $wgUser ) ) {
+                       $ip = $this->getRequest()->getIP();
+               } else {
+                       $ip = null;
+               }
+
+               // User/IP blocking
+               $block = Block::newFromTarget( $this, $ip, !$bFromSlave );
+
+               // Proxy blocking
+               if ( !$block instanceof Block && $ip !== null && !$this->isAllowed( 'proxyunbannable' )
+                       && !in_array( $ip, $wgProxyWhitelist )
+               ) {
+                       // Local list
+                       if ( self::isLocallyBlockedProxy( $ip ) ) {
+                               $block = new Block;
+                               $block->setBlocker( wfMessage( 'proxyblocker' )->text() );
+                               $block->mReason = wfMessage( 'proxyblockreason' )->text();
+                               $block->setTarget( $ip );
+                       } elseif ( $this->isAnon() && $this->isDnsBlacklisted( $ip ) ) {
+                               $block = new Block;
+                               $block->setBlocker( wfMessage( 'sorbs' )->text() );
+                               $block->mReason = wfMessage( 'sorbsreason' )->text();
+                               $block->setTarget( $ip );
+                       }
+               }
+
+               // (bug 23343) Apply IP blocks to the contents of XFF headers, if enabled
+               if ( !$block instanceof Block
+                       && $wgApplyIpBlocksToXff
+                       && $ip !== null
+                       && !$this->isAllowed( 'proxyunbannable' )
+                       && !in_array( $ip, $wgProxyWhitelist )
+               ) {
+                       $xff = $this->getRequest()->getHeader( 'X-Forwarded-For' );
+                       $xff = array_map( 'trim', explode( ',', $xff ) );
+                       $xff = array_diff( $xff, array( $ip ) );
+                       $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$bFromSlave );
+                       $block = Block::chooseBlock( $xffblocks, $xff );
+                       if ( $block instanceof Block ) {
+                               # Mangle the reason to alert the user that the block
+                               # originated from matching the X-Forwarded-For header.
+                               $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->text();
+                       }
+               }
+
+               if ( $block instanceof Block ) {
+                       wfDebug( __METHOD__ . ": Found block.\n" );
+                       $this->mBlock = $block;
+                       $this->mBlockedby = $block->getByName();
+                       $this->mBlockreason = $block->mReason;
+                       $this->mHideName = $block->mHideName;
+                       $this->mAllowUsertalk = !$block->prevents( 'editownusertalk' );
+               } else {
+                       $this->mBlockedby = '';
+                       $this->mHideName = 0;
+                       $this->mAllowUsertalk = false;
+               }
+
+               // Extensions
+               Hooks::run( 'GetBlockedStatus', array( &$this ) );
+
+       }
+
+       /**
+        * Whether the given IP is in a DNS blacklist.
+        *
+        * @param string $ip IP to check
+        * @param bool $checkWhitelist Whether to check the whitelist first
+        * @return bool True if blacklisted.
+        */
+       public function isDnsBlacklisted( $ip, $checkWhitelist = false ) {
+               global $wgEnableDnsBlacklist, $wgDnsBlacklistUrls, $wgProxyWhitelist;
+
+               if ( !$wgEnableDnsBlacklist ) {
+                       return false;
+               }
+
+               if ( $checkWhitelist && in_array( $ip, $wgProxyWhitelist ) ) {
+                       return false;
+               }
+
+               return $this->inDnsBlacklist( $ip, $wgDnsBlacklistUrls );
+       }
+
+       /**
+        * Whether the given IP is in a given DNS blacklist.
+        *
+        * @param string $ip IP to check
+        * @param string|array $bases Array of Strings: URL of the DNS blacklist
+        * @return bool True if blacklisted.
+        */
+       public function inDnsBlacklist( $ip, $bases ) {
+
+               $found = false;
+               // @todo FIXME: IPv6 ???  (http://bugs.php.net/bug.php?id=33170)
+               if ( IP::isIPv4( $ip ) ) {
+                       // Reverse IP, bug 21255
+                       $ipReversed = implode( '.', array_reverse( explode( '.', $ip ) ) );
+
+                       foreach ( (array)$bases as $base ) {
+                               // Make hostname
+                               // If we have an access key, use that too (ProjectHoneypot, etc.)
+                               $basename = $base;
+                               if ( is_array( $base ) ) {
+                                       if ( count( $base ) >= 2 ) {
+                                               // Access key is 1, base URL is 0
+                                               $host = "{$base[1]}.$ipReversed.{$base[0]}";
+                                       } else {
+                                               $host = "$ipReversed.{$base[0]}";
+                                       }
+                                       $basename = $base[0];
+                               } else {
+                                       $host = "$ipReversed.$base";
+                               }
+
+                               // Send query
+                               $ipList = gethostbynamel( $host );
+
+                               if ( $ipList ) {
+                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $basename!" );
+                                       $found = true;
+                                       break;
+                               } else {
+                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $basename." );
+                               }
+                       }
+               }
+
+               return $found;
+       }
+
+       /**
+        * Check if an IP address is in the local proxy list
+        *
+        * @param string $ip
+        *
+        * @return bool
+        */
+       public static function isLocallyBlockedProxy( $ip ) {
+               global $wgProxyList;
+
+               if ( !$wgProxyList ) {
+                       return false;
+               }
+
+               if ( !is_array( $wgProxyList ) ) {
+                       // Load from the specified file
+                       $wgProxyList = array_map( 'trim', file( $wgProxyList ) );
+               }
+
+               if ( !is_array( $wgProxyList ) ) {
+                       $ret = false;
+               } elseif ( array_search( $ip, $wgProxyList ) !== false ) {
+                       $ret = true;
+               } elseif ( array_key_exists( $ip, $wgProxyList ) ) {
+                       // Old-style flipped proxy list
+                       $ret = true;
+               } else {
+                       $ret = false;
+               }
+               return $ret;
+       }
+
+       /**
+        * Is this user subject to rate limiting?
+        *
+        * @return bool True if rate limited
+        */
+       public function isPingLimitable() {
+               global $wgRateLimitsExcludedIPs;
+               if ( in_array( $this->getRequest()->getIP(), $wgRateLimitsExcludedIPs ) ) {
+                       // No other good way currently to disable rate limits
+                       // for specific IPs. :P
+                       // But this is a crappy hack and should die.
+                       return false;
+               }
+               return !$this->isAllowed( 'noratelimit' );
+       }
+
+       /**
+        * Primitive rate limits: enforce maximum actions per time period
+        * to put a brake on flooding.
+        *
+        * The method generates both a generic profiling point and a per action one
+        * (suffix being "-$action".
+        *
+        * @note When using a shared cache like memcached, IP-address
+        * last-hit counters will be shared across wikis.
+        *
+        * @param string $action Action to enforce; 'edit' if unspecified
+        * @param int $incrBy Positive amount to increment counter by [defaults to 1]
+        * @return bool True if a rate limiter was tripped
+        */
+       public function pingLimiter( $action = 'edit', $incrBy = 1 ) {
+               // Call the 'PingLimiter' hook
+               $result = false;
+               if ( !Hooks::run( 'PingLimiter', array( &$this, $action, &$result, $incrBy ) ) ) {
+                       return $result;
+               }
+
+               global $wgRateLimits;
+               if ( !isset( $wgRateLimits[$action] ) ) {
+                       return false;
+               }
+
+               // Some groups shouldn't trigger the ping limiter, ever
+               if ( !$this->isPingLimitable() ) {
+                       return false;
+               }
+
+               $limits = $wgRateLimits[$action];
+               $keys = array();
+               $id = $this->getId();
+               $userLimit = false;
+
+               if ( isset( $limits['anon'] ) && $id == 0 ) {
+                       $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
+               }
+
+               if ( isset( $limits['user'] ) && $id != 0 ) {
+                       $userLimit = $limits['user'];
+               }
+               if ( $this->isNewbie() ) {
+                       if ( isset( $limits['newbie'] ) && $id != 0 ) {
+                               $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
+                       }
+                       if ( isset( $limits['ip'] ) ) {
+                               $ip = $this->getRequest()->getIP();
+                               $keys["mediawiki:limiter:$action:ip:$ip"] = $limits['ip'];
+                       }
+                       if ( isset( $limits['subnet'] ) ) {
+                               $ip = $this->getRequest()->getIP();
+                               $matches = array();
+                               $subnet = false;
+                               if ( IP::isIPv6( $ip ) ) {
+                                       $parts = IP::parseRange( "$ip/64" );
+                                       $subnet = $parts[0];
+                               } elseif ( preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
+                                       // IPv4
+                                       $subnet = $matches[1];
+                               }
+                               if ( $subnet !== false ) {
+                                       $keys["mediawiki:limiter:$action:subnet:$subnet"] = $limits['subnet'];
+                               }
+                       }
+               }
+               // Check for group-specific permissions
+               // If more than one group applies, use the group with the highest limit
+               foreach ( $this->getGroups() as $group ) {
+                       if ( isset( $limits[$group] ) ) {
+                               if ( $userLimit === false
+                                       || $limits[$group][0] / $limits[$group][1] > $userLimit[0] / $userLimit[1]
+                               ) {
+                                       $userLimit = $limits[$group];
+                               }
+                       }
+               }
+               // Set the user limit key
+               if ( $userLimit !== false ) {
+                       list( $max, $period ) = $userLimit;
+                       wfDebug( __METHOD__ . ": effective user limit: $max in {$period}s\n" );
+                       $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
+               }
+
+               $cache = ObjectCache::getLocalClusterInstance();
+
+               $triggered = false;
+               foreach ( $keys as $key => $limit ) {
+                       list( $max, $period ) = $limit;
+                       $summary = "(limit $max in {$period}s)";
+                       $count = $cache->get( $key );
+                       // Already pinged?
+                       if ( $count ) {
+                               if ( $count >= $max ) {
+                                       wfDebugLog( 'ratelimit', "User '{$this->getName()}' " .
+                                               "(IP {$this->getRequest()->getIP()}) tripped $key at $count $summary" );
+                                       $triggered = true;
+                               } else {
+                                       wfDebug( __METHOD__ . ": ok. $key at $count $summary\n" );
+                               }
+                       } else {
+                               wfDebug( __METHOD__ . ": adding record for $key $summary\n" );
+                               if ( $incrBy > 0 ) {
+                                       $cache->add( $key, 0, intval( $period ) ); // first ping
+                               }
+                       }
+                       if ( $incrBy > 0 ) {
+                               $cache->incr( $key, $incrBy );
+                       }
+               }
+
+               return $triggered;
+       }
+
+       /**
+        * Check if user is blocked
+        *
+        * @param bool $bFromSlave Whether to check the slave database instead of
+        *   the master. Hacked from false due to horrible probs on site.
+        * @return bool True if blocked, false otherwise
+        */
+       public function isBlocked( $bFromSlave = true ) {
+               return $this->getBlock( $bFromSlave ) instanceof Block && $this->getBlock()->prevents( 'edit' );
+       }
+
+       /**
+        * Get the block affecting the user, or null if the user is not blocked
+        *
+        * @param bool $bFromSlave Whether to check the slave database instead of the master
+        * @return Block|null
+        */
+       public function getBlock( $bFromSlave = true ) {
+               $this->getBlockedStatus( $bFromSlave );
+               return $this->mBlock instanceof Block ? $this->mBlock : null;
+       }
+
+       /**
+        * Check if user is blocked from editing a particular article
+        *
+        * @param Title $title Title to check
+        * @param bool $bFromSlave Whether to check the slave database instead of the master
+        * @return bool
+        */
+       public function isBlockedFrom( $title, $bFromSlave = false ) {
+               global $wgBlockAllowsUTEdit;
+
+               $blocked = $this->isBlocked( $bFromSlave );
+               $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk : false );
+               // If a user's name is suppressed, they cannot make edits anywhere
+               if ( !$this->mHideName && $allowUsertalk && $title->getText() === $this->getName()
+                       && $title->getNamespace() == NS_USER_TALK ) {
+                       $blocked = false;
+                       wfDebug( __METHOD__ . ": self-talk page, ignoring any blocks\n" );
+               }
+
+               Hooks::run( 'UserIsBlockedFrom', array( $this, $title, &$blocked, &$allowUsertalk ) );
+
+               return $blocked;
+       }
+
+       /**
+        * If user is blocked, return the name of the user who placed the block
+        * @return string Name of blocker
+        */
+       public function blockedBy() {
+               $this->getBlockedStatus();
+               return $this->mBlockedby;
+       }
+
+       /**
+        * If user is blocked, return the specified reason for the block
+        * @return string Blocking reason
+        */
+       public function blockedFor() {
+               $this->getBlockedStatus();
+               return $this->mBlockreason;
+       }
+
+       /**
+        * If user is blocked, return the ID for the block
+        * @return int Block ID
+        */
+       public function getBlockId() {
+               $this->getBlockedStatus();
+               return ( $this->mBlock ? $this->mBlock->getId() : false );
+       }
+
+       /**
+        * Check if user is blocked on all wikis.
+        * Do not use for actual edit permission checks!
+        * This is intended for quick UI checks.
+        *
+        * @param string $ip IP address, uses current client if none given
+        * @return bool True if blocked, false otherwise
+        */
+       public function isBlockedGlobally( $ip = '' ) {
+               if ( $this->mBlockedGlobally !== null ) {
+                       return $this->mBlockedGlobally;
+               }
+               // User is already an IP?
+               if ( IP::isIPAddress( $this->getName() ) ) {
+                       $ip = $this->getName();
+               } elseif ( !$ip ) {
+                       $ip = $this->getRequest()->getIP();
+               }
+               $blocked = false;
+               Hooks::run( 'UserIsBlockedGlobally', array( &$this, $ip, &$blocked ) );
+               $this->mBlockedGlobally = (bool)$blocked;
+               return $this->mBlockedGlobally;
+       }
+
+       /**
+        * Check if user account is locked
+        *
+        * @return bool True if locked, false otherwise
+        */
+       public function isLocked() {
+               if ( $this->mLocked !== null ) {
+                       return $this->mLocked;
+               }
+               global $wgAuth;
+               $authUser = $wgAuth->getUserInstance( $this );
+               $this->mLocked = (bool)$authUser->isLocked();
+               Hooks::run( 'UserIsLocked', array( $this, &$this->mLocked ) );
+               return $this->mLocked;
+       }
+
+       /**
+        * Check if user account is hidden
+        *
+        * @return bool True if hidden, false otherwise
+        */
+       public function isHidden() {
+               if ( $this->mHideName !== null ) {
+                       return $this->mHideName;
+               }
+               $this->getBlockedStatus();
+               if ( !$this->mHideName ) {
+                       global $wgAuth;
+                       $authUser = $wgAuth->getUserInstance( $this );
+                       $this->mHideName = (bool)$authUser->isHidden();
+                       Hooks::run( 'UserIsHidden', array( $this, &$this->mHideName ) );
+               }
+               return $this->mHideName;
+       }
+
+       /**
+        * Get the user's ID.
+        * @return int The user's ID; 0 if the user is anonymous or nonexistent
+        */
+       public function getId() {
+               if ( $this->mId === null && $this->mName !== null && User::isIP( $this->mName ) ) {
+                       // Special case, we know the user is anonymous
+                       return 0;
+               } elseif ( !$this->isItemLoaded( 'id' ) ) {
+                       // Don't load if this was initialized from an ID
+                       $this->load();
+               }
+               return $this->mId;
+       }
+
+       /**
+        * Set the user and reload all fields according to a given ID
+        * @param int $v User ID to reload
+        */
+       public function setId( $v ) {
+               $this->mId = $v;
+               $this->clearInstanceCache( 'id' );
+       }
+
+       /**
+        * Get the user name, or the IP of an anonymous user
+        * @return string User's name or IP address
+        */
+       public function getName() {
+               if ( $this->isItemLoaded( 'name', 'only' ) ) {
+                       // Special case optimisation
+                       return $this->mName;
+               } else {
+                       $this->load();
+                       if ( $this->mName === false ) {
+                               // Clean up IPs
+                               $this->mName = IP::sanitizeIP( $this->getRequest()->getIP() );
+                       }
+                       return $this->mName;
+               }
+       }
+
+       /**
+        * Set the user name.
+        *
+        * This does not reload fields from the database according to the given
+        * name. Rather, it is used to create a temporary "nonexistent user" for
+        * later addition to the database. It can also be used to set the IP
+        * address for an anonymous user to something other than the current
+        * remote IP.
+        *
+        * @note User::newFromName() has roughly the same function, when the named user
+        * does not exist.
+        * @param string $str New user name to set
+        */
+       public function setName( $str ) {
+               $this->load();
+               $this->mName = $str;
+       }
+
+       /**
+        * Get the user's name escaped by underscores.
+        * @return string Username escaped by underscores.
+        */
+       public function getTitleKey() {
+               return str_replace( ' ', '_', $this->getName() );
+       }
+
+       /**
+        * Check if the user has new messages.
+        * @return bool True if the user has new messages
+        */
+       public function getNewtalk() {
+               $this->load();
+
+               // Load the newtalk status if it is unloaded (mNewtalk=-1)
+               if ( $this->mNewtalk === -1 ) {
+                       $this->mNewtalk = false; # reset talk page status
+
+                       // Check memcached separately for anons, who have no
+                       // entire User object stored in there.
+                       if ( !$this->mId ) {
+                               global $wgDisableAnonTalk;
+                               if ( $wgDisableAnonTalk ) {
+                                       // Anon newtalk disabled by configuration.
+                                       $this->mNewtalk = false;
+                               } else {
+                                       $this->mNewtalk = $this->checkNewtalk( 'user_ip', $this->getName() );
+                               }
+                       } else {
+                               $this->mNewtalk = $this->checkNewtalk( 'user_id', $this->mId );
+                       }
+               }
+
+               return (bool)$this->mNewtalk;
+       }
+
+       /**
+        * Return the data needed to construct links for new talk page message
+        * alerts. If there are new messages, this will return an associative array
+        * with the following data:
+        *     wiki: The database name of the wiki
+        *     link: Root-relative link to the user's talk page
+        *     rev: The last talk page revision that the user has seen or null. This
+        *         is useful for building diff links.
+        * If there are no new messages, it returns an empty array.
+        * @note This function was designed to accomodate multiple talk pages, but
+        * currently only returns a single link and revision.
+        * @return array
+        */
+       public function getNewMessageLinks() {
+               $talks = array();
+               if ( !Hooks::run( 'UserRetrieveNewTalks', array( &$this, &$talks ) ) ) {
+                       return $talks;
+               } elseif ( !$this->getNewtalk() ) {
+                       return array();
+               }
+               $utp = $this->getTalkPage();
+               $dbr = wfGetDB( DB_SLAVE );
+               // Get the "last viewed rev" timestamp from the oldest message notification
+               $timestamp = $dbr->selectField( 'user_newtalk',
+                       'MIN(user_last_timestamp)',
+                       $this->isAnon() ? array( 'user_ip' => $this->getName() ) : array( 'user_id' => $this->getID() ),
+                       __METHOD__ );
+               $rev = $timestamp ? Revision::loadFromTimestamp( $dbr, $utp, $timestamp ) : null;
+               return array( array( 'wiki' => wfWikiID(), 'link' => $utp->getLocalURL(), 'rev' => $rev ) );
+       }
+
+       /**
+        * Get the revision ID for the last talk page revision viewed by the talk
+        * page owner.
+        * @return int|null Revision ID or null
+        */
+       public function getNewMessageRevisionId() {
+               $newMessageRevisionId = null;
+               $newMessageLinks = $this->getNewMessageLinks();
+               if ( $newMessageLinks ) {
+                       // Note: getNewMessageLinks() never returns more than a single link
+                       // and it is always for the same wiki, but we double-check here in
+                       // case that changes some time in the future.
+                       if ( count( $newMessageLinks ) === 1
+                               && $newMessageLinks[0]['wiki'] === wfWikiID()
+                               && $newMessageLinks[0]['rev']
+                       ) {
+                               /** @var Revision $newMessageRevision */
+                               $newMessageRevision = $newMessageLinks[0]['rev'];
+                               $newMessageRevisionId = $newMessageRevision->getId();
+                       }
+               }
+               return $newMessageRevisionId;
+       }
+
+       /**
+        * Internal uncached check for new messages
+        *
+        * @see getNewtalk()
+        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
+        * @param string|int $id User's IP address for anonymous users, User ID otherwise
+        * @return bool True if the user has new messages
+        */
+       protected function checkNewtalk( $field, $id ) {
+               $dbr = wfGetDB( DB_SLAVE );
+
+               $ok = $dbr->selectField( 'user_newtalk', $field, array( $field => $id ), __METHOD__ );
+
+               return $ok !== false;
+       }
+
+       /**
+        * Add or update the new messages flag
+        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
+        * @param string|int $id User's IP address for anonymous users, User ID otherwise
+        * @param Revision|null $curRev New, as yet unseen revision of the user talk page. Ignored if null.
+        * @return bool True if successful, false otherwise
+        */
+       protected function updateNewtalk( $field, $id, $curRev = null ) {
+               // Get timestamp of the talk page revision prior to the current one
+               $prevRev = $curRev ? $curRev->getPrevious() : false;
+               $ts = $prevRev ? $prevRev->getTimestamp() : null;
+               // Mark the user as having new messages since this revision
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'user_newtalk',
+                       array( $field => $id, 'user_last_timestamp' => $dbw->timestampOrNull( $ts ) ),
+                       __METHOD__,
+                       'IGNORE' );
+               if ( $dbw->affectedRows() ) {
+                       wfDebug( __METHOD__ . ": set on ($field, $id)\n" );
+                       return true;
+               } else {
+                       wfDebug( __METHOD__ . " already set ($field, $id)\n" );
+                       return false;
+               }
+       }
+
+       /**
+        * Clear the new messages flag for the given user
+        * @param string $field 'user_ip' for anonymous users, 'user_id' otherwise
+        * @param string|int $id User's IP address for anonymous users, User ID otherwise
+        * @return bool True if successful, false otherwise
+        */
+       protected function deleteNewtalk( $field, $id ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'user_newtalk',
+                       array( $field => $id ),
+                       __METHOD__ );
+               if ( $dbw->affectedRows() ) {
+                       wfDebug( __METHOD__ . ": killed on ($field, $id)\n" );
+                       return true;
+               } else {
+                       wfDebug( __METHOD__ . ": already gone ($field, $id)\n" );
+                       return false;
+               }
+       }
+
+       /**
+        * Update the 'You have new messages!' status.
+        * @param bool $val Whether the user has new messages
+        * @param Revision $curRev New, as yet unseen revision of the user talk
+        *   page. Ignored if null or !$val.
+        */
+       public function setNewtalk( $val, $curRev = null ) {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
+               $this->load();
+               $this->mNewtalk = $val;
+
+               if ( $this->isAnon() ) {
+                       $field = 'user_ip';
+                       $id = $this->getName();
+               } else {
+                       $field = 'user_id';
+                       $id = $this->getId();
+               }
+
+               if ( $val ) {
+                       $changed = $this->updateNewtalk( $field, $id, $curRev );
+               } else {
+                       $changed = $this->deleteNewtalk( $field, $id );
+               }
+
+               if ( $changed ) {
+                       $this->invalidateCache();
+               }
+       }
+
+       /**
+        * Generate a current or new-future timestamp to be stored in the
+        * user_touched field when we update things.
+        * @return string Timestamp in TS_MW format
+        */
+       private function newTouchedTimestamp() {
+               global $wgClockSkewFudge;
+
+               $time = wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
+               if ( $this->mTouched && $time <= $this->mTouched ) {
+                       $time = wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $this->mTouched ) + 1 );
+               }
+
+               return $time;
+       }
+
+       /**
+        * Clear user data from memcached
+        *
+        * Use after applying updates to the database; caller's
+        * responsibility to update user_touched if appropriate.
+        *
+        * Called implicitly from invalidateCache() and saveSettings().
+        *
+        * @param string $mode Use 'refresh' to clear now; otherwise before DB commit
+        */
+       public function clearSharedCache( $mode = 'changed' ) {
+               if ( !$this->getId() ) {
+                       return;
+               }
+
+               $cache = ObjectCache::getMainWANInstance();
+               $key = $this->getCacheKey( $cache );
+               if ( $mode === 'refresh' ) {
+                       $cache->delete( $key, 1 );
+               } else {
+                       wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $cache, $key ) {
+                               $cache->delete( $key );
+                       } );
+               }
+       }
+
+       /**
+        * Immediately touch the user data cache for this account
+        *
+        * Calls touch() and removes account data from memcached
+        */
+       public function invalidateCache() {
+               $this->touch();
+               $this->clearSharedCache();
+       }
+
+       /**
+        * Update the "touched" timestamp for the user
+        *
+        * This is useful on various login/logout events when making sure that
+        * a browser or proxy that has multiple tenants does not suffer cache
+        * pollution where the new user sees the old users content. The value
+        * of getTouched() is checked when determining 304 vs 200 responses.
+        * Unlike invalidateCache(), this preserves the User object cache and
+        * avoids database writes.
+        *
+        * @since 1.25
+        */
+       public function touch() {
+               $id = $this->getId();
+               if ( $id ) {
+                       $key = wfMemcKey( 'user-quicktouched', 'id', $id );
+                       ObjectCache::getMainWANInstance()->touchCheckKey( $key );
+                       $this->mQuickTouched = null;
+               }
+       }
+
+       /**
+        * Validate the cache for this account.
+        * @param string $timestamp A timestamp in TS_MW format
+        * @return bool
+        */
+       public function validateCache( $timestamp ) {
+               return ( $timestamp >= $this->getTouched() );
+       }
+
+       /**
+        * Get the user touched timestamp
+        *
+        * Use this value only to validate caches via inequalities
+        * such as in the case of HTTP If-Modified-Since response logic
+        *
+        * @return string TS_MW Timestamp
+        */
+       public function getTouched() {
+               $this->load();
+
+               if ( $this->mId ) {
+                       if ( $this->mQuickTouched === null ) {
+                               $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId );
+                               $cache = ObjectCache::getMainWANInstance();
+
+                               $this->mQuickTouched = wfTimestamp( TS_MW, $cache->getCheckKeyTime( $key ) );
+                       }
+
+                       return max( $this->mTouched, $this->mQuickTouched );
+               }
+
+               return $this->mTouched;
+       }
+
+       /**
+        * Get the user_touched timestamp field (time of last DB updates)
+        * @return string TS_MW Timestamp
+        * @since 1.26
+        */
+       public function getDBTouched() {
+               $this->load();
+
+               return $this->mTouched;
+       }
+
+       /**
+        * @deprecated Removed in 1.27.
+        * @return Password
+        * @since 1.24
+        */
+       public function getPassword() {
+               throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
+       }
+
+       /**
+        * @deprecated Removed in 1.27.
+        * @return Password
+        * @since 1.24
+        */
+       public function getTemporaryPassword() {
+               throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
+       }
+
+       /**
+        * Set the password and reset the random token.
+        * Calls through to authentication plugin if necessary;
+        * will have no effect if the auth plugin refuses to
+        * pass the change through or if the legal password
+        * checks fail.
+        *
+        * As a special case, setting the password to null
+        * wipes it, so the account cannot be logged in until
+        * a new password is set, for instance via e-mail.
+        *
+        * @deprecated since 1.27. AuthManager is coming.
+        * @param string $str New password to set
+        * @throws PasswordError On failure
+        * @return bool
+        */
+       public function setPassword( $str ) {
+               global $wgAuth;
+
+               if ( $str !== null ) {
+                       if ( !$wgAuth->allowPasswordChange() ) {
+                               throw new PasswordError( wfMessage( 'password-change-forbidden' )->text() );
+                       }
+
+                       $status = $this->checkPasswordValidity( $str );
+                       if ( !$status->isGood() ) {
+                               throw new PasswordError( $status->getMessage()->text() );
+                       }
+               }
+
+               if ( !$wgAuth->setPassword( $this, $str ) ) {
+                       throw new PasswordError( wfMessage( 'externaldberror' )->text() );
+               }
+
+               $this->setToken();
+               $this->setOption( 'watchlisttoken', false );
+               $this->setPasswordInternal( $str );
+
+               return true;
+       }
+
+       /**
+        * Set the password and reset the random token unconditionally.
+        *
+        * @deprecated since 1.27. AuthManager is coming.
+        * @param string|null $str New password to set or null to set an invalid
+        *  password hash meaning that the user will not be able to log in
+        *  through the web interface.
+        */
+       public function setInternalPassword( $str ) {
+               global $wgAuth;
+
+               if ( $wgAuth->allowSetLocalPassword() ) {
+                       $this->setToken();
+                       $this->setOption( 'watchlisttoken', false );
+                       $this->setPasswordInternal( $str );
+               }
+       }
+
+       /**
+        * Actually set the password and such
+        * @since 1.27 cannot set a password for a user not in the database
+        * @param string|null $str New password to set or null to set an invalid
+        *  password hash meaning that the user will not be able to log in
+        *  through the web interface.
+        */
+       private function setPasswordInternal( $str ) {
+               $id = self::idFromName( $this->getName(), self::READ_LATEST );
+               if ( $id == 0 ) {
+                       throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
+               }
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update(
+                       'user',
+                       array(
+                               'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
+                               'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
+                               'user_newpass_time' => $dbw->timestampOrNull( null ),
+                       ),
+                       array(
+                               'user_id' => $id,
+                       ),
+                       __METHOD__
+               );
+       }
+
+       /**
+        * Get the user's current token.
+        * @param bool $forceCreation Force the generation of a new token if the
+        *   user doesn't have one (default=true for backwards compatibility).
+        * @return string Token
+        */
+       public function getToken( $forceCreation = true ) {
+               $this->load();
+               if ( !$this->mToken && $forceCreation ) {
+                       $this->setToken();
+               }
+               return $this->mToken;
+       }
+
+       /**
+        * Set the random token (used for persistent authentication)
+        * Called from loadDefaults() among other places.
+        *
+        * @param string|bool $token If specified, set the token to this value
+        */
+       public function setToken( $token = false ) {
+               $this->load();
+               if ( !$token ) {
+                       $this->mToken = MWCryptRand::generateHex( self::TOKEN_LENGTH );
+               } else {
+                       $this->mToken = $token;
+               }
+       }
+
+       /**
+        * Set the password for a password reminder or new account email
+        *
+        * @deprecated since 1.27, AuthManager is coming
+        * @param string $str New password to set or null to set an invalid
+        *  password hash meaning that the user will not be able to use it
+        * @param bool $throttle If true, reset the throttle timestamp to the present
+        */
+       public function setNewpassword( $str, $throttle = true ) {
+               $id = $this->getId();
+               if ( $id == 0 ) {
+                       throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $update = array(
+                       'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
+               );
+
+               if ( $str === null ) {
+                       $update['user_newpass_time'] = null;
+               } elseif ( $throttle ) {
+                       $update['user_newpass_time'] = $dbw->timestamp();
+               }
+
+               $dbw->update( 'user', $update, array( 'user_id' => $id ), __METHOD__ );
+       }
+
+       /**
+        * Has password reminder email been sent within the last
+        * $wgPasswordReminderResendTime hours?
+        * @return bool
+        */
+       public function isPasswordReminderThrottled() {
+               global $wgPasswordReminderResendTime;
+
+               if ( !$wgPasswordReminderResendTime ) {
+                       return false;
+               }
+
+               $this->load();
+
+               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+               $newpassTime = $db->selectField(
+                       'user',
+                       'user_newpass_time',
+                       array( 'user_id' => $this->getId() ),
+                       __METHOD__
+               );
+
+               if ( $newpassTime === null ) {
+                       return false;
+               }
+               $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
+               return time() < $expiry;
+       }
+
+       /**
+        * Get the user's e-mail address
+        * @return string User's email address
+        */
+       public function getEmail() {
+               $this->load();
+               Hooks::run( 'UserGetEmail', array( $this, &$this->mEmail ) );
+               return $this->mEmail;
+       }
+
+       /**
+        * Get the timestamp of the user's e-mail authentication
+        * @return string TS_MW timestamp
+        */
+       public function getEmailAuthenticationTimestamp() {
+               $this->load();
+               Hooks::run( 'UserGetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
+               return $this->mEmailAuthenticated;
+       }
+
+       /**
+        * Set the user's e-mail address
+        * @param string $str New e-mail address
+        */
+       public function setEmail( $str ) {
+               $this->load();
+               if ( $str == $this->mEmail ) {
+                       return;
+               }
+               $this->invalidateEmail();
+               $this->mEmail = $str;
+               Hooks::run( 'UserSetEmail', array( $this, &$this->mEmail ) );
+       }
+
+       /**
+        * Set the user's e-mail address and a confirmation mail if needed.
+        *
+        * @since 1.20
+        * @param string $str New e-mail address
+        * @return Status
+        */
+       public function setEmailWithConfirmation( $str ) {
+               global $wgEnableEmail, $wgEmailAuthentication;
+
+               if ( !$wgEnableEmail ) {
+                       return Status::newFatal( 'emaildisabled' );
+               }
+
+               $oldaddr = $this->getEmail();
+               if ( $str === $oldaddr ) {
+                       return Status::newGood( true );
+               }
+
+               $this->setEmail( $str );
+
+               if ( $str !== '' && $wgEmailAuthentication ) {
+                       // Send a confirmation request to the new address if needed
+                       $type = $oldaddr != '' ? 'changed' : 'set';
+                       $result = $this->sendConfirmationMail( $type );
+                       if ( $result->isGood() ) {
+                               // Say to the caller that a confirmation mail has been sent
+                               $result->value = 'eauth';
+                       }
+               } else {
+                       $result = Status::newGood( true );
+               }
+
+               return $result;
+       }
+
+       /**
+        * Get the user's real name
+        * @return string User's real name
+        */
+       public function getRealName() {
+               if ( !$this->isItemLoaded( 'realname' ) ) {
+                       $this->load();
+               }
+
+               return $this->mRealName;
+       }
+
+       /**
+        * Set the user's real name
+        * @param string $str New real name
+        */
+       public function setRealName( $str ) {
+               $this->load();
+               $this->mRealName = $str;
+       }
+
+       /**
+        * Get the user's current setting for a given option.
+        *
+        * @param string $oname The option to check
+        * @param string $defaultOverride A default value returned if the option does not exist
+        * @param bool $ignoreHidden Whether to ignore the effects of $wgHiddenPrefs
+        * @return string User's current value for the option
+        * @see getBoolOption()
+        * @see getIntOption()
+        */
+       public function getOption( $oname, $defaultOverride = null, $ignoreHidden = false ) {
+               global $wgHiddenPrefs;
+               $this->loadOptions();
+
+               # We want 'disabled' preferences to always behave as the default value for
+               # users, even if they have set the option explicitly in their settings (ie they
+               # set it, and then it was disabled removing their ability to change it).  But
+               # we don't want to erase the preferences in the database in case the preference
+               # is re-enabled again.  So don't touch $mOptions, just override the returned value
+               if ( !$ignoreHidden && in_array( $oname, $wgHiddenPrefs ) ) {
+                       return self::getDefaultOption( $oname );
+               }
+
+               if ( array_key_exists( $oname, $this->mOptions ) ) {
+                       return $this->mOptions[$oname];
+               } else {
+                       return $defaultOverride;
+               }
+       }
+
+       /**
+        * Get all user's options
+        *
+        * @param int $flags Bitwise combination of:
+        *   User::GETOPTIONS_EXCLUDE_DEFAULTS  Exclude user options that are set
+        *                                      to the default value. (Since 1.25)
+        * @return array
+        */
+       public function getOptions( $flags = 0 ) {
+               global $wgHiddenPrefs;
+               $this->loadOptions();
+               $options = $this->mOptions;
+
+               # We want 'disabled' preferences to always behave as the default value for
+               # users, even if they have set the option explicitly in their settings (ie they
+               # set it, and then it was disabled removing their ability to change it).  But
+               # we don't want to erase the preferences in the database in case the preference
+               # is re-enabled again.  So don't touch $mOptions, just override the returned value
+               foreach ( $wgHiddenPrefs as $pref ) {
+                       $default = self::getDefaultOption( $pref );
+                       if ( $default !== null ) {
+                               $options[$pref] = $default;
+                       }
+               }
+
+               if ( $flags & self::GETOPTIONS_EXCLUDE_DEFAULTS ) {
+                       $options = array_diff_assoc( $options, self::getDefaultOptions() );
+               }
+
+               return $options;
+       }
+
+       /**
+        * Get the user's current setting for a given option, as a boolean value.
+        *
+        * @param string $oname The option to check
+        * @return bool User's current value for the option
+        * @see getOption()
+        */
+       public function getBoolOption( $oname ) {
+               return (bool)$this->getOption( $oname );
+       }
+
+       /**
+        * Get the user's current setting for a given option, as an integer value.
+        *
+        * @param string $oname The option to check
+        * @param int $defaultOverride A default value returned if the option does not exist
+        * @return int User's current value for the option
+        * @see getOption()
+        */
+       public function getIntOption( $oname, $defaultOverride = 0 ) {
+               $val = $this->getOption( $oname );
+               if ( $val == '' ) {
+                       $val = $defaultOverride;
+               }
+               return intval( $val );
+       }
+
+       /**
+        * Set the given option for a user.
+        *
+        * You need to call saveSettings() to actually write to the database.
+        *
+        * @param string $oname The option to set
+        * @param mixed $val New value to set
+        */
+       public function setOption( $oname, $val ) {
+               $this->loadOptions();
+
+               // Explicitly NULL values should refer to defaults
+               if ( is_null( $val ) ) {
+                       $val = self::getDefaultOption( $oname );
+               }
+
+               $this->mOptions[$oname] = $val;
+       }
+
+       /**
+        * Get a token stored in the preferences (like the watchlist one),
+        * resetting it if it's empty (and saving changes).
+        *
+        * @param string $oname The option name to retrieve the token from
+        * @return string|bool User's current value for the option, or false if this option is disabled.
+        * @see resetTokenFromOption()
+        * @see getOption()
+        * @deprecated 1.26 Applications should use the OAuth extension
+        */
+       public function getTokenFromOption( $oname ) {
+               global $wgHiddenPrefs;
+
+               $id = $this->getId();
+               if ( !$id || in_array( $oname, $wgHiddenPrefs ) ) {
+                       return false;
+               }
+
+               $token = $this->getOption( $oname );
+               if ( !$token ) {
+                       // Default to a value based on the user token to avoid space
+                       // wasted on storing tokens for all users. When this option
+                       // is set manually by the user, only then is it stored.
+                       $token = hash_hmac( 'sha1', "$oname:$id", $this->getToken() );
+               }
+
+               return $token;
+       }
+
+       /**
+        * Reset a token stored in the preferences (like the watchlist one).
+        * *Does not* save user's preferences (similarly to setOption()).
+        *
+        * @param string $oname The option name to reset the token in
+        * @return string|bool New token value, or false if this option is disabled.
+        * @see getTokenFromOption()
+        * @see setOption()
+        */
+       public function resetTokenFromOption( $oname ) {
+               global $wgHiddenPrefs;
+               if ( in_array( $oname, $wgHiddenPrefs ) ) {
+                       return false;
+               }
+
+               $token = MWCryptRand::generateHex( 40 );
+               $this->setOption( $oname, $token );
+               return $token;
+       }
+
+       /**
+        * Return a list of the types of user options currently returned by
+        * User::getOptionKinds().
+        *
+        * Currently, the option kinds are:
+        * - 'registered' - preferences which are registered in core MediaWiki or
+        *                  by extensions using the UserGetDefaultOptions hook.
+        * - 'registered-multiselect' - as above, using the 'multiselect' type.
+        * - 'registered-checkmatrix' - as above, using the 'checkmatrix' type.
+        * - 'userjs' - preferences with names starting with 'userjs-', intended to
+        *              be used by user scripts.
+        * - 'special' - "preferences" that are not accessible via User::getOptions
+        *               or User::setOptions.
+        * - 'unused' - preferences about which MediaWiki doesn't know anything.
+        *              These are usually legacy options, removed in newer versions.
+        *
+        * The API (and possibly others) use this function to determine the possible
+        * option types for validation purposes, so make sure to update this when a
+        * new option kind is added.
+        *
+        * @see User::getOptionKinds
+        * @return array Option kinds
+        */
+       public static function listOptionKinds() {
+               return array(
+                       'registered',
+                       'registered-multiselect',
+                       'registered-checkmatrix',
+                       'userjs',
+                       'special',
+                       'unused'
+               );
+       }
+
+       /**
+        * Return an associative array mapping preferences keys to the kind of a preference they're
+        * used for. Different kinds are handled differently when setting or reading preferences.
+        *
+        * See User::listOptionKinds for the list of valid option types that can be provided.
+        *
+        * @see User::listOptionKinds
+        * @param IContextSource $context
+        * @param array $options Assoc. array with options keys to check as keys.
+        *   Defaults to $this->mOptions.
+        * @return array The key => kind mapping data
+        */
+       public function getOptionKinds( IContextSource $context, $options = null ) {
+               $this->loadOptions();
+               if ( $options === null ) {
+                       $options = $this->mOptions;
+               }
+
+               $prefs = Preferences::getPreferences( $this, $context );
+               $mapping = array();
+
+               // Pull out the "special" options, so they don't get converted as
+               // multiselect or checkmatrix.
+               $specialOptions = array_fill_keys( Preferences::getSaveBlacklist(), true );
+               foreach ( $specialOptions as $name => $value ) {
+                       unset( $prefs[$name] );
+               }
+
+               // Multiselect and checkmatrix options are stored in the database with
+               // one key per option, each having a boolean value. Extract those keys.
+               $multiselectOptions = array();
+               foreach ( $prefs as $name => $info ) {
+                       if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
+                                       ( isset( $info['class'] ) && $info['class'] == 'HTMLMultiSelectField' ) ) {
+                               $opts = HTMLFormField::flattenOptions( $info['options'] );
+                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+
+                               foreach ( $opts as $value ) {
+                                       $multiselectOptions["$prefix$value"] = true;
+                               }
+
+                               unset( $prefs[$name] );
+                       }
+               }
+               $checkmatrixOptions = array();
+               foreach ( $prefs as $name => $info ) {
+                       if ( ( isset( $info['type'] ) && $info['type'] == 'checkmatrix' ) ||
+                                       ( isset( $info['class'] ) && $info['class'] == 'HTMLCheckMatrix' ) ) {
+                               $columns = HTMLFormField::flattenOptions( $info['columns'] );
+                               $rows = HTMLFormField::flattenOptions( $info['rows'] );
+                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+
+                               foreach ( $columns as $column ) {
+                                       foreach ( $rows as $row ) {
+                                               $checkmatrixOptions["$prefix$column-$row"] = true;
+                                       }
+                               }
+
+                               unset( $prefs[$name] );
+                       }
+               }
+
+               // $value is ignored
+               foreach ( $options as $key => $value ) {
+                       if ( isset( $prefs[$key] ) ) {
+                               $mapping[$key] = 'registered';
+                       } elseif ( isset( $multiselectOptions[$key] ) ) {
+                               $mapping[$key] = 'registered-multiselect';
+                       } elseif ( isset( $checkmatrixOptions[$key] ) ) {
+                               $mapping[$key] = 'registered-checkmatrix';
+                       } elseif ( isset( $specialOptions[$key] ) ) {
+                               $mapping[$key] = 'special';
+                       } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
+                               $mapping[$key] = 'userjs';
+                       } else {
+                               $mapping[$key] = 'unused';
+                       }
+               }
+
+               return $mapping;
+       }
+
+       /**
+        * Reset certain (or all) options to the site defaults
+        *
+        * The optional parameter determines which kinds of preferences will be reset.
+        * Supported values are everything that can be reported by getOptionKinds()
+        * and 'all', which forces a reset of *all* preferences and overrides everything else.
+        *
+        * @param array|string $resetKinds Which kinds of preferences to reset. Defaults to
+        *  array( 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' )
+        *  for backwards-compatibility.
+        * @param IContextSource|null $context Context source used when $resetKinds
+        *  does not contain 'all', passed to getOptionKinds().
+        *  Defaults to RequestContext::getMain() when null.
+        */
+       public function resetOptions(
+               $resetKinds = array( 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' ),
+               IContextSource $context = null
+       ) {
+               $this->load();
+               $defaultOptions = self::getDefaultOptions();
+
+               if ( !is_array( $resetKinds ) ) {
+                       $resetKinds = array( $resetKinds );
+               }
+
+               if ( in_array( 'all', $resetKinds ) ) {
+                       $newOptions = $defaultOptions;
+               } else {
+                       if ( $context === null ) {
+                               $context = RequestContext::getMain();
+                       }
+
+                       $optionKinds = $this->getOptionKinds( $context );
+                       $resetKinds = array_intersect( $resetKinds, self::listOptionKinds() );
+                       $newOptions = array();
+
+                       // Use default values for the options that should be deleted, and
+                       // copy old values for the ones that shouldn't.
+                       foreach ( $this->mOptions as $key => $value ) {
+                               if ( in_array( $optionKinds[$key], $resetKinds ) ) {
+                                       if ( array_key_exists( $key, $defaultOptions ) ) {
+                                               $newOptions[$key] = $defaultOptions[$key];
+                                       }
+                               } else {
+                                       $newOptions[$key] = $value;
+                               }
+                       }
+               }
+
+               Hooks::run( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) );
+
+               $this->mOptions = $newOptions;
+               $this->mOptionsLoaded = true;
+       }
+
+       /**
+        * Get the user's preferred date format.
+        * @return string User's preferred date format
+        */
+       public function getDatePreference() {
+               // Important migration for old data rows
+               if ( is_null( $this->mDatePreference ) ) {
+                       global $wgLang;
+                       $value = $this->getOption( 'date' );
+                       $map = $wgLang->getDatePreferenceMigrationMap();
+                       if ( isset( $map[$value] ) ) {
+                               $value = $map[$value];
+                       }
+                       $this->mDatePreference = $value;
+               }
+               return $this->mDatePreference;
+       }
+
+       /**
+        * Determine based on the wiki configuration and the user's options,
+        * whether this user must be over HTTPS no matter what.
+        *
+        * @return bool
+        */
+       public function requiresHTTPS() {
+               global $wgSecureLogin;
+               if ( !$wgSecureLogin ) {
+                       return false;
+               } else {
+                       $https = $this->getBoolOption( 'prefershttps' );
+                       Hooks::run( 'UserRequiresHTTPS', array( $this, &$https ) );
+                       if ( $https ) {
+                               $https = wfCanIPUseHTTPS( $this->getRequest()->getIP() );
+                       }
+                       return $https;
+               }
+       }
+
+       /**
+        * Get the user preferred stub threshold
+        *
+        * @return int
+        */
+       public function getStubThreshold() {
+               global $wgMaxArticleSize; # Maximum article size, in Kb
+               $threshold = $this->getIntOption( 'stubthreshold' );
+               if ( $threshold > $wgMaxArticleSize * 1024 ) {
+                       // If they have set an impossible value, disable the preference
+                       // so we can use the parser cache again.
+                       $threshold = 0;
+               }
+               return $threshold;
+       }
+
+       /**
+        * Get the permissions this user has.
+        * @return array Array of String permission names
+        */
+       public function getRights() {
+               if ( is_null( $this->mRights ) ) {
+                       $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
+                       Hooks::run( 'UserGetRights', array( $this, &$this->mRights ) );
+                       // Force reindexation of rights when a hook has unset one of them
+                       $this->mRights = array_values( array_unique( $this->mRights ) );
+               }
+               return $this->mRights;
+       }
+
+       /**
+        * Get the list of explicit group memberships this user has.
+        * The implicit * and user groups are not included.
+        * @return array Array of String internal group names
+        */
+       public function getGroups() {
+               $this->load();
+               $this->loadGroups();
+               return $this->mGroups;
+       }
+
+       /**
+        * Get the list of implicit group memberships this user has.
+        * This includes all explicit groups, plus 'user' if logged in,
+        * '*' for all accounts, and autopromoted groups
+        * @param bool $recache Whether to avoid the cache
+        * @return array Array of String internal group names
+        */
+       public function getEffectiveGroups( $recache = false ) {
+               if ( $recache || is_null( $this->mEffectiveGroups ) ) {
+                       $this->mEffectiveGroups = array_unique( array_merge(
+                               $this->getGroups(), // explicit groups
+                               $this->getAutomaticGroups( $recache ) // implicit groups
+                       ) );
+                       // Hook for additional groups
+                       Hooks::run( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
+                       // Force reindexation of groups when a hook has unset one of them
+                       $this->mEffectiveGroups = array_values( array_unique( $this->mEffectiveGroups ) );
+               }
+               return $this->mEffectiveGroups;
+       }
+
+       /**
+        * Get the list of implicit group memberships this user has.
+        * This includes 'user' if logged in, '*' for all accounts,
+        * and autopromoted groups
+        * @param bool $recache Whether to avoid the cache
+        * @return array Array of String internal group names
+        */
+       public function getAutomaticGroups( $recache = false ) {
+               if ( $recache || is_null( $this->mImplicitGroups ) ) {
+                       $this->mImplicitGroups = array( '*' );
+                       if ( $this->getId() ) {
+                               $this->mImplicitGroups[] = 'user';
+
+                               $this->mImplicitGroups = array_unique( array_merge(
+                                       $this->mImplicitGroups,
+                                       Autopromote::getAutopromoteGroups( $this )
+                               ) );
+                       }
+                       if ( $recache ) {
+                               // Assure data consistency with rights/groups,
+                               // as getEffectiveGroups() depends on this function
+                               $this->mEffectiveGroups = null;
+                       }
+               }
+               return $this->mImplicitGroups;
+       }
+
+       /**
+        * Returns the groups the user has belonged to.
+        *
+        * The user may still belong to the returned groups. Compare with getGroups().
+        *
+        * The function will not return groups the user had belonged to before MW 1.17
+        *
+        * @return array Names of the groups the user has belonged to.
+        */
+       public function getFormerGroups() {
+               $this->load();
+
+               if ( is_null( $this->mFormerGroups ) ) {
+                       $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+                               ? wfGetDB( DB_MASTER )
+                               : wfGetDB( DB_SLAVE );
+                       $res = $db->select( 'user_former_groups',
+                               array( 'ufg_group' ),
+                               array( 'ufg_user' => $this->mId ),
+                               __METHOD__ );
+                       $this->mFormerGroups = array();
+                       foreach ( $res as $row ) {
+                               $this->mFormerGroups[] = $row->ufg_group;
+                       }
+               }
+
+               return $this->mFormerGroups;
+       }
+
+       /**
+        * Get the user's edit count.
+        * @return int|null Null for anonymous users
+        */
+       public function getEditCount() {
+               if ( !$this->getId() ) {
+                       return null;
+               }
+
+               if ( $this->mEditCount === null ) {
+                       /* Populate the count, if it has not been populated yet */
+                       $dbr = wfGetDB( DB_SLAVE );
+                       // check if the user_editcount field has been initialized
+                       $count = $dbr->selectField(
+                               'user', 'user_editcount',
+                               array( 'user_id' => $this->mId ),
+                               __METHOD__
+                       );
+
+                       if ( $count === null ) {
+                               // it has not been initialized. do so.
+                               $count = $this->initEditCount();
+                       }
+                       $this->mEditCount = $count;
+               }
+               return (int)$this->mEditCount;
+       }
+
+       /**
+        * Add the user to the given group.
+        * This takes immediate effect.
+        * @param string $group Name of the group to add
+        * @return bool
+        */
+       public function addGroup( $group ) {
+               $this->load();
+
+               if ( !Hooks::run( 'UserAddGroup', array( $this, &$group ) ) ) {
+                       return false;
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               if ( $this->getId() ) {
+                       $dbw->insert( 'user_groups',
+                               array(
+                                       'ug_user' => $this->getID(),
+                                       'ug_group' => $group,
+                               ),
+                               __METHOD__,
+                               array( 'IGNORE' ) );
+               }
+
+               $this->loadGroups();
+               $this->mGroups[] = $group;
+               // In case loadGroups was not called before, we now have the right twice.
+               // Get rid of the duplicate.
+               $this->mGroups = array_unique( $this->mGroups );
+
+               // Refresh the groups caches, and clear the rights cache so it will be
+               // refreshed on the next call to $this->getRights().
+               $this->getEffectiveGroups( true );
+               $this->mRights = null;
+
+               $this->invalidateCache();
+
+               return true;
+       }
+
+       /**
+        * Remove the user from the given group.
+        * This takes immediate effect.
+        * @param string $group Name of the group to remove
+        * @return bool
+        */
+       public function removeGroup( $group ) {
+               $this->load();
+               if ( !Hooks::run( 'UserRemoveGroup', array( $this, &$group ) ) ) {
+                       return false;
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'user_groups',
+                       array(
+                               'ug_user' => $this->getID(),
+                               'ug_group' => $group,
+                       ), __METHOD__
+               );
+               // Remember that the user was in this group
+               $dbw->insert( 'user_former_groups',
+                       array(
+                               'ufg_user' => $this->getID(),
+                               'ufg_group' => $group,
+                       ),
+                       __METHOD__,
+                       array( 'IGNORE' )
+               );
+
+               $this->loadGroups();
+               $this->mGroups = array_diff( $this->mGroups, array( $group ) );
+
+               // Refresh the groups caches, and clear the rights cache so it will be
+               // refreshed on the next call to $this->getRights().
+               $this->getEffectiveGroups( true );
+               $this->mRights = null;
+
+               $this->invalidateCache();
+
+               return true;
+       }
+
+       /**
+        * Get whether the user is logged in
+        * @return bool
+        */
+       public function isLoggedIn() {
+               return $this->getID() != 0;
+       }
+
+       /**
+        * Get whether the user is anonymous
+        * @return bool
+        */
+       public function isAnon() {
+               return !$this->isLoggedIn();
+       }
+
+       /**
+        * Check if user is allowed to access a feature / make an action
+        *
+        * @param string ... Permissions to test
+        * @return bool True if user is allowed to perform *any* of the given actions
+        */
+       public function isAllowedAny() {
+               $permissions = func_get_args();
+               foreach ( $permissions as $permission ) {
+                       if ( $this->isAllowed( $permission ) ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        *
+        * @param string ... Permissions to test
+        * @return bool True if the user is allowed to perform *all* of the given actions
+        */
+       public function isAllowedAll() {
+               $permissions = func_get_args();
+               foreach ( $permissions as $permission ) {
+                       if ( !$this->isAllowed( $permission ) ) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Internal mechanics of testing a permission
+        * @param string $action
+        * @return bool
+        */
+       public function isAllowed( $action = '' ) {
+               if ( $action === '' ) {
+                       return true; // In the spirit of DWIM
+               }
+               // Patrolling may not be enabled
+               if ( $action === 'patrol' || $action === 'autopatrol' ) {
+                       global $wgUseRCPatrol, $wgUseNPPatrol;
+                       if ( !$wgUseRCPatrol && !$wgUseNPPatrol ) {
+                               return false;
+                       }
+               }
+               // Use strict parameter to avoid matching numeric 0 accidentally inserted
+               // by misconfiguration: 0 == 'foo'
+               return in_array( $action, $this->getRights(), true );
+       }
+
+       /**
+        * Check whether to enable recent changes patrol features for this user
+        * @return bool True or false
+        */
+       public function useRCPatrol() {
+               global $wgUseRCPatrol;
+               return $wgUseRCPatrol && $this->isAllowedAny( 'patrol', 'patrolmarks' );
+       }
+
+       /**
+        * Check whether to enable new pages patrol features for this user
+        * @return bool True or false
+        */
+       public function useNPPatrol() {
+               global $wgUseRCPatrol, $wgUseNPPatrol;
+               return (
+                       ( $wgUseRCPatrol || $wgUseNPPatrol )
+                               && ( $this->isAllowedAny( 'patrol', 'patrolmarks' ) )
+               );
+       }
+
+       /**
+        * Get the WebRequest object to use with this object
+        *
+        * @return WebRequest
+        */
+       public function getRequest() {
+               if ( $this->mRequest ) {
+                       return $this->mRequest;
+               } else {
+                       global $wgRequest;
+                       return $wgRequest;
+               }
+       }
+
+       /**
+        * Get the current skin, loading it if required
+        * @return Skin The current skin
+        * @todo FIXME: Need to check the old failback system [AV]
+        * @deprecated since 1.18 Use ->getSkin() in the most relevant outputting context you have
+        */
+       public function getSkin() {
+               wfDeprecated( __METHOD__, '1.18' );
+               return RequestContext::getMain()->getSkin();
+       }
+
+       /**
+        * Get a WatchedItem for this user and $title.
+        *
+        * @since 1.22 $checkRights parameter added
+        * @param Title $title
+        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
+        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
+        * @return WatchedItem
+        */
+       public function getWatchedItem( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
+               $key = $checkRights . ':' . $title->getNamespace() . ':' . $title->getDBkey();
+
+               if ( isset( $this->mWatchedItems[$key] ) ) {
+                       return $this->mWatchedItems[$key];
+               }
+
+               if ( count( $this->mWatchedItems ) >= self::MAX_WATCHED_ITEMS_CACHE ) {
+                       $this->mWatchedItems = array();
+               }
+
+               $this->mWatchedItems[$key] = WatchedItem::fromUserTitle( $this, $title, $checkRights );
+               return $this->mWatchedItems[$key];
+       }
+
+       /**
+        * Check the watched status of an article.
+        * @since 1.22 $checkRights parameter added
+        * @param Title $title Title of the article to look at
+        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
+        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
+        * @return bool
+        */
+       public function isWatched( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
+               return $this->getWatchedItem( $title, $checkRights )->isWatched();
+       }
+
+       /**
+        * Watch an article.
+        * @since 1.22 $checkRights parameter added
+        * @param Title $title Title of the article to look at
+        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
+        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
+        */
+       public function addWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
+               $this->getWatchedItem( $title, $checkRights )->addWatch();
+               $this->invalidateCache();
+       }
+
+       /**
+        * Stop watching an article.
+        * @since 1.22 $checkRights parameter added
+        * @param Title $title Title of the article to look at
+        * @param int $checkRights Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
+        *     Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
+        */
+       public function removeWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
+               $this->getWatchedItem( $title, $checkRights )->removeWatch();
+               $this->invalidateCache();
+       }
+
+       /**
+        * Clear the user's notification timestamp for the given title.
+        * If e-notif e-mails are on, they will receive notification mails on
+        * the next change of the page if it's watched etc.
+        * @note If the user doesn't have 'editmywatchlist', this will do nothing.
+        * @param Title $title Title of the article to look at
+        * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed.
+        */
+       public function clearNotification( &$title, $oldid = 0 ) {
+               global $wgUseEnotif, $wgShowUpdatedMarker;
+
+               // Do nothing if the database is locked to writes
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
+               // Do nothing if not allowed to edit the watchlist
+               if ( !$this->isAllowed( 'editmywatchlist' ) ) {
+                       return;
+               }
+
+               // If we're working on user's talk page, we should update the talk page message indicator
+               if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
+                       if ( !Hooks::run( 'UserClearNewTalkNotification', array( &$this, $oldid ) ) ) {
+                               return;
+                       }
+
+                       $that = $this;
+                       // Try to update the DB post-send and only if needed...
+                       DeferredUpdates::addCallableUpdate( function() use ( $that, $title, $oldid ) {
+                               if ( !$that->getNewtalk() ) {
+                                       return; // no notifications to clear
+                               }
+
+                               // Delete the last notifications (they stack up)
+                               $that->setNewtalk( false );
+
+                               // If there is a new, unseen, revision, use its timestamp
+                               $nextid = $oldid
+                                       ? $title->getNextRevisionID( $oldid, Title::GAID_FOR_UPDATE )
+                                       : null;
+                               if ( $nextid ) {
+                                       $that->setNewtalk( true, Revision::newFromId( $nextid ) );
+                               }
+                       } );
+               }
+
+               if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
+                       return;
+               }
+
+               if ( $this->isAnon() ) {
+                       // Nothing else to do...
+                       return;
+               }
+
+               // Only update the timestamp if the page is being watched.
+               // The query to find out if it is watched is cached both in memcached and per-invocation,
+               // and when it does have to be executed, it can be on a slave
+               // If this is the user's newtalk page, we always update the timestamp
+               $force = '';
+               if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
+                       $force = 'force';
+               }
+
+               $this->getWatchedItem( $title )->resetNotificationTimestamp(
+                       $force, $oldid, WatchedItem::DEFERRED
+               );
+       }
+
+       /**
+        * Resets all of the given user's page-change notification timestamps.
+        * If e-notif e-mails are on, they will receive notification mails on
+        * the next change of any watched page.
+        * @note If the user doesn't have 'editmywatchlist', this will do nothing.
+        */
+       public function clearAllNotifications() {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
+               // Do nothing if not allowed to edit the watchlist
+               if ( !$this->isAllowed( 'editmywatchlist' ) ) {
+                       return;
+               }
+
+               global $wgUseEnotif, $wgShowUpdatedMarker;
+               if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
+                       $this->setNewtalk( false );
+                       return;
+               }
+               $id = $this->getId();
+               if ( $id != 0 ) {
+                       $dbw = wfGetDB( DB_MASTER );
+                       $dbw->update( 'watchlist',
+                               array( /* SET */ 'wl_notificationtimestamp' => null ),
+                               array( /* WHERE */ 'wl_user' => $id, 'wl_notificationtimestamp IS NOT NULL' ),
+                               __METHOD__
+                       );
+                       // We also need to clear here the "you have new message" notification for the own user_talk page;
+                       // it's cleared one page view later in WikiPage::doViewUpdates().
+               }
+       }
+
+       /**
+        * Set a cookie on the user's client. Wrapper for
+        * WebResponse::setCookie
+        * @param string $name Name of the cookie to set
+        * @param string $value Value to set
+        * @param int $exp Expiration time, as a UNIX time value;
+        *                   if 0 or not specified, use the default $wgCookieExpiration
+        * @param bool $secure
+        *  true: Force setting the secure attribute when setting the cookie
+        *  false: Force NOT setting the secure attribute when setting the cookie
+        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
+        * @param array $params Array of options sent passed to WebResponse::setcookie()
+        * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
+        *        is passed.
+        */
+       protected function setCookie(
+               $name, $value, $exp = 0, $secure = null, $params = array(), $request = null
+       ) {
+               if ( $request === null ) {
+                       $request = $this->getRequest();
+               }
+               $params['secure'] = $secure;
+               $request->response()->setCookie( $name, $value, $exp, $params );
+       }
+
+       /**
+        * Clear a cookie on the user's client
+        * @param string $name Name of the cookie to clear
+        * @param bool $secure
+        *  true: Force setting the secure attribute when setting the cookie
+        *  false: Force NOT setting the secure attribute when setting the cookie
+        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
+        * @param array $params Array of options sent passed to WebResponse::setcookie()
+        */
+       protected function clearCookie( $name, $secure = null, $params = array() ) {
+               $this->setCookie( $name, '', time() - 86400, $secure, $params );
+       }
+
+       /**
+        * Set an extended login cookie on the user's client. The expiry of the cookie
+        * is controlled by the $wgExtendedLoginCookieExpiration configuration
+        * variable.
+        *
+        * @see User::setCookie
+        *
+        * @param string $name Name of the cookie to set
+        * @param string $value Value to set
+        * @param bool $secure
+        *  true: Force setting the secure attribute when setting the cookie
+        *  false: Force NOT setting the secure attribute when setting the cookie
+        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
+        */
+       protected function setExtendedLoginCookie( $name, $value, $secure ) {
+               global $wgExtendedLoginCookieExpiration, $wgCookieExpiration;
+
+               $exp = time();
+               $exp += $wgExtendedLoginCookieExpiration !== null
+                       ? $wgExtendedLoginCookieExpiration
+                       : $wgCookieExpiration;
+
+               $this->setCookie( $name, $value, $exp, $secure );
+       }
+
+       /**
+        * Set the default cookies for this session on the user's client.
+        *
+        * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
+        *        is passed.
+        * @param bool $secure Whether to force secure/insecure cookies or use default
+        * @param bool $rememberMe Whether to add a Token cookie for elongated sessions
+        */
+       public function setCookies( $request = null, $secure = null, $rememberMe = false ) {
+               global $wgExtendedLoginCookies;
+
+               if ( $request === null ) {
+                       $request = $this->getRequest();
+               }
+
+               $this->load();
+               if ( 0 == $this->mId ) {
+                       return;
+               }
+               if ( !$this->mToken ) {
+                       // When token is empty or NULL generate a new one and then save it to the database
+                       // This allows a wiki to re-secure itself after a leak of it's user table or $wgSecretKey
+                       // Simply by setting every cell in the user_token column to NULL and letting them be
+                       // regenerated as users log back into the wiki.
+                       $this->setToken();
+                       if ( !wfReadOnly() ) {
+                               $this->saveSettings();
+                       }
+               }
+               $session = array(
+                       'wsUserID' => $this->mId,
+                       'wsToken' => $this->mToken,
+                       'wsUserName' => $this->getName()
+               );
+               $cookies = array(
+                       'UserID' => $this->mId,
+                       'UserName' => $this->getName(),
+               );
+               if ( $rememberMe ) {
+                       $cookies['Token'] = $this->mToken;
+               } else {
+                       $cookies['Token'] = false;
+               }
+
+               Hooks::run( 'UserSetCookies', array( $this, &$session, &$cookies ) );
+
+               foreach ( $session as $name => $value ) {
+                       $request->setSessionData( $name, $value );
+               }
+               foreach ( $cookies as $name => $value ) {
+                       if ( $value === false ) {
+                               $this->clearCookie( $name );
+                       } elseif ( $rememberMe && in_array( $name, $wgExtendedLoginCookies ) ) {
+                               $this->setExtendedLoginCookie( $name, $value, $secure );
+                       } else {
+                               $this->setCookie( $name, $value, 0, $secure, array(), $request );
+                       }
+               }
+
+               /**
+                * If wpStickHTTPS was selected, also set an insecure cookie that
+                * will cause the site to redirect the user to HTTPS, if they access
+                * it over HTTP. Bug 29898. Use an un-prefixed cookie, so it's the same
+                * as the one set by centralauth (bug 53538). Also set it to session, or
+                * standard time setting, based on if rememberme was set.
+                */
+               if ( $request->getCheck( 'wpStickHTTPS' ) || $this->requiresHTTPS() ) {
+                       $this->setCookie(
+                               'forceHTTPS',
+                               'true',
+                               $rememberMe ? 0 : null,
+                               false,
+                               array( 'prefix' => '' ) // no prefix
+                       );
+               }
+       }
+
+       /**
+        * Log this user out.
+        */
+       public function logout() {
+               if ( Hooks::run( 'UserLogout', array( &$this ) ) ) {
+                       $this->doLogout();
+               }
+       }
+
+       /**
+        * Clear the user's cookies and session, and reset the instance cache.
+        * @see logout()
+        */
+       public function doLogout() {
+               $this->clearInstanceCache( 'defaults' );
+
+               $this->getRequest()->setSessionData( 'wsUserID', 0 );
+
+               $this->clearCookie( 'UserID' );
+               $this->clearCookie( 'Token' );
+               $this->clearCookie( 'forceHTTPS', false, array( 'prefix' => '' ) );
+
+               // Remember when user logged out, to prevent seeing cached pages
+               $this->setCookie( 'LoggedOut', time(), time() + 86400 );
+       }
+
+       /**
+        * Save this user's settings into the database.
+        * @todo Only rarely do all these fields need to be set!
+        */
+       public function saveSettings() {
+               if ( wfReadOnly() ) {
+                       // @TODO: caller should deal with this instead!
+                       // This should really just be an exception.
+                       MWExceptionHandler::logException( new DBExpectedError(
+                               null,
+                               "Could not update user with ID '{$this->mId}'; DB is read-only."
+                       ) );
+                       return;
+               }
+
+               $this->load();
+               if ( 0 == $this->mId ) {
+                       return; // anon
+               }
+
+               // Get a new user_touched that is higher than the old one.
+               // This will be used for a CAS check as a last-resort safety
+               // check against race conditions and slave lag.
+               $oldTouched = $this->mTouched;
+               $newTouched = $this->newTouchedTimestamp();
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update( 'user',
+                       array( /* SET */
+                               'user_name' => $this->mName,
+                               'user_real_name' => $this->mRealName,
+                               'user_email' => $this->mEmail,
+                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+                               'user_touched' => $dbw->timestamp( $newTouched ),
+                               'user_token' => strval( $this->mToken ),
+                               'user_email_token' => $this->mEmailToken,
+                               'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
+                       ), array( /* WHERE */
+                               'user_id' => $this->mId,
+                               'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
+                       ), __METHOD__
+               );
+
+               if ( !$dbw->affectedRows() ) {
+                       // Maybe the problem was a missed cache update; clear it to be safe
+                       $this->clearSharedCache( 'refresh' );
+                       // User was changed in the meantime or loaded with stale data
+                       $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave';
+                       throw new MWException(
+                               "CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" .
+                               " the version of the user to be saved is older than the current version."
+                       );
+               }
+
+               $this->mTouched = $newTouched;
+               $this->saveOptions();
+
+               Hooks::run( 'UserSaveSettings', array( $this ) );
+               $this->clearSharedCache();
+               $this->getUserPage()->invalidateCache();
+       }
+
+       /**
+        * If only this user's username is known, and it exists, return the user ID.
+        *
+        * @param int $flags Bitfield of User:READ_* constants; useful for existence checks
+        * @return int
+        */
+       public function idForName( $flags = 0 ) {
+               $s = trim( $this->getName() );
+               if ( $s === '' ) {
+                       return 0;
+               }
+
+               $db = ( ( $flags & self::READ_LATEST ) == self::READ_LATEST )
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+
+               $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
+                       ? array( 'LOCK IN SHARE MODE' )
+                       : array();
+
+               $id = $db->selectField( 'user',
+                       'user_id', array( 'user_name' => $s ), __METHOD__, $options );
+
+               return (int)$id;
+       }
+
+       /**
+        * Add a user to the database, return the user object
+        *
+        * @param string $name Username to add
+        * @param array $params Array of Strings Non-default parameters to save to
+        *   the database as user_* fields:
+        *   - email: The user's email address.
+        *   - email_authenticated: The email authentication timestamp.
+        *   - real_name: The user's real name.
+        *   - options: An associative array of non-default options.
+        *   - token: Random authentication token. Do not set.
+        *   - registration: Registration timestamp. Do not set.
+        *
+        * @return User|null User object, or null if the username already exists.
+        */
+       public static function createNew( $name, $params = array() ) {
+               foreach ( array( 'password', 'newpassword', 'newpass_time', 'password_expires' ) as $field ) {
+                       if ( isset( $params[$field] ) ) {
+                               wfDeprecated( __METHOD__ . " with param '$field'", '1.27' );
+                               unset( $params[$field] );
+                       }
+               }
+
+               $user = new User;
+               $user->load();
+               $user->setToken(); // init token
+               if ( isset( $params['options'] ) ) {
+                       $user->mOptions = $params['options'] + (array)$user->mOptions;
+                       unset( $params['options'] );
+               }
+               $dbw = wfGetDB( DB_MASTER );
+               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+
+               $noPass = PasswordFactory::newInvalidPassword()->toString();
+
+               $fields = array(
+                       'user_id' => $seqVal,
+                       'user_name' => $name,
+                       'user_password' => $noPass,
+                       'user_newpassword' => $noPass,
+                       'user_email' => $user->mEmail,
+                       'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
+                       'user_real_name' => $user->mRealName,
+                       'user_token' => strval( $user->mToken ),
+                       'user_registration' => $dbw->timestamp( $user->mRegistration ),
+                       'user_editcount' => 0,
+                       'user_touched' => $dbw->timestamp( $user->newTouchedTimestamp() ),
+               );
+               foreach ( $params as $name => $value ) {
+                       $fields["user_$name"] = $value;
+               }
+               $dbw->insert( 'user', $fields, __METHOD__, array( 'IGNORE' ) );
+               if ( $dbw->affectedRows() ) {
+                       $newUser = User::newFromId( $dbw->insertId() );
+               } else {
+                       $newUser = null;
+               }
+               return $newUser;
+       }
+
+       /**
+        * Add this existing user object to the database. If the user already
+        * exists, a fatal status object is returned, and the user object is
+        * initialised with the data from the database.
+        *
+        * Previously, this function generated a DB error due to a key conflict
+        * if the user already existed. Many extension callers use this function
+        * in code along the lines of:
+        *
+        *   $user = User::newFromName( $name );
+        *   if ( !$user->isLoggedIn() ) {
+        *       $user->addToDatabase();
+        *   }
+        *   // do something with $user...
+        *
+        * However, this was vulnerable to a race condition (bug 16020). By
+        * initialising the user object if the user exists, we aim to support this
+        * calling sequence as far as possible.
+        *
+        * Note that if the user exists, this function will acquire a write lock,
+        * so it is still advisable to make the call conditional on isLoggedIn(),
+        * and to commit the transaction after calling.
+        *
+        * @throws MWException
+        * @return Status
+        */
+       public function addToDatabase() {
+               $this->load();
+               if ( !$this->mToken ) {
+                       $this->setToken(); // init token
+               }
+
+               $this->mTouched = $this->newTouchedTimestamp();
+
+               $noPass = PasswordFactory::newInvalidPassword()->toString();
+
+               $dbw = wfGetDB( DB_MASTER );
+               $inWrite = $dbw->writesOrCallbacksPending();
+               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+               $dbw->insert( 'user',
+                       array(
+                               'user_id' => $seqVal,
+                               'user_name' => $this->mName,
+                               'user_password' => $noPass,
+                               'user_newpassword' => $noPass,
+                               'user_email' => $this->mEmail,
+                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+                               'user_real_name' => $this->mRealName,
+                               'user_token' => strval( $this->mToken ),
+                               'user_registration' => $dbw->timestamp( $this->mRegistration ),
+                               'user_editcount' => 0,
+                               'user_touched' => $dbw->timestamp( $this->mTouched ),
+                       ), __METHOD__,
+                       array( 'IGNORE' )
+               );
+               if ( !$dbw->affectedRows() ) {
+                       // The queries below cannot happen in the same REPEATABLE-READ snapshot.
+                       // Handle this by COMMIT, if possible, or by LOCK IN SHARE MODE otherwise.
+                       if ( $inWrite ) {
+                               // Can't commit due to pending writes that may need atomicity.
+                               // This may cause some lock contention unlike the case below.
+                               $options = array( 'LOCK IN SHARE MODE' );
+                               $flags = self::READ_LOCKING;
+                       } else {
+                               // Often, this case happens early in views before any writes when
+                               // using CentralAuth. It's should be OK to commit and break the snapshot.
+                               $dbw->commit( __METHOD__, 'flush' );
+                               $options = array();
+                               $flags = self::READ_LATEST;
+                       }
+                       $this->mId = $dbw->selectField( 'user', 'user_id',
+                               array( 'user_name' => $this->mName ), __METHOD__, $options );
+                       $loaded = false;
+                       if ( $this->mId ) {
+                               if ( $this->loadFromDatabase( $flags ) ) {
+                                       $loaded = true;
+                               }
+                       }
+                       if ( !$loaded ) {
+                               throw new MWException( __METHOD__ . ": hit a key conflict attempting " .
+                                       "to insert user '{$this->mName}' row, but it was not present in select!" );
+                       }
+                       return Status::newFatal( 'userexists' );
+               }
+               $this->mId = $dbw->insertId();
+               self::$idCacheByName[$this->mName] = $this->mId;
+
+               // Clear instance cache other than user table data, which is already accurate
+               $this->clearInstanceCache();
+
+               $this->saveOptions();
+               return Status::newGood();
+       }
+
+       /**
+        * If this user is logged-in and blocked,
+        * block any IP address they've successfully logged in from.
+        * @return bool A block was spread
+        */
+       public function spreadAnyEditBlock() {
+               if ( $this->isLoggedIn() && $this->isBlocked() ) {
+                       return $this->spreadBlock();
+               }
+               return false;
+       }
+
+       /**
+        * If this (non-anonymous) user is blocked,
+        * block the IP address they've successfully logged in from.
+        * @return bool A block was spread
+        */
+       protected function spreadBlock() {
+               wfDebug( __METHOD__ . "()\n" );
+               $this->load();
+               if ( $this->mId == 0 ) {
+                       return false;
+               }
+
+               $userblock = Block::newFromTarget( $this->getName() );
+               if ( !$userblock ) {
+                       return false;
+               }
+
+               return (bool)$userblock->doAutoblock( $this->getRequest()->getIP() );
+       }
+
+       /**
+        * Get whether the user is explicitly blocked from account creation.
+        * @return bool|Block
+        */
+       public function isBlockedFromCreateAccount() {
+               $this->getBlockedStatus();
+               if ( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ) {
+                       return $this->mBlock;
+               }
+
+               # bug 13611: if the IP address the user is trying to create an account from is
+               # blocked with createaccount disabled, prevent new account creation there even
+               # when the user is logged in
+               if ( $this->mBlockedFromCreateAccount === false && !$this->isAllowed( 'ipblock-exempt' ) ) {
+                       $this->mBlockedFromCreateAccount = Block::newFromTarget( null, $this->getRequest()->getIP() );
+               }
+               return $this->mBlockedFromCreateAccount instanceof Block
+                       && $this->mBlockedFromCreateAccount->prevents( 'createaccount' )
+                       ? $this->mBlockedFromCreateAccount
+                       : false;
+       }
+
+       /**
+        * Get whether the user is blocked from using Special:Emailuser.
+        * @return bool
+        */
+       public function isBlockedFromEmailuser() {
+               $this->getBlockedStatus();
+               return $this->mBlock && $this->mBlock->prevents( 'sendemail' );
+       }
+
+       /**
+        * Get whether the user is allowed to create an account.
+        * @return bool
+        */
+       public function isAllowedToCreateAccount() {
+               return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
+       }
+
+       /**
+        * Get this user's personal page title.
+        *
+        * @return Title User's personal page title
+        */
+       public function getUserPage() {
+               return Title::makeTitle( NS_USER, $this->getName() );
+       }
+
+       /**
+        * Get this user's talk page title.
+        *
+        * @return Title User's talk page title
+        */
+       public function getTalkPage() {
+               $title = $this->getUserPage();
+               return $title->getTalkPage();
+       }
+
+       /**
+        * Determine whether the user is a newbie. Newbies are either
+        * anonymous IPs, or the most recently created accounts.
+        * @return bool
+        */
+       public function isNewbie() {
+               return !$this->isAllowed( 'autoconfirmed' );
+       }
+
+       /**
+        * Check to see if the given clear-text password is one of the accepted passwords
+        * @deprecated since 1.27. AuthManager is coming.
+        * @param string $password User password
+        * @return bool True if the given password is correct, otherwise False
+        */
+       public function checkPassword( $password ) {
+               global $wgAuth, $wgLegacyEncoding;
+
+               $this->load();
+
+               // Some passwords will give a fatal Status, which means there is
+               // some sort of technical or security reason for this password to
+               // be completely invalid and should never be checked (e.g., T64685)
+               if ( !$this->checkPasswordValidity( $password )->isOK() ) {
+                       return false;
+               }
+
+               // Certain authentication plugins do NOT want to save
+               // domain passwords in a mysql database, so we should
+               // check this (in case $wgAuth->strict() is false).
+               if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
+                       return true;
+               } elseif ( $wgAuth->strict() ) {
+                       // Auth plugin doesn't allow local authentication
+                       return false;
+               } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
+                       // Auth plugin doesn't allow local authentication for this user name
+                       return false;
+               }
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+
+               try {
+                       $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
+                               'user', 'user_password', array( 'user_id' => $this->getId() ), __METHOD__
+                       ) );
+               } catch ( PasswordError $e ) {
+                       wfDebug( 'Invalid password hash found in database.' );
+                       $mPassword = PasswordFactory::newInvalidPassword();
+               }
+
+               if ( !$mPassword->equals( $password ) ) {
+                       if ( $wgLegacyEncoding ) {
+                               // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
+                               // Check for this with iconv
+                               $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
+                               if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
+                                       return false;
+                               }
+                       } else {
+                               return false;
+                       }
+               }
+
+               if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
+                       $this->setPasswordInternal( $password );
+               }
+
+               return true;
+       }
+
+       /**
+        * Check if the given clear-text password matches the temporary password
+        * sent by e-mail for password reset operations.
+        *
+        * @deprecated since 1.27. AuthManager is coming.
+        * @param string $plaintext
+        * @return bool True if matches, false otherwise
+        */
+       public function checkTemporaryPassword( $plaintext ) {
+               global $wgNewPasswordExpiry;
+
+               $this->load();
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+                       ? wfGetDB( DB_MASTER )
+                       : wfGetDB( DB_SLAVE );
+
+               $row = $db->selectRow(
+                       'user',
+                       array( 'user_newpassword', 'user_newpass_time' ),
+                       array( 'user_id' => $this->getId() ),
+                       __METHOD__
+               );
+               try {
+                       $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
+               } catch ( PasswordError $e ) {
+                       wfDebug( 'Invalid password hash found in database.' );
+                       $newPassword = PasswordFactory::newInvalidPassword();
+               }
+
+               if ( $newPassword->equals( $plaintext ) ) {
+                       if ( is_null( $row->user_newpass_time ) ) {
+                               return true;
+                       }
+                       $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
+                       return ( time() < $expiry );
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Alias for getEditToken.
+        * @deprecated since 1.19, use getEditToken instead.
+        *
+        * @param string|array $salt Array of Strings Optional function-specific data for hashing
+        * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
+        * @return string The new edit token
+        */
+       public function editToken( $salt = '', $request = null ) {
+               wfDeprecated( __METHOD__, '1.19' );
+               return $this->getEditToken( $salt, $request );
+       }
+
+       /**
+        * Internal implementation for self::getEditToken() and
+        * self::matchEditToken().
+        *
+        * @param string|array $salt
+        * @param WebRequest $request
+        * @param string|int $timestamp
+        * @return string
+        */
+       private function getEditTokenAtTimestamp( $salt, $request, $timestamp ) {
+               if ( $this->isAnon() ) {
+                       return self::EDIT_TOKEN_SUFFIX;
+               } else {
+                       $token = $request->getSessionData( 'wsEditToken' );
+                       if ( $token === null ) {
+                               $token = MWCryptRand::generateHex( 32 );
+                               $request->setSessionData( 'wsEditToken', $token );
+                       }
+                       if ( is_array( $salt ) ) {
+                               $salt = implode( '|', $salt );
+                       }
+                       return hash_hmac( 'md5', $timestamp . $salt, $token, false ) .
+                               dechex( $timestamp ) .
+                               self::EDIT_TOKEN_SUFFIX;
+               }
+       }
+
+       /**
+        * Initialize (if necessary) and return a session token value
+        * which can be used in edit forms to show that the user's
+        * login credentials aren't being hijacked with a foreign form
+        * submission.
+        *
+        * @since 1.19
+        *
+        * @param string|array $salt Array of Strings Optional function-specific data for hashing
+        * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
+        * @return string The new edit token
+        */
+       public function getEditToken( $salt = '', $request = null ) {
+               return $this->getEditTokenAtTimestamp(
+                       $salt, $request ?: $this->getRequest(), wfTimestamp()
+               );
+       }
+
+       /**
+        * Generate a looking random token for various uses.
+        *
+        * @return string The new random token
+        * @deprecated since 1.20: Use MWCryptRand for secure purposes or
+        *   wfRandomString for pseudo-randomness.
+        */
+       public static function generateToken() {
+               return MWCryptRand::generateHex( 32 );
+       }
+
+       /**
+        * Get the embedded timestamp from a token.
+        * @param string $val Input token
+        * @return int|null
+        */
+       public static function getEditTokenTimestamp( $val ) {
+               $suffixLen = strlen( self::EDIT_TOKEN_SUFFIX );
+               if ( strlen( $val ) <= 32 + $suffixLen ) {
+                       return null;
+               }
+
+               return hexdec( substr( $val, 32, -$suffixLen ) );
+       }
+
+       /**
+        * Check given value against the token value stored in the session.
+        * A match should confirm that the form was submitted from the
+        * user's own login session, not a form submission from a third-party
+        * site.
+        *
+        * @param string $val Input value to compare
+        * @param string $salt Optional function-specific data for hashing
+        * @param WebRequest|null $request Object to use or null to use $wgRequest
+        * @param int $maxage Fail tokens older than this, in seconds
+        * @return bool Whether the token matches
+        */
+       public function matchEditToken( $val, $salt = '', $request = null, $maxage = null ) {
+               if ( $this->isAnon() ) {
+                       return $val === self::EDIT_TOKEN_SUFFIX;
+               }
+
+               $timestamp = self::getEditTokenTimestamp( $val );
+               if ( $timestamp === null ) {
+                       return false;
+               }
+               if ( $maxage !== null && $timestamp < wfTimestamp() - $maxage ) {
+                       // Expired token
+                       return false;
+               }
+
+               $sessionToken = $this->getEditTokenAtTimestamp(
+                       $salt, $request ?: $this->getRequest(), $timestamp
+               );
+
+               if ( $val != $sessionToken ) {
+                       wfDebug( "User::matchEditToken: broken session data\n" );
+               }
+
+               return hash_equals( $sessionToken, $val );
+       }
+
+       /**
+        * Check given value against the token value stored in the session,
+        * ignoring the suffix.
+        *
+        * @param string $val Input value to compare
+        * @param string $salt Optional function-specific data for hashing
+        * @param WebRequest|null $request Object to use or null to use $wgRequest
+        * @param int $maxage Fail tokens older than this, in seconds
+        * @return bool Whether the token matches
+        */
+       public function matchEditTokenNoSuffix( $val, $salt = '', $request = null, $maxage = null ) {
+               $val = substr( $val, 0, strspn( $val, '0123456789abcdef' ) ) . self::EDIT_TOKEN_SUFFIX;
+               return $this->matchEditToken( $val, $salt, $request, $maxage );
+       }
+
+       /**
+        * Generate a new e-mail confirmation token and send a confirmation/invalidation
+        * mail to the user's given address.
+        *
+        * @param string $type Message to send, either "created", "changed" or "set"
+        * @return Status
+        */
+       public function sendConfirmationMail( $type = 'created' ) {
+               global $wgLang;
+               $expiration = null; // gets passed-by-ref and defined in next line.
+               $token = $this->confirmationToken( $expiration );
+               $url = $this->confirmationTokenUrl( $token );
+               $invalidateURL = $this->invalidationTokenUrl( $token );
+               $this->saveSettings();
+
+               if ( $type == 'created' || $type === false ) {
+                       $message = 'confirmemail_body';
+               } elseif ( $type === true ) {
+                       $message = 'confirmemail_body_changed';
+               } else {
+                       // Messages: confirmemail_body_changed, confirmemail_body_set
+                       $message = 'confirmemail_body_' . $type;
+               }
+
+               return $this->sendMail( wfMessage( 'confirmemail_subject' )->text(),
+                       wfMessage( $message,
+                               $this->getRequest()->getIP(),
+                               $this->getName(),
+                               $url,
+                               $wgLang->userTimeAndDate( $expiration, $this ),
+                               $invalidateURL,
+                               $wgLang->userDate( $expiration, $this ),
+                               $wgLang->userTime( $expiration, $this ) )->text() );
+       }
+
+       /**
+        * Send an e-mail to this user's account. Does not check for
+        * confirmed status or validity.
+        *
+        * @param string $subject Message subject
+        * @param string $body Message body
+        * @param User|null $from Optional sending user; if unspecified, default
+        *   $wgPasswordSender will be used.
+        * @param string $replyto Reply-To address
+        * @return Status
+        */
+       public function sendMail( $subject, $body, $from = null, $replyto = null ) {
+               global $wgPasswordSender;
+
+               if ( $from instanceof User ) {
+                       $sender = MailAddress::newFromUser( $from );
+               } else {
+                       $sender = new MailAddress( $wgPasswordSender,
+                               wfMessage( 'emailsender' )->inContentLanguage()->text() );
+               }
+               $to = MailAddress::newFromUser( $this );
+
+               return UserMailer::send( $to, $sender, $subject, $body, array(
+                       'replyTo' => $replyto,
+               ) );
+       }
+
+       /**
+        * Generate, store, and return a new e-mail confirmation code.
+        * A hash (unsalted, since it's used as a key) is stored.
+        *
+        * @note Call saveSettings() after calling this function to commit
+        * this change to the database.
+        *
+        * @param string &$expiration Accepts the expiration time
+        * @return string New token
+        */
+       protected function confirmationToken( &$expiration ) {
+               global $wgUserEmailConfirmationTokenExpiry;
+               $now = time();
+               $expires = $now + $wgUserEmailConfirmationTokenExpiry;
+               $expiration = wfTimestamp( TS_MW, $expires );
+               $this->load();
+               $token = MWCryptRand::generateHex( 32 );
+               $hash = md5( $token );
+               $this->mEmailToken = $hash;
+               $this->mEmailTokenExpires = $expiration;
+               return $token;
+       }
+
+       /**
+        * Return a URL the user can use to confirm their email address.
+        * @param string $token Accepts the email confirmation token
+        * @return string New token URL
+        */
+       protected function confirmationTokenUrl( $token ) {
+               return $this->getTokenUrl( 'ConfirmEmail', $token );
+       }
+
+       /**
+        * Return a URL the user can use to invalidate their email address.
+        * @param string $token Accepts the email confirmation token
+        * @return string New token URL
+        */
+       protected function invalidationTokenUrl( $token ) {
+               return $this->getTokenUrl( 'InvalidateEmail', $token );
+       }
+
+       /**
+        * Internal function to format the e-mail validation/invalidation URLs.
+        * This uses a quickie hack to use the
+        * hardcoded English names of the Special: pages, for ASCII safety.
+        *
+        * @note Since these URLs get dropped directly into emails, using the
+        * short English names avoids insanely long URL-encoded links, which
+        * also sometimes can get corrupted in some browsers/mailers
+        * (bug 6957 with Gmail and Internet Explorer).
+        *
+        * @param string $page Special page
+        * @param string $token Token
+        * @return string Formatted URL
+        */
+       protected function getTokenUrl( $page, $token ) {
+               // Hack to bypass localization of 'Special:'
+               $title = Title::makeTitle( NS_MAIN, "Special:$page/$token" );
+               return $title->getCanonicalURL();
+       }
+
+       /**
+        * Mark the e-mail address confirmed.
+        *
+        * @note Call saveSettings() after calling this function to commit the change.
+        *
+        * @return bool
+        */
+       public function confirmEmail() {
+               // Check if it's already confirmed, so we don't touch the database
+               // and fire the ConfirmEmailComplete hook on redundant confirmations.
+               if ( !$this->isEmailConfirmed() ) {
+                       $this->setEmailAuthenticationTimestamp( wfTimestampNow() );
+                       Hooks::run( 'ConfirmEmailComplete', array( $this ) );
+               }
+               return true;
+       }
+
+       /**
+        * Invalidate the user's e-mail confirmation, and unauthenticate the e-mail
+        * address if it was already confirmed.
+        *
+        * @note Call saveSettings() after calling this function to commit the change.
+        * @return bool Returns true
+        */
+       public function invalidateEmail() {
+               $this->load();
+               $this->mEmailToken = null;
+               $this->mEmailTokenExpires = null;
+               $this->setEmailAuthenticationTimestamp( null );
+               $this->mEmail = '';
+               Hooks::run( 'InvalidateEmailComplete', array( $this ) );
+               return true;
+       }
+
+       /**
+        * Set the e-mail authentication timestamp.
+        * @param string $timestamp TS_MW timestamp
+        */
+       public function setEmailAuthenticationTimestamp( $timestamp ) {
+               $this->load();
+               $this->mEmailAuthenticated = $timestamp;
+               Hooks::run( 'UserSetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
+       }
+
+       /**
+        * Is this user allowed to send e-mails within limits of current
+        * site configuration?
+        * @return bool
+        */
+       public function canSendEmail() {
+               global $wgEnableEmail, $wgEnableUserEmail;
+               if ( !$wgEnableEmail || !$wgEnableUserEmail || !$this->isAllowed( 'sendemail' ) ) {
+                       return false;
+               }
+               $canSend = $this->isEmailConfirmed();
+               Hooks::run( 'UserCanSendEmail', array( &$this, &$canSend ) );
+               return $canSend;
+       }
+
+       /**
+        * Is this user allowed to receive e-mails within limits of current
+        * site configuration?
+        * @return bool
+        */
+       public function canReceiveEmail() {
+               return $this->isEmailConfirmed() && !$this->getOption( 'disablemail' );
+       }
+
+       /**
+        * Is this user's e-mail address valid-looking and confirmed within
+        * limits of the current site configuration?
+        *
+        * @note If $wgEmailAuthentication is on, this may require the user to have
+        * confirmed their address by returning a code or using a password
+        * sent to the address from the wiki.
+        *
+        * @return bool
+        */
+       public function isEmailConfirmed() {
+               global $wgEmailAuthentication;
+               $this->load();
+               $confirmed = true;
+               if ( Hooks::run( 'EmailConfirmed', array( &$this, &$confirmed ) ) ) {
+                       if ( $this->isAnon() ) {
+                               return false;
+                       }
+                       if ( !Sanitizer::validateEmail( $this->mEmail ) ) {
+                               return false;
+                       }
+                       if ( $wgEmailAuthentication && !$this->getEmailAuthenticationTimestamp() ) {
+                               return false;
+                       }
+                       return true;
+               } else {
+                       return $confirmed;
+               }
+       }
+
+       /**
+        * Check whether there is an outstanding request for e-mail confirmation.
+        * @return bool
+        */
+       public function isEmailConfirmationPending() {
+               global $wgEmailAuthentication;
+               return $wgEmailAuthentication &&
+                       !$this->isEmailConfirmed() &&
+                       $this->mEmailToken &&
+                       $this->mEmailTokenExpires > wfTimestamp();
+       }
+
+       /**
+        * Get the timestamp of account creation.
+        *
+        * @return string|bool|null Timestamp of account creation, false for
+        *  non-existent/anonymous user accounts, or null if existing account
+        *  but information is not in database.
+        */
+       public function getRegistration() {
+               if ( $this->isAnon() ) {
+                       return false;
+               }
+               $this->load();
+               return $this->mRegistration;
+       }
+
+       /**
+        * Get the timestamp of the first edit
+        *
+        * @return string|bool Timestamp of first edit, or false for
+        *  non-existent/anonymous user accounts.
+        */
+       public function getFirstEditTimestamp() {
+               if ( $this->getId() == 0 ) {
+                       return false; // anons
+               }
+               $dbr = wfGetDB( DB_SLAVE );
+               $time = $dbr->selectField( 'revision', 'rev_timestamp',
+                       array( 'rev_user' => $this->getId() ),
+                       __METHOD__,
+                       array( 'ORDER BY' => 'rev_timestamp ASC' )
+               );
+               if ( !$time ) {
+                       return false; // no edits
+               }
+               return wfTimestamp( TS_MW, $time );
+       }
+
+       /**
+        * Get the permissions associated with a given list of groups
+        *
+        * @param array $groups Array of Strings List of internal group names
+        * @return array Array of Strings List of permission key names for given groups combined
+        */
+       public static function getGroupPermissions( $groups ) {
+               global $wgGroupPermissions, $wgRevokePermissions;
+               $rights = array();
+               // grant every granted permission first
+               foreach ( $groups as $group ) {
+                       if ( isset( $wgGroupPermissions[$group] ) ) {
+                               $rights = array_merge( $rights,
+                                       // array_filter removes empty items
+                                       array_keys( array_filter( $wgGroupPermissions[$group] ) ) );
+                       }
+               }
+               // now revoke the revoked permissions
+               foreach ( $groups as $group ) {
+                       if ( isset( $wgRevokePermissions[$group] ) ) {
+                               $rights = array_diff( $rights,
+                                       array_keys( array_filter( $wgRevokePermissions[$group] ) ) );
+                       }
+               }
+               return array_unique( $rights );
+       }
+
+       /**
+        * Get all the groups who have a given permission
+        *
+        * @param string $role Role to check
+        * @return array Array of Strings List of internal group names with the given permission
+        */
+       public static function getGroupsWithPermission( $role ) {
+               global $wgGroupPermissions;
+               $allowedGroups = array();
+               foreach ( array_keys( $wgGroupPermissions ) as $group ) {
+                       if ( self::groupHasPermission( $group, $role ) ) {
+                               $allowedGroups[] = $group;
+                       }
+               }
+               return $allowedGroups;
+       }
+
+       /**
+        * Check, if the given group has the given permission
+        *
+        * If you're wanting to check whether all users have a permission, use
+        * User::isEveryoneAllowed() instead. That properly checks if it's revoked
+        * from anyone.
+        *
+        * @since 1.21
+        * @param string $group Group to check
+        * @param string $role Role to check
+        * @return bool
+        */
+       public static function groupHasPermission( $group, $role ) {
+               global $wgGroupPermissions, $wgRevokePermissions;
+               return isset( $wgGroupPermissions[$group][$role] ) && $wgGroupPermissions[$group][$role]
+                       && !( isset( $wgRevokePermissions[$group][$role] ) && $wgRevokePermissions[$group][$role] );
+       }
+
+       /**
+        * Check if all users have the given permission
+        *
+        * @since 1.22
+        * @param string $right Right to check
+        * @return bool
+        */
+       public static function isEveryoneAllowed( $right ) {
+               global $wgGroupPermissions, $wgRevokePermissions;
+               static $cache = array();
+
+               // Use the cached results, except in unit tests which rely on
+               // being able change the permission mid-request
+               if ( isset( $cache[$right] ) && !defined( 'MW_PHPUNIT_TEST' ) ) {
+                       return $cache[$right];
+               }
+
+               if ( !isset( $wgGroupPermissions['*'][$right] ) || !$wgGroupPermissions['*'][$right] ) {
+                       $cache[$right] = false;
+                       return false;
+               }
+
+               // If it's revoked anywhere, then everyone doesn't have it
+               foreach ( $wgRevokePermissions as $rights ) {
+                       if ( isset( $rights[$right] ) && $rights[$right] ) {
+                               $cache[$right] = false;
+                               return false;
+                       }
+               }
+
+               // Allow extensions (e.g. OAuth) to say false
+               if ( !Hooks::run( 'UserIsEveryoneAllowed', array( $right ) ) ) {
+                       $cache[$right] = false;
+                       return false;
+               }
+
+               $cache[$right] = true;
+               return true;
+       }
+
+       /**
+        * Get the localized descriptive name for a group, if it exists
+        *
+        * @param string $group Internal group name
+        * @return string Localized descriptive group name
+        */
+       public static function getGroupName( $group ) {
+               $msg = wfMessage( "group-$group" );
+               return $msg->isBlank() ? $group : $msg->text();
+       }
+
+       /**
+        * Get the localized descriptive name for a member of a group, if it exists
+        *
+        * @param string $group Internal group name
+        * @param string $username Username for gender (since 1.19)
+        * @return string Localized name for group member
+        */
+       public static function getGroupMember( $group, $username = '#' ) {
+               $msg = wfMessage( "group-$group-member", $username );
+               return $msg->isBlank() ? $group : $msg->text();
+       }
+
+       /**
+        * Return the set of defined explicit groups.
+        * The implicit groups (by default *, 'user' and 'autoconfirmed')
+        * are not included, as they are defined automatically, not in the database.
+        * @return array Array of internal group names
+        */
+       public static function getAllGroups() {
+               global $wgGroupPermissions, $wgRevokePermissions;
+               return array_diff(
+                       array_merge( array_keys( $wgGroupPermissions ), array_keys( $wgRevokePermissions ) ),
+                       self::getImplicitGroups()
+               );
+       }
+
+       /**
+        * Get a list of all available permissions.
+        * @return string[] Array of permission names
+        */
+       public static function getAllRights() {
+               if ( self::$mAllRights === false ) {
+                       global $wgAvailableRights;
+                       if ( count( $wgAvailableRights ) ) {
+                               self::$mAllRights = array_unique( array_merge( self::$mCoreRights, $wgAvailableRights ) );
+                       } else {
+                               self::$mAllRights = self::$mCoreRights;
+                       }
+                       Hooks::run( 'UserGetAllRights', array( &self::$mAllRights ) );
+               }
+               return self::$mAllRights;
+       }
+
+       /**
+        * Get a list of implicit groups
+        * @return array Array of Strings Array of internal group names
+        */
+       public static function getImplicitGroups() {
+               global $wgImplicitGroups;
+
+               $groups = $wgImplicitGroups;
+               # Deprecated, use $wgImplicitGroups instead
+               Hooks::run( 'UserGetImplicitGroups', array( &$groups ), '1.25' );
+
+               return $groups;
+       }
+
+       /**
+        * Get the title of a page describing a particular group
+        *
+        * @param string $group Internal group name
+        * @return Title|bool Title of the page if it exists, false otherwise
+        */
+       public static function getGroupPage( $group ) {
+               $msg = wfMessage( 'grouppage-' . $group )->inContentLanguage();
+               if ( $msg->exists() ) {
+                       $title = Title::newFromText( $msg->text() );
+                       if ( is_object( $title ) ) {
+                               return $title;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Create a link to the group in HTML, if available;
+        * else return the group name.
+        *
+        * @param string $group Internal name of the group
+        * @param string $text The text of the link
+        * @return string HTML link to the group
+        */
+       public static function makeGroupLinkHTML( $group, $text = '' ) {
+               if ( $text == '' ) {
+                       $text = self::getGroupName( $group );
+               }
+               $title = self::getGroupPage( $group );
+               if ( $title ) {
+                       return Linker::link( $title, htmlspecialchars( $text ) );
+               } else {
+                       return htmlspecialchars( $text );
+               }
+       }
+
+       /**
+        * Create a link to the group in Wikitext, if available;
+        * else return the group name.
+        *
+        * @param string $group Internal name of the group
+        * @param string $text The text of the link
+        * @return string Wikilink to the group
+        */
+       public static function makeGroupLinkWiki( $group, $text = '' ) {
+               if ( $text == '' ) {
+                       $text = self::getGroupName( $group );
+               }
+               $title = self::getGroupPage( $group );
+               if ( $title ) {
+                       $page = $title->getFullText();
+                       return "[[$page|$text]]";
+               } else {
+                       return $text;
+               }
+       }
+
+       /**
+        * Returns an array of the groups that a particular group can add/remove.
+        *
+        * @param string $group The group to check for whether it can add/remove
+        * @return array Array( 'add' => array( addablegroups ),
+        *     'remove' => array( removablegroups ),
+        *     'add-self' => array( addablegroups to self),
+        *     'remove-self' => array( removable groups from self) )
+        */
+       public static function changeableByGroup( $group ) {
+               global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
+
+               $groups = array(
+                       'add' => array(),
+                       'remove' => array(),
+                       'add-self' => array(),
+                       'remove-self' => array()
+               );
+
+               if ( empty( $wgAddGroups[$group] ) ) {
+                       // Don't add anything to $groups
+               } elseif ( $wgAddGroups[$group] === true ) {
+                       // You get everything
+                       $groups['add'] = self::getAllGroups();
+               } elseif ( is_array( $wgAddGroups[$group] ) ) {
+                       $groups['add'] = $wgAddGroups[$group];
+               }
+
+               // Same thing for remove
+               if ( empty( $wgRemoveGroups[$group] ) ) {
+                       // Do nothing
+               } elseif ( $wgRemoveGroups[$group] === true ) {
+                       $groups['remove'] = self::getAllGroups();
+               } elseif ( is_array( $wgRemoveGroups[$group] ) ) {
+                       $groups['remove'] = $wgRemoveGroups[$group];
+               }
+
+               // Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility
+               if ( empty( $wgGroupsAddToSelf['user'] ) || $wgGroupsAddToSelf['user'] !== true ) {
+                       foreach ( $wgGroupsAddToSelf as $key => $value ) {
+                               if ( is_int( $key ) ) {
+                                       $wgGroupsAddToSelf['user'][] = $value;
+                               }
+                       }
+               }
+
+               if ( empty( $wgGroupsRemoveFromSelf['user'] ) || $wgGroupsRemoveFromSelf['user'] !== true ) {
+                       foreach ( $wgGroupsRemoveFromSelf as $key => $value ) {
+                               if ( is_int( $key ) ) {
+                                       $wgGroupsRemoveFromSelf['user'][] = $value;
+                               }
+                       }
+               }
+
+               // Now figure out what groups the user can add to him/herself
+               if ( empty( $wgGroupsAddToSelf[$group] ) ) {
+                       // Do nothing
+               } elseif ( $wgGroupsAddToSelf[$group] === true ) {
+                       // No idea WHY this would be used, but it's there
+                       $groups['add-self'] = User::getAllGroups();
+               } elseif ( is_array( $wgGroupsAddToSelf[$group] ) ) {
+                       $groups['add-self'] = $wgGroupsAddToSelf[$group];
+               }
+
+               if ( empty( $wgGroupsRemoveFromSelf[$group] ) ) {
+                       // Do nothing
+               } elseif ( $wgGroupsRemoveFromSelf[$group] === true ) {
+                       $groups['remove-self'] = User::getAllGroups();
+               } elseif ( is_array( $wgGroupsRemoveFromSelf[$group] ) ) {
+                       $groups['remove-self'] = $wgGroupsRemoveFromSelf[$group];
+               }
+
+               return $groups;
+       }
+
+       /**
+        * Returns an array of groups that this user can add and remove
+        * @return array Array( 'add' => array( addablegroups ),
+        *  'remove' => array( removablegroups ),
+        *  'add-self' => array( addablegroups to self),
+        *  'remove-self' => array( removable groups from self) )
+        */
+       public function changeableGroups() {
+               if ( $this->isAllowed( 'userrights' ) ) {
+                       // This group gives the right to modify everything (reverse-
+                       // compatibility with old "userrights lets you change
+                       // everything")
+                       // Using array_merge to make the groups reindexed
+                       $all = array_merge( User::getAllGroups() );
+                       return array(
+                               'add' => $all,
+                               'remove' => $all,
+                               'add-self' => array(),
+                               'remove-self' => array()
+                       );
+               }
+
+               // Okay, it's not so simple, we will have to go through the arrays
+               $groups = array(
+                       'add' => array(),
+                       'remove' => array(),
+                       'add-self' => array(),
+                       'remove-self' => array()
+               );
+               $addergroups = $this->getEffectiveGroups();
+
+               foreach ( $addergroups as $addergroup ) {
+                       $groups = array_merge_recursive(
+                               $groups, $this->changeableByGroup( $addergroup )
+                       );
+                       $groups['add'] = array_unique( $groups['add'] );
+                       $groups['remove'] = array_unique( $groups['remove'] );
+                       $groups['add-self'] = array_unique( $groups['add-self'] );
+                       $groups['remove-self'] = array_unique( $groups['remove-self'] );
+               }
+               return $groups;
+       }
+
+       /**
+        * Deferred version of incEditCountImmediate()
+        */
+       public function incEditCount() {
+               $that = $this;
+               wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $that ) {
+                       $that->incEditCountImmediate();
+               } );
+       }
+
+       /**
+        * Increment the user's edit-count field.
+        * Will have no effect for anonymous users.
+        * @since 1.26
+        */
+       public function incEditCountImmediate() {
+               if ( $this->isAnon() ) {
+                       return;
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               // No rows will be "affected" if user_editcount is NULL
+               $dbw->update(
+                       'user',
+                       array( 'user_editcount=user_editcount+1' ),
+                       array( 'user_id' => $this->getId(), 'user_editcount IS NOT NULL' ),
+                       __METHOD__
+               );
+               // Lazy initialization check...
+               if ( $dbw->affectedRows() == 0 ) {
+                       // Now here's a goddamn hack...
+                       $dbr = wfGetDB( DB_SLAVE );
+                       if ( $dbr !== $dbw ) {
+                               // If we actually have a slave server, the count is
+                               // at least one behind because the current transaction
+                               // has not been committed and replicated.
+                               $this->initEditCount( 1 );
+                       } else {
+                               // But if DB_SLAVE is selecting the master, then the
+                               // count we just read includes the revision that was
+                               // just added in the working transaction.
+                               $this->initEditCount();
+                       }
+               }
+               // Edit count in user cache too
+               $this->invalidateCache();
+       }
+
+       /**
+        * Initialize user_editcount from data out of the revision table
+        *
+        * @param int $add Edits to add to the count from the revision table
+        * @return int Number of edits
+        */
+       protected function initEditCount( $add = 0 ) {
+               // Pull from a slave to be less cruel to servers
+               // Accuracy isn't the point anyway here
+               $dbr = wfGetDB( DB_SLAVE );
+               $count = (int)$dbr->selectField(
+                       'revision',
+                       'COUNT(rev_user)',
+                       array( 'rev_user' => $this->getId() ),
+                       __METHOD__
+               );
+               $count = $count + $add;
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update(
+                       'user',
+                       array( 'user_editcount' => $count ),
+                       array( 'user_id' => $this->getId() ),
+                       __METHOD__
+               );
+
+               return $count;
+       }
+
+       /**
+        * Get the description of a given right
+        *
+        * @param string $right Right to query
+        * @return string Localized description of the right
+        */
+       public static function getRightDescription( $right ) {
+               $key = "right-$right";
+               $msg = wfMessage( $key );
+               return $msg->isBlank() ? $right : $msg->text();
+       }
+
+       /**
+        * Make a new-style password hash
+        *
+        * @param string $password Plain-text password
+        * @param bool|string $salt Optional salt, may be random or the user ID.
+        *  If unspecified or false, will generate one automatically
+        * @return string Password hash
+        * @deprecated since 1.24, use Password class
+        */
+       public static function crypt( $password, $salt = false ) {
+               wfDeprecated( __METHOD__, '1.24' );
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $hash = $passwordFactory->newFromPlaintext( $password );
+               return $hash->toString();
+       }
+
+       /**
+        * Compare a password hash with a plain-text password. Requires the user
+        * ID if there's a chance that the hash is an old-style hash.
+        *
+        * @param string $hash Password hash
+        * @param string $password Plain-text password to compare
+        * @param string|bool $userId User ID for old-style password salt
+        *
+        * @return bool
+        * @deprecated since 1.24, use Password class
+        */
+       public static function comparePasswords( $hash, $password, $userId = false ) {
+               wfDeprecated( __METHOD__, '1.24' );
+
+               // Check for *really* old password hashes that don't even have a type
+               // The old hash format was just an md5 hex hash, with no type information
+               if ( preg_match( '/^[0-9a-f]{32}$/', $hash ) ) {
+                       global $wgPasswordSalt;
+                       if ( $wgPasswordSalt ) {
+                               $password = ":B:{$userId}:{$hash}";
+                       } else {
+                               $password = ":A:{$hash}";
+                       }
+               }
+
+               $passwordFactory = new PasswordFactory();
+               $passwordFactory->init( RequestContext::getMain()->getConfig() );
+               $hash = $passwordFactory->newFromCiphertext( $hash );
+               return $hash->equals( $password );
+       }
+
+       /**
+        * Add a newuser log entry for this user.
+        * Before 1.19 the return value was always true.
+        *
+        * @param string|bool $action Account creation type.
+        *   - String, one of the following values:
+        *     - 'create' for an anonymous user creating an account for himself.
+        *       This will force the action's performer to be the created user itself,
+        *       no matter the value of $wgUser
+        *     - 'create2' for a logged in user creating an account for someone else
+        *     - 'byemail' when the created user will receive its password by e-mail
+        *     - 'autocreate' when the user is automatically created (such as by CentralAuth).
+        *   - Boolean means whether the account was created by e-mail (deprecated):
+        *     - true will be converted to 'byemail'
+        *     - false will be converted to 'create' if this object is the same as
+        *       $wgUser and to 'create2' otherwise
+        *
+        * @param string $reason User supplied reason
+        *
+        * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
+        */
+       public function addNewUserLogEntry( $action = false, $reason = '' ) {
+               global $wgUser, $wgNewUserLog;
+               if ( empty( $wgNewUserLog ) ) {
+                       return true; // disabled
+               }
+
+               if ( $action === true ) {
+                       $action = 'byemail';
+               } elseif ( $action === false ) {
+                       if ( $this->equals( $wgUser ) ) {
+                               $action = 'create';
+                       } else {
+                               $action = 'create2';
+                       }
+               }
+
+               if ( $action === 'create' || $action === 'autocreate' ) {
+                       $performer = $this;
+               } else {
+                       $performer = $wgUser;
+               }
+
+               $logEntry = new ManualLogEntry( 'newusers', $action );
+               $logEntry->setPerformer( $performer );
+               $logEntry->setTarget( $this->getUserPage() );
+               $logEntry->setComment( $reason );
+               $logEntry->setParameters( array(
+                       '4::userid' => $this->getId(),
+               ) );
+               $logid = $logEntry->insert();
+
+               if ( $action !== 'autocreate' ) {
+                       $logEntry->publish( $logid );
+               }
+
+               return (int)$logid;
+       }
+
+       /**
+        * Add an autocreate newuser log entry for this user
+        * Used by things like CentralAuth and perhaps other authplugins.
+        * Consider calling addNewUserLogEntry() directly instead.
+        *
+        * @return bool
+        */
+       public function addNewUserLogEntryAutoCreate() {
+               $this->addNewUserLogEntry( 'autocreate' );
+
+               return true;
+       }
+
+       /**
+        * Load the user options either from cache, the database or an array
+        *
+        * @param array $data Rows for the current user out of the user_properties table
+        */
+       protected function loadOptions( $data = null ) {
+               global $wgContLang;
+
+               $this->load();
+
+               if ( $this->mOptionsLoaded ) {
+                       return;
+               }
+
+               $this->mOptions = self::getDefaultOptions();
+
+               if ( !$this->getId() ) {
+                       // For unlogged-in users, load language/variant options from request.
+                       // There's no need to do it for logged-in users: they can set preferences,
+                       // and handling of page content is done by $pageLang->getPreferredVariant() and such,
+                       // so don't override user's choice (especially when the user chooses site default).
+                       $variant = $wgContLang->getDefaultVariant();
+                       $this->mOptions['variant'] = $variant;
+                       $this->mOptions['language'] = $variant;
+                       $this->mOptionsLoaded = true;
+                       return;
+               }
+
+               // Maybe load from the object
+               if ( !is_null( $this->mOptionOverrides ) ) {
+                       wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" );
+                       foreach ( $this->mOptionOverrides as $key => $value ) {
+                               $this->mOptions[$key] = $value;
+                       }
+               } else {
+                       if ( !is_array( $data ) ) {
+                               wfDebug( "User: loading options for user " . $this->getId() . " from database.\n" );
+                               // Load from database
+                               $dbr = ( $this->queryFlagsUsed & self::READ_LATEST )
+                                       ? wfGetDB( DB_MASTER )
+                                       : wfGetDB( DB_SLAVE );
+
+                               $res = $dbr->select(
+                                       'user_properties',
+                                       array( 'up_property', 'up_value' ),
+                                       array( 'up_user' => $this->getId() ),
+                                       __METHOD__
+                               );
+
+                               $this->mOptionOverrides = array();
+                               $data = array();
+                               foreach ( $res as $row ) {
+                                       $data[$row->up_property] = $row->up_value;
+                               }
+                       }
+                       foreach ( $data as $property => $value ) {
+                               $this->mOptionOverrides[$property] = $value;
+                               $this->mOptions[$property] = $value;
+                       }
+               }
+
+               $this->mOptionsLoaded = true;
+
+               Hooks::run( 'UserLoadOptions', array( $this, &$this->mOptions ) );
+       }
+
+       /**
+        * Saves the non-default options for this user, as previously set e.g. via
+        * setOption(), in the database's "user_properties" (preferences) table.
+        * Usually used via saveSettings().
+        */
+       protected function saveOptions() {
+               $this->loadOptions();
+
+               // Not using getOptions(), to keep hidden preferences in database
+               $saveOptions = $this->mOptions;
+
+               // Allow hooks to abort, for instance to save to a global profile.
+               // Reset options to default state before saving.
+               if ( !Hooks::run( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) {
+                       return;
+               }
+
+               $userId = $this->getId();
+
+               $insert_rows = array(); // all the new preference rows
+               foreach ( $saveOptions as $key => $value ) {
+                       // Don't bother storing default values
+                       $defaultOption = self::getDefaultOption( $key );
+                       if ( ( $defaultOption === null && $value !== false && $value !== null )
+                               || $value != $defaultOption
+                       ) {
+                               $insert_rows[] = array(
+                                       'up_user' => $userId,
+                                       'up_property' => $key,
+                                       'up_value' => $value,
+                               );
+                       }
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               $res = $dbw->select( 'user_properties',
+                       array( 'up_property', 'up_value' ), array( 'up_user' => $userId ), __METHOD__ );
+
+               // Find prior rows that need to be removed or updated. These rows will
+               // all be deleted (the later so that INSERT IGNORE applies the new values).
+               $keysDelete = array();
+               foreach ( $res as $row ) {
+                       if ( !isset( $saveOptions[$row->up_property] )
+                               || strcmp( $saveOptions[$row->up_property], $row->up_value ) != 0
+                       ) {
+                               $keysDelete[] = $row->up_property;
+                       }
+               }
+
+               if ( count( $keysDelete ) ) {
+                       // Do the DELETE by PRIMARY KEY for prior rows.
+                       // In the past a very large portion of calls to this function are for setting
+                       // 'rememberpassword' for new accounts (a preference that has since been removed).
+                       // Doing a blanket per-user DELETE for new accounts with no rows in the table
+                       // caused gap locks on [max user ID,+infinity) which caused high contention since
+                       // updates would pile up on each other as they are for higher (newer) user IDs.
+                       // It might not be necessary these days, but it shouldn't hurt either.
+                       $dbw->delete( 'user_properties',
+                               array( 'up_user' => $userId, 'up_property' => $keysDelete ), __METHOD__ );
+               }
+               // Insert the new preference rows
+               $dbw->insert( 'user_properties', $insert_rows, __METHOD__, array( 'IGNORE' ) );
+       }
+
+       /**
+        * Lazily instantiate and return a factory object for making passwords
+        *
+        * @deprecated since 1.27, create a PasswordFactory directly instead
+        * @return PasswordFactory
+        */
+       public static function getPasswordFactory() {
+               wfDeprecated( __METHOD__, '1.27' );
+               $ret = new PasswordFactory();
+               $ret->init( RequestContext::getMain()->getConfig() );
+               return $ret;
+       }
+
+       /**
+        * Provide an array of HTML5 attributes to put on an input element
+        * intended for the user to enter a new password.  This may include
+        * required, title, and/or pattern, depending on $wgMinimalPasswordLength.
+        *
+        * Do *not* use this when asking the user to enter his current password!
+        * Regardless of configuration, users may have invalid passwords for whatever
+        * reason (e.g., they were set before requirements were tightened up).
+        * Only use it when asking for a new password, like on account creation or
+        * ResetPass.
+        *
+        * Obviously, you still need to do server-side checking.
+        *
+        * NOTE: A combination of bugs in various browsers means that this function
+        * actually just returns array() unconditionally at the moment.  May as
+        * well keep it around for when the browser bugs get fixed, though.
+        *
+        * @todo FIXME: This does not belong here; put it in Html or Linker or somewhere
+        *
+        * @deprecated since 1.27
+        * @return array Array of HTML attributes suitable for feeding to
+        *   Html::element(), directly or indirectly.  (Don't feed to Xml::*()!
+        *   That will get confused by the boolean attribute syntax used.)
+        */
+       public static function passwordChangeInputAttribs() {
+               global $wgMinimalPasswordLength;
+
+               if ( $wgMinimalPasswordLength == 0 ) {
+                       return array();
+               }
+
+               # Note that the pattern requirement will always be satisfied if the
+               # input is empty, so we need required in all cases.
+
+               # @todo FIXME: Bug 23769: This needs to not claim the password is required
+               # if e-mail confirmation is being used.  Since HTML5 input validation
+               # is b0rked anyway in some browsers, just return nothing.  When it's
+               # re-enabled, fix this code to not output required for e-mail
+               # registration.
+               # $ret = array( 'required' );
+               $ret = array();
+
+               # We can't actually do this right now, because Opera 9.6 will print out
+               # the entered password visibly in its error message!  When other
+               # browsers add support for this attribute, or Opera fixes its support,
+               # we can add support with a version check to avoid doing this on Opera
+               # versions where it will be a problem.  Reported to Opera as
+               # DSK-262266, but they don't have a public bug tracker for us to follow.
+               /*
+               if ( $wgMinimalPasswordLength > 1 ) {
+                       $ret['pattern'] = '.{' . intval( $wgMinimalPasswordLength ) . ',}';
+                       $ret['title'] = wfMessage( 'passwordtooshort' )
+                               ->numParams( $wgMinimalPasswordLength )->text();
+               }
+               */
+
+               return $ret;
+       }
+
+       /**
+        * Return the list of user fields that should be selected to create
+        * a new user object.
+        * @return array
+        */
+       public static function selectFields() {
+               return array(
+                       'user_id',
+                       'user_name',
+                       'user_real_name',
+                       'user_email',
+                       'user_touched',
+                       'user_token',
+                       'user_email_authenticated',
+                       'user_email_token',
+                       'user_email_token_expires',
+                       'user_registration',
+                       'user_editcount',
+               );
+       }
+
+       /**
+        * Factory function for fatal permission-denied errors
+        *
+        * @since 1.22
+        * @param string $permission User right required
+        * @return Status
+        */
+       static function newFatalPermissionDeniedStatus( $permission ) {
+               global $wgLang;
+
+               $groups = array_map(
+                       array( 'User', 'makeGroupLinkWiki' ),
+                       User::getGroupsWithPermission( $permission )
+               );
+
+               if ( $groups ) {
+                       return Status::newFatal( 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
+               } else {
+                       return Status::newFatal( 'badaccess-group0' );
+               }
+       }
+
+       /**
+        * Checks if two user objects point to the same user.
+        *
+        * @since 1.25
+        * @param User $user
+        * @return bool
+        */
+       public function equals( User $user ) {
+               return $this->getName() === $user->getName();
+       }
+}
diff --git a/includes/user/UserArray.php b/includes/user/UserArray.php
new file mode 100644 (file)
index 0000000..31bd601
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Class to walk into a list of User objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+abstract class UserArray implements Iterator {
+       /**
+        * @param ResultWrapper $res
+        * @return UserArrayFromResult
+        */
+       static function newFromResult( $res ) {
+               $userArray = null;
+               if ( !Hooks::run( 'UserArrayFromResult', array( &$userArray, $res ) ) ) {
+                       return null;
+               }
+               if ( $userArray === null ) {
+                       $userArray = self::newFromResult_internal( $res );
+               }
+               return $userArray;
+       }
+
+       /**
+        * @param array $ids
+        * @return UserArrayFromResult
+        */
+       static function newFromIDs( $ids ) {
+               $ids = array_map( 'intval', (array)$ids ); // paranoia
+               if ( !$ids ) {
+                       // Database::select() doesn't like empty arrays
+                       return new ArrayIterator( array() );
+               }
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select(
+                       'user',
+                       User::selectFields(),
+                       array( 'user_id' => array_unique( $ids ) ),
+                       __METHOD__
+               );
+               return self::newFromResult( $res );
+       }
+
+       /**
+        * @since 1.25
+        * @param array $names
+        * @return UserArrayFromResult
+        */
+       static function newFromNames( $names ) {
+               $names = array_map( 'strval', (array)$names ); // paranoia
+               if ( !$names ) {
+                       // Database::select() doesn't like empty arrays
+                       return new ArrayIterator( array() );
+               }
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select(
+                       'user',
+                       User::selectFields(),
+                       array( 'user_name' => array_unique( $names ) ),
+                       __METHOD__
+               );
+               return self::newFromResult( $res );
+       }
+
+       /**
+        * @param ResultWrapper $res
+        * @return UserArrayFromResult
+        */
+       protected static function newFromResult_internal( $res ) {
+               return new UserArrayFromResult( $res );
+       }
+}
diff --git a/includes/user/UserArrayFromResult.php b/includes/user/UserArrayFromResult.php
new file mode 100644 (file)
index 0000000..fb533d0
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Class to walk into a list of User objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class UserArrayFromResult extends UserArray implements Countable {
+       /** @var ResultWrapper */
+       public $res;
+
+       /** @var int */
+       public $key;
+
+       /** @var bool|stdClass */
+       public $current;
+
+       /**
+        * @param ResultWrapper $res
+        */
+       function __construct( $res ) {
+               $this->res = $res;
+               $this->key = 0;
+               $this->setCurrent( $this->res->current() );
+       }
+
+       /**
+        * @param bool|stdClass $row
+        * @return void
+        */
+       protected function setCurrent( $row ) {
+               if ( $row === false ) {
+                       $this->current = false;
+               } else {
+                       $this->current = User::newFromRow( $row );
+               }
+       }
+
+       /**
+        * @return int
+        */
+       public function count() {
+               return $this->res->numRows();
+       }
+
+       /**
+        * @return User
+        */
+       function current() {
+               return $this->current;
+       }
+
+       function key() {
+               return $this->key;
+       }
+
+       function next() {
+               $row = $this->res->next();
+               $this->setCurrent( $row );
+               $this->key++;
+       }
+
+       function rewind() {
+               $this->res->rewind();
+               $this->key = 0;
+               $this->setCurrent( $this->res->current() );
+       }
+
+       /**
+        * @return bool
+        */
+       function valid() {
+               return $this->current !== false;
+       }
+}
diff --git a/includes/user/UserRightsProxy.php b/includes/user/UserRightsProxy.php
new file mode 100644 (file)
index 0000000..e686ae3
--- /dev/null
@@ -0,0 +1,287 @@
+<?php
+/**
+ * Representation of an user on a other locally-hosted wiki.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Cut-down copy of User interface for local-interwiki-database
+ * user rights manipulation.
+ */
+class UserRightsProxy {
+
+       /**
+        * Constructor.
+        *
+        * @see newFromId()
+        * @see newFromName()
+        * @param IDatabase $db Db connection
+        * @param string $database Database name
+        * @param string $name User name
+        * @param int $id User ID
+        */
+       private function __construct( $db, $database, $name, $id ) {
+               $this->db = $db;
+               $this->database = $database;
+               $this->name = $name;
+               $this->id = intval( $id );
+               $this->newOptions = array();
+       }
+
+       /**
+        * Accessor for $this->database
+        *
+        * @return string Database name
+        */
+       public function getDBName() {
+               return $this->database;
+       }
+
+       /**
+        * Confirm the selected database name is a valid local interwiki database name.
+        *
+        * @param string $database Database name
+        * @return bool
+        */
+       public static function validDatabase( $database ) {
+               global $wgLocalDatabases;
+               return in_array( $database, $wgLocalDatabases );
+       }
+
+       /**
+        * Same as User::whoIs()
+        *
+        * @param string $database Database name
+        * @param int $id User ID
+        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
+        * @return string User name or false if the user doesn't exist
+        */
+       public static function whoIs( $database, $id, $ignoreInvalidDB = false ) {
+               $user = self::newFromId( $database, $id, $ignoreInvalidDB );
+               if ( $user ) {
+                       return $user->name;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Factory function; get a remote user entry by ID number.
+        *
+        * @param string $database Database name
+        * @param int $id User ID
+        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
+        * @return UserRightsProxy|null If doesn't exist
+        */
+       public static function newFromId( $database, $id, $ignoreInvalidDB = false ) {
+               return self::newFromLookup( $database, 'user_id', intval( $id ), $ignoreInvalidDB );
+       }
+
+       /**
+        * Factory function; get a remote user entry by name.
+        *
+        * @param string $database Database name
+        * @param string $name User name
+        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
+        * @return UserRightsProxy|null If doesn't exist
+        */
+       public static function newFromName( $database, $name, $ignoreInvalidDB = false ) {
+               return self::newFromLookup( $database, 'user_name', $name, $ignoreInvalidDB );
+       }
+
+       /**
+        * @param string $database
+        * @param string $field
+        * @param string $value
+        * @param bool $ignoreInvalidDB
+        * @return null|UserRightsProxy
+        */
+       private static function newFromLookup( $database, $field, $value, $ignoreInvalidDB = false ) {
+               global $wgSharedDB, $wgSharedTables;
+               // If the user table is shared, perform the user query on it,
+               // but don't pass it to the UserRightsProxy,
+               // as user rights are normally not shared.
+               if ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) {
+                       $userdb = self::getDB( $wgSharedDB, $ignoreInvalidDB );
+               } else {
+                       $userdb = self::getDB( $database, $ignoreInvalidDB );
+               }
+
+               $db = self::getDB( $database, $ignoreInvalidDB );
+
+               if ( $db && $userdb ) {
+                       $row = $userdb->selectRow( 'user',
+                               array( 'user_id', 'user_name' ),
+                               array( $field => $value ),
+                               __METHOD__ );
+
+                       if ( $row !== false ) {
+                               return new UserRightsProxy( $db, $database,
+                                       $row->user_name,
+                                       intval( $row->user_id ) );
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Open a database connection to work on for the requested user.
+        * This may be a new connection to another database for remote users.
+        *
+        * @param string $database
+        * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
+        * @return IDatabase|null If invalid selection
+        */
+       public static function getDB( $database, $ignoreInvalidDB = false ) {
+               global $wgDBname;
+               if ( $ignoreInvalidDB || self::validDatabase( $database ) ) {
+                       if ( $database == $wgDBname ) {
+                               // Hmm... this shouldn't happen though. :)
+                               return wfGetDB( DB_MASTER );
+                       } else {
+                               return wfGetDB( DB_MASTER, array(), $database );
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * @return int
+        */
+       public function getId() {
+               return $this->id;
+       }
+
+       /**
+        * @return bool
+        */
+       public function isAnon() {
+               return $this->getId() == 0;
+       }
+
+       /**
+        * Same as User::getName()
+        *
+        * @return string
+        */
+       public function getName() {
+               return $this->name . '@' . $this->database;
+       }
+
+       /**
+        * Same as User::getUserPage()
+        *
+        * @return Title
+        */
+       public function getUserPage() {
+               return Title::makeTitle( NS_USER, $this->getName() );
+       }
+
+       /**
+        * Replaces User::getUserGroups()
+        * @return array
+        */
+       function getGroups() {
+               $res = $this->db->select( 'user_groups',
+                       array( 'ug_group' ),
+                       array( 'ug_user' => $this->id ),
+                       __METHOD__ );
+               $groups = array();
+               foreach ( $res as $row ) {
+                       $groups[] = $row->ug_group;
+               }
+               return $groups;
+       }
+
+       /**
+        * Replaces User::addUserGroup()
+        * @param string $group
+        *
+        * @return bool
+        */
+       function addGroup( $group ) {
+               $this->db->insert( 'user_groups',
+                       array(
+                               'ug_user' => $this->id,
+                               'ug_group' => $group,
+                       ),
+                       __METHOD__,
+                       array( 'IGNORE' ) );
+
+               return true;
+       }
+
+       /**
+        * Replaces User::removeUserGroup()
+        * @param string $group
+        *
+        * @return bool
+        */
+       function removeGroup( $group ) {
+               $this->db->delete( 'user_groups',
+                       array(
+                               'ug_user' => $this->id,
+                               'ug_group' => $group,
+                       ),
+                       __METHOD__ );
+
+               return true;
+       }
+
+       /**
+        * Replaces User::setOption()
+        * @param string $option
+        * @param mixed $value
+        */
+       public function setOption( $option, $value ) {
+               $this->newOptions[$option] = $value;
+       }
+
+       public function saveSettings() {
+               $rows = array();
+               foreach ( $this->newOptions as $option => $value ) {
+                       $rows[] = array(
+                               'up_user' => $this->id,
+                               'up_property' => $option,
+                               'up_value' => $value,
+                       );
+               }
+               $this->db->replace( 'user_properties',
+                       array( array( 'up_user', 'up_property' ) ),
+                       $rows, __METHOD__
+               );
+               $this->invalidateCache();
+       }
+
+       /**
+        * Replaces User::touchUser()
+        */
+       function invalidateCache() {
+               $this->db->update( 'user',
+                       array( 'user_touched' => $this->db->timestamp() ),
+                       array( 'user_id' => $this->id ),
+                       __METHOD__ );
+
+               $wikiId = $this->db->getWikiID();
+               $userId = $this->id;
+               $this->db->onTransactionPreCommitOrIdle( function() use ( $wikiId, $userId ) {
+                       User::purge( $wikiId, $userId );
+               } );
+       }
+}
index 119805e..fd7030e 100644 (file)
@@ -713,7 +713,7 @@ class IP {
        /**
         * Checks if an IP is a trusted proxy provider.
         * Useful to tell if X-Forwarded-For data is possibly bogus.
-        * Squid cache servers for the site are whitelisted.
+        * CDN cache servers for the site are whitelisted.
         * @since 1.24
         *
         * @param string $ip
index 10e4334..e2de900 100644 (file)
@@ -37,6 +37,7 @@ class UIDGenerator {
 
        protected $lockFile88; // string; local file path
        protected $lockFile128; // string; local file path
+       protected $lockFileUUID; // string; local file path
 
        /** @var array */
        protected $fileHandles = array(); // cache file handles
@@ -79,6 +80,7 @@ class UIDGenerator {
                // This is dealt with by initializing the clock sequence number and counters randomly.
                $this->lockFile88 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-88';
                $this->lockFile128 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-128';
+               $this->lockFileUUID = wfTempDir() . '/mw-' . __CLASS__ . '-UUID-128';
        }
 
        /**
@@ -114,18 +116,25 @@ class UIDGenerator {
                Assert::parameter( $base >= 2, '$base', 'must be >= 2' );
 
                $gen = self::singleton();
-               $time = $gen->getTimestampAndDelay( 'lockFile88', 1, 1024 );
-
-               return Wikimedia\base_convert( $gen->getTimestampedID88( $time ), 2, $base );
+               $info = $gen->getTimeAndDelay( 'lockFile88', 1, 1024, 1024 );
+               $info['offsetCounter'] = $info['offsetCounter'] % 1024;
+               return Wikimedia\base_convert( $gen->getTimestampedID88( $info ), 2, $base );
        }
 
        /**
-        * @param array $info (UIDGenerator::millitime(), counter, clock sequence)
+        * @param array $info The result of UIDGenerator::getTimeAndDelay() or
+        *  a plain (UIDGenerator::millitime(), counter, clock sequence) array.
         * @return string 88 bits
         * @throws RuntimeException
         */
        protected function getTimestampedID88( array $info ) {
-               list( $time, $counter ) = $info;
+               if ( isset( $info['time'] ) ) {
+                       $time = $info['time'];
+                       $counter = $info['offsetCounter'];
+               } else {
+                       $time = $info[0];
+                       $counter = $info[1];
+               }
                // Take the 46 MSBs of "milliseconds since epoch"
                $id_bin = $this->millisecondsSinceEpochBinary( $time );
                // Add a 10 bit counter resulting in 56 bits total
@@ -160,19 +169,29 @@ class UIDGenerator {
                Assert::parameter( $base >= 2, '$base', 'must be >= 2' );
 
                $gen = self::singleton();
-               $time = $gen->getTimestampAndDelay( 'lockFile128', 16384, 1048576 );
+               $info = $gen->getTimeAndDelay( 'lockFile128', 16384, 1048576, 1048576 );
+               $info['offsetCounter'] = $info['offsetCounter'] % 1048576;
 
-               return Wikimedia\base_convert( $gen->getTimestampedID128( $time ), 2, $base );
+               return Wikimedia\base_convert( $gen->getTimestampedID128( $info ), 2, $base );
        }
 
        /**
-        * @param array $info (UIDGenerator::millitime(), counter, clock sequence)
+        * @param array $info The result of UIDGenerator::getTimeAndDelay() or
+        *  a plain (UIDGenerator::millitime(), counter, clock sequence) array.
         * @return string 128 bits
         * @throws RuntimeException
         */
        protected function getTimestampedID128( array $info ) {
-               list( $time, $counter, $clkSeq ) = $info;
-               // Take the 46 MSBs of "milliseconds since epoch"
+               if ( isset( $info['time'] ) ) {
+                       $time = $info['time'];
+                       $counter = $info['offsetCounter'];
+                       $clkSeq = $info['clkSeq'];
+               } else {
+                       $time = $info[0];
+                       $counter = $info[1];
+                       $clkSeq = $info[2];
+               }
+               // Take the 46 bits of "milliseconds since epoch"
                $id_bin = $this->millisecondsSinceEpochBinary( $time );
                // Add a 20 bit counter resulting in 66 bits total
                $id_bin .= str_pad( decbin( $counter ), 20, '0', STR_PAD_LEFT );
@@ -188,6 +207,74 @@ class UIDGenerator {
                return $id_bin;
        }
 
+       /**
+        * Return an RFC4122 compliant v1 UUID
+        *
+        * @return string
+        * @throws RuntimeException
+        * @since 1.27
+        */
+       public static function newUUIDv1() {
+               $gen = self::singleton();
+               // There can be up to 10000 intervals for the same millisecond timestamp.
+               // [0,4999] counter + [0,5000] offset is in [0,9999] for the offset counter.
+               // Add this onto the timestamp to allow making up to 5000 IDs per second.
+               return $gen->getUUIDv1( $gen->getTimeAndDelay( 'lockFileUUID', 16384, 5000, 5001 ) );
+       }
+
+       /**
+        * Return an RFC4122 compliant v1 UUID
+        *
+        * @return string 32 hex characters with no hyphens
+        * @throws RuntimeException
+        * @since 1.27
+        */
+       public static function newRawUUIDv1() {
+               return str_replace( '-', '', self::newUUIDv1() );
+       }
+
+       /**
+        * @param array $info Result of UIDGenerator::getTimeAndDelay()
+        * @return string 128 bits
+        */
+       protected function getUUIDv1( array $info ) {
+               $clkSeq_bin = Wikimedia\base_convert( $info['clkSeq'], 10, 2, 14 );
+               $time_bin = $this->intervalsSinceGregorianBinary( $info['time'], $info['offsetCounter'] );
+               // Take the 32 bits of "time low"
+               $id_bin = substr( $time_bin, 28, 32 );
+               // Add 16 bits of "time mid" resulting in 48 bits total
+               $id_bin .= substr( $time_bin, 12, 16 );
+               // Add 4 bit version resulting in 52 bits total
+               $id_bin .= '0001';
+               // Add 12 bits of "time high" resulting in 64 bits total
+               $id_bin .= substr( $time_bin, 0, 12 );
+               // Add 2 bits of "variant" resulting in 66 bits total
+               $id_bin .= '10';
+               // Add 6 bits of "clock seq high" resulting in 72 bits total
+               $id_bin .= substr( $clkSeq_bin, 0, 6 );
+               // Add 8 bits of "clock seq low" resulting in 80 bits total
+               $id_bin .= substr( $clkSeq_bin, 6, 8 );
+               // Add the 48 bit node ID resulting in 128 bits total
+               $id_bin .= $this->nodeId48;
+               // Convert to a 32 char hex string with dashes
+               if ( strlen( $id_bin ) !== 128 ) {
+                       throw new RuntimeException( "Detected overflow for millisecond timestamp." );
+               }
+               $hex = Wikimedia\base_convert( $id_bin, 2, 16, 32 );
+               return sprintf( '%s-%s-%s-%s-%s',
+                       // "time_low" (32 bits)
+                       substr( $hex, 0, 8 ),
+                       // "time_mid" (16 bits)
+                       substr( $hex, 8, 4 ),
+                       // "time_hi_and_version" (16 bits)
+                       substr( $hex, 12, 4 ),
+                       // "clk_seq_hi_res" (8 bits) and "clk_seq_low" (8 bits)
+                       substr( $hex, 16, 4 ),
+                       // "node" (48 bits)
+                       substr( $hex, 20, 12 )
+               );
+       }
+
        /**
         * Return an RFC4122 compliant v4 UUID
         *
@@ -207,7 +294,7 @@ class UIDGenerator {
                        substr( $hex, 8, 4 ),
                        // "time_hi_and_version" (16 bits)
                        '4' . substr( $hex, 12, 3 ),
-                       // "clk_seq_hi_res (8 bits, variant is binary 10x) and "clk_seq_low" (8 bits)
+                       // "clk_seq_hi_res" (8 bits, variant is binary 10x) and "clk_seq_low" (8 bits)
                        dechex( 0x8 | ( hexdec( $hex[15] ) & 0x3 ) ) . $hex[16] . substr( $hex, 17, 2 ),
                        // "node" (48 bits)
                        substr( $hex, 19, 12 )
@@ -342,17 +429,17 @@ class UIDGenerator {
         * @param string $lockFile Name of a local lock file
         * @param int $clockSeqSize The number of possible clock sequence values
         * @param int $counterSize The number of possible counter values
+        * @param int $offsetSize The number of possible offset values
         * @return array (result of UIDGenerator::millitime(), counter, clock sequence)
         * @throws RuntimeException
         */
-       protected function getTimestampAndDelay( $lockFile, $clockSeqSize, $counterSize ) {
+       protected function getTimeAndDelay( $lockFile, $clockSeqSize, $counterSize, $offsetSize ) {
                // Get the UID lock file handle
-               $path = $this->$lockFile;
-               if ( isset( $this->fileHandles[$path] ) ) {
-                       $handle = $this->fileHandles[$path];
+               if ( isset( $this->fileHandles[$lockFile] ) ) {
+                       $handle = $this->fileHandles[$lockFile];
                } else {
-                       $handle = fopen( $path, 'cb+' );
-                       $this->fileHandles[$path] = $handle ?: null; // cache
+                       $handle = fopen( $this->$lockFile, 'cb+' );
+                       $this->fileHandles[$lockFile] = $handle ?: null; // cache
                }
                // Acquire the UID lock file
                if ( $handle === false ) {
@@ -387,7 +474,7 @@ class UIDGenerator {
                } else { // last UID info not initialized
                        $clkSeq = mt_rand( 0, $clockSeqSize - 1 );
                        $counter = 0;
-                       $offset = mt_rand( 0, $counterSize - 1 );
+                       $offset = mt_rand( 0, $offsetSize - 1 );
                        $time = self::millitime();
                }
                // microtime() and gettimeofday() can drift from time() at least on Windows.
@@ -404,7 +491,7 @@ class UIDGenerator {
                        // Bump the clock sequence number and also randomize the counter offset,
                        // which is useful for UIDs that do not include the clock sequence number.
                        $clkSeq = ( $clkSeq + 1 ) % $clockSeqSize;
-                       $offset = mt_rand( 0, $counterSize - 1 );
+                       $offset = mt_rand( 0, $offsetSize - 1 );
                        trigger_error( "Clock was set back; sequence number incremented." );
                }
                // Update the (clock sequence number, timestamp, counter)
@@ -415,7 +502,13 @@ class UIDGenerator {
                // Release the UID lock file
                flock( $handle, LOCK_UN );
 
-               return array( $time, ( $counter + $offset ) % $counterSize, $clkSeq );
+               return array(
+                       'time'          => $time,
+                       'counter'       => $counter,
+                       'clkSeq'        => $clkSeq,
+                       'offset'        => $offset,
+                       'offsetCounter' => $counter + $offset
+               );
        }
 
        /**
@@ -452,6 +545,36 @@ class UIDGenerator {
                return substr( Wikimedia\base_convert( $ts, 10, 2, 46 ), -46 );
        }
 
+       /**
+        * @param array $time Result of UIDGenerator::millitime()
+        * @param integer $delta Number of intervals to add on to the timestamp
+        * @return string 60 bits of "100ns intervals since 15 October 1582" (rolls over in 3400)
+        * @throws RuntimeException
+        */
+       protected function intervalsSinceGregorianBinary( array $time, $delta = 0 ) {
+               list( $sec, $msec ) = $time;
+               $offset = '122192928000000000';
+               if ( PHP_INT_SIZE >= 8 ) { // 64 bit integers
+                       $ts = ( 1000 * $sec + $msec ) * 10000 + (int)$offset + $delta;
+                       $id_bin = str_pad( decbin( $ts % pow( 2, 60 ) ), 60, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'gmp' ) ) {
+                       $ts = gmp_add( gmp_mul( (string) $sec, '1000' ), (string) $msec ); // ms
+                       $ts = gmp_add( gmp_mul( $ts, '10000' ), $offset ); // 100ns intervals
+                       $ts = gmp_add( $ts, (string) $delta );
+                       $ts = gmp_mod( $ts, gmp_pow( '2', '60' ) ); // wrap around
+                       $id_bin = str_pad( gmp_strval( $ts, 2 ), 60, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'bcmath' ) ) {
+                       $ts = bcadd( bcmul( $sec, 1000 ), $msec ); // ms
+                       $ts = bcadd( bcmul( $ts, 10000 ), $offset ); // 100ns intervals
+                       $ts = bcadd( $ts, $delta );
+                       $ts = bcmod( $ts, bcpow( 2, 60 ) ); // wrap around
+                       $id_bin = Wikimedia\base_convert( $ts, 10, 2, 60 );
+               } else {
+                       throw new RuntimeException( 'bcmath or gmp extension required for 32 bit machines.' );
+               }
+               return $id_bin;
+       }
+
        /**
         * @return array (current time in seconds, milliseconds since then)
         */
index e70469e..f27094d 100644 (file)
        "createacct-reason": "ЗыпкъырыкIырэр:",
        "createacct-reason-ph": "Сыда пэмыкI аккаунт зэкIэублэрэр?",
        "createacct-submit": "Уи аккаунт бгъэпсын",
-       "createacct-another-submit": "Ð\9dÑ\8dмÑ\8bкI Ð°ÐºÐºÐ°Ñ\83нÑ\82 ÐºÑ\8aÑ\8dÑ\83бл",
+       "createacct-another-submit": "Ð\90ккаÑ\83нÑ\82 Ñ\83блÑ\8d",
        "createacct-benefit-heading": "{{SITENAME}}-м ощ фэдэхэр дэлажьэх.",
        "createacct-benefit-body1": "{{PLURAL:$1|еӀэзэныгъэ|еӀэзэныгъ}}",
        "createacct-benefit-body2": "{{PLURAL:$1|нэкӀубгъо|нэкӀубгъу}}",
        "passwordreset-email": "Емэйл адрес:",
        "passwordreset-emailtitle": "Аккаунт и гъэпсыкIэхэр, мий щыI {{SITENAME}}",
        "passwordreset-emailelement": "НэбгырацIэ: \n$1\n\nTemporary password: \n$2",
-       "passwordreset-emailsent": "ШÑ\8aÑ\8dÑ\84гÑ\83Ñ\89Ñ\8b\8dм Ð¸ Ð·Ñ\8dÑ\82едзÑ\8bм Ð¿Ð°Ðµ ÐµÐ¼Ñ\8dйл Ð°Ð³Ñ\8aÑ\8dÑ\85Ñ\8cÑ\8bгÑ\8a.",
+       "passwordreset-emailsent": "Ð\9cÑ\8bÑ\80 Ñ\80егиÑ\81Ñ\82Ñ\80Ñ\8bгÑ\8aÑ\8d ÐµÐ¼Ñ\8dйлÑ\8dÑ\83 Ñ\89Ñ\8bÑ\82мÑ\8d Ñ\83и Ð°ÐºÐºÐ°Ñ\83нÑ\82Ñ\8bм Ð¿Ð°Ðµ, Ñ\88Ñ\8aÑ\8dÑ\84гÑ\83Ñ\89Ñ\8b\8dм Ð¸ Ð·Ñ\8dÑ\82едз ÐµÐ¼Ñ\8dйл ÐºÑ\8aÑ\8bпÑ\84агÑ\8aÑ\8dÑ\85Ñ\8cÑ\8bÑ\89Ñ\82.",
        "passwordreset-emailsent-capture": "ШъэфгущыIэм изэтедз фэгъэхьыгъэ емэйлыр гъахьыгъэ, ычIэгъкIэ ар олъэгъу.",
-       "changeemail": "Зэблэхъу емэйл адресыр",
+       "changeemail": "Зэблэхъу е тегъэкI емэйл адресыр",
        "changeemail-no-info": "Мы нэкIубгъом занкIэу укIонэу уфаемэ, системэм ухэхьэгъэн фае.",
        "changeemail-oldemail": "Джырэ емэйл адрес:",
        "changeemail-newemail": "Емэйл адресыкIэр:",
        "prefs-watchlist-token": "Лъыплъэ купым и токен:",
        "prefs-misc": "ПэмыкI гъэпсыкIэхэр",
        "prefs-resetpass": "ШъэфгущыIэр зэблэхъу",
-       "prefs-changeemail": "Зэблэхъу емэйл адресыр",
+       "prefs-changeemail": "Зэблэхъу е тегъэкI емэйл адресыр",
        "prefs-setemail": "Игъахь уи емэйл адресыр",
        "prefs-email": "Емэйл гъэпсыкIэхэр",
        "prefs-rendering": "Ышъотеплъэ",
        "deletepage": "ТегъэкI нэкIубгъор",
        "confirm": "Теубыт",
        "excontent": "дэтхэгъагъэр: \"$1\"",
-       "excontentauthor": "дэтхэгъагъэр: \"$1\" (хэлэжьэкIо закъоэр \"[[Special:Contributions/$2|$2]]\")",
+       "excontentauthor": "дэтхагъэщтыгъэхэр: \"$1\", ыкIи хэлэжьэкIо закъощтыгъэр \"[[Special:Contributions/$2|$2]]\"([[User talk:$2|тегущыIэн]])",
        "delete-confirm": "ТегъэкI \"$1\"",
        "delete-legend": "ТегъэкI",
        "actioncomplete": "ЗэшIогъэкIыгъэ",
index 0a68c0d..51e930c 100644 (file)
        "movenosubpage": "Die bladsy het geen subbladsye nie.",
        "movereason": "Rede:",
        "revertmove": "rol terug",
-       "delete_and_move": "Skrap en skuif",
        "delete_and_move_text": "==Skrapping benodig==\n\nDie teikenartikel \"[[:$1]]\" bestaan reeds. Wil u dit skrap om plek te maak vir die skuif?",
        "delete_and_move_confirm": "Ja, skrap die bladsy",
        "delete_and_move_reason": "Geskrap om plek te maak vir skuif vanaf \"[[$1]]\"",
index 3df549d..d6a89ca 100644 (file)
        "passwordreset-emailtext-ip": "أحد ما (قد يكون أنت، من العنوان $1)  طلب إعادة ضبط كلمة سر حسابك على {{SITENAME}} ($4). {{PLURAL:$3||الحساب|الحسابان| الحسابات}} أدناه قد اقترنت ببريدك الإلكتروني :\n\n$2\n\n{{PLURAL:$3||كلمة السر المؤقتة|كلمات السر المؤقتة}} ستنتهي صلاحيتها في {{PLURAL:$5||يوم واحد|يومين|$5 أيام|$5 يوما|$5 يوم}}\nيمكنك تسجيل الدخول واختيار كلمة سر جديدة. إذا كان هذا الطلب تم بواسطة شخص أخر، أو إذا تذكرت كلمة السر الأصلية الخاصة بك، ولم تعد ترغب في تغييرها، يمكنك تجاهل هذه الرسالة ومتابعة استخدام كلمة السر القديمة.",
        "passwordreset-emailtext-user": "المستخدم $1 على {{SITENAME}} طلب إعادة ضبط كلمة سر حسابك على {{SITENAME}} ($4). {{PLURAL:$3||الحساب|الحسابان| الحسابات}} أدناه قد اقترنت ببريدك الإلكتروني :\n\n$2\n\n{{PLURAL:$3||كلمة السر المؤقتة|كلمات السر المؤقتة}} ستنتهي صلاحيتها في {{PLURAL:$5||يوم واحد|يومين|$5 أيام|$5 يوما|$5 يوم}}\nيمكنك تسجيل الدخول واختيار كلمة سر جديدة. إذا كان هذا الطلب تم بواسطة شخص أخر، أو إذا تذكرت كلمة السر الأصلية الخاصة بك، ولم تعد ترغب في تغييرها، يمكنك تجاهل هذه الرسالة ومتابعة استخدام كلمة السر القديمة.",
        "passwordreset-emailelement": "اسم {{GENDER:$1\n|المستخدم|المستخدمة}}: \n$1\n\nكلمة السر المؤقتة: \n$2",
-       "passwordreset-emailsent": "أُرسل بريد إلكتروني لإعادة ضبط كلمة السر.",
+       "passwordreset-emailsentemail": "أُرسل بريد إلكتروني لإعادة ضبط كلمة السر.",
        "passwordreset-emailsent-capture": "أُرسل بريد إلكتروني لإعادة ضبط كلمة السر، وهو معروض بالأسفل.",
        "passwordreset-emailerror-capture": "تم توليد رسالة بريد إلكتروني لتصفير كلمة السر نصّه التالي، إلا أنه تعذّر إرسال الرّسالة إلى {{GENDER:$2|المستخدم|المستخدمة}}: $1",
        "changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
        "prefs-help-recentchangescount": "بما في ذلك أحدث التغييرات وتاريخ الصفحات والسجلات.",
        "prefs-help-watchlist-token2": "هذا هو المفتاح السري لتغذية الوِب لقائمة مراقبتك.\nيمكن لأي شخص يعرفه أن يقرأ قائمة مراقبتك، ولذا لا تتشاركه مع أحد. [[Special:ResetTokens|انقر هنا إذا أردت إعادة ضبطه]].",
        "savedprefs": "تم حفظ تفضيلاتك.",
+       "savedrights": "حُفظت الصلاحيات الجديدة {{GENDER:$1|للمستخدم|للمستخدمة}} $1.",
        "timezonelegend": "المنطقة الزمنية:",
        "localtime": "الوقت المحلي:",
        "timezoneuseserverdefault": "استخدام الويكي الافتراضي ($1)",
        "contributions": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}}",
        "contributions-title": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}} $1",
        "mycontris": "مساهماتي",
+       "anoncontribs": "مساهمات",
        "contribsub2": "ل{{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "حساب المستخدم \"$1\" غير مسجل.",
        "nocontribs": "لم يتم العثور على تغييرات تطابق هذه المحددات.",
        "movenosubpage": "ليس لهذه الصفحة صفحات فرعية.",
        "movereason": "السبب:",
        "revertmove": "استرجع",
-       "delete_and_move": "حذف ونقل",
        "delete_and_move_text": "==الحذف مطلوب==\nالصفحة الهدف \"[[:$1]]\" موجودة بالفعل.\nهل تريد حذفها لإفساح المجال للنقل؟",
        "delete_and_move_confirm": "نعم، احذف الصفحة",
        "delete_and_move_reason": "حُذِفت لإفساح مجال لنقل \"[[$1]]\"",
index 8d37c4f..3db46b7 100644 (file)
        "wlheader-showupdated": "الصفحات اللى اتغيرت  بعد زيارتك ليها اخر مرة معروضة بالخط '''العريض'''",
        "wlnote": "تحت فى {{PLURAL:$1|آخر تغيير|آخر '''$1''' تغيير}} فى آخر {{PLURAL:$2|ساعه|'''$2''' ساعه}}، من الوقت $3، $4.",
        "wlshowlast": "عرض اخر $1 ساعات $2 ايام",
+       "watchlistall2": "الكل",
        "watchlist-options": "اختيارات قايمة المراقبة",
        "watching": "بيراقب...",
        "unwatching": "بيبطل مراقبه...",
        "ipbreason-dropdown": "*أسباب المنع المشهورة\n** تدخيل معلومات غلط\n** مسح المحتوى من الصفحات\n** سبام لينك لمواقع خارجية\n** كتابة كلام مالوش معنى فى الصفحات\n** سلوك عدواني/تحرش\n** إساءة استخدام اكتر من حسابات\n** اسم يوزر مش مقبول",
        "ipbcreateaccount": "امنع فتح الحسابات",
        "ipbemailban": "منع اليوزر ده من بعتان إيميل",
-       "ipbenableautoblock": " امنع آخر عنوان أيبى استخدمه اليوزر دا اوتوماتيكي، وأى عناوين أيبى تانية يحاول التحرير منها",
+       "ipbenableautoblock": "امنع آخر عنوان أيبى استخدمه اليوزر دا اوتوماتيكي، وأى عناوين أيبى تانية يحاول التحرير منها",
        "ipbsubmit": "منع اليوزر دا",
        "ipbother": "وقت تاني:",
        "ipboptions": "2 ساعه:2 hours,1 يوم:1 day,3 يوم:3 days,1 اسبوع:1 week,2 اسبوع:2 weeks,1 شهر:1 month,3 شهر:3 months,6 شهر:6 months,1 سنه:1 year,على طول:infinite",
        "movenosubpage": "الصفحه دى مافيهاش صفحات فرعيه.",
        "movereason": "السبب:",
        "revertmove": "رجّع",
-       "delete_and_move": "مسح ونقل",
        "delete_and_move_text": "==المسح مطلوب==\nالصفحة الهدف \"[[:$1]]\" موجودة فعلا.\nانت عايز تمسحها علشان تقدر تنقلها؟",
        "delete_and_move_confirm": "ايوة، امسح الصفحة",
        "delete_and_move_reason": "اتمسحت علشان تسمح بالنقل من \"[[$1]]\"",
index 29e39cb..acfcd1d 100644 (file)
        "rev-deleted-event": "(ল'গ সবিশেষ আঁতৰোৱা হ'ল)",
        "rev-deleted-user-contribs": "[সদস্যনাম বা আই-পি ঠিকনা আঁতৰোৱা হ'ল - সম্পাদনা বৰঙনিসমূহৰ পৰা আঁৰ কৰা হৈছে]",
        "rev-deleted-text-permission": "পৃষ্ঠাৰ এই সংশোধনটি '''বিলোপ''' কৰা হ'ল ।\nসবিশেষ পাব [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অবলুপ্তি অভিলেখত]",
-       "rev-deleted-text-unhide": "পৃষ্ঠাখনৰ এই সংশোধনটো '''বিলোপ''' কৰা হৈছে | \nসবিশেষ পাব [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অৱলুপ্তি অভিলেখত]।\nআপুনি মন কৰিলে [$1 এই সংশোধনটো চাব পাৰে]।",
+       "rev-deleted-text-unhide": "পৃষ্ঠাখনৰ এই সংশোধনটো <strong>বিলোপ</strong> কৰা হৈছে। \n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অৱলুপ্তি অভিলেখত ইয়াৰ সবিশেষ পাব]।\nআপুনি মন কৰিলে [$1 এই সংশোধনটো চাব পাৰে]।",
        "rev-suppressed-text-unhide": "পৃষ্ঠাটোৰ এই সংশোধনটো '''নিবাৰণ''' কৰা হৈছে ।\nসবিশেষ পাব [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} নিবাৰণ অভিলেখত]।\nআপুনি মন কৰিলে [$1 এই সংশোধনটো চাব পাৰে]।",
        "rev-deleted-text-view": "পৃষ্ঠাৰ এই সংশোধনটো '''বিলোপ''' কৰা হ'ল ।\nআপুনি এইটো চাব পাৰে; সবিশেষ পাব [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অবলুপ্তি অভিলেখত]।",
        "rev-suppressed-text-view": "পৃষ্ঠাৰ এই সংশোধনটো '''নিবাৰণ''' কৰা হ’ল।\nআপুনি এইটো চাব পাৰে; সবিশেষ পাব [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} নিবাৰণ অভিলেখত]।",
        "speciallogtitlelabel": "গন্তব্য (title or user):",
        "log": "অভিলেখ/ল'গ",
        "all-logs-page": "সকলোবোৰ ৰাজহুৱা সূচী",
-       "alllogstext": "{{SITENAME}} à¦¸à¦\95লà§\8b à¦²â\80\99à¦\97ৰ à¦¸à¦¨à§\8dমিলিত à¦ªà§\8dৰদৰà§\8dশন à¥¤\nà¦\86পà§\81নি à¦²â\80\99à¦\97ৰ à¦ªà§\8dৰà¦\95াৰ, à¦¸à¦¦à¦¸à§\8dযৰ à¦¨à¦¾à¦® à¦¬à¦¾ à¦ªà§\83ষà§\8dঠাà¦\96নৰ নাম নিৰ্বাচন কৰি প্ৰদৰ্শনটোৰ আকাৰ সৰু কৰিব পাৰে ।",
+       "alllogstext": "{{SITENAME}} à¦¸à¦\95লà§\8b à¦²â\80\99à¦\97ৰ à¦¸à¦¨à§\8dমিলিত à¦ªà§\8dৰদৰà§\8dশন à¥¤\nà¦\86পà§\81নি à¦²â\80\99à¦\97ৰ à¦ªà§\8dৰà¦\95াৰ, à¦¸à¦¦à¦¸à§\8dযৰ à¦¨à¦¾à¦® à¦¬à¦¾ à¦ªà§\83ষà§\8dঠাà¦\9fà§\8bৰ নাম নিৰ্বাচন কৰি প্ৰদৰ্শনটোৰ আকাৰ সৰু কৰিব পাৰে ।",
        "logempty": "কোনো মিল থকা আইটেম লগত নাই ।",
        "log-title-wildcard": "এই পাঠেৰে আৰম্ভ হোৱা শিৰোনামাসমূহ অনুসন্ধান কৰক",
        "showhideselectedlogentries": "নিৰ্বাচিত ল'গ ভুক্তি দেখুৱাওক/লুকুৱাওক",
        "protect-text": "'''$1''' পৃষ্ঠাটোৰ সুৰক্ষা-স্তৰ আপুনি চাব আৰু সলনি কৰিব পাৰে।",
        "protect-locked-blocked": "বাধাপ্ৰাপ্ত অৱস্থাত আপুনি সুৰক্ষা স্তৰ সলাব নোৱাৰে ।\n'''$1''' পৃষ্ঠাৰ বৰ্তমান ছেটিং সমূহ ইয়াত দিয়া হ’ল:",
        "protect-locked-dblock": "এটা সক্ৰিয় অথ্যভঁৰাল প্ৰতিবন্ধকৰ বাবে সুৰক্ষা স্তৰ সলাব নোৱাৰি ।\n'''$1''' পৃষ্ঠাৰ বৰ্তমান ছেটিং সমূহ ইয়াত দিয়া হ’ল:",
-       "protect-locked-access": "এই পৃষ্ঠাটোৰ সুৰক্ষা-স্তৰ সলনি কৰাৰ অনুমতি আপোনাক দিয়া হোৱা নাই ।\n'''$1''' পৃষ্ঠাখনৰ সুৰক্ষা-স্তৰৰ গাঁথনি ইয়াত আছে:",
+       "protect-locked-access": "এই পৃষ্ঠাটোৰ সুৰক্ষা-স্তৰ সলনি কৰাৰ অনুমতি আপোনাক দিয়া হোৱা নাই ।\nপৃষ্ঠাটোৰ বৰ্তমান ছেটিংছ ইয়াত পাব:\n<strong>$1</strong>:",
        "protect-cascadeon": "এই পৃষ্ঠাটো বৰ্তমান সুৰক্ষিত কাৰণ ই {{PLURAL:$1|খন পৃষ্ঠাৰ|খন পৃষ্ঠাৰ}} অন্তৰ্গত য’ত প্ৰপাতাকাৰ সুৰক্ষা সক্ৰিয় ।\nএই পৃষ্ঠাৰ সুৰক্ষা স্তৰ সলালে প্ৰপাতাকাৰ সুৰক্ষাত কোনো প্ৰভাৱ নেপেলায় ।",
        "protect-default": "সকলো ব্যৱহাৰকাৰীৰ বাবে",
        "protect-fallback": "কেৱল \"$1\" অনুমতি থকা ব্যৱহাৰকাৰীকহে সুযোগ দিয়া হয়",
        "move-page-legend": "পৃষ্ঠাটো স্থানান্তৰ কৰক",
        "movepagetext": "তলৰ প্ৰপত্ৰ ব্যৱহাৰ কৰিলে এই পৃষ্ঠাৰ শিৰোনাম সলনি হ'ব, লগতে সমগ্ৰ ইতিহাস নতুন শিৰোনামলৈ স্থানান্তৰ কৰা হ'ব।\nপুৰণা শিৰোনামটো নতুন শিৰোনামালৈ এটা পুনৰ্নিৰ্দেশনা হৈ ৰ'ব।\nপুৰণা শিৰোনামলৈ পোনাৱা পুনৰ্নিৰ্দেশনাসমূহ আপুনি স্বয়ংক্ৰিয়ভাৱে আপডে'ট কৰিব পাৰিব।\nযদি এইটো কৰিব নিবিচাৰে তেনেহ'লে  [[Special:DoubleRedirects|দ্বি-পুনৰ্নিৰ্দেশনাসমূহ]] বা [[Special:BrokenRedirects|ভঙা পুনৰ্নিৰ্দেশনাসমূহ]] বাছনি কৰে যেন।\nসকলো সংযোগ সঠিক দিশলৈ পোনাৱাৰ দায়িত্ব আপোনাৰ।\n\nমন কৰিব যে পৃষ্ঠাটো স্থানান্তৰ কৰা '''নহ'ব''' যদিহে নতুন শিৰোনামটোত পূৰ্বৰপৰা এটা পৃষ্ঠা আছেই, আৰু যদিহে পূৰ্বৰ পৃষ্ঠাটো কোনো পুনৰ্নিৰ্দেশ নহয় আৰু তাৰ কোনো সম্পাদনাৰ পূৰ্বইতিহাস নাই।\nইয়াৰ অৰ্থ এয়ে যে ভুল হলে পৃষ্ঠাটো আগৰ ঠাইতে থাকিব, আৰু আপুনি প্ৰচলিত পৃষ্ঠা এটাক আন পৃষ্ঠা এটাৰে সলনি কৰিব নোৱাৰে।\n\n'''সতৰ্কবাণী !'''\nজনপ্ৰিয় পৃষ্ঠা এটাৰ বাবে এয়া এক ডাঙৰ আৰু অনাকাংক্ষিত সাল-সলনি হ’ব পাৰে;\nআগবঢ়াৰ পূৰ্বে এই কাৰ্যৰ পৰিণাম ভালদৰে বিবেচনা কৰি লয় যেন।",
        "movepagetext-noredirectfixer": "তলৰ প্ৰপত্ৰ ব্যৱহাৰ কৰিলে এই পৃষ্ঠাৰ শিৰোনামা সলনি হ'ব, লগতে সমগ্ৰ ইতিহাস নতুন শিৰোনামালৈ স্থানান্তৰ কৰা হ'ব।\nপুৰণা শিৰোনামাটো নতুন শিৰোনামালৈ এটা পুনৰ্নিৰ্দেশনা হৈ ৰ'ব।\n[[Special:DoubleRedirects|দ্বি পুনৰ্নিৰ্দেশনাসমূহ]] বা [[Special:BrokenRedirects|ভঙা পুনৰ্নিৰ্দেশনসমূহ]] পৰীক্ষা কৰিবলৈ নাপাহৰিব।\nসকলো সংযোগে যাতে সঠিক দিশলৈ পোনায়, সেয়া লক্ষ্য কৰা দায়িত্ব আপোনাৰ।\n\nমন কৰিব যে নতুন শিৰোনামাতো যদি প্ৰচলিত, এই পৃষ্ঠা নতুন শিৰোনামালৈ সলনি কৰা '''নহ'ব''' যদিহে সেই পৃষ্ঠা খালী বা কোনো পুনৰ্নিৰ্দেশনৰ পূৰ্ব ইতিহাস নাই।\nইয়াৰ অৰ্থ এয়ে যে ভুল হলে পৃষ্ঠাটো আগৰ ঠাইতে থাকিব, আৰু আপুনি প্ৰচলিত পৃষ্ঠা এটাক আন পৃষ্ঠা এখনেৰে সলনি কৰিব নোৱাৰে।\n\n'''সতৰ্কবাণী !'''\nজনপ্ৰিয় পৃষ্ঠা এটাৰ বাবে এয়া এক ডাঙৰ আৰু অকানাংক্ষিত সাল-সলনি হ'ব পাৰে;\nএই কাৰ্য্যৰ পৰিণাম ভালদৰে বিবেচনা কৰি লয় যেন।",
-       "movepagetalktext": "পà§\83ষà§\8dঠাà¦\96নৰ à¦²à¦\97তà§\87 à¦¸à¦\82শà§\8dলিষà§\8dà¦\9f à¦\86লà§\8bà¦\9aনা à¦ªà§\83ষà§\8dঠাà¦\96নà§\8b à¦¸à§\8dবয়à¦\82à¦\95à§\8dৰিয়ভাৱà§\87 à¦¸à§\8dথানানà§\8dতৰ à¦¹â\80\99ব; à¦\8fনà§\87 à¦¨à¦¹à¦¯à¦¼ '''যদিহà§\87:'''\n*নতà§\81ন à¦¶à¦¿à§°à§\8bনামাৰ à¦\85ধà§\80নত à¦\8fà¦\9fা à¦\96ালি à¦¨à§\8bহà§\8bৱা à¦\86লà§\8bà¦\9aনা à¦ªà§\83ষà§\8dঠা à¦\87তিমধà§\8dযà§\87à¦\87 à¦¥à¦¾à¦\95à§\87, à¦¬à¦¾\n*à¦\86পà§\81নি à¦¤à¦²à§° à¦\98ৰà¦\9fà§\8b à¦\85à¦\9aিহà§\8dনিত à¦\95ৰà§\87 à¥¤\n\nতà§\87নà§\87 à¦\95à§\8dষà§\87তà§\8dৰত à¦\86পà§\81নি à¦\86পà§\81নি à¦\87à¦\9aà§\8dà¦\9bা à¦\95ৰিলà§\87 à¦¨à¦¿à¦\9c à¦¹à¦¾à¦¤à§\87 à¦ªà§\83ষà§\8dঠাà¦\9fà§\8b à¦¸à§\8dথানানà§\8dতৰ à¦¬à¦¾ à¦\8fà¦\95তà§\8dৰà§\80à¦\95ৰণ à¦\95ৰিব à¦ªà¦¾à§°à§\87 ।",
+       "movepagetalktext": "à¦\8fà¦\87 à¦¬à¦¾à¦\95à¦\9bà¦\9fà§\8b à¦\9aিহà§\8dনিত à¦\95ৰিলà§\87 à¦ªà§\83ষà§\8dঠাà¦\9fà§\8bৰ à¦²à¦\97তà§\87 à¦¸à¦\82শà§\8dলিষà§\8dà¦\9f à¦\86লà§\8bà¦\9aনা à¦ªà§\83ষà§\8dঠাà¦\93 à¦¸à§\8dবয়à¦\82à¦\95à§\8dৰিয়ভাৱà§\87 à¦¸à§\8dথানানà§\8dতৰ à¦¹â\80\99ব; à¦\8fনà§\87 à¦¨à¦¹à¦¯à¦¼ à¦¯à¦¦à¦¿à¦¹à§\87 à¦\8fà¦\9fা à¦\96ালি à¦¨à§\8bহà§\8bৱা à¦\86লà§\8bà¦\9aনা à¦ªà§\83ষà§\8dঠা à¦\87তিমধà§\8dযà§\87à¦\87 à¦¥à¦¾à¦\95à§\87।\n\nতà§\87নà§\87 à¦\95à§\8dষà§\87তà§\8dৰত à¦\86পà§\81নি à¦\86পà§\81নি à¦\87à¦\9aà§\8dà¦\9bা à¦\95ৰিলà§\87 à¦¨à¦¿à¦\9c à¦¹à¦¾à¦¤à§\87 à¦ªà§\83ষà§\8dঠাà¦\9fà§\8b à¦¸à§\8dথানানà§\8dতৰ à¦¬à¦¾ à¦\8fà¦\95তà§\8dৰà§\80à¦\95ৰণ à¦\95ৰিব à¦ªà¦¾à§°à§\87।",
        "moveuserpage-warning": "'''সতৰ্কবাণী:''' আপুনি এখন সদস্যপৃষ্ঠা স্থানান্তৰ কৰিবলৈ বিছাৰিছে । অনুগ্ৰহ কৰি মন কৰক যে কেৱল সদস্যপৃষ্ঠাখনহে স্থানান্তৰ হ’ব আৰু সদস্যজনৰ পুনঃনামাকৰণ নহ’ব ।",
        "movenologintext": "পৃষ্ঠা স্থানান্তৰ কৰিবলৈ আপুনি ভুক্ত সদস্য হৈ [[Special:UserLogin|প্ৰৱেশ]] কৰিব লাগিব ।",
        "movenotallowed": "পৃষ্ঠা স্থানান্তৰ কৰিবলৈ আপোনাৰ অনুমতি নাই ।",
        "movenosubpage": "এই পৃষ্ঠাৰ কোনো উপপৃষ্ঠা নাই ।",
        "movereason": "কাৰণ:",
        "revertmove": "আগৰ অৱস্থালৈ ঘূৰি যাওক",
-       "delete_and_move": "বিলোপ আৰু স্থানান্তৰ কৰক",
        "delete_and_move_text": "== বিলোপন আৱশ্যক ==\nলক্ষ্য পৃষ্ঠা \"[[:$1]]\" ইতিমেধ্যে আছেই ।\nআপুনি স্থানান্তৰ কৰিবলৈ এইখন বিলোপ কৰিব খুজিছে নেকি ?",
        "delete_and_move_confirm": "হয়, পৃষ্ঠাটো বিলোপ কৰক",
        "delete_and_move_reason": "\"[[$1]]\"ৰ পৰা স্থানান্তৰৰ স্বাৰ্থত বিলোপ কৰা হৈছে",
        "tooltip-pt-logout": "প্ৰস্থান",
        "tooltip-pt-createaccount": "আপোনাক এটা একাউণ্ট সৃষ্টি কৰি প্ৰৱেশ কৰিবলৈ অনুৰোধ জনোৱা হৈছে, কিন্তু এয়া বাধ্যতামূলক নহয়",
        "tooltip-ca-talk": "সংশ্লিষ্ট প্ৰবন্ধ সম্পৰ্কীয় আলোচনা",
-       "tooltip-ca-edit": "এই পৃষ্ঠাখন সম্পাদনা কৰক",
+       "tooltip-ca-edit": "এই পৃষ্ঠা সম্পাদনা কৰক",
        "tooltip-ca-addsection": "নতুন অনুচ্ছেদ আৰম্ভ কৰক",
        "tooltip-ca-viewsource": "এই পৃষ্ঠাটো সুৰক্ষিত কৰা হৈছে, আপুনি ইয়াৰ উৎস চাব পাৰে।",
        "tooltip-ca-history": "এই পৃষ্ঠাৰ যোৱা সংস্কৰণসমূহ",
        "tooltip-ca-nstab-main": "এই ৱিকিৰ সূচী চাওক",
        "tooltip-ca-nstab-user": "সদস্য পৃষ্ঠা চাওক",
        "tooltip-ca-nstab-media": "মিডিয়া পৃষ্ঠাটো চাওক",
-       "tooltip-ca-nstab-special": "এইটো এটা বিশেষ পৃষ্ঠা, আপুনি সম্পাদনা কৰিব নোৱাৰে",
+       "tooltip-ca-nstab-special": "à¦\8fà¦\87à¦\9fà§\8b à¦\8fà¦\9fা à¦¬à¦¿à¦¶à§\87ষ à¦ªà§\83ষà§\8dঠা, à¦\86ৰà§\81 à¦\8fà¦\87à¦\9fà§\8b à¦\86পà§\81নি à¦¸à¦®à§\8dপাদনা à¦\95ৰিব à¦¨à§\8bৱাৰà§\87",
        "tooltip-ca-nstab-project": "প্ৰকল্প পৃষ্ঠা চাওক",
        "tooltip-ca-nstab-image": "নথিৰ পৃষ্ঠা চাওক",
        "tooltip-ca-nstab-mediawiki": "প্ৰণালী বাৰ্তা চাওক",
index 954255b..38d1f4b 100644 (file)
@@ -46,6 +46,7 @@
        "tog-watchlisthidebots": "Anubrir les ediciones de bots na llista de siguimientu",
        "tog-watchlisthideminor": "Anubrir les ediciones menores na llista de siguimientu",
        "tog-watchlisthideliu": "Anubrir les ediciones d'usuarios identificaos na llista de siguimientu",
+       "tog-watchlistreloadautomatically": "Recargar la llista de siguimientu automáticamente cuando se cambie un filtru (rique JavaScript).",
        "tog-watchlisthideanons": "Anubrir les ediciones d'usuarios anónimos na llista de siguimientu",
        "tog-watchlisthidepatrolled": "Anubrir les ediciones patrullaes na llista de siguimientu",
        "tog-watchlisthidecategorization": "Tapecer la categorización de páxines",
        "morenotlisted": "Esta llista nun ta completa.",
        "mypage": "Páxina",
        "mytalk": "Alderique",
-       "anontalk": "Alderique pa esta IP",
+       "anontalk": "Alderique",
        "navigation": "Navegación",
        "and": "&#32;y",
        "qbfind": "Alcontrar",
        "databaseerror-query": "Consulta: $1",
        "databaseerror-function": "Función: $1",
        "databaseerror-error": "Error: $1",
+       "transaction-duration-limit-exceeded": "Para evitar crear un gran atrasu na replicación, esta transaición albortóse porque la duración de la escritura ($1) pasó la llende de $2 segundos.\nSi tas cambiando munchos oxetos al mesmu tiempu, intenta meyor facer operaciones múltiples más pequeñes.",
        "laggedslavemode": "'''Avisu:''' Esta páxina pue que nun tenga actualizaciones recientes.",
        "readonly": "Base de datos candada",
        "enterlockreason": "Introduz un motivu pal candáu, amestando una estimación de cuándo va tener llugar el descandáu",
        "wrongpasswordempty": "La contraseña taba en blanco.\nVuelvi a intentalo.",
        "passwordtooshort": "Les contraseñes han de tener polo menos {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
        "passwordtoolong": "Les contraseñes nun puen ser mayores de {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
+       "passwordtoopopular": "Les contraseñes más escoyíes de vezu nun pueden usase. Escueye una contraseña más única.",
        "password-name-match": "La contraseña tien de ser distinta del nome d'usuariu.",
        "password-login-forbidden": "Ta torgao usar esti nome d'usuariu y contraseña.",
        "mailmypassword": "Reaniciar contraseña",
        "passwordreset-emailtext-ip": "Dalguién (seique vusté, dende la direición IP $1)solicitó'l reaniciu de la so contraseña de {{SITENAME}} ($4).\n{{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}}\na esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona,\no si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir\nusando la contraseña antigua.",
        "passwordreset-emailtext-user": "L'usuariu $1 de {{SITENAME}} solicitó un reaniciu de la so contraseña de {{SITENAME}} ($4). {{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}} con esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona, o si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir usando la contraseña antigua.",
        "passwordreset-emailelement": "Nome d'usuariu: \n$1\n\nContraseña temporal: \n$2",
-       "passwordreset-emailsent": "Si esta ye una direición de corréu electrónicu rexistrada pa la to cuenta, unviaráse un corréu pa reaniciar la contraseña.",
+       "passwordreset-emailsentemail": "Si esta ye una direición de corréu electrónicu rexistrada pa la to cuenta, unviaráse un corréu pa reaniciar la contraseña.",
        "passwordreset-emailsent-capture": "Unvióse un corréu electrónicu pa reaniciar la contraseña, que s'amuesa abaxo.",
        "passwordreset-emailerror-capture": "Unvióse un corréu electrónicu pa reaniciar la contraseña, que s'amuesa abaxo, pero falló l'unviu {{GENDER:$2|al usuariu|a la usuaria}}: $1",
        "changeemail": "Camudar o desaniciar la dirección de corréu electrónicu",
        "wlshowlast": "Amosar les últimes $1 hores, los últimos $2 díes",
        "watchlistall2": "toos",
        "watchlist-hide": "Anubrir",
-       "wlshowtime": "Ver últimos:",
+       "wlshowtime": "Periodu de tiempu a amosar:",
        "wlshowhideminor": "ediciones menores",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "usuarios rexistraos",
        "contributions": "Collaboraciones {{GENDER:$1|del usuariu|de la usuaria}}",
        "contributions-title": "Contribuciones d'usuariu pa $1",
        "mycontris": "Collaboraciones",
+       "anoncontribs": "Contribuciones",
        "contribsub2": "Pa {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "La cuenta d'usuariu «$1» nun ta rexistrada.",
        "nocontribs": "Nun s'atoparon cambeos que coincidan con esi criteriu.",
        "movenosubpage": "Esta páxina nun tien subpáxines.",
        "movereason": "Motivu:",
        "revertmove": "revertir",
-       "delete_and_move": "Esborrar y treslladar",
        "delete_and_move_text": "==Necesítase esborrar==\n\nLa páxina de destín \"[[:$1]]\" yá esiste. ¿Quies esborrala pa dexar sitiu pal treslláu?",
        "delete_and_move_confirm": "Sí, esborrar la páxina",
        "delete_and_move_reason": "Desaniciada pa facer sitiu pa treslladar dende «[[$1]]»",
        "tooltip-pt-preferences": "Les tos preferencies",
        "tooltip-pt-watchlist": "Llista de les páxines nes que tas vixilando los cambios",
        "tooltip-pt-mycontris": "Llista de les tos collaboraciones",
+       "tooltip-pt-anoncontribs": "Una llista d'ediciones feches dende esta dirección IP",
        "tooltip-pt-login": "T'encamentamos que t'identifiques, anque nun ye obligatorio",
        "tooltip-pt-logout": "Salir",
        "tooltip-pt-createaccount": "Encamentámoste que crees una cuenta y qu'anicies sesión; sicasí, nun ye obligatorio",
index e805a73..b2948f7 100644 (file)
@@ -26,7 +26,8 @@
                        "Arystanbek",
                        "Dağlı95",
                        "Sayginer",
-                       "Şeyx Şamil"
+                       "Şeyx Şamil",
+                       "Serkanland"
                ]
        },
        "tog-underline": "Keçidlərin altını xətlə:",
        "pagecategories": "$1 {{PLURAL:$1|Kateqoriya|Kateqoriya}}",
        "category_header": "\"$1\" kateqoriyasındakı məqalələr",
        "subcategories": "Alt kateqoriyalar",
-       "category-media-header": "\"$1\" kateqoriyasında mediya",
+       "category-media-header": "\"$1\" kateqoriyasındakı fayllar",
        "category-empty": "\"Bu kateqoriya hal-hazırda boşdur.\"",
        "hidden-categories": "{{PLURAL:$1|Gizli kateqoriya|Gizli kateqoriyalar}}",
        "hidden-category-category": "Gizli kateqoriyalar",
        "passwordreset-email": "E-mail ünvanı:",
        "passwordreset-emailtitle": "{{SITENAME}} hesabın yaradılması",
        "passwordreset-emailelement": "İstifadəçi adı: \n$1\n\nMüvəqqəti parol: \n$2",
-       "passwordreset-emailsent": "Xəbərdarlıq məktubu e-maillə göndərildi.",
+       "passwordreset-emailsentemail": "Xəbərdarlıq məktubu e-maillə göndərildi.",
        "changeemail": "E-məktub ünvanını dəyiş",
        "changeemail-oldemail": "Hazırkı e-poçt ünvanı:",
        "changeemail-newemail": "Yeni e-poçt ünvanı:",
        "unwatching": "İzlənilmir...",
        "enotif_reset": "Baxılmış bütün səhifələri işarələ.",
        "enotif_impersonal_salutation": "{{SITENAME}} istifadəçisi",
+       "enotif_body_intro_moved": "{{SITENAME}}da  $1 səhifəsinin adı $PAGEEDITDATE tarixində $2 tərəfindən {{GENDER:$2|dəyişdirilib}}, son versiya üçün bura baxın: $3.",
        "enotif_lastvisited": "Sonuncu ziyarətinizdən indiyədək olan bütün dəyişiklikləri görmək üçün baxın: $1.",
        "enotif_lastdiff": "Bu dəyişikliyi görmək üçün $1 səhifəsinə baxın.",
        "enotif_anon_editor": "qeydiyyatsız istifadəçi $1",
        "movenosubpage": "Bu səhifənin altsəhifəsi yoxdur.",
        "movereason": "Səbəb:",
        "revertmove": "Əvvəlki vəziyyətinə",
-       "delete_and_move": "Sil və apar",
        "delete_and_move_text": "==Hazırki məqalənin silinməsi lazımdır==\n\n\"[[$1]]\" məqaləsi mövcuddur. Bu dəyişikliyin yerinə yetirilə bilməsi üçün həmin məqalənin silinməsini istəyirsinizmi?",
        "delete_and_move_confirm": "Bəli, səhifəni sil",
        "delete_and_move_reason": "[[$1]] Ad dəyişməyə yer açmaq üçün silinmişdir",
        "markaspatrolleddiff": "Yoxlanıldı",
        "markaspatrolledtext": "Səhifəni patrullanmış kimi işarələ",
        "markedaspatrolled": "Yoxlanıldı",
-       "markedaspatrolledtext": "[[:$1]] üçün seçilmiş versiya gözdən keçirilərək işarələndi.",
+       "markedaspatrolledtext": "[[:$1]] məqaləsinin seçilmiş versiyası patrullanmış kimi işarələndi.",
        "rcpatroldisabled": "Son dəyişikliklərin patrullanması qadağandır",
        "rcpatroldisabledtext": "Son dəyişikliklərin Yoxlanılması hal-hazırda mümkün deyil.",
        "markedaspatrollederror": "Yoxlanmadı",
        "markedaspatrollederror-noautopatrol": "Öz dəyişikliklərinizi yoxlayıb işarələyə bilməzsiniz.",
+       "markedaspatrollednotify": "\"$1\" səhifəsindəki bu redaktə patrullanmış kimi işarələndi.",
        "patrol-log-page": "Patrul gündəliyi",
        "patrol-log-header": "Bu yoxlanmış dəyişikliklərin gündəliyidir.",
        "log-show-hide-patrol": "$1 patrul gündəliyi",
index 02e9c3e..ab0dd0e 100644 (file)
        "create": "یارات",
        "create-local": "یئرلی آچیقلاما آرتیر",
        "editthispage": "بۇ صحیفه‌‌نی دَییشدیر",
-       "create-this-page": "بۇ صحیفه‌‌نی يارات",
+       "create-this-page": "بۇ صفحه‌‌نی يارات",
        "delete": "سیل",
        "deletethispage": "بۇ صحیفه‌‌نی سیل",
        "undeletethispage": "بۇ صحیفه‌نی دیریلت",
        "passwordreset-emailtext-ip": "بیر کس (احتیمالاً سیز، $1 آی‌پی آدرسی‌له)، {{SITENAME}} ($4) سایتینداکی حسابینیز اوچون رمزی یئنیله‌مک ایسته‌ییب‌دیر. آشاغیداکی ایستیفاده‌چی {{PLURAL:$3|حسابی|حسابلاری}} بو ایمیل ایله ایلگی‌لی‌دیرلر:\n\n$2\n\nبو گئچیجی {{PLURAL:$3|رمز|رمزلر}}، {{PLURAL:$5|بیر گون|$5 گون}}‌ده {{PLURAL:$3|واختی|واختلاری}} قورتاراجاق‌دیر.\nسیز گرک ایندی سایتا گیریب و یئنی بیر رمز سئچه‌سینیز. باشقا آدام بو ایستَگی وئرمیش‌سه، یوخسا سیز اسکی رمزینیزی یادا گتیرمیشسینیزسه، و داها اونو چئویرمک ایسته‌میرسینیزسه، بو مئساژی سایماییب و اسکی رمزینیزی ایشلدمگه داوام ائده بیلرسینیز.",
        "passwordreset-emailtext-user": "{{SITENAME}} سایتیندا، $1 ایستیفاده‌چی، سیزین اوردا ($4) حسابینیزین رمزینی یئنیله‌مک ایستگی وئریب‌دیر. آشاغیداکی {{PLURAL:$3|ایستیفاده‌چی|ایستیفاده‌چیلر}} بو ایمیل ایله ایلگیلیدیرلر:\n\n$2\n\nبو گئچیجی {{PLURAL:$3|رمز|رمزلر}}، {{PLURAL:$5|بیر|$5گون}} سونرا واختلاری قورتاراجاق‌دیر. \nسیز گرک ایندی گیریب و بیر یئنی رمز سئچه‌سینیز. باشقا آدام بو ایستَگی وئرمیش‌سه، یوخسا سیز اسکی رمزینیزی یادا گتیرمیشسینیزسه، و داها اونو چئویرمک ایسته‌میرسینیزسه، بو مئساژی سایماییب و اسکی رمزینیزی ایشلدمگه داوام ائده بیلرسینیز.",
        "passwordreset-emailelement": "ایشلدن آدی: \n$1\n\nگئچیجی رمز: \n$2",
-       "passwordreset-emailsent": "بیر رمز یئنیله‌مه ایمیلی گؤندریلیب‌دیر.",
+       "passwordreset-emailsentemail": "بیر رمز یئنیله‌مه ایمیلی گؤندریلیب‌دیر.",
        "passwordreset-emailsent-capture": "آشاغیدا گؤستریلن کیمی بیر رمز یئنیله‌مه ایمیلی گؤندریلیب‌دیر.",
        "passwordreset-emailerror-capture": "آشاغیدا گؤستریلن کیمی بیر رمز یئنیله‌مه ایمیلی یارادیلیب‌دیر، اما {{GENDER:$2ایستیفاده‌چی}}‌یه گؤندرمگی باشاریلی اولمادی: $1",
        "changeemail": "ایمیل آدرسینی دَییشدیر یا سیل",
        "movenosubpage": "بو صحیفه‌نین آلت صحیفه‌سی یوخ‌دور.",
        "movereason": "ندن:",
        "revertmove": "قایتار",
-       "delete_and_move": "سیل و آپار",
        "delete_and_move_text": "==هازیرکی مقاله‌نین سیلینمه‌سی لازیم‌دیر==\n\n«[[:$1]]» مقاله‌سی مؤوجوددور. بو دییشیکلیگین یئرینه یئتیریله بیلمه‌سی اوچون همین مقاله‌نین سیلینمه‌سینی ایستییرسینیزمی؟",
        "delete_and_move_confirm": "بلی، صحیفنی سیل",
        "delete_and_move_reason": "«[[$1]]» آد دَییشمه ‌یه یئر آچماق اوچون سیلینمیش‌دیر",
        "semiprotectedpagemovewarning": "'''قئید:' بو صحیفه کیلیدلنمیش، یالنیز قئیدیات‌لی ایستیفاده‌چی‌لر داشییا بیلر.\nسون گونده‌لیک گیردی‌سی ایستیناد مقصدلی آشاغیدا وئریلمیش‌دیر:",
        "move-over-sharedrepo": "== فایل مؤوجود ==\n[[:$1]] پایلاشیلمیش هوووزدا مؤوجود. بیر فایلی بو باشلیغا داشیماق پایلاشیلمیش فایلین اوستونه گله‌جک.",
        "file-exists-sharedrepo": "سئچیلن آد پایلاشیلمیش بیر هوووزدا اونسوز دا مؤوجود.\nخاهیش ائدیریک باشقا بیر آد سئچین.",
-       "export": "صحیفه‌‌لری ائشیگه چیخارت",
+       "export": "صفحه‌‌لری ائشیگه چیخارت",
        "exporttext": "مویین بیر صحیفه و یا صحیفه کومانداسینین متنی و دییشدیرمه کئچمیشینی خمل ایله ساری‌لی اولا‌راق خاریجه کؤچوره بیلرسینیز.\nبو، مئدیاویکی ایستیفاده باشقا بیر ویکی [[Special:Import|ایچه کؤچورمه صحیفه‌سی]] ایله ایچه کؤچوروله بیلر.\n\nصحیفه‌لری خاریجه کؤچورمک اوچون، باش‌لیق‌لاری آشاغی‌داکی متن قوتوسونا داخیل ائدین، هر سطره بیر دنه، و کؤهنه سوروملئرلئ بیرلیکده ایندیکی وئرسیاسی، صحیفه کئچمیشی سطرلرینی، یا دا سون دییشیک‌لیک ملوماتییلا بیرلیکده آکتوال وئرسیاسی ایسته‌ییب ایستمدیگینیزی قئید ائدین.\n\nسونونجو حالدا، بیر لینک ده ایستیفاده ائده بیلرسینیز، هؤر: \"[[{{MediaWiki:Mainpage}}]]\" صحیفه‌سی اوچون [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]].",
        "exportall": "بوتون صحیفه‌لری خاریجه کؤچور",
        "exportcuronly": "بوتون تاریخچنی دئییل، یالنیز حال-هازیرکی نوسخه نی داخیل ائت",
        "autosumm-blank": "صحیفه‌‌نی بوشالتدی",
        "autosumm-replace": "صحیفه‌‌نین مظمونو ' $1' يازیسی ایله ديَیشدیریلدی",
        "autoredircomment": "[[$1]] صحیفه‌‌سینه ایستیقامتلندیریلیر",
-       "autosumm-new": "صحیفه‌‌نی ' $1' ایله يارات",
+       "autosumm-new": "صفحه‌‌نی ' $1' ایله ياراتدی",
        "autosumm-newblank": "بوش صحفه یاراندی",
        "lag-warn-normal": "$1 {{PLURAL:$1 | سانیيه‌دن | سانیيه‌ده}} يئنی ديَیشیکلیکلر بو سیياهیدا گؤرولمه‌يه.",
        "lag-warn-high": "وئریلنلر بازاسی سونوجوسونداکی هددیندن آرتیق گئجیکمه‌دن گؤره، $1 {{PLURAL:$1 | سانیيه‌دن | سانیيه‌دن}} يئنی ديَیشیکلیکلر بو سیياهیدا گؤرونمئيئبیلیر.",
        "specialpages": "اؤزل صفحه‌لر",
        "specialpages-note": "* نورمال اؤزل صفحه‌لر.\n* <span class=\"mw-specialpagerestricted\">محدودلاشدیریلمیش اؤزل صفحه‌لر.</span>",
        "specialpages-group-maintenance": "جاری مروزه‌لر",
-       "specialpages-group-other": "دÛ\8cگر Ø®ØµÙ\88صÛ\8c ØµØ­Û\8cÙ\81ه‌لر",
+       "specialpages-group-other": "Ø¢Û\8cرÛ\8c Ø§Ø¤Ø²Ù\84 ØµÙ\81Ø­ه‌لر",
        "specialpages-group-login": "گیریش / حساب یاراد",
        "specialpages-group-changes": "سون دییشیک‌لیک‌لر و قئیدلر",
        "specialpages-group-media": "مئدیا مروزه‌لری و یوکلمه‌لر",
        "specialpages-group-users": "ایستیفاده‌چی‌لر و حاقلار",
        "specialpages-group-highuse": "ان چوخ ایستیفاده ائدیلن صحیفه‌لر",
        "specialpages-group-pages": "صحیفه‌لرین سیاهی‌لاری",
-       "specialpages-group-pagetools": "صحیفه آلتلری",
+       "specialpages-group-pagetools": "صفحه آلتلری",
        "specialpages-group-wiki": "بیلگیلر و آلتلر",
        "specialpages-group-redirects": "خصوصی ایستیقامتلندیرمه صحیفه‌لری",
        "specialpages-group-spam": "هرزه یازماق آلت‌لری",
        "tags-edit-chosen-no-results": "تای اولان اِتیکِت تاپیلمادی",
        "tags-edit-reason": "ندن:",
        "tags-edit-nooldid-title": "گئچرسیز هدف نوسخه",
-       "comparepages": "صحیفه‌لری قارشی‌لاش‌دیر",
+       "comparepages": "صفحه‌لری موقایسه ائت",
        "compare-page1": "صفحه 1",
        "compare-page2": "صفحه ۲",
        "compare-rev1": "نوسخه ۱",
index 720adeb..c651a44 100644 (file)
@@ -50,6 +50,7 @@
        "tog-watchlisthidebots": "Хаваць праўкі робатаў у сьпісе назіраньня",
        "tog-watchlisthideminor": "Хаваць дробныя праўкі ў сьпісе назіраньня",
        "tog-watchlisthideliu": "Хаваць праўкі зарэгістраваных удзельнікаў у сьпісе назіраньня",
+       "tog-watchlistreloadautomatically": "Аўтаматычна перазагружаць сьпіс назіраньня пры зьмене фільтру (патрэбны JavaScript)",
        "tog-watchlisthideanons": "Хаваць праўкі ананімаў у сьпісе назіраньня",
        "tog-watchlisthidepatrolled": "Хаваць патруляваныя праўкі ў сьпісе назіраньня",
        "tog-watchlisthidecategorization": "Хаваць катэгарызацыю старонак",
        "morenotlisted": "Гэта ня поўны сьпіс.",
        "mypage": "Старонка",
        "mytalk": "Гутаркі",
-       "anontalk": "Гутаркі для гэтага IP-адрасу",
+       "anontalk": "Гутаркі",
        "navigation": "Навігацыя",
        "and": "&#32;і",
        "qbfind": "Знайсьці",
        "databaseerror-query": "Запыт: $1",
        "databaseerror-function": "Функцыя: $1",
        "databaseerror-error": "Памылка: $1",
+       "transaction-duration-limit-exceeded": "Каб пазьбегнуць вялікай затрымкі пры рэплікацыі, гэтая транзакцыя была спыненая, таму што працягласьць запісу ($1) перавысіла ліміт у $2 сэк.\nКалі вы адначасова зьмяняеце некалькі элемэнтаў, паспрабуйце замест гэтага зрабіць некалькі невялікіх апэрацыяў.",
        "laggedslavemode": "<strong>Увага:</strong> старонка можа ня ўтрымліваць апошнія зьмены.",
        "readonly": "База зьвестак заблякаваная",
        "enterlockreason": "Пазначце прычыну блякаваньня і заплянаваны час разблякаваньня",
        "wrongpasswordempty": "Быў уведзены пусты пароль. Калі ласка, паспрабуйце яшчэ раз.",
        "passwordtooshort": "Паролі павінны ўтрымліваць ня менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}.",
        "passwordtoolong": "Паролі ня могуць быць даўжэй за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}.",
+       "passwordtoopopular": "Нельга выкарыстоўваць простыя паролі. Калі ласка, абярыце больш складаны пароль.",
        "password-name-match": "Ваш пароль павінен адрозьнівацца ад Вашага імя ўдзельніка.",
        "password-login-forbidden": "Выкарыстаньне гэтага імя ўдзельніка і паролю было забароненае.",
        "mailmypassword": "Скінуць пароль",
        "passwordreset-emailtext-ip": "Нехта (магчыма Вы, з IP-адрасу $1) зрабіў запыт на скіданьне вашага паролю ў {{GRAMMAR:месны|{{SITENAME}}}} ($4). {{PLURAL:$3|1=Наступны рахунак удзельніка зьвязаны|Наступныя рахункі ўдзельнікаў зьвязаныя}} з гэтым адрасам электроннай пошты:\n\n$2\n\n{{PLURAL:$3|1=Гэты часовы пароль будзе|Гэтыя часовыя паролі будуць}} дзейнічаць $5 {{PLURAL:$5|дзень|дні|дзён}}.\nЦяпер Вам неабходна ўвайсьці і выбраць новы пароль. Калі нехта іншы зрабіў гэты запыт, ці Вы ўспомнілі Ваш пачатковы пароль, які ня хочаце мяняць, Вы можаце праігнараваць гэтае паведамленьне, і працягваць выкарыстоўваць стары пароль.",
        "passwordreset-emailtext-user": "Удзельнік $1 зрабіў запыт на скіданьне вашага паролю ў {{GRAMMAR:месны|{{SITENAME}}}} ($4). {{PLURAL:$3|1=Наступны рахунак удзельніка зьвязаны|Наступныя рахункі ўдзельнікаў зьвязаныя}} з гэтым адрасам электроннай пошты:\n\n$2\n\n{{PLURAL:$3|1=Гэты часовы пароль будзе|Гэтыя часовыя паролі будуць}} дзейнічаць $5 {{PLURAL:$5|дзень|дні|дзён}}.\nЦяпер Вам неабходна ўвайсьці і выбраць новы пароль. Калі нехта іншы зрабіў гэты запыт, ці Вы ўспомнілі Ваш пачатковы пароль, які ня хочаце мяняць, Вы можаце праігнараваць гэтае паведамленьне, і працягваць выкарыстоўваць стары пароль.",
        "passwordreset-emailelement": "Імя ўдзельніка: \n$1\n\nЧасовы пароль: \n$2",
-       "passwordreset-emailsent": "Калі гэты адрас электроннай пошты зарэгістраваны для вашага рахунку, тады будзе дасланы ліст пра скідваньне паролю.",
+       "passwordreset-emailsentemail": "Калі гэты адрас электроннай пошты зарэгістраваны для вашага рахунку, тады будзе дасланы ліст пра скідваньне паролю.",
+       "passwordreset-emailsentusername": "Калі зарэгістраваны адпаведны адрас электроннай пошты, тады будзе дасланы ліст пра скідваньне паролю.",
        "passwordreset-emailsent-capture": "Ліст пра скіданьне паролю быў дасланы, што паказана ніжэй.",
        "passwordreset-emailerror-capture": "Ліст пра скіданьне паролю быў створаны і паказаны ніжэй, але не ўдалося адправіць яго {{GENDER:$2|ўдзельніку|ўдзельніцы}}: $1",
        "changeemail": "Зьмяніць або выдаліць адрас электроннай пошты",
        "recentchanges-label-plusminus": "Памер старонкі зьмяніўся на такую колькасьць байтаў",
        "recentchanges-legend-heading": "'''Легенда:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (глядзіце таксама [[Special:NewPages|сьпіс новых старонак]])",
+       "recentchanges-submit": "Паказаць",
        "rcnotefrom": "Ніжэй {{PLURAL:$5|знаходзіцца зьмена|знаходзяцца зьмены}} з <strong>$4 $3</strong> (да <strong>$1</strong> на старонку).",
        "rclistfrom": "Паказаць зьмены з $2 $3",
        "rcshowhideminor": "$1 дробныя праўкі",
        "wlshowlast": "Паказаць за апошнія $1 гадзінаў, $2 дзён",
        "watchlistall2": "усё",
        "watchlist-hide": "Схаваць",
-       "wlshowtime": "Паказаць апошнія:",
+       "wlshowtime": "Пэрыяд часу для паказу:",
        "wlshowhideminor": "дробныя праўкі",
        "wlshowhidebots": "робатаў",
        "wlshowhideliu": "зарэгістраваных удзельнікаў",
        "contributions": "Унёсак {{GENDER:$1|удзельніка|удзельніцы}}",
        "contributions-title": "Унёсак {{GENDER:$1|удзельніка|удзельніцы}} $1",
        "mycontris": "Унёсак",
+       "anoncontribs": "Унёсак",
        "contribsub2": "Для {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Рахунак удзельніка «$1» не зарэгістраваны.",
        "nocontribs": "Ня знойдзена зьменаў, якія адпавядаюць гэтым крытэрыям.",
        "movenosubpage": "Гэтая старонка ня мае падстаронак.",
        "movereason": "Прычына:",
        "revertmove": "адкат",
-       "delete_and_move": "Выдаліць і перанесьці",
        "delete_and_move_text": "==Патрабуецца выдаленьне==\nМэтавая старонка «[[:$1]]» ужо існуе.\nЦі жадаеце Вы яе выдаліць, каб вызваліць месца для пераносу?",
        "delete_and_move_confirm": "Так, выдаліць старонку",
        "delete_and_move_reason": "Выдаленая, каб вызваліць месца для пераносу «[[$1]]»",
        "tooltip-pt-preferences": "Вашыя налады",
        "tooltip-pt-watchlist": "Сьпіс старонак, за зьменамі якіх Вы назіраеце",
        "tooltip-pt-mycontris": "Ваш унёсак",
+       "tooltip-pt-anoncontribs": "Сьпіс рэдагаваньняў, зробленых з гэтага IP-адрасу",
        "tooltip-pt-login": "Вас запрашаюць увайсьці, хаця гэта і неабавязкова.",
        "tooltip-pt-logout": "Выйсьці",
        "tooltip-pt-createaccount": "Мы прапануем вам стварыць рахунак і ўвайсьці, але гэта не абавязкова",
index 44f6654..f503418 100644 (file)
        "movenosubpage": "Старонка не мае пад-старонак.",
        "movereason": "Прычына:",
        "revertmove": "адкат",
-       "delete_and_move": "Сцерці і перанесці",
        "delete_and_move_text": "==Патрабуецца сціранне==\n\nУжо існуе артыкул з мэтавай назвай \"[[:$1]]\". Дык ці жадаеце сцерці яго, каб зрабіць месца для пераносу?",
        "delete_and_move_confirm": "Так, сцерці старонку",
        "delete_and_move_reason": "Сцёрта, каб зрабіць месца для пераносу \"[[$1]]\"",
index 1375684..e31a79a 100644 (file)
@@ -31,7 +31,8 @@
                        "V111P",
                        "Лорд Бъмбъри",
                        "Matma Rex",
-                       "Xð"
+                       "Xð",
+                       "Miroslav35232"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "mainpage": "Начална страница",
        "mainpage-description": "Начална страница",
        "policy-url": "Project:Политика",
-       "portal": "Ð\9fоÑ\80Ñ\82ал Ð·а общността",
+       "portal": "Ð\9fоÑ\80Ñ\82ал Ð½а общността",
        "portal-url": "Проект:Портал на общността",
        "privacy": "Защита на личните данни",
        "privacypage": "Проект:Защита на личните данни",
        "passwordreset-emailtext-ip": "Някой (вероятно вие, от IP адрес $1) поиска възстановяване на паролата за сметката в {{SITENAME}} ($4). За {{PLURAL:$3|следната сметка|следните сметки}}\nе посочен този адрес за електронна поща:\n\n$2\n\n{{PLURAL:$3|Тази временна парола ще бъде активна|Тези временни пароли ще бъдат активни}} {{PLURAL:$5|един ден|$5 дни}}.\nСега би трябвало да влезете в системата и да си изберете нова парола. Ако заявката е направена от друг или пък сте си спомнили паролата и не искате да я променяте, можете да пренебрегнете това съобщение и да продължите да използвате старата си парола.",
        "passwordreset-emailtext-user": "Потребител $1 от {{SITENAME}} поиска възстановяване на паролата за сметката в {{SITENAME}}\n($4). За {{PLURAL:$3|следната сметка|следните сметки}} е посочен този адрес за електронна поща:\n\n$2\n\n{{PLURAL:$3|Тази временна парола ще бъде активна|Тези временни пароли ще бъдат активни}} {{PLURAL:$5|един ден|$5 дни}}.\nСега би трябвало да влезете в системата и да изберете нова парола. Ако заявката е направена \nот друг или пък сте си спомнили паролата и не искате да я променяте, можете да пренебрегнете \nтова съобщение и да продължите да използвате старата си парола.",
        "passwordreset-emailelement": "Потребителско име: \n$1\n\nВременна парола: \n$2",
-       "passwordreset-emailsent": "На електронната поща беше изпратено писмо за възстановяване на паролата.",
+       "passwordreset-emailsentemail": "На електронната поща беше изпратено писмо за възстановяване на паролата.",
        "passwordreset-emailsent-capture": "По-долу е показано електронното писмо за възстановяване на паролата, което беше изпратено.",
        "passwordreset-emailerror-capture": "По-долу е показано създадено електронно писмо за възстановяване на паролата, което не беше изпратено на {{GENDER:$2|потребителя}}: $1",
        "changeemail": "Промяна на адреса за е-поща",
        "recentchangeslinked-summary": "Тук се показват последните промени на страниците, към които се препраща от дадена страница. При избиране на категория, се показват промените по страниците, влизащи в нея. ''Пример:'' Ако изберете страницата '''А''', която съдържа препратки към '''Б''' и '''В''', тогава ще можете да прегледате промените по '''Б''' и '''В'''.\n\nАко пък сложите отметка пред '''Обръщане на релацията''', ще можете да прегледате промените в обратна посока: ще се включат тези страници, които съдържат препратки към посочената страница.\n\nСтраниците от списъка ви за наблюдение се показват в '''получер'''.",
        "recentchangeslinked-page": "Име на страницата:",
        "recentchangeslinked-to": "Обръщане на релацията, така че да се показват промените на страниците, сочещи към избраната страница",
-       "upload": "Ð\9aаÑ\87ване",
+       "upload": "Ð\9aаÑ\87и Ñ\84айл",
        "uploadbtn": "Качване",
        "reuploaddesc": "Връщане към формуляра за качване.",
        "upload-tryagain": "Съхраняване на промененото описание на файла",
        "contributions": "{{GENDER:$1|Потребителски}} приноси",
        "contributions-title": "Потребителски приноси за $1",
        "mycontris": "Приноси",
+       "anoncontribs": "Приноси",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Няма регистрирана потребителска сметка за „$1“.",
        "nocontribs": "Не са намерени промени, отговарящи на критерия.",
        "movenosubpage": "Тази страница няма подстраници.",
        "movereason": "Причина:",
        "revertmove": "връщане",
-       "delete_and_move": "Изтриване и преместване",
        "delete_and_move_text": "== Наложително изтриване ==\n\nЦелевата страница „[[:$1]]“ вече съществува. Искате ли да я изтриете, за да освободите място за преместването?",
        "delete_and_move_confirm": "Да, искам да изтрия тази страница.",
        "delete_and_move_reason": "Изтрита, за да се освободи място за преместване от „[[$1]]“",
        "tooltip-pt-preferences": "Вашите настройки",
        "tooltip-pt-watchlist": "Списък на страници, чиито промени сте избрали да наблюдавате",
        "tooltip-pt-mycontris": "Списък на вашите приноси",
-       "tooltip-pt-login": "Ð\9dаÑ\81Ñ\8aÑ\80Ñ\87аваме Ð²и да влезете, въпреки че не е задължително.",
+       "tooltip-pt-login": "Ð\9dаÑ\81Ñ\8aÑ\80Ñ\87аваме Ð\92и да влезете, въпреки че не е задължително.",
        "tooltip-pt-logout": "Излизане от {{SITENAME}}",
        "tooltip-pt-createaccount": "Насърчаваме Ви да си създадете сметка и да влезете, въпреки че не е задължително.",
        "tooltip-ca-talk": "Беседа относно страницата",
-       "tooltip-ca-edit": "Ð\9cожеÑ\82е Ð´Ð° Ñ\80едакÑ\82иÑ\80аÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а. Ð\98зползвайÑ\82е Ð±Ñ\83Ñ\82она Ð·Ð° Ð¿Ñ\80едваÑ\80иÑ\82елен Ð¿Ñ\80еглед Ð¿Ñ\80еди Ð´Ð° Ñ\81Ñ\8aÑ\85Ñ\80аниÑ\82е.",
+       "tooltip-ca-edit": "РедакÑ\82иÑ\80ане Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а",
        "tooltip-ca-addsection": "Започване на нов раздел",
        "tooltip-ca-viewsource": "Страницата е защитена. Можете да разгледате изходния й код.",
        "tooltip-ca-history": "Предишни версии на страницата",
        "tooltip-search": "Претърсване на {{SITENAME}}",
        "tooltip-search-go": "Отиване на страницата, ако тя съществува с точно това име",
        "tooltip-search-fulltext": "Търсене в страниците за този текст",
-       "tooltip-p-logo": "Ð\9dачалната страница",
+       "tooltip-p-logo": "Ð\9fоÑ\81еÑ\89аване Ð½Ð° Ð½ачалната страница",
        "tooltip-n-mainpage": "Началната страница",
        "tooltip-n-mainpage-description": "Посещаване на началната страница",
        "tooltip-n-portal": "Информация за проекта — какво, къде, как",
-       "tooltip-n-currentevents": "Информация за текущите събития по света",
-       "tooltip-n-recentchanges": "Списък на последните промени в {{SITENAME}}",
+       "tooltip-n-currentevents": "Информация за текущи събития",
+       "tooltip-n-recentchanges": "Списък на последните промени в уикито",
        "tooltip-n-randompage": "Зареждане на случайна страница",
-       "tooltip-n-help": "Ð\9fомоÑ\89наÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а",
+       "tooltip-n-help": "Ð\9cÑ\8fÑ\81Ñ\82о ÐºÑ\8aдеÑ\82о Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ñ\81е Ð¸Ð½Ñ\84оÑ\80миÑ\80аÑ\82е",
        "tooltip-t-whatlinkshere": "Списък на всички страници, сочещи насам",
        "tooltip-t-recentchangeslinked": "Последните промени на страници, сочени от тази страница",
        "tooltip-feed-rss": "RSS feed за страницата",
        "tooltip-t-contributions": "Показване на приносите на потребителя",
        "tooltip-t-emailuser": "Изпращане на писмо до потребителя",
        "tooltip-t-info": "Повече за тази страница",
-       "tooltip-t-upload": "Ð\9aаÑ\87ване Ð½Ð° файлове",
+       "tooltip-t-upload": "Ð\9aаÑ\87и файлове",
        "tooltip-t-specialpages": "Списък на всички специални страници",
        "tooltip-t-print": "Версия за печат на страницата",
        "tooltip-t-permalink": "Постоянна препратка към тази версия на страницата",
        "spam_reverting": "Връщане на последната версия, несъдържаща препратки към $1",
        "spam_blanking": "Всички версии, съдържащи препратки към $1, изчистване",
        "spam_deleting": "Всички версии съдържат препратки към $1, изтриване",
-       "simpleantispam-label": "Проверка за спам.\nНеобходимо е да <strong>НЕ</strong> попълвате това поле!",
+       "simpleantispam-label": "Проверка за спам.\n<strong>НЕ</strong> попълвайте това поле!",
        "pageinfo-title": "Информация за \"$1\"",
        "pageinfo-not-current": "За съжаление тази информация не може да бъде предоставена за стари версии.",
        "pageinfo-header-basic": "Основна информация",
index c49cded..ac0204f 100644 (file)
        "contributions": "{{GENDER:$1|کار زوروک}} ئی شراکت ئان",
        "contributions-title": "$1 ئی کار زوروکئ شراکت ئان",
        "mycontris": "شراکت ئان",
+       "anoncontribs": "شراکت ئان",
        "contribsub2": "په {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "«$1» ئی کار زوروکین حساب راجستر نه بوته.",
        "nocontribs": "هیچ تغیری گۆ ای مشخصات ئان ودێ نه بوت",
        "movenosubpage": "ای تاکدیم هیچ گۆنڈدیم ئی نداریت.",
        "movereason": "دلیل:",
        "revertmove": "بیرگردینتین",
-       "delete_and_move": "پاک کورتین یا جابیجا",
        "delete_and_move_confirm": "هان،تاکدیم پاک بیئت",
        "delete_and_move_reason": "پاک کورتین  «[[$1]]» جابجایی امکانا",
        "immobile-source-page": "ای دیم جابیجا ئه نه بیئت.",
index d11c197..5c3a37c 100644 (file)
@@ -61,6 +61,7 @@
        "tog-watchlisthidebots": "বটের করা সম্পাদনাগুলি নজরতালিকায় না দেখানো হোক",
        "tog-watchlisthideminor": "অনুল্লেখ্য সম্পাদনাগুলো নজর তালিকায় না দেখানো হোক",
        "tog-watchlisthideliu": "নজরতালিকাতে অ্যাকাউন্টে লগ-ইন করা ব্যবহারকারীদের সম্পাদনা আড়ালে রাখা হোক",
+       "tog-watchlistreloadautomatically": "প্রতিবার একটি ছাঁকনি পরিবর্তন হওয়া মাত্রই স্বয়ংক্রিয়ভাবে নজরতালিকায় পুনঃলোড করো (জাভাস্ক্রিপ্ট প্রয়োজন)",
        "tog-watchlisthideanons": "নজরতালিকাতে বেনামী ব্যবহারকারীদের সম্পাদনা আড়ালে রাখা হোক",
        "tog-watchlisthidepatrolled": "পরীক্ষিত সম্পাদনা গুলো নজরতালিকায় আড়াল করো",
        "tog-watchlisthidecategorization": "পাতার শ্রেণীবদ্ধকরণ লুকান",
        "morenotlisted": "এটি একটি অসম্পূর্ণ তালিকা।",
        "mypage": " পাতা",
        "mytalk": "আলোচনা",
-       "anontalk": "à¦\8fà¦\87 à¦¬à§\87নামà§\80 à¦¬à§\8dযবহারà¦\95ারà§\80র à¦\86লাপà§\87র à¦ªà¦¾à¦¤à¦¾",
+       "anontalk": "à¦\86লাপ",
        "navigation": "পরিভ্রমণ",
        "and": "&#32;এবং",
        "qbfind": "অনুসন্ধান",
        "passwordreset-emailtext-ip": "কেউ একজন (সম্ভবত আপনি, $1 আইপি ঠিকানা থেকে) {{SITENAME}} ($4) সাইটের জন্য আপনার\nপাসওয়ার্ড বদলের জন্য অনুরোধ করেছে। নিচের ব্যবহারকারী {{PLURAL:$3|অ্যাকাউন্টটি|অ্যাকাউন্টগুলো}}\nএই ই-মেইল ঠিকানার সাথে সংযুক্ত:\n\n$2\n\n{{PLURAL:$3|এই অস্থায়ী পাসওয়ার্ডটি|এই অস্থায়ী পাসওয়ার্ডগুলো}} আগামী {{PLURAL:$5|এক দিন|$5 দিন}} পর মেয়াদোত্তীর্ণ হয়ে যাবে।\nআপনার অবশ্যই লগ-ইন করে একটি নতুন পাসওয়ার্ড পছন্দ করা উচিত। যদি অন্য কেউ এই অনুরোধ করে থাকে,\nঅথবা আপনি যদি পুরোনো পাসওয়ার্ড মনে করতে পারেন, এবং আপনার সেটি পরিবর্তন করার কোনো ইচ্ছা না থাকে, তবে\nআপনি এই বার্তাটি উপেক্ষা করতে পারে, এবং আপনার পুরোনো পাসওয়ার্ড ব্যবহার করা চালিয়ে যেতে পারেন।",
        "passwordreset-emailtext-user": "ব্যবহারকারী $1 {{SITENAME}} ($4) সাইটের জন্য আপনার পাসওয়ার্ড বদলের জন্য অনুরোধ করেছে। নিচের ব্যবহারকারী {{PLURAL:$3|অ্যাকাউন্টটি|অ্যাকাউন্টগুলো}}\nএই ই-মেইল ঠিকানার সাথে সংযুক্ত:\n\n$2\n\n{{PLURAL:$3|এই অস্থায়ী পাসওয়ার্ডটি|এই অস্থায়ী পাসওয়ার্ডগুলো}} আগামী {{PLURAL:$5|এক দিন|$5 দিন}} পর মেয়াদোত্তীর্ণ হয়ে যাবে।\nআপনার অবশ্যই লগ-ইন করে একটি নতুন পাসওয়ার্ড পছন্দ করা উচিত। যদি অন্য কেউ এই অনুরোধ করে থাকে,\nঅথবা আপনি যদি পুরোনো পাসওয়ার্ড মনে করতে পারেন, এবং আপনার সেটি পরিবর্তন করার কোনো ইচ্ছা না থাকে, তবে\nআপনি এই বার্তাটি উপেক্ষা করতে পারে, এবং আপনার পুরোনো পাসওয়ার্ড ব্যবহার করা চালিয়ে যেতে পারেন।",
        "passwordreset-emailelement": "ব্যবহারকারী নাম: \n$1\n\nঅস্থায়ী পাসওয়ার্ড: \n$2",
-       "passwordreset-emailsent": "যদি আপনার অ্যাকাউন্টের জন্য এটি একটি নিবন্ধিত ইমেল ঠিকানা হয়, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
+       "passwordreset-emailsentemail": "যদি আপনার অ্যাকাউন্টের জন্য এটি একটি নিবন্ধিত ইমেল ঠিকানা হয়, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
        "passwordreset-emailsent-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল করা হয়েছে, যা নিচে দেখানো হচ্ছে।",
        "passwordreset-emailerror-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল তৈরী করা হয়েছিল, যা নিচে দেখানো হচ্ছে, তবে $1 {{GENDER:$2|ব্যবহারকারীকে}} এটি পাঠানো যায়নি!",
        "changeemail": "ই-মেইল ঠিকানা পরিবর্তন বা বাতিল",
        "revdelete-show-file-submit": "হ্যাঁ",
        "revdelete-selected-text": "[[:$2]] পাতার {{PLURAL:$1|নির্বাচিত সংশোধন|নির্বাচিত সংশোধনসমূহ}}:",
        "revdelete-selected-file": "[[:$2]]-এর {{PLURAL:$1|নির্বাচিত ফাইল সংস্করণ|নির্বাচিত ফাইল সংস্করণগুলি}}:",
-       "logdelete-selected": "{{PLURAL:$1|à¦\9fি à¦¨à¦¿à¦°à§\8dবাà¦\9aিত à¦²à¦\97-à¦\98à¦\9fনা|à¦\9fি à¦¨à¦¿à¦°à§\8dবাà¦\9aিত à¦²à¦\97-ঘটনা}}:",
+       "logdelete-selected": "{{PLURAL:$1|নিরà§\8dবাà¦\9aিত à¦²à¦\97à§\87র ঘটনা}}:",
        "revdelete-text-text": "অপসারিত সংস্করণসমূহ এখনও পাতা ইতিহাসে প্রদর্শিত হয়, কিন্তু সেই বিষয়বস্তুর অংশগুলি সর্বসাধারণ দেখতে পারবে না।",
        "revdelete-text-file": "অপসারিত ফাইলের সংস্করণসমূহ এখনও ফাইল ইতিহাসে প্রদর্শিত হয়, কিন্তু সেই বিষয়বস্তুর অংশগুলি সর্বসাধারণ দেখতে পারবে না।",
        "logdelete-text": "অপসারিত লগ ইভেন্টসমূহ এখনও লগে প্রদর্শিত হয়, কিন্তু সেই বিষয়বস্তুর অংশগুলি সর্বসাধারণ দেখতে পারেবে না।",
        "action-deletedhistory": "পাতার মুছে ফেলা ইতিহাস দেখাও",
        "action-browsearchive": "অপসারিত পাতায় অনুসন্ধান করুন",
        "action-undelete": "পাতাটি পুনরুদ্ধার করো",
-       "action-suppressrevision": "লà§\81à¦\95ানà§\8b à¦¸à¦\82সà§\8dà¦\95রণà¦\97à§\81লà§\8b à¦°à¦¿à¦­à¦¿à¦\89 à¦\8fবà¦\82 à¦°à¦¿à¦¸à§\8dà¦\9fà§\8bর করুন",
+       "action-suppressrevision": "লà§\81à¦\95ানà§\8b à¦¸à¦\82সà§\8dà¦\95রণà¦\97à§\81লà§\8b à¦ªà¦°à§\8dযালà§\8bà¦\9aনা à¦\8fবà¦\82 à¦ªà§\81নà¦\83সà§\8dথাপন করুন",
        "action-suppressionlog": "এই ব্যক্তিগত লগ দেখাও",
        "action-block": "এই ব্যবহারকারীকে সম্পাদনা করতে বাঁধা দাও",
        "action-protect": "এই পাতার সুরক্ষার মাত্রা পরিবর্তন করো",
        "recentchanges-legend-heading": "'''ব্যাখ্যামূলক বর্ণনা:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (আরও দেখুন [[Special:NewPages|নতুন পাতার তালিকা]])",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
+       "recentchanges-submit": "দেখাও",
        "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)।",
        "rclistfrom": "$2, $3 তারিখের পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও",
        "rcshowhideminor": "অনুল্লেখ্য পরিবর্তনগুলো $1",
        "mostrevisions": "সবচেয়ে বেশী বার সম্পাদিত নিবন্ধসমূহ",
        "prefixindex": "উপসর্গ সহ সমস্ত পাতা",
        "prefixindex-namespace": "উপসর্গ সহ সকল পাতা ($1 নামস্থান)",
+       "prefixindex-submit": "দেখাও",
        "prefixindex-strip": "তালিকা থেকে প্রিফিক্স সরাও",
        "shortpages": "সংক্ষিপ্ত পাতাসমূহ",
        "longpages": "দীর্ঘ পাতাসমূহ",
        "protectedpages-performer": "ব্যবহারকারীকে সুরক্ষিত করা হচ্ছে",
        "protectedpages-params": "সুরক্ষা প্যারামিটার",
        "protectedpages-reason": "কারণ",
+       "protectedpages-submit": "পাতা প্রদর্শন করুন",
        "protectedpages-unknown-timestamp": "অজানা",
        "protectedpages-unknown-performer": "অজানা ব্যবহারকারী",
        "protectedtitles": "সুরক্ষিত শিরোনামগুলি",
        "protectedtitles-summary": "এই পাতায় বর্তমানে সৃষ্টি করা থেকে সুরক্ষিত পাতার শিরোনামের তালিকা রয়েছে। বিদ্যমান সুরক্ষিত পাতার একটি তালিকা দেখার জন্য, [[{{#special:ProtectedPages}}|{{int:protectedpages}}]] দেখুন।",
        "protectedtitlesempty": "কোন শিরোনাম বর্তমানে এই প্যারামিটারগুলিসহ সুরক্ষিত নয়।",
+       "protectedtitles-submit": "শিরোনাম প্রদর্শন করুন",
        "listusers": "ব্যবহারকারীর তালিকা",
        "listusers-editsonly": "শুধুমাত্র এমন ব্যবহারকারীদের দেখাও যাদের অবদান আছে",
        "listusers-creationsort": "তৈরির তারিখ অনুসারে সাজাও",
        "activeusers-hidebots": "বট লুকাও",
        "activeusers-hidesysops": "প্রশাসক লুকাও",
        "activeusers-noresult": "কোনো ব্যবহারকারী পাওয়া যায়নি।",
+       "activeusers-submit": "সক্রিয় ব্যবহারকারী প্রদর্শন করুন",
        "listgrouprights": "দলগত ব্যবহারকারী অধিকার",
        "listgrouprights-summary": "এই উইকির ব্যবহারকারীদের একটি গ্রুপগুলোর তালিকা দেখানো হচ্ছে, সাথে গ্রুপের কার্যপরিধিও উল্লেখ করা হয়েছে।\nনির্দিষ্ট গ্রুপের কার্যপরিধি সম্পর্কে জানতে [[{{MediaWiki:Listgrouprights-helppage}}|অতিরিক্ত তথ্য]] দেখুন।",
        "listgrouprights-key": "লিজেন্ড:\n* <span class=\"listgrouprights-granted\">অনুমোদিত অধিকার</span>\n* <span class=\"listgrouprights-revoked\">বাধাপ্রাপ্ত অধিকার</span>",
        "wlshowlast": "সর্বশেষ $1 ঘণ্টা $2 দিনে দেখাও",
        "watchlistall2": "সমস্ত",
        "watchlist-hide": "আড়াল করো",
-       "wlshowtime": "সর্বশেষটি দেখাও:",
+       "watchlist-submit": "দেখাও",
+       "wlshowtime": "প্রদর্শনের সময় কাল:",
        "wlshowhideminor": "অনুল্লেখ্য সম্পাদনা",
        "wlshowhidebots": "বট",
        "wlshowhideliu": "নিবন্ধিত ব্যবহারকারী",
        "contributions": "{{GENDER:$1|ব্যবহারকারীর}} অবদান",
        "contributions-title": "$1 ব্যবহারকারীর অবদানসমূহ",
        "mycontris": "অবদান",
+       "anoncontribs": "অবদান",
        "contribsub2": "{{GENDER:$3|$1}} ($2)-এর জন্য",
        "contributions-userdoesnotexist": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
        "nocontribs": "এই শর্তগুলির সাথে মিলে যায়, এমন কোন পরিবর্তন খুঁজে পাওয়া যায়নি।",
        "whatlinkshere-hidelinks": "সংযোগ $1",
        "whatlinkshere-hideimages": "$1 ফাইল সংযোগ",
        "whatlinkshere-filters": "ছাকনী",
+       "whatlinkshere-submit": "চলো",
        "autoblockid": "স্বয়ংক্রিয় বাধা #$1",
        "block": "ব্যবহারকারীকে বাধা দাও",
        "unblock": "ব্যবহারকারীর উপর থেকে বাধা অপসারণ",
        "movenosubpage": "এই পাতাটির কোনো উপপাতা নেই।",
        "movereason": "কারণ:",
        "revertmove": "পূর্বাবস্থায় ফেরত নেওয়া হোক",
-       "delete_and_move": "মুছে ফেলা হোক ও সরানো হোক",
        "delete_and_move_text": "==মুছে ফেলা আবশ্যক==\n\n\"[[:$1]]\" শিরোনামের গন্তব্য পাতাটি ইতিমধ্যেই বিদ্যমান। আপনি কি স্থানান্তর সফল করার জন্য পাতাটি মুছে দিতে চান?",
        "delete_and_move_confirm": "হ্যাঁ, পাতাটি মুছে ফেলা হোক",
        "delete_and_move_reason": "\"[[$1]]\" থেকে স্থানান্তরের স্বার্থে মুছে ফেলা হয়েছে",
        "tooltip-pt-preferences": "আমার পছন্দ",
        "tooltip-pt-watchlist": "যে পাতাগুলির পরিবর্তন আপনি নজরে রেখেছেন, তাদের তালিকা",
        "tooltip-pt-mycontris": "আপনার অবদানগুলোর তালিকা",
+       "tooltip-pt-anoncontribs": "এই আইপি ঠিকানা থেকে করা সম্পাদনার একটি তালিকা",
        "tooltip-pt-login": "আপনার প্রবেশ করাটা বাঞ্চনীয়, কিন্তু তা বাধ্যতামূলক নয়।",
        "tooltip-pt-logout": "প্রস্থান",
        "tooltip-pt-createaccount": "আপনাকে একটি অ্যাকাউন্ট তৈরি করে প্রবেশ করার পরামর্শ দেওয়া হচ্ছে; তবে এটা বাধ্যতামূলক নয়",
        "tags-edit-revision-selected": "[[:$2]] পাতার {{PLURAL:$1|নির্বাচিত সংশোধন|নির্বাচিত সংশোধনসমূহ}}:",
        "tags-edit-logentry-selected": "{{PLURAL:$1|নির্বাচিত লগ ইভেন্ট}}:",
        "tags-edit-existing-tags": "বিদ্যমান ট্যাগ:",
+       "tags-edit-existing-tags-none": "''কোনটি নয়''",
        "tags-edit-new-tags": "নতুন ট্যাগ:",
        "tags-edit-chosen-placeholder": "কিছু ট্যাগ নির্বাচন করুন",
        "tags-edit-chosen-no-results": "কোন ট্যাগ মিল পাওয়া যায়নি",
        "tags-edit-reason": "কারণ:",
+       "tags-edit-revision-submit": "Apply changes to {{PLURAL:$1|এই সংশোধনে|$1 সংশোধনসমূহে}} পরিবর্তন প্রয়োগ করুন",
        "tags-edit-success": "পরিবর্তন সফলভাবে প্রয়োগ করা হয়েছে।",
        "tags-edit-failure": "পরিবর্তন প্রয়োগ করা যায়নি: $1",
        "tags-edit-nooldid-title": "লক্ষ্য সংশোধন অবৈধ",
        "logentry-suppress-block": "$1 {{GENDER:$4|$3}} কে $5 মেয়াদের জন্য {{GENDER:$2|বাধাদান}} করেছেন $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$4|$3}}-এর জন্য বাধাদান সেটিং $5 সময়ের জন্য {{GENDER:$2|পরিবর্তন}} করেছেন $6",
        "logentry-import-upload": "$1 ফাইল আপলোড দ্বারা $3 {{GENDER:$2|আমদানি করেছেন}}",
+       "logentry-import-upload-details": "$1 ফাইল আপলোড দ্বারা $3 {{GENDER:$2|আমদানি করেছেন}} ($4টি {{PLURAL:$4|সংশোধন}})",
        "logentry-import-interwiki": "$1 অন্য একটি উইকিতে থেকে $3 {{GENDER:$2|আমদানি করেছে}}",
+       "logentry-import-interwiki-details": "$1 $5 থেকে $3 {{GENDER:$2|আমদানি করেছেন}} ($4টি {{PLURAL:$4|সংশোধন}})",
        "logentry-merge-merge": "$1 $4-এ $3 {{GENDER:$2|একত্রীকরণ করেছেন}} ($5 তারিখের সংশোধন পর্যন্ত)",
        "logentry-move-move": "$1 ব্যবহারকারী $3 পাতাটিকে $4 শিরোনামে {{GENDER:$2|স্থানান্তর}} করেছেন",
        "logentry-move-move-noredirect": "$1 ব্যবহারকারী $3 পাতাটিকে $4 শিরোনামে কোনো পুনর্নির্দেশনা ছাড়াই {{GENDER:$2|স্থানান্তর}} করেছেন",
        "api-error-stashfailed": "অভ্যন্তরীণ ত্রুটি: সার্ভার অস্থায়ী ফাইলটি সংরক্ষণ করতে ব্যর্থ হয়েছে।",
        "api-error-publishfailed": "অভ্যন্তরীন ত্রুটি: সার্ভার অস্থায়ী ফাইলটি প্রকাশ করতে ব্যর্থ হয়েছে।",
        "api-error-stasherror": "স্ট্যাশে আপলোডের সময় চিত্র আপলোডের সময় একটি সমস্যা দেখা দিয়েছে।",
+       "api-error-stashfilestorage": "স্ট্যাশে ফাইল সংরক্ষণের সময় একটি ত্রুটি হয়েছে।",
        "api-error-timeout": "কাঙ্খিত সময়ের মধ্যে সার্ভারের কোন সাড়া পাওয়া যায়নি।",
        "api-error-unclassified": "একটি অজানা ত্রুটি দেখা দিয়েছে",
        "api-error-unknown-code": "অজানা ত্রুটি: \"$1\"",
index c62206b..6268559 100644 (file)
        "morenotlisted": "Ovaj spisak nije potpun.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
-       "anontalk": "Razgovor za ovu IP adresu",
+       "anontalk": "Razgovor",
        "navigation": "Navigacija",
        "and": "&#32;i",
        "qbfind": "Pronađite",
        "userlogin-yourname": "Korisničko ime",
        "userlogin-yourname-ph": "Unesite Vaše korisničko ime",
        "createacct-another-username-ph": "Unesite korisničko ime",
-       "yourpassword": "Šifra:",
+       "yourpassword": "Lozinka:",
        "userlogin-yourpassword": "Lozinka",
        "userlogin-yourpassword-ph": "Unesite Vašu lozinku",
        "createacct-yourpassword-ph": "Unesite lozinku",
-       "yourpasswordagain": "Ponovo upišite šifru:",
+       "yourpasswordagain": "Ponovo upišite lozinku:",
        "createacct-yourpasswordagain": "Potvrdite lozinku",
        "createacct-yourpasswordagain-ph": "Unesite lozinku opet",
-       "remembermypassword": "Zapamti moju šifru na ovom pregledniku (najduže $1 {{PLURAL:$1|dan|dana}})",
+       "remembermypassword": "Zapamti moju lozinku na ovom pregledniku (najduže $1 {{PLURAL:$1|dan|dana}})",
        "userlogin-remembermypassword": "Ostavi me prijavljenog/-u",
        "userlogin-signwithsecure": "Koristite sigurnu konekciju",
        "yourdomainname": "Vaš domen:",
        "createacct-emailoptional": "Adresa e-pošte (opcionalno)",
        "createacct-email-ph": "Unesite Vašu adresu e-pоšte",
        "createacct-another-email-ph": "Unesite adresu e-pošte",
-       "createaccountmail": "Koristite privremenu, slučajno stvorenu šifru/lozinku i pošaljite na navedenu adrеsu e-pošte",
+       "createaccountmail": "Koristite privremenu, slučajno stvorenu lozinku i pošaljite na navedenu adrеsu e-pošte",
        "createacct-realname": "Pravo ime (opcionalno)",
        "createaccountreason": "Razlog:",
        "createacct-reason": "Razlog",
        "createacct-reason-ph": "Zašto pravite još jedan korisnički račun?",
        "createacct-submit": "Napravite svoj korisnički račun",
        "createacct-another-submit": "Napravi korisnički račun",
-       "createacct-benefit-heading": "{{SITENAME}} je napravljena od strane ljudi kao što ste Vi.",
+       "createacct-benefit-heading": "{{GRAMMAR:akuzativ|{{SITENAME}}}} stvaraju ljudi poput Vas.",
        "createacct-benefit-body1": "{{PLURAL:$1|izmjena|izmjene}}",
        "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice|stranica}}",
        "createacct-benefit-body3": "nedavnih {{PLURAL:$1|doprinosa}}",
-       "badretype": "Šifre koje ste unijeli se ne poklapaju.",
+       "badretype": "Lozinke koje ste unijeli se ne poklapaju",
        "usernameinprogress": "Račun za ovo korisničko ime već se pravi. Molimo sačekajte.",
        "userexists": "Korisničko ime je već u upotrebi.\nIzaberite drugo.",
        "loginerror": "Greška pri prijavljivanju",
        "createacct-error": "Došlo je do greške pri otvaranju naloga",
        "createaccounterror": "Ne može se napraviti račun: $1",
-       "nocookiesnew": "Korisnički nalog je napravljen, ali niste prijavljeni.\n{{SITENAME}} koristi kolačiće (cookies) da bi se korisnici prijavili.\nVi ste isključili kolačiće na Vašem računaru.\nMolimo Vas da ih uključite, a onda se prijavite sa svojim novim korisničkim imenom i šifrom.",
+       "nocookiesnew": "Korisnički nalog je napravljen, ali niste prijavljeni.\n{{SITENAME}} koristi kolačiće (cookies) da bi se korisnici prijavili.\nVi ste isključili kolačiće na Vašem računaru.\nMolimo Vas da ih uključite, a onda se prijavite sa svojim novim korisničkim imenom i lozinkom.",
        "nocookieslogin": "{{SITENAME}} koristi kolačiće (''cookies'') da bi se korisnici prijavili.  Vi ste onemogućili kolačiće na Vašem kompjuteru.  Molimo Vas da ih omogućite i da pokušate ponovo sa prijavom.",
        "nocookiesfornew": "Korisnički račun nije napravljen, jer nismo mogli da potvrdimo njegov izvor.\nProvjerite da li su cookies omogućeni, ponovo učitajte ovu stranicu i pokušajte ponovo.",
        "noname": "Niste izabrali ispravno korisničko ime.",
        "nosuchusershort": "Ne postoji korisnik s imenom \"$1\".\nProvjerite jeste li dobro ukucali.",
        "nouserspecified": "Morate izabrati korisničko ime.",
        "login-userblocked": "Ovaj korisnik je blokiran. Prijava nije dopuštena.",
-       "wrongpassword": "Šifra koju ste unijeli je netačna.\nPokušate ponovno.",
-       "wrongpasswordempty": "Šifra koju ste unijeli je bila prazna.\nMolimo Vas da pokušate ponovno.",
-       "passwordtooshort": "Šifra mora imati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}.",
-       "passwordtoolong": "Šifre ne mogu biti duže od {{PLURAL:$1|jednog znaka|$1 znaka|$1 znakova}}.",
+       "wrongpassword": "Lozinka koju ste unijeli je netačna.\nPokušate ponovno.",
+       "wrongpasswordempty": "Lozinka koju ste unijeli je bila prazna.\nMolimo Vas da pokušate ponovno.",
+       "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}.",
+       "passwordtoolong": "Lozinke ne mogu biti duže od {{PLURAL:$1|jednog znaka|$1 znaka|$1 znakova}}.",
        "password-name-match": "Vaša šifra mora biti različita od Vašeg korisničkog imena.",
        "password-login-forbidden": "Korištenje ovih korisničkih imena i šifara je zabranjeo.",
        "mailmypassword": "Poništi lozinku",
        "passwordreset-emailtext-ip": "Neko (vjerovatno Vi, s IP adrese $1) je zatražio podsjetnik Vaših detalja računa za {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun korisnika je|računi korisnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena šifra|Ove privremene šifre}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu šifru. Ako je neko drugi napravio ovaj zahtjev, ili ako ste se sjetili Vaše početne šifre, a ne želite je promijeniti, možete zanemariti ovu poruku i nastaviti koristiti staru šifru.",
        "passwordreset-emailtext-user": "Korisnik $1 na {{SITENAME}} je zatražio podsjetnik o detaljima Vašeg računa za {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|korisnički račun je|korisnički računi su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena šifra|Ove privremene šifre}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu šifru. Ako je neko drugi napravio ovaj zahtjev, ili ako ste se sjetili Vaše originalne šifre, a ne želite je više promijeniti, možete zanemariti ovu poruku i nastaviti koristiti staru šifru.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena šifra: \n$2",
-       "passwordreset-emailsent": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre će vam biti poslan na vašu adresu e-pošte.",
+       "passwordreset-emailsentemail": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre će vam biti poslan na vašu adresu e-pošte.",
        "passwordreset-emailsent-capture": "Poslan je podsjetnik preko e-pošte (prikazano ispod).",
        "passwordreset-emailerror-capture": "E-poruka za resetiranje lozinke, prikazano ispod, poslana je, ali slanje {{GENDER:$2|korisniku|korisnici}} nije uspjelo: $1",
        "changeemail": "Promjena ili uklanjanje e-adrese",
        "shown-title": "Pokaži $1 {{PLURAL:$1|rezultat|rezultata}} po stranici",
        "viewprevnext": "Pogledaj ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Postoji stranica pod nazivom \"[[:$1]]\" na ovoj wiki'''",
-       "searchmenu-new": "<strong>Napravi stranicu \"[[:$1]]\" na ovoj wiki!</strong> {{PLURAL:$2|0=|Pogledajte također straniu pronađenu vašom pretragom.|Pogledajte također i vaše rezultate pretrage.}}",
+       "searchmenu-new": "<strong>Napravi stranicu \"[[:$1]]\" na ovoj wiki!</strong> {{PLURAL:$2|0=|Pogledajte također stranicu pronađenu vašom pretragom.|Pogledajte također i vaše rezultate pretrage.}}",
        "searchprofile-articles": "Stranice sadržaja",
        "searchprofile-images": "Multimedija",
        "searchprofile-everything": "Sve",
        "search-section": "(sekcija $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(podudara se sadržaj datoteke)",
-       "search-suggest": "Da li ste mislili: $1",
+       "search-suggest": "Jeste li mislili: $1",
        "search-rewritten": "Prikazujem rezultate za $1. Umjesto toga potraži $2.",
        "search-interwiki-caption": "Srodni projekti",
        "search-interwiki-default": "$1 rezultati:",
        "prefs-watchlist-edits-max": "Najveći broj: 1000",
        "prefs-watchlist-token": "Žeton praćenih članaka:",
        "prefs-misc": "Ostala podešavanja",
-       "prefs-resetpass": "Promijeni šifru",
+       "prefs-resetpass": "Promijeni lozinku",
        "prefs-changeemail": "Promijeni ili ukloni adresu e-pošte",
        "prefs-setemail": "Postavite e-mail adresu",
        "prefs-email": "Opcije e-pošte",
        "contributions": "Doprinosi {{GENDER:$1|korisnika|korisnice|korisnika}}",
        "contributions-title": "Doprinosi korisnika $1",
        "mycontris": "Doprinosi",
+       "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Korisnički račun \"$1\" nije registrovan.",
        "nocontribs": "Nisu nađene promjene koje zadovoljavaju ove uslove.",
        "sp-contributions-blocked-notice-anon": "Ova IP adresa je trenutno blokirana.\nPosljednje stavke zapisnika blokiranja možete pogledati ispod:",
        "sp-contributions-search": "Pretraži doprinose",
        "sp-contributions-username": "IP adresa ili korisničko ime:",
-       "sp-contributions-toponly": "Prikaži samo izmjene koje su posljednje revizije",
+       "sp-contributions-toponly": "Prikaži samo najnovije izmjene",
        "sp-contributions-newonly": "Prikaži samo izmjene kojima su napravljene nove stranice",
        "sp-contributions-submit": "Traži",
        "whatlinkshere": "Šta vodi ovamo",
        "movenosubpage": "Ova stranica nema podstranica.",
        "movereason": "Razlog:",
        "revertmove": "vrati",
-       "delete_and_move": "Obriši i premjesti",
        "delete_and_move_text": "==Potebno brisanje==\nOdredišna stranica \"[[:$1]]\" već postoji.\nDa li je želite obrisati kako bi ste mogli izvršiti premještanje?",
        "delete_and_move_confirm": "Da, obriši stranicu",
        "delete_and_move_reason": "Obrisano da bi se napravio prostor za premještanje iz \"[[$1]]\"",
index 9cc6cd1..41e9f71 100644 (file)
@@ -52,7 +52,9 @@
                        "Pginer",
                        "Eduardo Martinez",
                        "Matma Rex",
-                       "KRLS"
+                       "KRLS",
+                       "Jaumeortola",
+                       "Kippelboy"
                ]
        },
        "tog-underline": "Subratlla els enllaços:",
@@ -87,6 +89,7 @@
        "tog-watchlisthidebots": "Amaga de la llista de seguiment les edicions fetes per usuaris bots",
        "tog-watchlisthideminor": "Amaga les edicions menors de la llista de seguiment",
        "tog-watchlisthideliu": "Amaga a la llista les edicions d'usuaris registrats",
+       "tog-watchlistreloadautomatically": "Recarrega la llista de seguiment automàticament sempre que canviï un filtre (cal JavaScript)",
        "tog-watchlisthideanons": "Amaga a la llista les edicions d'usuaris anònims",
        "tog-watchlisthidepatrolled": "Amaga edicions patrullades de la llista de seguiment",
        "tog-watchlisthidecategorization": "Amaga la categorització de les pàgines",
        "underline-default": "Per defecte del navegador",
        "editfont-style": "Estil de lletra en edició:",
        "editfont-default": "Per defecte del navegador",
-       "editfont-monospace": "Font monoespaiada",
-       "editfont-sansserif": "Font de pal sec",
+       "editfont-monospace": "Lletra monoespaiada",
+       "editfont-sansserif": "Lletra de pal sec",
        "editfont-serif": "Lletra amb gràcia",
        "sunday": "diumenge",
        "monday": "dilluns",
        "morenotlisted": "Aquesta llista no és completa.",
        "mypage": "Pàgina",
        "mytalk": "Discussió",
-       "anontalk": "Discussió d'aquesta IP",
+       "anontalk": "Discussió",
        "navigation": "Navegació",
        "and": "&#32;i",
        "qbfind": "Cerca",
        "privacy": "Política de privadesa",
        "privacypage": "Project:Política de privadesa",
        "badaccess": "Error de permisos",
-       "badaccess-group0": "No teniu permís per a executar l'acció que heu soŀlicitat.",
-       "badaccess-groups": "L'acció que heu soŀlicitat es limita als usuaris {{PLURAL:$2|del grup|dels grups}}: $1.",
+       "badaccess-group0": "No teniu permís per a executar l'acció que heu solicitat.",
+       "badaccess-groups": "L'acció que heu solicitat es limita als usuaris {{PLURAL:$2|del grup|dels grups}}: $1.",
        "versionrequired": "Cal la versió $1 del MediaWiki",
-       "versionrequiredtext": "Cal la versió $1 del MediaWiki per a utilitzar aquesta pàgina. Vegeu [[Special:Version]]",
+       "versionrequiredtext": "Cal la versió $1 del MediaWiki per a utilitzar aquesta pàgina. Vegeu [[Special:Version]].",
        "ok": "D’acord",
        "pagetitle": "$1 - {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "nstab-category": "Categoria",
        "mainpage-nstab": "Pàgina principal",
        "nosuchaction": "No es reconeix aquesta operació",
-       "nosuchactiontext": "L'acció especificada per la URL no és vàlida.\nPotser heu escrit malament la URL o heu seguit un enllaç incorrecte.\nAixò també pot ser causat per un error al programari utilitzat pel projecte {{SITENAME}}.",
+       "nosuchactiontext": "L'acció especificada per l'URL no és vàlida.\nPotser heu escrit malament l'URL o heu seguit un enllaç incorrecte.\nAixò també pot ser causat per un error en el programari utilitzat pel projecte {{SITENAME}}.",
        "nosuchspecialpage": "No es troba la pàgina especial que busqueu",
        "nospecialpagetext": "<strong>La pàgina especial que demaneu no és vàlida.</strong>\n\nVegeu la llista de pàgines especials a [[Special:SpecialPages]].",
        "error": "Error",
        "databaseerror-function": "Funció: $1",
        "databaseerror-error": "Error:$1",
        "laggedslavemode": "Avís: La pàgina podria mancar de modificacions recents.",
-       "readonly": "La base de dades es troba bloquejada",
+       "readonly": "La base de dades es bloquejada",
        "enterlockreason": "Escriviu una raó pel bloqueig, així com una estimació de quan tindrà lloc el desbloqueig",
        "readonlytext": "La base de dades està temporalment bloquejada segurament per tasques de manteniment, després de les quals es tornarà a la normalitat.\n\nL'administrador que l'ha bloquejada ha donat aquesta explicació: $1",
        "missing-article": "La base de dades no ha trobat el text d'una pàgina que hauria d'haver trobat, anomenada «$1» $2.\n\nNormalment això passa perquè s'ha seguit una diferència desactualitzada o un enllaç d'historial a una pàgina que s'ha suprimit.\n\nSi no fos el cas, podríeu haver trobat un error en el programari.\nAviseu-ho llavors a un [[Special:ListUsers/sysop|administrador]], deixant-li clar l'adreça URL causant del problema.",
        "filedeleteerror": "No s'ha pogut eliminar el fitxer «$1».",
        "directorycreateerror": "No s'ha pogut crear el directori «$1».",
        "directoryreadonlyerror": "El directori \"$1\" és de només lectura.",
-       "directorynotreadableerror": "El directori \"$1\" no és llegible",
+       "directorynotreadableerror": "El directori \"$1\" no és llegible.",
        "filenotfound": "No s'ha pogut trobar el fitxer «$1».",
        "unexpected": "S'ha trobat un valor imprevist: «$1»=«$2».",
-       "formerror": "Error: no s'ha pogut enviar les dades del formulari",
-       "badarticleerror": "Aquesta operació no es pot dur a terme en aquesta pàgina",
+       "formerror": "Error: No s'han pogut enviar les dades del formulari.",
+       "badarticleerror": "Aquesta operació no es pot dur a terme en aquesta pàgina.",
        "cannotdelete": "No s'ha pogut suprimir la pàgina o fitxer «$1».\nPotser ja l'ha suprimit algú altre.",
        "cannotdelete-title": "No es pot suprimir la pàgina \" $1 \"",
        "delete-hook-aborted": "Un «hook» ha interromput la supressió.\nNo ha donat cap explicació.",
        "invalidtitle-unknownnamespace": "Títol no vàlid amb espai de noms desconegut de número «$1» i text «$2»",
        "exception-nologin": "No has iniciat sessió",
        "exception-nologin-text": "Cal que inicieu una sessió per accedir a aquesta pàgina o acció.",
-       "exception-nologin-text-manual": "Si us plau, $1 per poder accedir a aquesta pàgina o acció.",
+       "exception-nologin-text-manual": "Si us plau, $1 per poder accedir a aquesta pàgina o acció.",
        "virus-badscanner": "Mala configuració: antivirus desconegut: ''$1''",
        "virus-scanfailed": "escaneig fallit (codi $1)",
        "virus-unknownscanner": "antivirus desconegut:",
        "userlogin-signwithsecure": "Connexió segura",
        "yourdomainname": "El vostre domini",
        "password-change-forbidden": "No podeu canviar les contrasenyes en aquest wiki.",
-       "externaldberror": "Hi ha hagut una fallida en el servidor d'autenticació externa de la base de dades i no teniu permís per a actualitzar el vostre compte d'accès extern.",
+       "externaldberror": "Hi ha hagut un error en la base de dades d'autenticació o bé no teniu permís per a actualitzar el vostre compte extern.",
        "login": "Inici de sessió",
        "nav-login-createaccount": "Inicia una sessió / crea un compte",
        "userlogin": "Inicia una sessió / crea un compte",
        "loginerror": "Error d'inici de sessió",
        "createacct-error": "Error de creació de compte",
        "createaccounterror": "No s'ha pogut crear el compte: $1",
-       "nocookiesnew": "S'ha creat el compte d'usuari, però no esteu enregistrat. El projecte {{SITENAME}} usa galetes per enregistrar els usuaris. Si us plau activeu-les, per a poder enregistrar-vos amb el vostre nom d'usuari i la clau.",
+       "nocookiesnew": "S'ha creat el compte d'usuari, però no s'ha iniciat la sessió.\nEl projecte {{SITENAME}} usa galetes per a iniciar la sessió d'usuari. \nTeniu les galetes desactivades. \nActiveu-les per a poder iniciar la sessió amb el nou nom d'usuari i la nova clau.",
        "nocookieslogin": "El programari {{SITENAME}} utilitza galetes per enregistrar usuaris. Teniu les galetes desactivades. Activeu-les i torneu a provar.",
        "nocookiesfornew": "No s'ha creat el compte d'usuari, ja que no es podia confirmar el seu origen.\nVerifiqueu que teniu habilitades les galetes al vostre navegador, torneu a carregar aquesta pàgina i intenteu-lo de nou.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
        "wrongpasswordempty": "La contrasenya que s'ha introduït estava en blanc. Torneu-ho a provar.",
        "passwordtooshort": "La contrasenya ha de tenir un mínim {{PLURAL:$1|d'un caràcter|de $1 caràcters}}.",
        "passwordtoolong": "La contrasenya ha de tenir un màxim {{PLURAL:$1|d'un caràcter|de $1 caràcters}}.",
-       "password-name-match": "La contrasenya ha de ser diferent al vostre nom d'usuari.",
+       "passwordtoopopular": "No poden utilitzar-se contrasenyes d'ús habitual. Trieu-ne una més única.",
+       "password-name-match": "La contrasenya ha de ser diferent del vostre nom d'usuari.",
        "password-login-forbidden": "No és permès d'utilitzar aquest nom d'usuari i contrasenya.",
        "mailmypassword": "Restableix la contrasenya",
        "passwordremindertitle": "Nova contrasenya temporal per al projecte {{SITENAME}}",
-       "passwordremindertext": "Algú (vós mateix segurament, des de l'adreça l'IP $1) ha soŀlicitat que us enviéssim una nova contrasenya per a iniciar la sessió al projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si aquesta fou la vostra intenció, ara hauríeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquí {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta soŀlicitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla vostra antiga contrasenya.",
+       "passwordremindertext": "Algú (vós mateix segurament, des de l'adreça IP $1) ha sol·licitat que us enviéssim una nova contrasenya per a iniciar la sessió en el projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si la vostra intenció era aquesta, ara hauríeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquí a {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla contrasenya antiga.",
        "noemail": "No hi ha cap adreça electrònica registrada de l'usuari «$1».",
        "noemailcreate": "Heu d’indicar una adreça electrònica vàlida.",
        "passwordsent": "S'ha enviat una nova contrasenya a l'adreça electrònica registrada per «$1».\nInicieu una sessió després que la rebeu.",
        "accountcreated": "S'ha creat el compte",
        "accountcreatedtext": "S'ha creat el compte d'usuari de [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|discussió]]).",
        "createaccount-title": "Creació d'un compte a {{SITENAME}}",
-       "createaccount-text": "Algú ha creat un compte d'usuari anomenat $2 al projecte {{SITENAME}}\n($4) amb la vostra adreça de correu electrònic. La contrasenya per a l'usuari «$2» és «$3». Hauríeu d'accedir al compte i canviar-vos aquesta contrasenya quan abans millor.\n\nSi no hi teniu cap relació i aquest compte s'ha creat per error, simplement ignoreu el missatge.",
+       "createaccount-text": "Algú ha creat un compte d'usuari anomenat $2 en el projecte {{SITENAME}}\n($4) amb la vostra adreça de correu electrònic. La contrasenya per a l'usuari «$2» és «$3». Hauríeu d'accedir al compte i canviar-vos aquesta contrasenya com més aviat millor.\n\nSi no hi teniu cap relació i aquest compte s'ha creat per error, simplement ignoreu el missatge.",
        "login-throttled": "Heu realitzat massa intents d'accés a la sessió.\nEspereu $1 abans de tornar-ho a provar.",
-       "login-abort-generic": "L'entrada al compte d'usuari no ha reeixit - Abortada",
+       "login-abort-generic": "L'entrada al compte d'usuari no ha reeixit - S'ha interromput.",
        "login-migrated-generic": "S'ha migrat el vostre compte, i el vostre nom d'usuari ja no existeix en aquest wiki.",
        "loginlanguagelabel": "Llengua: $1",
-       "suspicious-userlogout": "S'ha denegat la vostra petició per tancar la sessió ja què sembla que va ser enviada per un navegador defectuós o un proxy cau.",
+       "suspicious-userlogout": "S'ha denegat la vostra petició per a tancar la sessió, ja que sembla que va ser enviada per un navegador defectuós o un servidor intermediari.",
        "createacct-another-realname-tip": "El nom real és opcional.\nSi decidiu proporcionar-lo, s'utilitzarà per a reconèixer a l'usuari el seu treball.",
        "pt-login": "Inicia la sessió",
        "pt-login-button": "Inicia sessió",
        "user-mail-no-addy": "S'ha intentat enviar un missatge de correu electrònic sense adreça.",
        "user-mail-no-body": "Vas intentar enviar un correu electrònic amb un cos buit o excessivament curt.",
        "changepassword": "Canvia la contrasenya",
-       "resetpass_announce": "Per tal de completar l'inici de sessió heu de definir una contrasenya nova.",
+       "resetpass_announce": "Per a completar l'inici de sessió heu de definir una contrasenya nova.",
        "resetpass_text": "<!-- Afegiu-hi un text -->",
        "resetpass_header": "Canvia la contrasenya del compte",
        "oldpassword": "Contrasenya antiga",
        "resetpass_forbidden": "No poden canviar-se les contrasenyes",
        "resetpass-no-info": "Heu d'estar registrats en un compte per a poder accedir directament a aquesta pàgina.",
        "resetpass-submit-loggedin": "Canvia la contrasenya",
-       "resetpass-submit-cancel": "Canceŀla",
+       "resetpass-submit-cancel": "Cancela",
        "resetpass-wrong-oldpass": "Contrasenya actual o temporal no vàlida.\nDeveu haver canviat la vostra contrasenya o demanat una nova contrasenya temporal.",
        "resetpass-recycled": "Restabliu la contrasenya amb un text diferent que el de la contrasenya actual.",
        "resetpass-temp-emailed": "Heu iniciat una sessió amb un codi temporal enviat per correu.\nPer completar l'inici de sessió heu de definir una contrasenya nova a continuació:",
        "passwordreset": "Restablir contrasenya",
        "passwordreset-text-one": "Cal completar aquest formulari per reiniciar la contrasenya",
        "passwordreset-text-many": "{{PLURAL:$1|Ompliu un dels camps per a rebre una contrasenya temporal al vostre correu electrònic.}}",
-       "passwordreset-disabled": "S'ha desactivat el restabliment de contranyes en aquest wiki.",
+       "passwordreset-disabled": "S'ha desactivat el restabliment de contrasenyes en aquest wiki.",
        "passwordreset-emaildisabled": "Les opcions de correu electrònic no estan habilitades en aquest wiki.",
        "passwordreset-username": "Nom d'usuari:",
        "passwordreset-domain": "Domini",
        "passwordreset-emailtext-ip": "Algú (vós mateix segurament, des de l'adreça IP $1) ha demanat una reinicialització de la vostra contrasenya al projecte {{SITENAME}} ($4). {{PLURAL:$3|El següent compte d'usuari està associat|Els següents comptes d'usuari estan associats}} amb aquesta adreça de correu electrònic:\n\n$2\n\n{{PLURAL:$3|Aquesta contrasenya temporal caducarà|Aquestes contrasenyes temporals caducaran}} en {{PLURAL:$5|un dia|$5 dies}}.\nHauríeu d'entrar al compte per a fixar-hi una nova contrasenya al més aviat possible. Si algú que no sou vós és qui ha fet aquesta petició o si heu recordat la contrasenya original i ja no la voleu canviar, podeu ignorar aquest missatge i seguir utilitzant la vostra antiga contrasenya.",
        "passwordreset-emailtext-user": "L'usuari $1 de {{SITENAME}} ha demanat una reinicialització de la vostra contrasenya per al projecte {{SITENAME}} ($4). {{PLURAL:$3|El següent compte d'usuari està associat|Els següents comptes d'usuari estan associats}} amb aquesta adreça de correu electrònic:\n\n$2\n\n{{PLURAL:$3|Aquesta contrasenya temporal caducarà|Aquestes contrasenyes temporals caducaran}} en {{PLURAL:$5|un dia|$5 dies}}.\nHauríeu d'entrar ara per fixar una nova contrasenya. Si algú que no sou vós és qui ha fet aquesta petició o si heu recordat la contrasenya original i ja no la voleu canviar, podeu ignorar aquest missatge i seguir utilitzant la vostra antiga contrasenya.",
        "passwordreset-emailelement": "Nom d'usuari: \n$1\n\nContrasenya temporal: \n$2",
-       "passwordreset-emailsent": "Si aquesta és una adreça electrònica registrada amb el vostre compte, s’hi enviarà un missatge de restabliment de contrasenya.",
+       "passwordreset-emailsentemail": "Si aquesta és una adreça electrònica registrada amb el vostre compte, s’hi enviarà un missatge de restabliment de contrasenya.",
        "passwordreset-emailsent-capture": "S'ha enviat un correu electrònic de reinicialització de contrasenya, tal com es mostra a continuació.",
        "passwordreset-emailerror-capture": "S'ha generat un correu electrònic de renovació de contrasenya, que es mostra a continuació, però ha fallat l'enviament a {{GENDER:$2:l'usuari|la usuària}}: $1",
        "changeemail": "Canvia o elimina l’adreça electrònica",
        "changeemail-no-info": "Heu d'entrar en un compte d'usuari per accedir directament a aquesta pàgina.",
        "changeemail-oldemail": "Adreça electrònica actual:",
        "changeemail-newemail": "Adreça electrònica nova:",
+       "changeemail-newemail-help": "Aquest camp s'ha de deixar en blanc si voleu eliminar la vostra adreça de correu electrònic. Si s'elimina l'adreça electrònica, no podreu restablir la contrasenya si l'oblideu i no rebreu correus electrònics des d'aquest wiki.",
        "changeemail-none": "(cap)",
        "changeemail-password": "La vostra contrasenya a {{SITENAME}}:",
        "changeemail-submit": "Canvia de correu electrònic",
        "note": "'''Nota:'''",
        "previewnote": "'''Recorda que això és només una previsualització.'''\nEls vostres canvis encara no s'han desat!",
        "continue-editing": "Aneu a l'àrea d'edició",
-       "previewconflict": "Aquesta previsualització reflecteix, a l'àrea\nd'edició superior, el text tal com apareixerà si trieu desar-lo.",
+       "previewconflict": "Aquesta previsualització reflecteix, a l'àrea\nd'edició superior, el text tal com apareixerà si trieu desar-lo.",
        "session_fail_preview": "'''No s'ha pogut processar la vostra modificació a causa d'una pèrdua de dades de la sessió.\nSi us plau, proveu-ho una altra vegada. Si continués sense funcionar, proveu de [[Special:UserLogout|finalitzar la sessió]] i torneu a iniciar-ne una.'''",
        "session_fail_preview_html": "'''Ho sentim, no s'han pogut processar les vostres modificacions a causa d'una pèrdua de dades de la sessió.'''\n\n''Com que el projecte {{SITENAME}} té habilitat l'ús de codi HTML cru, s'ha amagat la previsualització com a prevenció contra atacs mitjançant codis JavaScript.''\n\n'''Si es tracta d'una contribució legítima, si us plau, intenteu-ho una altra vegada. Si continua havent-hi problemes, [[Special:UserLogout|finalitzeu la sessió]] i torneu a iniciar-ne una.'''",
        "token_suffix_mismatch": "'''S'ha rebutjat la vostra modificació perquè el vostre client ha fet malbé els caràcters de puntuació en el testimoni d'edició. S'ha rebutjat la modificació per a evitar la corrupció del text de la pàgina. Açò passa a vegades quan s'utilitza un servei web de servidor intermediari anònim amb problemes.'''",
        "explainconflict": "Algú més ha canviat aquesta pàgina des que l'heu editada.\nL'àrea de text superior conté el text de la pàgina com existeix actualment.\nEls vostres canvis es mostren en l'àrea de text inferior.\nHaureu de fusionar els vostres canvis en el text existent.\n'''Només''' el text de l'àrea superior es desarà quan premeu el botó «{{int:savearticle}}».",
        "yourtext": "El vostre text",
        "storedversion": "Versió emmagatzemada",
-       "nonunicodebrowser": "'''Alerta: El vostre navegador no és compatible amb unicode.'''\nS'ha activat una alternativa que us permetrà modificar pàgines amb seguretat: el caràcters que no són ASCII us apareixeran en la caixa d'edició com a codis hexadecimals.",
+       "nonunicodebrowser": "<strong>Alerta: El vostre navegador no és compatible amb Unicode.</strong>\nS'ha activat una alternativa que us permetrà modificar pàgines amb seguretat: els caràcters que no són ASCII us apareixeran en la caixa d'edició com a codis hexadecimals.",
        "editingold": "'''AVÍS: Esteu editant una revisió desactualitzada de la pàgina.\nSi la deseu, es perdran els canvis que hàgiu fet des de llavors.'''",
        "yourdiff": "Diferències",
        "copyrightwarning": "Si us plau, tingueu en compte que totes les contribucions per al projecte {{SITENAME}} es consideren com a publicades sota els termes de la llicència $2 (vegeu-ne més detalls a $1). Si no desitgeu la modificació i distribució lliure dels vostres escrits sense el vostre consentiment, no els poseu ací.<br />\nA més a més, en enviar el vostre text, doneu fe que és vostra l'autoria, o bé de fonts en el domini públic o recursos lliures similars. Heu de saber que aquest '''no''' és el cas de la majoria de pàgines que hi ha a Internet.\n'''No feu servir textos amb drets d'autor sense permís!'''",
        "permissionserrors": "Error de permisos",
        "permissionserrorstext": "No teniu permisos per a fer-ho, {{PLURAL:$1|pel següent motiu|pels següents motius}}:",
        "permissionserrorstext-withaction": "No teniu permís per a $2, {{PLURAL:$1|pel motiu següent|pels motius següents}}:",
+       "contentmodelediterror": "No podeu modificar aquesta revisió perquè el seu model de contingut és <code>$1</code>, i el model de contingut actual de la pàgina és <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Avís: esteu creant una pàgina que s'ha suprimit prèviament.'''\n\nHauríeu de considerar si és realment necessari continuar editant aquesta pàgina.\nA continuació s'ofereix el registre de supressions i de reanomenaments de la pàgina:",
        "moveddeleted-notice": "S'ha suprimit aquesta pàgina.\nA continuació us mostrem com a referència el registre d'esborraments i reanomenaments de la pàgina.",
        "moveddeleted-notice-recent": "S’ha suprimit aquesta pàgina recentment (en les últimes 24 hores).\nA continuació us mostrem com a referència el registre de supressions i reanomenaments de la pàgina.",
        "defaultmessagetext": "Missatge per defecte",
        "content-failed-to-parse": "Ha fallat l'anàlisi del contingut de $2 per al model $1: $3",
        "invalid-content-data": "Dades de contingut no vàlides",
-       "content-not-allowed-here": "No Ã©s permés el contingut \"$1\" a la pàgina [[$2]]",
-       "editwarning-warning": "Si sortiu d'aquesta pàgina perdreu tots els canvis que hàgiu fet.\nSi teniu un compte d'usuari, podeu eliminar aquest avís a la secció «{{int:prefs-editing}}» de les vostres preferències.",
+       "content-not-allowed-here": "No Ã©s permès el contingut \"$1\" a la pàgina [[$2]]",
+       "editwarning-warning": "Si sortiu d'aquesta pàgina, perdreu tots els canvis que hàgiu fet.\nSi teniu un compte d'usuari, podeu eliminar aquest avís en la secció «{{int:prefs-editing}}» de les vostres preferències.",
        "editpage-notsupportedcontentformat-title": "No s'admet el format del contingut",
        "editpage-notsupportedcontentformat-text": "No s'admet el format del contingut $1 pel model de contingut $2.",
        "content-model-wikitext": "wikitext",
        "expensive-parserfunction-category": "Pàgines amb massa crides de parser function",
        "post-expand-template-inclusion-warning": "Avís: La mida d'inclusió de la plantilla és massa gran.\nNo s'inclouran algunes plantilles.",
        "post-expand-template-inclusion-category": "Pàgines on s'excedeix la mida d'inclusió de les plantilles",
-       "post-expand-template-argument-warning": "Avís: Aquesta pàgina conté com a mínim un argument de plantilla que té una mida d'expansió massa llarga.\nSe n'han omès els arguments.",
+       "post-expand-template-argument-warning": "Avís: Aquesta pàgina conté com a mínim un argument de plantilla que té una mida d'expansió massa gran.\nSe n'han omès els arguments.",
        "post-expand-template-argument-category": "Pàgines que contenen arguments de plantilla que s'han omès",
        "parser-template-loop-warning": "S'ha detectat un bucle de plantilla: [[$1]]",
        "parser-template-recursion-depth-warning": "S'ha excedit el límit de recursivitat de plantilles ($1)",
        "parser-unstrip-recursion-limit": "S'ha excedit el límit ($1) de recursivitat no desmuntable",
        "converter-manual-rule-error": "Error detectat a la norma de conversió de llengua manual",
        "undo-success": "Pot desfer-se la modificació. Si us plau, reviseu la comparació de sota per a assegurar-vos que és el que voleu fer; llavors deseu els canvis per a finalitzar la desfeta de l'edició.",
-       "undo-failure": "No pot desfer-se la modificació perquè hi ha edicions entre mig que hi entren en conflicte.",
+       "undo-failure": "No pot desfer-se la modificació perquè hi ha edicions intermèdies en conflicte.",
        "undo-norev": "No s'ha pogut desfer l'edició perquè no existeix o s'ha suprimit.",
        "undo-nochange": "Sembla que ja s'ha desfet la modificació.",
        "undo-summary": "Es desfà la revisió $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussió]])",
        "undo-summary-username-hidden": "Desfés la revisió $1 d'un usuari ocult",
        "cantcreateaccounttitle": "No es pot crear el compte",
        "cantcreateaccount-text": "[[User:$3|$3]] ha bloquejat la creació de comptes des d'aquesta adreça IP ('''$1''').\n\nEl motiu donat per $3 és ''$2''",
-       "cantcreateaccount-range-text": "La creació de comptes des de les adreces IP en el rang '''$1''', que inclou la vostra adreça IP ('''$4'''), ha esta blocada per [[User:$3|$3]].\n\nEl motiu donat per $3 és ''$2''",
+       "cantcreateaccount-range-text": "La creació de comptes des de les adreces IP en el rang '''$1''', que inclou la vostra adreça IP ('''$4'''), ha estat blocada per [[User:$3|$3]].\n\nEl motiu donat per $3 és ''$2''",
        "viewpagelogs": "Visualitza els registres d'aquesta pàgina",
        "nohistory": "No hi ha un historial de revisions per a aquesta pàgina.",
        "currentrev": "Revisió actual",
        "rev-deleted-no-diff": "No podeu veure aquesta comparativa perquè s'ha '''suprimit''' una de les versions.\nPotser trobareu detalls al [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registre d'esborrats].",
        "rev-suppressed-no-diff": "No podeu veure aquesta diferència perquè s'ha '''suprimit''' una de les revisions.",
        "rev-deleted-unhide-diff": "S'ha '''eliminat''' una de les revisions d'aquesta comparativa.\nVegeu-ne més detalls al [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registre de supressions].\nEncara podeu [$1 veure aquesta comparativa] si així ho desitgeu.",
-       "rev-suppressed-unhide-diff": "S¡ha '''suprimit''' una de les revisions d'aquesta comparativa.\nPodeu veure'n més detalls al [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registre de supressions].\nPodeu seguir [$1 veient aquesta comparativa] si així ho desitgeu.",
+       "rev-suppressed-unhide-diff": "S'ha <strong>suprimit</strong> una de les revisions d'aquesta comparativa.\nPodeu veure'n més detalls en el [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registre de supressions].\nEncara podeu [$1 veure aquesta comparativa] si així ho desitgeu.",
        "rev-deleted-diff-view": "S'ha '''suprimit'' una de les revisions d'aquesta comparativa.\nPodeu veure aquesta comparativa; poden haver-hi més detalls al [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registre d'esborraments].",
        "rev-suppressed-diff-view": "S'ha '''suprimit'' una de les revisions d'aquesta comparativa.\nVegeu-ne més detalls al [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registre de supressions].",
        "rev-delundel": "mostra/amaga",
        "mergehistory-empty": "No pot fusionar-se cap revisió.",
        "mergehistory-done": "{{PLURAL:$3|S’ha|S’han}} fusionat correctament $3 {{PLURAL:$3|revisió|revisions}} de $1 a [[:$2]].",
        "mergehistory-fail": "No s'ha pogut realitzar la fusió de l'historial, comproveu la pàgina i els paràmetres horaris.",
-       "mergehistory-fail-toobig": "No s'ha pogut realitzar la fusió de l'historial perquè es mourien més del limit de $1 {{PLURAL:$1|revisió|revisions}}.",
+       "mergehistory-fail-toobig": "No s'ha pogut fer la fusió de l'historial perquè es mourien més del límit de $1 {{PLURAL:$1|revisió|revisions}}.",
        "mergehistory-no-source": "La pàgina d'origen $1 no existeix.",
        "mergehistory-no-destination": "La pàgina de destinació $1 no existeix.",
        "mergehistory-invalid-source": "La pàgina d'origen ha de tenir un títol vàlid.",
        "rows": "Files",
        "columns": "Columnes",
        "searchresultshead": "Preferències de la cerca",
-       "stub-threshold": "Límit per a formatar l'enllaç com <a href=\"#\" class=\"stub\">esborrany</a> (en octets):",
+       "stub-threshold": "Límit per a formatar com a enllaç a esborrany ($1):",
        "stub-threshold-sample-link": "mostra",
        "stub-threshold-disabled": "Inhabilitat",
        "recentchangesdays": "Dies a mostrar en els canvis recents:",
        "prefs-help-recentchangescount": "Inclou els canvis recents, els historials de pàgines i els registres.",
        "prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, així que no la compartiu.\n[[Special:ResetTokens|Cliqueu aquí si voleu restaurar-la]].",
        "savedprefs": "S’han desat les vostres preferències.",
+       "savedrights": "S'han desat els permisos d'usuari de {{GENDER:$1|$1}}.",
        "timezonelegend": "Fus horari:",
        "localtime": "Hora local:",
        "timezoneuseserverdefault": "Utilitza l'hora per defecte del wiki ($1)",
        "userrights-unchangeable-col": "Grups que no podeu canviar",
        "userrights-irreversible-marker": "$1*",
        "userrights-conflict": "Conflicte de canvis dels permisos d'usuari. Reviseu i confirmeu els canvis.",
-       "userrights-removed-self": "Heu suprimit els propis permisos correctament. Per tant, ja no podreu tornar a accedir a aquesta pàgina.",
+       "userrights-removed-self": "Heu suprimit els vostres propis permisos correctament. Per tant, ja no podeu tornar a accedir a aquesta pàgina.",
        "group": "Grup:",
        "group-user": "Usuaris",
        "group-autoconfirmed": "Usuaris autoconfirmats",
        "right-upload": "Carregar fitxers",
        "right-reupload": "Carregar al damunt d'un fitxer existent",
        "right-reupload-own": "Carregar al damunt d'un fitxer que havia carregat el propi usuari",
-       "right-reupload-shared": "Carregar localment fitxers amb un nom usat en el repostori multimèdia compartit",
+       "right-reupload-shared": "Sobreescriure localment fitxers presents al repositori multimèdia compartit",
        "right-upload_by_url": "Carregar un fitxer des de l'adreça URL",
        "right-purge": "Purgar la memòria cau del lloc web sense pàgina de confirmació",
        "right-autoconfirmed": "Modificar pàgines semiprotegides",
        "right-editsemiprotected": "Edita les pàgines protegides com «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "Editar el model de contingut d'una pàgina",
        "right-editinterface": "Editar la interfície d'usuari",
-       "right-editusercssjs": "Editar els fitxers de configuració CSS i JS d'altres usuaris",
-       "right-editusercss": "Editar els fitxers de configuració CSS d'altres usuaris",
-       "right-edituserjs": "Editar els fitxers de configuració JS d'altres usuaris",
-       "right-editmyusercss": "Editeu els fitxers CSS propis",
-       "right-editmyuserjs": "Editeu els propis fitxers de JavaScript",
+       "right-editusercssjs": "Modificar els fitxers CSS i JavaScript d'altres usuaris",
+       "right-editusercss": "Modificar els fitxers CSS d'altres usuaris",
+       "right-edituserjs": "Modificar els fitxers JavaScript d'altres usuaris",
+       "right-editmyusercss": "Modificar els vostres fitxers d'usuari CSS",
+       "right-editmyuserjs": "Modificar els vostres fitxers d'usuari JavaScript",
        "right-viewmywatchlist": "Mostra la llista de seguiment pròpia",
        "right-editmywatchlist": "Edita la llista de seguiment pròpia. Tingueu en compte que algunes accions encara afegiran pàgina fins i tot sense aquest permís.",
        "right-viewmyprivateinfo": "Mostra les dades privades (p. ex., adreça electrònica o nom real)",
        "right-siteadmin": "Blocar i desblocar la base de dades",
        "right-override-export-depth": "Exportar pàgines incloent aquelles enllaçades fins a una fondària de 5",
        "right-sendemail": "Enviar missatges de correu electrònic a altres usuaris",
-       "right-passwordreset": "Veure les soŀlicituds de restabliment de contrasenya per correu electrònic",
+       "right-passwordreset": "Veure les solicituds de restabliment de contrasenya per correu electrònic",
        "right-managechangetags": "Crear i suprimir [[Special:Tags|etiquetes]] des de la base de dades",
        "right-applychangetags": "Aplica les [[Special:Tags|etiquetes]] juntament amb els canvis propis",
        "right-changetags": "Afegeix i suprimeix [[Special:Tags|etiquetes]] en revisions individuals i entrades de registre",
        "action-undelete": "recuperar aquesta pàgina",
        "action-suppressrevision": "revisar i recuperar aquesta revisió oculta",
        "action-suppressionlog": "visualitzar aquest registre privat",
-       "action-block": "blocar aquest usuari per a què no pugui editar",
+       "action-block": "blocar aquest usuari perquè no pugui editar",
        "action-protect": "canviar els nivells de protecció d'aquesta pàgina",
        "action-rollback": "desfer ràpidament les modificacions de l'últim usuari que va editar una determinada pàgina",
        "action-import": "importa pàgines des d'un altre wiki",
        "action-editcontentmodel": "editar el model de contingut d'una pàgina",
        "action-managechangetags": "crear i suprimir etiquetes de la base de dades",
        "action-applychangetags": "aplica les etiquetes juntament amb els canvis",
-       "action-changetags": "afegeix i elimina etiquetes a les revisions y entrades de registre individuals",
+       "action-changetags": "afegeix i elimina etiquetes a les revisions i les entrades de registre individuals",
        "nchanges": "$1 {{PLURAL:$1|canvi|canvis}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|des de la darrera visita}}",
        "enhancedrc-history": "historial",
        "recentchanges-legend-heading": "'''Llegenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vegeu també la [[Special:NewPages|llista de pàgines noves]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Mostra",
        "rcnotefrom": "A sota hi ha {{PLURAL:$5|el canvi|els canvis}} a partir de <strong>$3, $4</strong> (fins a <strong>$1</strong>).",
        "rclistfrom": "Mostra els canvis nous des de $3, $2",
        "rcshowhideminor": "$1 edicions menors",
        "filepageexists": "La pàgina de descripció d'aquest fitxer ja ha estat creada (<strong>[[:$1]]</strong>), però de moment no hi ha cap fitxer amb aquest nom. La descripció que heu posat no apareixerà a la pàgina de descripció. Si voleu que hi aparegui haureu d'editar-la manualment.\n[[$1|thumb]]",
        "fileexists-extension": "Ja existeix un fitxer amb un nom semblant: [[$2|thumb]]\n* Nom del fitxer que es puja: <strong>[[:$1]]</strong>\n* Nom del fitxer existent: <strong>[[:$2]]</strong>\nPotser voleu fer servir un nom més fàcil de distingir?",
        "fileexists-thumbnail-yes": "Aquest fitxer sembla ser una imatge en mida reduïda (<em>miniatura</em>). [[$1|thumb]]\nComproveu si us plau el fitxer <strong>[[:$1]]</strong>.\nSi el fitxer és la mateixa imatge a mida original, no cal carregar cap miniatura més.",
-       "file-thumbnail-no": "El nom del fitxer comença per <strong>$1</strong>.\nSembla ser una imatge de mida reduïda ''(miniatura)''.\nSi teniu la imatge en resolució completa, pugeu-la, sinó mireu de canviar-li el nom, si us plau.",
+       "file-thumbnail-no": "El nom del fitxer comença per <strong>$1</strong>.\nSembla una imatge de mida reduïda <em>(miniatura)</em>.\nSi teniu la imatge en alta resolució, pugeu-la. Si no, mireu de canviar-li el nom.",
        "fileexists-forbidden": "Ja hi existeix un fitxer amb aquest nom i no es pot sobreescriure.\nSi us plau, torneu enrere i carregueu aquest fitxer sota un altre nom. [[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "Ja hi ha un fitxer amb aquest nom al fons comú de fitxers.\nSi us plau, si encara desitgeu carregar el vostre fitxer, torneu enrera i carregueu-ne una còpia amb un altre nom. [[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Ja hi ha un fitxer amb aquest nom en el fons comú de fitxers.\nSi encara voleu pujar el fitxer, torneu enrere i pugeu-ne una còpia amb un altre nom. [[File:$1|thumb|center|$1]]",
        "file-exists-duplicate": "Aquest fitxer és un duplicat {{PLURAL:$1|del fitxer |dels següents fitxers:}}",
        "file-deleted-duplicate": "S'ha suprimit anteriorment un fitxer idèntic a aquest ([[:$1]]). Hauríeu de comprovar el registre de supressions del fitxer abans de tornar-lo a carregar.",
        "file-deleted-duplicate-notitle": "Un fitxer idèntic a aquest fitxer havia estat suprimit abans, i també el títol. Hauríeu de demanar a algú que pugui veure les dades suprimides del fitxer que revisi la situació abans de procedir a tornar a carregar-lo.",
        "upload-scripted-pi-callback": "No es poden carregar arxius que continguin instruccions de processament de pàgines d'estil XML",
        "uploaded-script-svg": "S’ha trobat l’element programable «$1» al fitxer SVG carregat.",
        "uploaded-hostile-svg": "S’ha trobat codi CSS no segur a l’element d’estil del fitxer SVG carregat.",
-       "uploaded-event-handler-on-svg": "No es permet establir els atributs de gestió d’events <code>$1=\"$2\"</code> als fitxers SVG.",
+       "uploaded-event-handler-on-svg": "No es permet establir els atributs de gestió d’esdeveniments <code>$1=\"$2\"</code> en fitxers SVG.",
        "uploaded-href-attribute-svg": "No es permeten els atributs d’«href» <code>&lt;$1 $2=\"$3\"&gt;</code> amb objectius no locals (p. ex., http:// i javascript:) als fitxers SVG.",
        "uploaded-href-unsafe-target-svg": "S’ha trobat un element «href» amb un objectiu no segur <code>&lt;$1 $2=\"$3\"&gt;</code> al fitxer SVG carregat.",
        "uploaded-animate-svg": "S'ha trobat l'etiqueta «animate» que pot estar canviant l'href mitjançant l'atribut <code>&lt;$1 $2=\"$3\"&gt;</code> en el fitxer SVG carregat.",
        "upload-file-error-text": "S'ha produït un error de càrrega desconegut quan s'intentava crear un fitxer temporal al servidor. Poseu-vos en contacte amb un [[Special:ListUsers/sysop|administrador]].",
        "upload-misc-error": "S'ha produït un error de càrrega desconegut",
        "upload-misc-error-text": "S'ha produït un error desconegut durant la càrrega. Verifiqueu que l'URL és vàlid i accessible, i torneu-ho a provar. Si el problema persisteix, adreceu-vos a un [[Special:ListUsers/sysop|administrador]].",
-       "upload-too-many-redirects": "LURL conté massa redireccions",
+       "upload-too-many-redirects": "L'URL conté massa redireccions",
        "upload-http-error": "Ha ocorregut un error HTTP: $1",
        "upload-copy-upload-invalid-domain": "Les càrregues de còpia no són disponibles des d'aquest domini.",
        "upload-dialog-title": "Carrega un fitxer",
        "backend-fail-stream": "No s'ha pogut transmetre el fitxer $1.",
        "backend-fail-backup": "No s'ha pogut fer una còpia de seguretat del fitxer $1.",
        "backend-fail-notexists": "El fitxer $1 no existeix.",
-       "backend-fail-hashes": "No s'han pogut obtenir els resums dels fitxer per fer-ne comparació.",
+       "backend-fail-hashes": "No s'han pogut obtenir els codis hash dels fitxers per a fer-ne comparació.",
        "backend-fail-notsame": "Ja existeix un fitxer no idèntic a $1.",
        "backend-fail-invalidpath": "$1 no és un camí d'emmagatzemament vàlid.",
        "backend-fail-delete": "No s'ha pogut suprimir el fitxer $1.",
        "backend-fail-batchsize": "El rerefons d'emmagatzemament ha rebut un lot {{PLURAL:$1|d'$1 operació|de $1 operacions}} de fitxer; el límit és $2 {{PLURAL:$2|operació|operacions}}.",
        "backend-fail-usable": "No s'ha pogut llegir ni escriure el fitxer \"$1\" a causa de permisos insuficients o perquè hi manquen directoris/contenidors.",
        "filejournal-fail-dbconnect": "No es pot connectar amb la base de dades per emmagatzemar el backend \"$1\".",
-       "filejournal-fail-dbquery": "No es pot actualitzat la base de dades per a emmagatzemar el backend \"$1\".",
+       "filejournal-fail-dbquery": "No es pot actualitzar la base de dades per a emmagatzemar el backend \"$1\".",
        "lockmanager-notlocked": "No s'ha pogut desbloquejar «$1»; no és bloquejat.",
        "lockmanager-fail-closelock": "No s'ha pogut bloquejar el fitxer per «$1».",
        "lockmanager-fail-deletelock": "No s'ha pogut suprimir el fitxer de bloqueig per «$1».",
        "lockmanager-fail-svr-release": "No s'han pogut alliberar els bloquejos al servidor $1.",
        "zip-file-open-error": "S'ha trobat un error en obrir l'arxiu ZIP per a fer-hi comprovacions.",
        "zip-wrong-format": "El fitxer especificat no és un arxiu ZIP.",
-       "zip-bad": "El fitxer està corrupte o és un arxiu ZIP iŀlegible.\nNo s'hi ha pogut comprovar la seguretat.",
+       "zip-bad": "El fitxer està corrupte o és un arxiu ZIP ilegible.\nNo s'hi ha pogut comprovar la seguretat.",
        "zip-unsupported": "El fitxer és un arxiu ZIP que utilitza facilitats no acceptades pel MediaWiki. No s'hi ha pogut realitzar la comprovació de seguretat.",
        "uploadstash": "Carrega fitxers en reserva",
        "uploadstash-summary": "Aquesta pàgina permet accedir als fitxers que han estat carregats (o estan en procés de ser carregats), però que encara no s'han publicat al wiki. Aquests fitxers només són visibles per a l'usuari que els ha carregats.",
        "img-auth-streaming": "Lectura corrent de \"$1\".",
        "img-auth-public": "La funció de img_auth.php és de sortida de fitxers d'un lloc wiki privat.\nAquest wiki està configurat com a wiki públic.\nPer seguretat, img_auth.php està desactivat.",
        "img-auth-noread": "L'usuari no té accés a la lectura de \"$1\".",
-       "http-invalid-url": "URL incorrecta: $1",
+       "http-invalid-url": "URL incorrecte: $1",
        "http-invalid-scheme": "Les URLs amb l'esquema \"$1\" no són compatibles.",
        "http-request-error": "La petició HTTP ha fallat per un error desconegut.",
        "http-read-error": "Error de lectura HTTP.",
        "upload_source_url": " (el fitxer que heu seleccionat des d'un URL vàlid i accessible públicament)",
        "upload_source_file": " (un fitxer triat del vostre ordinador)",
        "listfiles-delete": "elimina",
-       "listfiles-summary": "Aquesta pàgina especial mostra tots els fitxers carregats.\nSi filtreu per usuari només es mostraran els fitxers la versió més recent dels quals hagi estat carregada per aquell.",
+       "listfiles-summary": "Aquesta pàgina especial mostra tots els fitxers carregats.",
        "listfiles_search_for": "Cerca el nom d'un fitxer de medis:",
        "listfiles-userdoesnotexist": "El compte d’usuari «$1» no s’ha registrat.",
        "imgfile": "fitxer",
        "filehist-comment": "Comentari",
        "imagelinks": "Ús del fitxer",
        "linkstoimage": "{{PLURAL:$1|La pàgina següent enllaça|Les $1 pàgines següents enllacen}} a aquest fitxer:",
-       "linkstoimage-more": "Hi ha més de $1 {{PLURAL:$1|pàgina que enllaça|pàgines que enllaçen}} a aquest fitxer.\nLa següent llista només mostra {{PLURAL:$1|la primera d'elles|les primeres $1 d'aquestes pàgines}}.\nPodeu consultar la [[Special:WhatLinksHere/$2|llista completa]].",
+       "linkstoimage-more": "Hi ha més de $1 {{PLURAL:$1|pàgina que enllaça|pàgines que enllacen}} a aquest fitxer.\nLa següent llista només mostra {{PLURAL:$1|la primera d'aquestes pàgines|les primeres $1 d'aquestes pàgines}}.\nPodeu consultar la [[Special:WhatLinksHere/$2|llista completa]].",
        "nolinkstoimage": "No hi ha pàgines que enllacin a aquesta imatge.",
        "morelinkstoimage": "Visualitza [[Special:WhatLinksHere/$1|més enllaços]] que porten al fitxer.",
        "linkstoimage-redirect": "$1 (fitxer redirigit) $2",
        "duplicatesoffile": "{{PLURAL:$1|Aquest fitxer és un duplicat del que apareix a continuació|A continuació s'indiquen els $1 duplicats d'aquest fitxer}} ([[Special:FileDuplicateSearch/$2|vegeu-ne més detalls]]):",
        "sharedupload": "Aquest fitxer prové de $1 i pot ser utilitzat per altres projectes.",
-       "sharedupload-desc-there": "Aquest fitxer prové de $1 i pot ser utilitzat per altres projectes.\nSi us plau vegeu la [$2 pàgina de descripció del fitxer] per a més informació.",
+       "sharedupload-desc-there": "Aquest fitxer prové de $1 i pot ser utilitzat per altres projectes.\nVegeu la [$2 pàgina de descripció del fitxer] per a més informació.",
        "sharedupload-desc-here": "Aquest fitxer prové de $1 i pot ser usat per altres projectes.\nLa descripció de la seva [$2 pàgina de descripció] es mostra a continuació.",
        "sharedupload-desc-edit": "Aquest fitxer és de $1 i potser el fan servir altres projectes.\nPotser voleu modificar-ne la descripció en la seva [$2 pàgina de descripció].",
        "sharedupload-desc-create": "Aquest fitxer és de $1 i potser el fan servir altres projectes.\nPotser voleu modificar-ne la descripció en la seva [$2 pàgina de descripció].",
        "statistics-header-hooks": "Altres estadístiques",
        "statistics-articles": "Pàgines de contingut",
        "statistics-pages": "Pàgines",
-       "statistics-pages-desc": "Totes les pàgines del wiki, incloent les pàgines de discussió, redireccions, etc.",
+       "statistics-pages-desc": "Totes les pàgines del wiki, incloses les pàgines de discussió, redireccions, etc.",
        "statistics-files": "Fitxers carregats",
        "statistics-edits": "Edicions en pàgines des que el projecte {{SITENAME}} fou instal·lat",
        "statistics-edits-average": "Edicions per pàgina de mitjana",
        "pageswithprop-prophidden-long": "valor de propietat text llarg ocult ($1)",
        "pageswithprop-prophidden-binary": "valor de propietat binària oculta ($1)",
        "doubleredirects": "Redireccions dobles",
-       "doubleredirectstext": "Aquesta pàgina llista les pàgines que redirigeixen a altres pàgines de redirecció.\nCada fila conté enllaços a la primera i segona redireccions, així com el destí de la segona redirecció, què generalment és la pàgina destí \"real\", a la què hauria d'apuntar la primera redirecció.\nLes entrades <del>ratllades</del> s'han resolt.",
+       "doubleredirectstext": "Aquesta pàgina llista les pàgines que redirigeixen a altres pàgines de redirecció.\nCada fila conté enllaços a la primera i la segona redireccions, així com la destinació de la segona redirecció, que generalment és la pàgina de destinació \"real\" a la qual hauria d'apuntar la primera redirecció.\nLes entrades <del>ratllades</del> s'han resolt.",
        "double-redirect-fixed-move": "S'ha reanomenat [[$1]].\nS'ha actualitzat automàticament i ara redirigeix a [[$2]].",
        "double-redirect-fixed-maintenance": "S'ha arreglat automàticament la redirecció doble de [[$1]] a [[$2]] en un treball de manteniment.",
        "double-redirect-fixer": "Supressor de dobles redireccions",
        "wantedfiles": "Fitxers demanats",
        "wantedfiletext-cat": "Els fitxers següents s'utilitzen per no existeixen. Els fitxers de repositoris aliens poden ser llistats encara que existeixin. Aquells que siguin fals positius es <del>ratllaran</del>. A més, les pàgines que tinguin fitxers incrustats que no existeixin es llistaran a [[:$1]].",
        "wantedfiletext-cat-noforeign": "Els fitxers següents s'utilitzen, però no existeixen. Addicionalment, s'enumeren a [[:$1]] les pàgines que tenen fitxers inserits que no existeixen.",
-       "wantedfiletext-nocat": "Els fitxers següents es fan servir però no existeixen. Els fitxers d'un repositori aliè poden ser llistats encara que existeixin. Tots aquells fals positius es <del>tatxaran</del>.",
+       "wantedfiletext-nocat": "Els fitxers següents es fan servir però no existeixen. Els fitxers d'un repositori aliè poden ser llistats encara que existeixin. Tots aquests falsos positius es <del>ratllaran</del>.",
        "wantedfiletext-nocat-noforeign": "Els fitxers següents s'utilitzen però no existeixen.",
        "wantedtemplates": "Plantilles demanades",
        "mostlinked": "Pàgines més enllaçades",
        "mostrevisions": "Pàgines més modificades",
        "prefixindex": "Totes les pàgines per prefix",
        "prefixindex-namespace": "Totes les pàgines amb prefix (espai de noms $1)",
+       "prefixindex-submit": "Mostra",
        "prefixindex-strip": "Suprimeix el prefix a la llista",
        "shortpages": "Pàgines curtes",
        "longpages": "Pàgines llargues",
        "deadendpages": "Pàgines atzucac",
-       "deadendpagestext": "Aquestes pàgines no tenen enllaços a d'altres pàgines del projecte {{SITENAME}}.",
+       "deadendpagestext": "Aquestes pàgines no tenen enllaços a altres pàgines del projecte {{SITENAME}}.",
        "protectedpages": "Pàgines protegides",
        "protectedpages-indef": "Només proteccions indefinides",
-       "protectedpages-summary": "Aquesta pàgina llista les pàgines existents que estan protegides actualment. Per consultar la llista de títols protegits per tal que no puguin crear-se'n pàgines, vegeu [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "Aquesta pàgina llista les pàgines existents que estan protegides actualment. Per a consultar la llista de títols protegits perquè no puguin crear-se'n pàgines, vegeu [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Només proteccions en cascada",
        "protectedpages-noredirect": "Amaga redireccions",
        "protectedpagesempty": "No hi ha cap pàgina protegida per ara",
        "protectedpages-performer": "Protecció de l'usuari",
        "protectedpages-params": "Paràmetres de protecció",
        "protectedpages-reason": "Motiu",
+       "protectedpages-submit": "Mostra les pàgines",
        "protectedpages-unknown-timestamp": "Desconegut",
        "protectedpages-unknown-performer": "Usuari desconegut",
        "protectedtitles": "Títols protegits",
        "protectedtitles-summary": "Aquesta pàgina llista títols protegits perquè no puguin crear-se'n pàgines. Per consultar una llista actual de pàgines protegides, vegeu [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "No hi ha cap títol protegit actualment amb aquests paràmetres.",
+       "protectedtitles-submit": "Mostra els títols",
        "listusers": "Llista d'usuaris",
        "listusers-editsonly": "Mostra només usuaris amb edicions",
        "listusers-creationsort": "Ordena per data de creació",
        "cachedspecial-viewing-cached-ts": "Esteu veient una versió a la memòria cau de la pàgina, que podria no ser completament actual.",
        "cachedspecial-refresh-now": "Mostra la darrera.",
        "categories": "Categories",
-       "categoriespagetext": "{{PLURAL:$1|La següent categoria conté|Les següents categories contenen}} pàgines, o fitxers multimèdia.\n[[Special:UnusedCategories|Les categories no usades]] no s'hi mostren.\nVegeu també [[Special:WantedCategories|les categories soŀlicitades]].",
+       "categoriespagetext": "{{PLURAL:$1|La següent categoria conté|Les següents categories contenen}} pàgines, o fitxers multimèdia.\n[[Special:UnusedCategories|Les categories no usades]] no s'hi mostren.\nVegeu també [[Special:WantedCategories|les categories solicitades]].",
        "categoriesfrom": "Mostra les categories que comencen a:",
        "special-categories-sort-count": "ordena per recompte",
        "special-categories-sort-abc": "ordena alfabèticament",
        "activeusers-hidebots": "Amaga bots",
        "activeusers-hidesysops": "Amaga administradors",
        "activeusers-noresult": "No s'han trobat usuaris.",
+       "activeusers-submit": "Mostra els usuaris actius",
        "listgrouprights": "Drets dels grups d'usuaris",
        "listgrouprights-summary": "A continuació hi ha una llista dels grups d'usuaris definits en aquest wiki, així com dels seus drets d'accés associats.\nPot ser que hi hagi més informació sobre drets individuals [[{{MediaWiki:Listgrouprights-helppage}}|aquí]].",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Dret concedit</span>\n* <span class=\"listgrouprights-revoked\">Dret retirat</span>",
        "emailccsubject": "Còpia del vostre missatge a $1: $2",
        "emailsent": "Correu electrònic enviat",
        "emailsenttext": "S'ha enviat el vostre correu electrònic.",
-       "emailuserfooter": "Aquest missatge de correu electrònic l'ha enviat $1 a $2 amb la funció «{{int:emailuser}}» de {{SITENAME}}.",
+       "emailuserfooter": "Aquest missatge de correu electrònic l'ha {{GENDER:$1|enviat}} $1 a {{GENDER:$2|$2}} amb la funció «{{int:emailuser}}» de {{SITENAME}}.",
        "usermessage-summary": "Deixant missatges de sistema.",
        "usermessage-editor": "Missatger del sistema",
        "watchlist": "Llista de seguiment",
        "wlheader-showupdated": "Les pàgines que s'han canviat des de la vostra darrera visita es mostren en '''negreta'''.",
        "wlnote": "A sota hi ha {{PLURAL:$1|el darrer canvi|els darrers <strong>$1</strong> canvis}} en {{PLURAL:$2|la darrera hora|les <strong>$2</strong> darreres hores}}, a $4 del $3.",
        "wlshowlast": "Mostra les darreres $1 hores, els darrers $2 dies",
-       "watchlistall2": "totes",
+       "watchlistall2": "tots",
        "watchlist-hide": "Amaga",
+       "watchlist-submit": "Mostra",
        "wlshowhideminor": "edicions menors",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "usuaris registrats",
        "deletereason-dropdown": "*Motius freqüents d'esborrat\n** Brossa\n** Vandalisme\n** Violació del copyright\n** Demanada per l'autor\n** Redirecció trencada",
        "delete-edit-reasonlist": "Edita els motius d'eliminació",
        "delete-toobig": "Aquesta pàgina té un historial d'edicions molt gran, amb més de $1 {{PLURAL:$1|canvi|canvis}}. L'eliminació d'aquestes pàgines està restringida per a prevenir que hi pugui haver un desajustament seriós de la base de dades de tot el projecte {{SITENAME}} per accident.",
-       "delete-warning-toobig": "Aquesta pàgina té un historial d'edicions molt gran, amb més de $1 {{PLURAL:$1|canvi|canvis}}. Eliminar-la podria suposar un seriós desajustament de la base de dades de tot el projecte {{SITENAME}}; aneu en compte abans dur a terme l'acció.",
+       "delete-warning-toobig": "Aquesta pàgina té un historial d'edicions molt gran, amb més de $1 {{PLURAL:$1|canvi|canvis}}. Eliminar-la podria suposar un seriós desajustament de la base de dades de tot el projecte {{SITENAME}}; aneu amb compte abans dur a terme l'acció.",
        "deleteprotected": "No podeu eliminar la pàgina perquè ha estat protegida.",
        "deleting-backlinks-warning": "'''Avís:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Altres pàgines]] enllacen o transclouen de la pàgina que esteu a punt de suprimir.",
        "rollback": "Reverteix edicions",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "rollbacklinkcount-morethan": "reverteix més de $1 {{PLURAL:$1|edició|edicions}}",
        "rollbackfailed": "No s'ha pogut revocar",
-       "cantrollback": "No s'ha pogut revertir les edicions; el darrer coŀlaborador és l'únic autor de la pàgina.",
+       "cantrollback": "No s'han pogut revertir les edicions; el darrer col·laborador és l'únic autor de la pàgina.",
        "alreadyrolled": "No es pot revertir la darrera modificació de [[:$1]]\nde l'usuari [[User:$2|$2]] ([[User talk:$2|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]). Algú altre ja ha modificat o revertit la pàgina.\n\nLa darrera modificació l'ha fet l'usuari [[User:$3|$3]] ([[User talk:$3|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "El resum d'edició és: «$1».",
        "revertpage": "Revertides les edicions de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussió]]) a l'última versió de [[User:$1|$1]]",
        "prot_1movedto2": "[[$1]] mogut a [[$2]]",
        "protect-badnamespace-title": "Espai de nom no-protectable",
        "protect-badnamespace-text": "Les pàgines en aquest espai de nom no pot ser protegit.",
-       "protect-norestrictiontypes-text": "Aquesta pàgina no es pot protegir ja que no hi ha cap tipus de restricció disponible.",
+       "protect-norestrictiontypes-text": "Aquesta pàgina no es pot protegir, ja que no hi ha cap tipus de restricció disponible.",
        "protect-norestrictiontypes-title": "Pàgina no protegible",
        "protect-legend": "Confirmeu la protecció",
        "protectcomment": "Motiu:",
        "contributions": "Contribucions de {{GENDER:$1|l’usuari|la usuària}}",
        "contributions-title": "Contribucions de l'usuari $1",
        "mycontris": "Contribucions",
+       "anoncontribs": "Contribucions",
        "contribsub2": "Per a {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "El compte d'usuari «$1» no està registrat.",
-       "nocontribs": "No s’ha trobat cap canvi que encaixessi amb aquests criteris.",
+       "nocontribs": "No s’ha trobat cap canvi que encaixés amb aquests criteris.",
        "uctop": "(actual)",
        "month": "Mes (i anteriors):",
        "year": "Any (i anteriors):",
        "sp-contributions-logs": "registres",
        "sp-contributions-talk": "discussió",
        "sp-contributions-userrights": "gestió de drets d'usuari",
-       "sp-contributions-blocked-notice": "En aquests moments, aquest compte d'usuari es troba blocat.\nPer més detalls, la última entrada del registre es mostra a continuació:",
-       "sp-contributions-blocked-notice-anon": "En aquests moments, aquesta adreça IP es troba blocada.\nPer més detalls, lúltima entrada del registre es mostra a continuació:",
+       "sp-contributions-blocked-notice": "En aquests moments aquest compte d'usuari està blocat.\nPer a més informació, a continuació es mostra l'última entrada del registre:",
+       "sp-contributions-blocked-notice-anon": "En aquests moments, aquesta adreça IP es troba blocada.\nPer més detalls, l'última entrada del registre es mostra a continuació:",
        "sp-contributions-search": "Cerca les contribucions",
        "sp-contributions-username": "Adreça IP o nom d'usuari:",
        "sp-contributions-toponly": "Mostra només les darreres revisions",
        "whatlinkshere-hidelinks": "$1 enllaços",
        "whatlinkshere-hideimages": "$1 enllaços de fitxers",
        "whatlinkshere-filters": "Filtres",
+       "whatlinkshere-submit": "Vés-hi",
        "autoblockid": "Autoblocatge #$1",
        "block": "Blocatge d'usuaris",
        "unblock": "Desblocatge d'usuaris",
-       "blockip": "Bloca {{GENDER:$1|l'usuari|l'usuària}}",
+       "blockip": "Bloca {{GENDER:$1|l'usuari|lusuària}}",
        "blockip-legend": "Bloca l'usuari",
        "blockiptext": "Empreu el següent formulari per blocar l'accés\nd'escriptura des d'una adreça IP específica o des d'un usuari determinat.\naixò només s'hauria de fer per prevenir el vandalisme, i\nd'acord amb la [[{{MediaWiki:Policy-url}}|política del projecte]].\nEmpleneu el diàleg de sota amb un motiu específic (per exemple, citant\nquines pàgines en concret estan sent vandalitzades).",
        "ipaddressorusername": "Adreça IP o nom de l'usuari",
        "emailblock": "s'ha blocat l'enviament de correus electrònics",
        "blocklist-nousertalk": "no podeu modificar la pàgina de discussió pròpia",
        "ipblocklist-empty": "La llista de bloqueigs està buida.",
-       "ipblocklist-no-results": "L'adreça IP o nom d'usuari soŀlicitat no està bloquejat.",
+       "ipblocklist-no-results": "L'adreça IP o nom d'usuari solicitat no està bloquejat.",
        "blocklink": "bloqueja",
        "unblocklink": "desbloca",
        "change-blocklink": "canvia el blocatge",
        "blocklog-showsuppresslog": "S'ha blocat i amagat aquest usuari prèviament.\nPer més detalls, a sota es mostra el registre de supressions:",
        "blocklogentry": "ha blocat l'{{GENDER:$1|usuari|usuària}} [[$1]] per un període de: $2 $3",
        "reblock-logentry": "canviades les opcions del blocatge a [[$1]] amb caducitat a $2, $3",
-       "blocklogtext": "Això és una relació de accions de bloqueig i desbloqueig. Les adreces IP bloquejades automàticament no apareixen. Vegeu la [[Special:BlockList|llista de bloqueigs]] per veure una llista dels actuals bloqueigs operatius.",
+       "blocklogtext": "Això és una relació d'accions de bloqueig i desbloqueig. Les adreces IP bloquejades automàticament no apareixen. Vegeu la [[Special:BlockList|llista de bloqueigs]] per a veure una llista dels actuals bloqueigs operatius.",
        "unblocklogentry": "ha desblocat $1",
        "block-log-flags-anononly": "només els usuaris anònims",
        "block-log-flags-nocreate": "s'ha desactivat la creació de comptes",
        "unblock-hideuser": "No podeu desblocar aquest usuari, perquè el seu nom d'usuari està ocult.",
        "ipb_cant_unblock": "Errada: No s'ha trobat el núm. ID de bloqueig $1. És possible que ja s'haguera desblocat.",
        "ipb_blocked_as_range": "Error: L'adreça IP $1 no està blocada directament i per tant no pot ésser desbloquejada. Ara bé, sí que ho està per formar part del rang $2 que sí que pot ser desblocat.",
-       "ip_range_invalid": "Rang dIP no vàlid.",
-       "ip_range_toolarge": "No estan permesos el bloquejos de rangs més grans que /$1.",
+       "ip_range_invalid": "Rang d'IP no vàlid.",
+       "ip_range_toolarge": "No són permesos els bloquejos de rangs més grans que /$1.",
        "proxyblocker": "Bloqueig de proxy",
        "proxyblockreason": "S'ha blocat la vostra adreça IP perquè és un proxy obert. Contactau el vostre proveïdor d'Internet o servei tècnic i informau-los d'aquest seriós problema de seguretat.",
        "sorbsreason": "La vostra adreça IP està llistada com a servidor intermediari (''proxy'') obert dins la llista negra de DNS que fa servir el projecte {{SITENAME}}.",
        "sorbs_create_account_reason": "La vostra adreça IP està llistada com a servidor intermediari (''proxy'') obert a la llista negra de DNS que utilitza el projecte {{SITENAME}}. No podeu crear-vos-hi un compte",
-       "xffblockreason": "Una adreça IP present en la capçalera X-Forwarded-For, ja sigui vostra o la d'un servidor proxy que esteu utilitzant, ha estat blocada. El motiu inicial del bloqueig és: $1",
+       "xffblockreason": "Una adreça IP present en la capçalera X-Forwarded-For, sigui vostra o la d'un servidor proxy que esteu utilitzant, ha estat blocada. El motiu inicial del bloqueig és: $1",
        "cant-see-hidden-user": "L'usuari que esteu intentant blocar ja ha estat blocat i ocultat. Com que no teniu el permís hideuser no podeu veure ni modificar el seu blocatge.",
        "ipbblocked": "No podeu blocar o desblocar altres usuaris, perquè vós {{GENDER:|mateix|mateixa|mateix}} esteu {{GENDER:|blocat|blocada|blocat}}.",
        "ipbnounblockself": "No teniu permís per a treure el vostre bloqueig",
        "lockdb": "Bloca la base de dades",
        "unlockdb": "Desbloca la base de dades",
-       "lockdbtext": "Si es bloca la base de dades impedirà la capacitat a tots els usuaris d'editar pàgines, canviar les preferències, editar la llista de seguiment i altres canvis que calen de modificacions a la base de dades.\nConfirmeu que això és el que voleu fer, i sobretot no us oblideu de desblocar la base de dades quan acabeu el manteniment.",
+       "lockdbtext": "Bloquejar la base de dades inhabilitarà a tots els usuaris per a modificar pàgines, canviar preferències, editar la llista de seguiment i altres accions que requereixen canvis en la base de dades.\nConfirmeu que això és el que voleu fer, i sobretot no us oblideu de desblocar la base de dades quan acabeu el manteniment.",
        "unlockdbtext": "Desblocant la base de dades es restaurarà l'habilitat de tots\nels usuaris d'editar pàgines, canviar les preferències, editar els llistats de seguiment, i\naltres accions que requereixen canvis en la base de dades.\nConfirmeu que això és el que voleu fer.",
        "lockconfirm": "Sí, realment vull blocar la base de dades.",
-       "unlockconfirm": "Sí, realment vull desblocar la base dades.",
+       "unlockconfirm": "Sí, realment vull desblocar la base de dades.",
        "lockbtn": "Bloca la base de dades",
        "unlockbtn": "Desbloca la base de dades",
        "locknoconfirm": "No heu respost al diàleg de confirmació.",
        "movepagetext-noredirectfixer": "Amb el formulari següent podeu reanomenar una pàgina movent tot el seu historial al nom nou.\nEl títol anterior es convertirà en una pàgina de redirecció al nou títol. \nAssegureu-vos de verificar les redireccions [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|trencades]].\nÉs responsabilitat vostra assegurar que els enllaços continuen apuntant cap a on se suposa que han d'anar. \n\nTingueu en compte que la pàgina '''no''' serà traslladada si ja existeix una pàgina amb el títol nou, tret que sigui una redirecció i no tingui més historial. \nAixò significa que podeu reanomenar de nou una pàgina al seu títol original si cometeu un error, i que no podeu sobreescriure una pàgina existent.\n \n'''Atenció!''' \nAixò pot ser un canvi dràstic i inesperat per una pàgina popular; \nassegureu-vos que sabeu el que feu abans de continuar.",
        "movepagetalktext": "La pàgina de discussió associada també serà traslladada automàticament '''tret que''':\n* Ja existeixi una pàgina de discussió no buida amb el nou nom, o\n* Desactiveu l'opció de més avall.\n\nEn aquests casos, haureu de traslladar o fusionar la pàgina manualment si ho desitgeu.",
        "moveuserpage-warning": "'''Atenció:''' Esteu a punt de moure una pàgina d'usuari. Tingueu en compte que només la pàgina es desplaçarà i que el compte d'usuari ''no'' canviarà de nom.",
-       "movecategorypage-warning": "<strong>Avís:</strong> Esteu a punt de moure una pàgina de categoria. Tingueu en compte que només es moure la pàgina i qualsevol de les pàgines a l'antiga categoria <em>no</em> es recategoritzarà automàticament en la nova.",
+       "movecategorypage-warning": "<strong>Avís:</strong> Esteu a punt de moure una pàgina de categoria. Tingueu en compte que només es mourà aquesta pàgina, i que les pàgines dins la categoria antiga <em>no</em> es recategoritzaran automàticament en la nova.",
        "movenologintext": "Heu de ser un usuari registrat i estar [[Special:UserLogin|dintre d'una sessió]]\nper reanomenar una pàgina.",
        "movenotallowed": "No teniu permís per a moure pàgines.",
        "movenotallowedfile": "No teniu el permís per a moure fitxers.",
        "cantmove-titleprotected": "No podeu moure una pàgina a aquesta ubicació, perquè s'ha protegit la creació del títol nou",
        "movetalk": "Mou la pàgina de discussió associada",
        "move-subpages": "Desplaça'n també les subpàgines (fins a $1)",
-       "move-talk-subpages": "Desplaça també les subpàgines de la pàgina de discussió (fins un màxim de $1)",
+       "move-talk-subpages": "Desplaça també les subpàgines de la pàgina de discussió (fins un màxim de $1)",
        "movepage-page-exists": "La pàgina $1 ja existeix i no pot sobreescriure's automàticament.",
        "movepage-page-moved": "La pàgina $1 s'ha traslladat a $2.",
        "movepage-page-unmoved": "La pàgina $1 no s'ha pogut moure a $2.",
        "movenosubpage": "Aquesta pàgina no té subpàgines.",
        "movereason": "Motiu:",
        "revertmove": "reverteix",
-       "delete_and_move": "Elimina i trasllada",
        "delete_and_move_text": "==Cal l'eliminació==\n\nLa pàgina de destinació, «[[:$1]]», ja existeix. Voleu eliminar-la per a fer lloc al trasllat?",
        "delete_and_move_confirm": "Sí, esborra la pàgina",
        "delete_and_move_reason": "S'ha eliminat per a permetre el reanomenament de \" [[$1]] \"",
        "export-addns": "Afegir",
        "export-download": "Ofereix desar com a fitxer",
        "export-templates": "Inclou les plantilles",
-       "export-pagelinks": "Inclou pàgines enllaçades fins una profunditat de:",
+       "export-pagelinks": "Inclou pàgines enllaçades fins una profunditat de:",
        "allmessages": "Tots els missatges del sistema",
        "allmessagesname": "Nom",
        "allmessagesdefault": "Text per defecte",
        "allmessagescurrent": "Text actual",
-       "allmessagestext": "Tot seguit hi ha una llista dels missatges del sistema que es troben a l'espai de noms ''MediaWiki''. La traducció genèrica d'aquests missatges no s'hauria de fer localment sinó a la traducció del programari MediaWiki. Si voleu ajudar-hi visiteu [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] i [//translatewiki.net translatewiki.net].",
+       "allmessagestext": "Tot seguit hi ha una llista dels missatges del sistema que es troben en l'espai de noms ''MediaWiki''. La traducció genèrica d'aquests missatges no s'hauria de fer localment sinó en la traducció del programari MediaWiki. Si voleu ajudar-hi, visiteu [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] i [//translatewiki.net translatewiki.net].",
        "allmessagesnotsupportedDB": "No es pot processar '''{{ns:special}}:Allmessages''' perquè la variable '''$wgUseDatabaseMessages''' està desactivada.",
        "allmessages-filter-legend": "Filtre",
        "allmessages-filter": "Filtra per l'estat de personalització:",
        "thumbnail_error_remote": "Missatge d'error de $1:\n$2",
        "djvu_page_error": "La pàgina DjVu està fora de l'abast",
        "djvu_no_xml": "No s'ha pogut recollir l'XML per al fitxer DjVu",
-       "thumbnail-temp-create": "No s'ha pogut creat el fitxer de miniatura temporal",
+       "thumbnail-temp-create": "No s'ha pogut crear el fitxer de miniatura temporal",
        "thumbnail-dest-create": "No es pot desar la miniatura a la destinació",
        "thumbnail_invalid_params": "Els paràmetres de les miniatures no són vàlids",
        "thumbnail_toobigimagearea": "Fitxer amb dimensions més gran que $1",
        "importuploaderrorsize": "La càrrega del fitxer d'importació ha fallat. El fitxer és més gran que la mida de càrrega permesa.",
        "importuploaderrorpartial": "La càrrega del fitxer d'importació ha fallat. El fitxer s'ha penjat només parcialment.",
        "importuploaderrortemp": "La càrrega del fitxer d'importació ha fallat. Manca una carpeta temporal.",
-       "import-parse-failure": "error en importar l'XML",
+       "import-parse-failure": "error en importar l'XML",
        "import-noarticle": "No hi ha cap pàgina per importar!",
        "import-nonewrevisions": "No s'ha importat cap revisió (ja hi eren abans o s'han omès a causa d'errors).",
        "xml-error-string": "$1 a la línia $2, columna $3 (byte $4): $5",
        "javascripttest-pagetext-unknownframework": "L'entorn de proves «$1» és desconegut.",
        "javascripttest-pagetext-unknownaction": "Acció desconeguda «$1».",
        "javascripttest-pagetext-frameworks": "Trieu un dels següents entorns de prova: $1",
-       "javascripttest-pagetext-skins": "Trieu un tema on executar-hi els tests:",
+       "javascripttest-pagetext-skins": "Trieu un tema per a executar-hi els tests:",
        "javascripttest-qunit-intro": "Consulteu la [documentació de tests de $1] a mediawiki.org.",
        "tooltip-pt-userpage": "La vostra pàgina d'usuari",
        "tooltip-pt-anonuserpage": "La pàgina d'usuari per la ip que utilitzeu",
        "tooltip-pt-mytalk": "La vostra pàgina de discussió.",
        "tooltip-pt-anontalk": "Discussió sobre les edicions per aquesta adreça ip.",
        "tooltip-pt-preferences": "Les vostres preferències.",
-       "tooltip-pt-watchlist": "La llista de pàgines de les que estau vigilant els canvis.",
+       "tooltip-pt-watchlist": "La llista de pàgines de les quals vigileu els canvis.",
        "tooltip-pt-mycontris": "Llista de les vostres contribucions.",
        "tooltip-pt-login": "Us animem a registrar-vos, però no és obligatori",
        "tooltip-pt-logout": "Finalitza la sessió d'usuari",
        "tooltip-ca-protect": "Protegeix aquesta pàgina.",
        "tooltip-ca-unprotect": "Desprotegeix aquesta pàgina",
        "tooltip-ca-delete": "Elimina aquesta pàgina",
-       "tooltip-ca-undelete": "Restaura les edicions fetes a aquesta pàgina abans de que fos esborrada.",
+       "tooltip-ca-undelete": "Restaura les edicions fetes en aquesta pàgina abans que fos esborrada.",
        "tooltip-ca-move": "Reanomena aquesta pàgina",
        "tooltip-ca-watch": "Afegiu aquesta pàgina a la vostra llista de seguiment",
        "tooltip-ca-unwatch": "Suprimiu aquesta pàgina de la vostra llista de seguiment",
        "group-bureaucrat.css": "/* El CSS d'aquí només afectarà els buròcrates */",
        "common.js": "/* Es carregarà per a tots els usuaris, i per a qualsevol pàgina, el codi JavaScript que hi haja després d'aquesta línia. */",
        "group-autoconfirmed.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als usuaris autoconfirmats */",
-       "group-user.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als usuaris rgistrats */",
+       "group-user.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als usuaris registrats */",
        "group-bot.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als bots */",
        "group-sysop.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als sysops */",
        "group-bureaucrat.js": "/* Qualsevol JavaScript d'aquí es carregarà només per als buròcrates */",
        "pageinfo-robot-policy": "Indexació per robots",
        "pageinfo-robot-index": "Permès",
        "pageinfo-robot-noindex": "No permès",
-       "pageinfo-watchers": "Número d'usuaris que vigilen la pàgina",
+       "pageinfo-watchers": "Nombre d'usuaris que vigilen la pàgina",
        "pageinfo-visiting-watchers": "Nombre de vigilants de la pàgina que han visitat els canvis recents",
        "pageinfo-few-watchers": "Menys de $1 {{PLURAL:$1|observador|observadors}}",
        "pageinfo-redirects-name": "Nombre de redireccions a aquesta pàgina",
        "pageinfo-redirects-value": "$1",
        "pageinfo-subpages-name": "Subpàgines d'aquesta pàgina",
-       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirecció|redireccions}}; $3 {{PLURAL:$3|no redireció|no redireccions}})",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirecció|redireccions}}; $3 {{PLURAL:$3|no redirecció|no redireccions}})",
        "pageinfo-firstuser": "Creador de la pàgina",
        "pageinfo-firsttime": "Data de la creació de la pàgina",
        "pageinfo-lastuser": "Últim editor",
        "pageinfo-lasttime": "Data de l'última edició",
-       "pageinfo-edits": "Número total d'edicions",
-       "pageinfo-authors": "Número total d'autors diferents",
-       "pageinfo-recent-edits": "Número d'edicions recents (en els darrers $1)",
-       "pageinfo-recent-authors": "Número recent d'autors diferents",
+       "pageinfo-edits": "Nombre total d'edicions",
+       "pageinfo-authors": "Nombre total d'autors diferents",
+       "pageinfo-recent-edits": "Nombre d'edicions recents (en els darrers $1)",
+       "pageinfo-recent-authors": "Nombre recent d'autors diferents",
        "pageinfo-magic-words": "{{PLURAL:$1|Paraula clau|Paraules clau}} ($1)",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Categoria oculta|Categories ocultes}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|plantilla inclosa|plantilles incloses}} ($1)",
        "file-info-png-looped": "embuclat",
        "file-info-png-repeat": "s'ha reproduït $1 {{PLURAL:$1|vegada|vegades}}",
        "file-info-png-frames": "$1 {{PLURAL:$1|fotograma|fotogrames}}",
-       "file-no-thumb-animation": "'''Nota: degut a limitacions tècniques no s'animaran les miniatures per aquest fitxer.'''",
-       "file-no-thumb-animation-gif": "''' Nota: degut a limitacions tècniques no s'animaran les miniatures d'alta resolució d'imatges GIF com aquesta.'''",
+       "file-no-thumb-animation": "<strong>Nota: per limitacions tècniques no s'animaran les miniatures per aquest fitxer.</strong>",
+       "file-no-thumb-animation-gif": "<strong>Nota: per limitacions tècniques no s'animaran les miniatures d'alta resolució d'imatges GIF com aquesta.</strong>",
        "newimages": "Galeria de fitxers nous",
        "imagelisttext": "Llista {{PLURAL:$1|d'un sol fitxer|de '''$1''' fitxers ordenats $2}}.",
        "newimages-summary": "Aquesta pàgina especial mostra els darrers fitxers carregats.",
        "saturday-at": "Dissabte a les $1",
        "sunday-at": "Diumenge a les $1",
        "yesterday-at": "Ahir a les $1",
-       "bad_image_list": "El format ha de ser el següent:\n\nNomés els elements de llista (les línies que comencin amb un *) es prenen en consideració. El primer enllaç de cada línia ha de ser el d'un fitxer dolent.\nLa resta d'enllaços de la línia són les excepcions, és a dir, les pàgines on s'hi pot encabir el fitxer.",
+       "bad_image_list": "El format ha de ser el següent:\n\nNomés els elements de llista (les línies que comencin amb un *) es prenen en consideració. El primer enllaç de cada línia ha de ser el d'un fitxer dolent.\nLa resta d'enllaços de la línia són les excepcions, és a dir, les pàgines on es pot encabir el fitxer.",
        "variantname-zh-cn": "cn",
        "variantname-zh-tw": "tw",
        "variantname-zh-hk": "hk",
        "exif-jpeginterchangeformatlength": "Octets de dades JPEG",
        "exif-whitepoint": "Cromositat del punt blanc",
        "exif-primarychromaticities": "Coordenada cromàtica del color primari",
-       "exif-ycbcrcoefficients": "Quoficients de la matriu de transformació de l'espai colorimètric",
+       "exif-ycbcrcoefficients": "Coeficients de la matriu de transformació de l'espai colorimètric",
        "exif-referenceblackwhite": "Valors de referència negre i blanc",
        "exif-datetime": "Data i hora de modificació del fitxer",
        "exif-imagedescription": "Títol de la imatge",
        "exif-exposuremode": "Mode d'exposició",
        "exif-whitebalance": "Balanç de blancs",
        "exif-digitalzoomratio": "Escala d'ampliació digital (zoom)",
-       "exif-focallengthin35mmfilm": "Distància focal per a peŀlícula de 35 mm",
+       "exif-focallengthin35mmfilm": "Distància focal per a película de 35 mm",
        "exif-scenecapturetype": "Tipus de captura d'escena",
        "exif-gaincontrol": "Control d'escena",
        "exif-contrast": "Contrast",
        "exif-gpsaltituderef": "Referència d'altitud",
        "exif-gpsaltitude": "Altitud",
        "exif-gpstimestamp": "Hora GPS (rellotge atòmic)",
-       "exif-gpssatellites": "Satèŀlits utilitzats en la mesura",
+       "exif-gpssatellites": "Satèlits utilitzats en la mesura",
        "exif-gpsstatus": "Estat del receptor",
        "exif-gpsmeasuremode": "Mode de mesura",
        "exif-gpsdop": "Precisió de la mesura",
        "exif-cameraownername": "Propietari de la càmera",
        "exif-label": "Etiqueta",
        "exif-datetimemetadata": "Data que s'ha modificat les metadades per última vegada",
-       "exif-nickname": "Nom informal de l'imatge",
+       "exif-nickname": "Nom informal de limatge",
        "exif-rating": "Valoració (sobre 5)",
        "exif-rightscertificate": "Certificat de gestió de drets",
        "exif-copyrighted": "Estat dels drets d'autor",
        "exif-originaldocumentid": "ID únic del document original",
        "exif-licenseurl": "Direcció de llicències de drets d'autor",
        "exif-morepermissionsurl": "Alternativa informació de llicència",
-       "exif-attributionurl": "Quan re-utilitzis aquest treball, si us plau posa un enllaç a",
-       "exif-preferredattributionname": "Quan re-utilitzis aquest treball, si us plau posa un credit a",
+       "exif-attributionurl": "Quan reutilitzeu aquest treball, si us plau, poseu un enllaç a",
+       "exif-preferredattributionname": "Quan reutilitzeu aquest treball, si us plau posa un credit a",
        "exif-pngfilecomment": "Comentari del fitxer PNG",
        "exif-disclaimer": "Avís general",
        "exif-contentwarning": "Advertència de contingut",
        "exif-originalimageheight": "Alçada de la imatge abans que fos retallada",
        "exif-originalimagewidth": "Amplada de la imatge abans que fos retallada",
        "exif-compression-1": "Sense compressió",
-       "exif-compression-2": "Codificació CCITT Grup 3 longitud monodimensional de Huffman modificat",
+       "exif-compression-2": "Codificació CCITT Grup 3 longitud unidimensional de Huffman modificat",
        "exif-compression-3": "Codificació de fax CCITT grup 3",
        "exif-compression-4": "Codificació de fax CCITT grup 4",
        "exif-compression-6": "JPEG (antic)",
        "exif-orientation-2": "Invertit horitzontalment",
        "exif-orientation-3": "Girat 180°",
        "exif-orientation-4": "Invertit verticalment",
-       "exif-orientation-5": "Rotat 90° en sentit antihorari i invertit verticalment",
-       "exif-orientation-6": "Rotat 90° en sentit antihorari",
-       "exif-orientation-7": "Rotat 90° en sentit horari i invertit verticalment",
-       "exif-orientation-8": "Rotat 90° en sentit horari",
+       "exif-orientation-5": "Girat 90° en sentit antihorari i invertit verticalment",
+       "exif-orientation-6": "Girat 90° en sentit antihorari",
+       "exif-orientation-7": "Girat 90° en sentit horari i invertit verticalment",
+       "exif-orientation-8": "Girat 90° en sentit horari",
        "exif-planarconfiguration-1": "a blocs densos (chunky)",
        "exif-planarconfiguration-2": "format pla",
        "exif-xyresolution-i": "$1 ppp",
        "exif-lightsource-18": "Llum estàndard B",
        "exif-lightsource-19": "Llum estàndard C",
        "exif-lightsource-24": "Bombeta de tungstè d'estudi ISO",
-       "exif-lightsource-255": "Altre font de llum",
+       "exif-lightsource-255": "Una altra font de llum",
        "exif-flash-fired-0": "No s'ha disparat el flaix",
        "exif-flash-fired-1": "Flaix disparat",
        "exif-flash-return-0": "no hi ha funció de detecció del retorn de la llum estroboscòpica",
        "exif-gpsdestdistance-k": "Quilòmetres",
        "exif-gpsdestdistance-m": "Milles",
        "exif-gpsdestdistance-n": "Milles nàutiques",
-       "exif-gpsdop-excellent": "Exceŀlent ($1)",
+       "exif-gpsdop-excellent": "Excelent ($1)",
        "exif-gpsdop-good": "Bona ($1)",
        "exif-gpsdop-moderate": "Moderada ($1)",
        "exif-gpsdop-fair": "Justa ($1)",
        "confirmemail_pending": "Ja s'ha enviat el vostre codi de confirmació per correu electrònic; si\nfa poc hi heu creat el vostre compte, abans de mirar de demanar un nou\ncodi, primer hauríeu d'esperar alguns minuts per a rebre'l.",
        "confirmemail_send": "Envia per correu electrònic un codi de confirmació",
        "confirmemail_sent": "S'ha enviat un missatge de confirmació.",
-       "confirmemail_oncreate": "S'ha enviat un codi de confirmació a la vostra adreça de correu electrònic.\nNo es requereix aquest codi per a autenticar-s'hi, però vos caldrà proporcionar-lo\nabans d'activar qualsevol funcionalitat del wiki basada en missatges\nde correu electrònic.",
+       "confirmemail_oncreate": "S'ha enviat un codi de confirmació a la vostra adreça de correu electrònic.\nAquest codi no cal per a autenticar-se, però haureu de proporcionar-lo abans d'activar qualsevol funcionalitat del wiki basada en missatges de correu electrònic.",
        "confirmemail_sendfailed": "{{SITENAME}} no ha pogut enviar el vostre missatge de confirmació.\nComproveu que l'adreça no tingui caràcters no vàlids.\n\nEl programari de correu retornà el següent missatge: $1",
        "confirmemail_invalid": "El codi de confirmació no és vàlid. Aquest podria haver vençut.",
        "confirmemail_needlogin": "Necessiteu $1 per a confirmar la vostra adreça electrònica.",
        "confirmemail_success": "S'ha confirmat la vostra adreça electrònica.\nAra podeu [[Special:UserLogin|iniciar una sessió]] i gaudir del wiki.",
        "confirmemail_loggedin": "Ja s'ha confirmat la vostra adreça electrònica.",
        "confirmemail_subject": "Confirmació de l'adreça electrònica del projecte {{SITENAME}}",
-       "confirmemail_body": "Algú, segurament vós, ha registrat el compte «$2» al projecte {{SITENAME}}\namb aquesta adreça electrònica des de l'adreça IP $1.\n\nPer a confirmar que aquesta adreça electrònica us pertany realment\ni així activar les opcions de correu del programari, seguiu aquest enllaç:\n\n$3\n\nSi *no* heu estat qui ho ha fet, seguiu aquest altre enllaç per a canceŀlar la confirmació demanada:\n\n$5\n\nAquest codi de confirmació caducarà a $4.",
+       "confirmemail_body": "Algú, segurament vós, ha registrat el compte «$2» al projecte {{SITENAME}}\namb aquesta adreça electrònica des de l'adreça IP $1.\n\nPer a confirmar que aquesta adreça electrònica us pertany realment\ni així activar les opcions de correu del programari, seguiu aquest enllaç:\n\n$3\n\nSi *no* heu estat qui ho ha fet, seguiu aquest altre enllaç per a cancelar la confirmació demanada:\n\n$5\n\nAquest codi de confirmació caducarà a $4.",
        "confirmemail_body_changed": "Algú, segurament vós, des de l'adreça IP $1, ha canviat al projecte {{SITENAME}} l'adreça de correu del compte \"$2\" a aquesta adreça.\n\nPer confirmar que aquest compte realment us pertany i per reactivar\nles opcions de correu a {{SITENAME}}, obriu el següent enllaç al vostre navegador:\n\n$3\n\nSi el compte *no* us pertany, seguiu l'enllaç següent\nper a cancel·lar la confirmació d'adreça de correu:\n\n$5\n\nAquest codi de confirmació expirarà el $4.",
        "confirmemail_body_set": "Algú, probablement vós, des de l'adreça IP $1, \nha establert aquesta adreça de correu electrònic com la del compte «$2» del lloc {{SITENAME}}. \n\nPer confirmar que aquest compte realment us pertany i reactivar \nles facilitats de correu electrònic a {{SITENAME}}, cal que obriu al navegador aquest enllaç:\n\n$3\n\nSi el compte *no* us pertany, cancel·leu l'adreça de correu electrònic seguint aquest enllaç: \n\n$5\n\nAquest codi de confirmació caducarà el $4.",
-       "confirmemail_invalidated": "Confirmació d'adreça electrònica canceŀlada",
-       "invalidateemail": "Canceŀlació d'adreça electrònica",
+       "confirmemail_invalidated": "Confirmació d'adreça electrònica cancelada",
+       "invalidateemail": "Cancelació d'adreça electrònica",
        "scarytranscludedisabled": "[S'ha inhabilitat la transclusió interwiki]",
        "scarytranscludefailed": "[Ha fallat la recuperació de la plantilla per a $1]",
        "scarytranscludefailed-httpstatus": "[Ha fallat la recuperació de la plantilla per a $1: HTTP $2]",
        "duplicate-displaytitle": "<strong>Avís:</strong> El títol a mostrar «$2» sobreescriu l'anterior títol a mostrar «$1».",
        "invalid-indicator-name": "<strong>Error:</strong> No pot estar buit l'atribut <code>name</code> dels indicadors d'estat de la pàgina.",
        "version": "Versió",
-       "version-extensions": "Extensions instaŀlades",
+       "version-extensions": "Extensions instalades",
        "version-skins": "Temes instal·lats",
        "version-specialpages": "Pàgines especials",
        "version-parserhooks": "Extensions de l'analitzador",
        "version-poweredby-others": "altres",
        "version-poweredby-translators": "Traductors de translatewiki.net",
        "version-credits-summary": "El nostre reconeixement a les següents persones per la seva aportació a [[Special:Version|MediaWiki]]",
-       "version-license-info": "MediaWiki és programari lliure, podeu redistribuir-lo i/o modificar-lo sota els termes de la Llicència Pública General GNU publicada per la Free Software Foundation, ja sigui de la seva versió 2 o (a elecció vostra) qualsevol versió posterior. \n\nMediaWiki es distribueix en l'esperança de ser d'utilitat, però SENSE CAP GARANTIA; ni tan sols la garantia implícita de COMERCIALITZACIÓ o ADEQUACIÓ A UNA FINALITAT DETERMINADA. En trobareu més detalls a  la Llicència Pública General GNU.\n\nAmb aquest programa heu d'haver rebut [{{SERVER}}{{SCRIPTPATH}}/COPYING una còpia de la Llicència Pública General GNU]; si no és així, adreceu-vos a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA o bé [//www.gnu.org/licenses/old-licenses/gpl-2.0.html llegiu-la en línia].",
+       "version-license-info": "MediaWiki és programari lliure, podeu redistribuir-lo i/o modificar-lo sota els termes de la Llicència Pública General GNU publicada per la Free Software Foundation, sigui de la seva versió 2 o (a elecció vostra) de qualsevol versió posterior. \n\nMediaWiki es distribueix en l'esperança de ser d'utilitat, però SENSE CAP GARANTIA; ni tan sols la garantia implícita de COMERCIALITZACIÓ o ADEQUACIÓ A UNA FINALITAT DETERMINADA. En trobareu més detalls a  la Llicència Pública General GNU.\n\nAmb aquest programa heu d'haver rebut [{{SERVER}}{{SCRIPTPATH}}/COPYING una còpia de la Llicència Pública General GNU]; si no és així, adreceu-vos a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA o bé [//www.gnu.org/licenses/old-licenses/gpl-2.0.html llegiu-la en línia].",
        "version-software": "Programari instal·lat",
        "version-software-product": "Producte",
        "version-software-version": "Versió",
        "specialpages-group-developer": "Eines de desenvolupador",
        "blankpage": "Pàgina en blanc",
        "intentionallyblankpage": "Pàgina intencionadament en blanc",
-       "external_image_whitelist": " #Deixeu aquesta línia exactament igual com està<pre>\n#Poseu fragments d'expressions regulars (regexps) (només la part entre els //) a sota\n#Aquests fragments es correspondran amb les URL d'imatges externes\n#Se'n mostraran com a imatges si coincideixen, i sinó es mostraran com a enllaços\n#Les línies que comencen amb un # es tracten com a comentaris\n#S'hi distingeixen majúscules i minúscules\n\n#Poseu tots els fragments regex al damunt d'aquesta línia. Deixeu aquesta línia exactament com està</pre>",
+       "external_image_whitelist": " #Deixeu aquesta línia exactament igual com està.<pre>\n#Poseu fragments d'expressions regulars (regex) (només la part entre els //) a sota.\n#Aquests fragments es correspondran amb els URL d'imatges externes.\n#Es mostraran com a imatges si coincideixen, i si no es mostraran com a enllaços.\n#Les línies que comencen amb un # es tracten com a comentaris.\n#S'hi distingeixen majúscules i minúscules.\n\n#Poseu tots els fragments regex al damunt d'aquesta línia. Deixeu aquesta línia exactament com està.</pre>",
        "tags": "Etiquetes de canvi vàlides",
        "tag-filter": "Filtre d'[[Special:Tags|etiquetes]]:",
        "tag-filter-submit": "Filtra",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetes}}]]: $2)",
        "tags-title": "Etiquetes",
-       "tags-intro": "Aquesta pàgina llista les etiquetes amb les què el programari pot marcar una modificació, i llur significat.",
+       "tags-intro": "Aquesta pàgina llista les etiquetes amb què el programari pot marcar una modificació, i el seu significat.",
        "tags-tag": "Nom de l'etiqueta",
        "tags-display-header": "Aparença de la llista de canvis",
        "tags-description-header": "Descripció completa del significat",
        "tags-create-submit": "Crea",
        "tags-create-no-name": "Heu d'especificar un nom d'etiqueta.",
        "tags-create-invalid-chars": "Els noms d'etiqueta no han de contenir comes (<code>,</code>) o barres (<code>/</code>).",
-       "tags-create-invalid-title-chars": "Els noms d'etiqueta no poden contenir caracters que no es poden usar en els títols de pàgina",
+       "tags-create-invalid-title-chars": "Els noms d'etiqueta no poden contenir caràcters que no es poden usar en els títols de pàgina.",
        "tags-create-already-exists": "L'etiqueta \"$1\" ja existeix.",
        "tags-create-warnings-above": "{{PLURAL:$2|S'ha registrat la següent advertència|S'han registrat les següents advertències}} durant la creació de l'etiqueta \"$1\":",
        "tags-create-warnings-below": "Voleu continuar creant l'etiqueta?",
        "tags-apply-not-allowed-multi": "No es permet aplicar manualment {{PLURAL:$2|l'etiqueta següent|les etiquetes següents}}: $1",
        "tags-update-no-permission": "No teniu permisos per a afegir o suprimir etiquetes de canvi de revisions individuals o entrades de registre.",
        "tags-update-add-not-allowed-one": "No es permet afegir manualment l'etiqueta «$1».",
-       "tags-update-add-not-allowed-multi": "No es permet afegir manualment {{PLURAL:$2|letiqueta següent|les etiquetes següents}}: $1",
+       "tags-update-add-not-allowed-multi": "No es permet afegir manualment {{PLURAL:$2|l'etiqueta següent|les etiquetes següents}}: $1",
        "tags-update-remove-not-allowed-one": "No es permet treure l’etiqueta «$1».",
-       "tags-update-remove-not-allowed-multi": "No es permet eliminar manualment {{PLURAL:$2|letiqueta següent|les etiquetes següents}}: $1",
+       "tags-update-remove-not-allowed-multi": "No es permet eliminar manualment {{PLURAL:$2|l'etiqueta següent|les etiquetes següents}}: $1",
        "tags-edit-title": "Modifica les etiquetes",
        "tags-edit-manage-link": "Gestiona les etiquetes",
        "tags-edit-revision-selected": "{{PLURAL:$1|Revisió seleccionada|Revisions seleccionades}} de [[:$2]]:",
+       "tags-edit-logentry-legend": "Afegeix o suprimeix etiquetes {{PLURAL:$1|d'aquesta entrada del registres|de totes les entrades del registre}}",
        "tags-edit-existing-tags": "Etiquetes existents:",
        "tags-edit-existing-tags-none": "''Cap''",
        "tags-edit-new-tags": "Etiquetes noves:",
        "tags-edit-chosen-placeholder": "Seleccioneu algunes etiquetes",
        "tags-edit-chosen-no-results": "No s’han trobat coincidències d’etiquetes",
        "tags-edit-reason": "Motiu:",
+       "tags-edit-revision-submit": "Aplica els canvis a {{PLURAL:$1|a aquesta revisió|$1 revisions}}",
+       "tags-edit-logentry-submit": "Aplica els canvis a {{PLURAL:$1|aquesta entrada de registre|$1 entrades de registre}}",
        "tags-edit-success": "S’han aplicat els canvis correctament.",
        "tags-edit-failure": "No s’han pogut aplicar els canvis:\n$1",
        "tags-edit-nooldid-title": "Revisió de l'objectiu no vàlida",
        "htmlform-select-badoption": "El valor que heu especificat no és una opció vàlida.",
        "htmlform-int-invalid": "El valor que heu especificat no és un nombre enter.",
        "htmlform-float-invalid": "El valor especificat no és un nombre.",
-       "htmlform-int-toolow": "El valor que heu especifcat està per sota del mínim de $1",
+       "htmlform-int-toolow": "El valor que heu especificat està per sota del mínim de $1.",
        "htmlform-int-toohigh": "El valor que heu especificat està per sobre del màxim de $1",
        "htmlform-required": "Aquest valor és necessari",
        "htmlform-submit": "Tramet",
        "htmlform-title-not-exists": "$1 no existeix.",
        "htmlform-user-not-exists": "<strong>$1</strong> no existeix.",
        "htmlform-user-not-valid": "<strong>$1</strong> no és nom d'usuari vàlid.",
-       "sqlite-has-fts": "$1, amb suport de búsqueda de text íntegre",
-       "sqlite-no-fts": "$1, sense supor de búsqueda de text íntegre",
+       "sqlite-has-fts": "$1, amb suport de cerca de text íntegre",
+       "sqlite-no-fts": "$1, sense supor de cerca de text íntegre",
        "logentry-delete-delete": "$1 {{GENDER:$2|ha esborrat}} la pàgina $3",
        "logentry-delete-restore": "$1 ha restaurat $3",
        "logentry-delete-event": "$1 {{GENDER:$2|ha canviat}} la visibilitat {{PLURAL:$5|d'un esdeveniment al registre|de $5 esdeveniments al registre}} de $3: $4",
        "logentry-newusers-create2": "El compte d'usuari $3 {{GENDER:$2|ha estat creat}} per $1",
        "logentry-newusers-byemail": "El compte d'usuari $3 {{GENDER:$2|ha estat creat}} per $1 i la contrasenya ha estat enviada per correu electrònic",
        "logentry-newusers-autocreate": "El compte d'usuari $1 {{GENDER:$2|ha estat creat}} automàticament",
+       "logentry-protect-protect": "$1 {{GENDER:$2|ha protegit}} $3 $4",
+       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|ha protegit}} $3 $4 [en cascada]",
+       "logentry-protect-modify": "$1 {{GENDER:$2|ha canviat}} el nivell de protecció de $3 $4",
+       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|ha canviat}} el nivell de protecció de $3 $4 [en cascada]",
        "logentry-rights-rights": "$1 {{GENDER:$2|ha canviat}} la pertinença de grup per $3 de $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|ha canviat}} la pertinença de grup per $3",
        "logentry-rights-autopromote": "$1 ha estat {{GENDER:$2|promogut}} automàticament de $4 a $5",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha carregat}} una nova versió de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|ha carregat}} $3",
        "log-name-managetags": "Registre de gestió d'etiquetes",
-       "log-description-managetags": "Aquesta pàgina té llistades les tasques de gestió referents a les [[Special:Tags|etiquetes]]. El registre conté només les accions dutes a terme manuament per un administrador; algunes etiquetes poden ser creades o eliminades pel programari wiki sense deixar inventariada una entrada en aquest registre.",
+       "log-description-managetags": "Aquesta pàgina té llistades les tasques de gestió referents a les [[Special:Tags|etiquetes]]. El registre conté només les accions dutes a terme manualment per un administrador; algunes etiquetes poden ser creades o eliminades pel programari wiki sense deixar inventariada una entrada en aquest registre.",
        "logentry-managetags-create": "$1 {{GENDER:$2|va crear}} l'etiqueta «$4»",
        "logentry-managetags-activate": "$1 {{GENDER:$2|ha activat}} l'etiqueta \"$4\" per a ser utilitzada en usuaris i bots",
        "logentry-managetags-deactivate": "$1 {{GENDER:$2|ha desactivat}} l'etiqueta \"$4\" per a ser utilitzada en usuaris i bots",
        "feedback-bugcheck": "Fantàstic! Comproveu que no sigui un dels [$1 problemes ja coneguts].",
        "feedback-bugnew": "Ja ho he comprovat. Informeu d'un nou problema",
        "feedback-bugornote": "Si podeu descriure un problema tècnic en detall, [$1 informeu-ne].\nAltrament, podeu fer servir un senzill formulari a continuació. El vostre comentari s'afegirà a la pàgina «[$3 $2]», juntament amb el vostre nom d'usuari i el navegador que esteu emprant.",
-       "feedback-cancel": "Canceŀla",
+       "feedback-cancel": "Cancela",
        "feedback-close": "Fet",
        "feedback-external-bug-report-button": "Arxiva una tasca tècnica",
        "feedback-dialog-title": "Envia el comentari",
        "api-error-publishfailed": "Error intern: el servidor no ha pogut publicar el fitxer temporal.",
        "api-error-stasherror": "S'ha produït un error en carregar el fitxer al dipòsit.",
        "api-error-stashedfilenotfound": "No s'ha trobat el fitxer de l'espai temporal quan es provava de carregar-lo d'allà.",
-       "api-error-stashpathinvalid": "El camí on s'havia trobar el fitxer de l'espai temporal no és vàlid.",
+       "api-error-stashpathinvalid": "El camí on s'havia de trobar el fitxer de l'espai temporal no és vàlid.",
        "api-error-stashfilestorage": "S'ha produït un error en emmagatzemar el fitxer en l'espai temporal.",
        "api-error-stashzerolength": "El servidor no ha pogut desar el fitxer a l'espai temporal perquè tenia longitud zero.",
        "api-error-stashnotloggedin": "Cal haver iniciat una sessió per desar fitxers en l'espai temporal de càrrega.",
        "duration-years": "$1 {{PLURAL:$1|any|anys}}",
        "duration-decades": "$1 {{PLURAL:$1|dècada|dècades}}",
        "duration-centuries": "$1 {{PLURAL:$1|segle|segles}}",
-       "duration-millennia": "$1 {{PLURAL:$1|mil·leni|mil·lenis}}",
+       "duration-millennia": "$1 {{PLURAL:$1|mil·lenni|mil·lennis}}",
        "rotate-comment": "Imatge girada $1 {{PLURAL:$1|grau|graus}} en el sentit de les agulles del rellotge",
        "limitreport-title": "Perfil de dades de l'analitzador:",
        "limitreport-cputime": "Temps d'ús de CPU",
        "limitreport-templateargumentsize": "Mida de l'argument de plantilla",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Profunditat màxima d'expansió",
-       "limitreport-expensivefunctioncount": "Número de funcions d'anàlisi dispendioses",
+       "limitreport-expensivefunctioncount": "Nombre de funcions d'anàlisi dispendioses",
        "expandtemplates": "Expansió de plantilles",
        "expand_templates_intro": "Aquesta pàgina especial expandeix de forma recursiva totes les plantilles d'un text donat.\nTambé expandeix les funcions sintàctiques, com ara <code><nowiki>{{</nowiki>#language:…}}</code>, i les variables predefinides, com <code><nowiki>{{</nowiki>CURRENTDAY}}</code> &mdash;de fet, gairebé tot que estigui entre claus dobles.",
        "expand_templates_title": "Títol per contextualitzar ({{FULLPAGENAME}}, etc):",
        "special-characters-group-ipa": "AFI",
        "special-characters-group-symbols": "Símbols",
        "special-characters-group-greek": "Grec",
-       "special-characters-group-cyrillic": "Ciríŀlic",
+       "special-characters-group-cyrillic": "Cirílic",
        "special-characters-group-arabic": "Aràbic",
        "special-characters-group-arabicextended": "Aràbic estès",
        "special-characters-group-persian": "Persa",
index 4f94977..114428f 100644 (file)
@@ -50,7 +50,7 @@
        "tog-showhiddencats": "Гайта къайлаха йолу категореш",
        "tog-norollbackdiff": "Юха яьккхиначул тӀаьхьа ма гайта версийн башхо",
        "tog-useeditwarning": "Хаамбе бина хийцамаш дӀаязцабеш аса болх дӀатосучу хенахь",
-       "tog-prefershttps": "Ð\94аима Ð»ÐµÐ»Ð° Ð¹Ðµ Ð»Ð°Ñ\80дина Ñ\81иÑ\81Ñ\82емин Ñ\87Ñ\83далар",
+       "tog-prefershttps": "СиÑ\81Ñ\82емин Ð´Ð¾Ð²Ð·Ð¸Ð¹Ñ\82ина Ñ\87Ñ\83л Ñ\82Ó\80еÑ\85Ñ\8cа Ð´Ð°Ð¸Ð¼Ð°Ð½ Ð»ÐµÐ»Ð°Ð´Ðµ Ð»Ð°Ñ\80дина Ð²Ð¾Ð²Ñ\88аÑ\85Ñ\82аÑ\81ар",
        "underline-always": "Даимна",
        "underline-never": "Цкъа а",
        "underline-default": "Лелае браузеран нисярца",
        "morenotlisted": "ХӀара могӀа буьззина бац.",
        "mypage": "Долахь йолу агӀо",
        "mytalk": "Сан дийцаре агӀо",
-       "anontalk": "Дийцаре хӀокху IP-адресна",
+       "anontalk": "Дийцаре",
        "navigation": "Навигаци",
        "and": "&#32;а",
        "qbfind": "Лахар",
        "userloginnocreate": "Довзийта",
        "logout": "Болх дӀаберзор",
        "userlogout": "Болх дӀаберзор",
-       "notloggedin": "Ð¥Ó\80инÑ\86а Ð° Ð°Ñ\85Ñ\8cа Ñ\81иÑ\81Ñ\82емин Ñ\87оÑ\85Ñ\8c Ð±Ð¾Ð»Ñ\85 Ð±ÐµÑ\88 Ð±Ð°Ñ\86",
+       "notloggedin": "ЦÓ\80аÑ\80Ñ\86а Ð´Ð¾Ñ\86Ñ\83Ñ\88",
        "userlogin-noaccount": "Декъашхочун дӀаяздар дац хьа?",
        "userlogin-joinproject": "Проектехь дӀаяздар кхоллар",
        "nologin": "Декъашхочун дӀаяздар дац хьа? '''$1'''.",
        "passwordreset-emailtext-ip": "{{SITENAME}} ($4) проектехь цхьам я ахьа хӀокху IP-адрес $1 тӀера хьа декъашхочун пароль кхоссар дехна,\nоьцу электронан адресца дихкина ду {{PLURAL:$3|1хӀара декъашхочун дӀаяздар|хӀара декъашхочун дӀаяздар}}:\n\n$2\n\n{{PLURAL:$3|ХӀара хана пароль|ХӀара хана паролаш}} лелар ю {{PLURAL:$5|$5 дийнахь}}.\nСистемин чугӀой харжа керла пароль. \nХьой пароль кхоссар дехна дацахь я хьалхалера пароль дага еънехь хӀума цадеш Ӏад битта хӀара хаам хьа йиш ю шира пароль лелаян.",
        "passwordreset-emailtext-user": "{{SITENAME}} ($4) проектера декъашхочо $1 хьа декъашхочун пароль кхоссар дехна,\nоьцу электронан адресца дихкина ду {{PLURAL:$3|1хӀара декъашхочун дӀаяздар|хӀара декъашхочун дӀаяздар}}:\n\n$2\n\n{{PLURAL:$3|ХӀара хана пароль|ХӀара хана паролаш}} лелар ю {{PLURAL:$5|$5 дийнахь}}.\nСистемин чугӀой харжа керла пароль. \nХьой пароль кхоссар дехна дацахь я хьалхалера пароль дага еънехь хӀума цадеш Ӏад битта хӀара хаам хьа йиш ю шира пароль лелаян.",
        "passwordreset-emailelement": "Декъашхочун цӀе: \n$1\n\nХанна йолу пароль: \n$2",
-       "passwordreset-emailsent": "Электронан хаам баийтина кхоьссинчу паролах лаьцна хаам чохь болуш.",
+       "passwordreset-emailsentemail": "Электронан хаам баийтина кхоьссинчу паролах лаьцна хаам чохь болуш.",
        "passwordreset-emailsent-capture": "Электронан хаам баийтина кхоьссинчу паролах лаьцна хаам чохь болуш. \nцуна йозане хьажа йиш ю лахахь.",
        "passwordreset-emailerror-capture": "Пароль кхоссаран хаам чохь болуш электронан кехат кхоьллина, цуна йоза хьажа йиш ю лахахь, амма иза {{GENDER:$2|декъашхочунга}} дӀадахьийта тар цаделира бахьнехь: $1",
        "changeemail": "Хийца электронан пошт",
        "duplicate-args-category": "Кепийн кхайкхамашкахь аргументаш юх-юха лелош йолу агӀонаш",
        "expensive-parserfunction-warning": "'''Тидам бе!''' Ресурсийн функцийн дехарш сов даьлла агӀонаш .\n\nДукху хилла ца деза {{PLURAL:$2|$2 дехар|$2 дехарш|1=цхьана дехар}}, хӀинца $1 {{PLURAL:$1|дехар}} ду.",
        "expensive-parserfunction-category": "Ресурсийн функцийн дехарш сов даьлла агӀонаш",
-       "post-expand-template-inclusion-warning": "Ð\94Ó\80аÑ\85Ñ\8cедаÑ\80: Ñ\8eкÑ\8aа Ñ\82оÑ\8cÑ\85на ÐºÐµÐ¿Ð°Ñ\88ан жамӀан барам тӀех бокха бу. Цхьайолу кепаш юкъа тухур яц.",
-       "post-expand-template-inclusion-category": "ЧÑ\83 Ð´Ñ\83Ñ\8cÑ\85кÑ\83Ñ\88 Ð´Ð¾Ð»Ñ\83 ÐºÐµÐ¿Ð°Ñ\88ан барам тӀех баьлла агӀонаш",
-       "post-expand-template-argument-category": "Ð\9aепаÑ\88ан аргументаш юкъахь йитина агӀонаш",
+       "post-expand-template-inclusion-warning": "Ð\94Ó\80аÑ\85Ñ\8cедаÑ\80: Ñ\8eкÑ\8aа Ñ\82оÑ\8cÑ\85на ÐºÐµÐ¿Ð¸Ð¹н жамӀан барам тӀех бокха бу. Цхьайолу кепаш юкъа тухур яц.",
+       "post-expand-template-inclusion-category": "ЧÑ\83 Ð´Ñ\83Ñ\8cÑ\85кÑ\83Ñ\88 Ð´Ð¾Ð»Ñ\83 ÐºÐµÐ¿Ð¸Ð¹н барам тӀех баьлла агӀонаш",
+       "post-expand-template-argument-category": "Ð\9aепийн аргументаш юкъахь йитина агӀонаш",
        "parser-template-loop-warning": "Карийна кепаш юкъахь хилла шад: [[$1]]",
        "parser-template-recursion-depth-warning": "Дозанал хьаладаьлла кӀоргенца юх юха дина кеп ($1)",
        "node-count-exceeded-category": "Шедийн дукхалла сов даьлла агӀонаш",
        "uploadbtn": "Файл чуяккхар",
        "reuploaddesc": "Юху гӀо файл чуйоккху агӀоне",
        "upload-tryagain": "ДӀадахьийта хийцина файлах лаьцнарг",
-       "uploadnologin": "Ð\90Ñ\85Ñ\8cа Ñ\81иÑ\81Ñ\82емин Ñ\87оÑ\85Ñ\8c Ð±Ð¾Ð»Ñ\85 Ð±ÐµÑ\88 Ð±Ð°Ñ\86",
+       "uploadnologin": "ЦÓ\80аÑ\80Ñ\86а Ð´Ð¾Ñ\86Ñ\83Ñ\88",
        "uploadnologintext": "Серверан чу файлаш яха хьо $1.",
        "uploaderror": "Файл чуяккхаран гӀалат",
        "upload-recreate-warning": "'''Тегам бе: иштта цӀе йолу файл дӀаяьккхина я цӀе хийцина.'''\n\nЛахахьа гойтуш ю хӀокху агӀона тептар:",
        "contributions": "{{GENDER:$1|Декъашхочун}} къинхьегам",
        "contributions-title": "{{GENDER:$1|Декъашхочун}} къинхьегам $1",
        "mycontris": "Сан къинхьегам",
+       "anoncontribs": "Къинхьегам",
        "contribsub2": "Къинхьегам $1 ($2)",
        "contributions-userdoesnotexist": "«$1» ишта декъашхочун дӀаяздар дац.",
        "nocontribs": "Дехарца хийцамаш цакарий.",
        "movenosubpage": "ХӀокху агӀона бухара агӀонаш яц.",
        "movereason": "Бахьана:",
        "revertmove": "юхаяккха",
-       "delete_and_move": "Цle а хуьйцуш дӀаяккха",
        "delete_and_move_text": "== ДӀаяккха хьокъ ю ==\nИ цӀе йолу аг1о «[[:$1]]» йолуш ю. \nЛаьий хьуна и дӀаяккха, цӀе хийца таро хилийта?",
        "delete_and_move_confirm": "ХӀаъ, дӀаяккха хӀара агӀо",
        "delete_and_move_reason": "ДӀаяьккхина цӀе хийца я таро хилийта  «[[$1]]»",
        "javascripttest": "JavaScript хьажар",
        "tooltip-pt-userpage": "Декъашхочун агӀо",
        "tooltip-pt-mytalk": "Сан дийцаре агlо",
+       "tooltip-pt-anontalk": "Сан IP адресан дийцаре агӀо",
        "tooltip-pt-preferences": "Хьан гlирс нисбар",
        "tooltip-pt-watchlist": "Ахьа тергам бо агӀонийн хийцаман могӀам",
        "tooltip-pt-mycontris": "Хьан нисдаран могӀам",
+       "tooltip-pt-anoncontribs": "ХӀокху IP-адресца бина хийцамийн могӀам",
        "tooltip-pt-login": "Кхузахь дӀаяздар кхолла мега, амма иза тӀедожийна дац.",
        "tooltip-pt-logout": "Дlадерзадо болх бар",
        "tooltip-pt-createaccount": "Шу йиш ю дӀаяздар кхоьллина системин чудаха, амма иза тӀедожийна дац.",
index 5d5f538..9af461a 100644 (file)
        "passwordreset-emailtext-ip": "‫کەسێک (لەوانەیە خۆت، بە ناونیشانی ئایپیی $1) داوای ڕیسێتکردنەوەی تێپەڕوشەکەت لە {{SITENAME}}دا ($4) کردووە. {{PLURAL:$3|ھەژماری بەکارھێنەریی ژێرەوە پەیوەندیی ھەیە|ھەژمارە بەکارھێنەرییەکانی ژێرەوە پەیوەندییان ھەیە}} بەم ناونیشانەی ئیمەیلەوە:\n\n$2\n\n{{PLURAL:$3|ئەم تێپەڕوشە کاتییە|ئەم تێپەڕوشە کاتییانە}} لە {{PLURAL:$5|ڕۆژێک|$5 ڕۆژ}}دا بەسەردەچێت.\nدەبێ بچیتە ژوورەوە و ھەر ئێستا تێپەڕوشەیەکی نوێ ھەڵبژێریت. ئەگەر کەسێکی تر ئەم داواکارییەی کردووە،\nیان ئەگەر تێپەڕوشە سەرەتاییەکەت ھاتووەتەوە بیرت و ئیتر ناتەوێ بیگۆڕی، دەتوانی گوێ بەم پەیامە نەدەیت و ھەر لە تێپەڕوشە کۆنەکەت کەڵک وەربگریت.",
        "passwordreset-emailtext-user": "‫بەکارھێنەر $1 لە {{SITENAME}} ڕیسێتکردنەوەی تێپەڕوشەکەت لە {{SITENAME}}دا ($4) کردووە. {{PLURAL:$3|ھەژماری بەکارھێنەریی ژێرەوە پەیوەندیی ھەیە|ھەژمارە بەکارھێنەرییەکانی ژێرەوە پەیوەندییان ھەیە}} بەم ناونیشانەی ئیمەیلەوە:\n\n$2\n\n{{PLURAL:$3|ئەم تێپەڕوشە کاتییە|ئەم تێپەڕوشە کاتییانە}} لە {{PLURAL:$5|ڕۆژێک|$5 ڕۆژ}}دا بەسەردەچێت.\nدەبێ بچیتە ژوورەوە و ھەر ئێستا تێپەڕوشەیەکی نوێ ھەڵبژێریت. ئەگەر کەسێکی تر ئەم داواکارییەی کردووە، یان ئەگەر تێپەڕوشە سەرەتاییەکەت ھاتووەتەوە بیرت و ئیتر ناتەوێ بیگۆڕی، \nدەتوانی گوێ بەم پەیامە نەدەیت و ھەر لە تێپەڕوشە کۆنەکەت کەڵک وەربگریت.",
        "passwordreset-emailelement": "ناوی بەکارھێنەری: \n$1\n\nتێپەڕوشەی کاتی: \n$2",
-       "passwordreset-emailsent": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا.",
+       "passwordreset-emailsentemail": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا.",
        "passwordreset-emailsent-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە.",
        "passwordreset-emailerror-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە، بەڵام ناردنەکەی بۆ {{GENDER:$2|بەکارھێنەر}} سەرکەوتوو نەبوو: $1",
        "changeemail": "گۆڕینی ناونیشانی ئیمەیل",
        "contributions": "بەشدارییەکانی {{GENDER:$1|بەکارھێنەر}}",
        "contributions-title": "بەشدارییەکانی بەکارھێنەر $1",
        "mycontris": "بەشدارییەکان",
+       "anoncontribs": "بەشدارییەکان",
        "contribsub2": "بۆ {{GENDER:$3|$1}} ($2)",
        "nocontribs": "هیچ گۆڕانکاریەکی هاوتای ئەم پێوەرانە نودۆزرایەوە",
        "uctop": "(ھەنووکە)",
        "movenosubpage": "ئەم پەڕەیە ھیچ ژێرپەڕەیەکی نییە.",
        "movereason": "ھۆکار:",
        "revertmove": "پێچەوانەکردنەوە",
-       "delete_and_move": "بیسڕەوە و بیگوازەوە",
        "delete_and_move_text": "== پێویستییەکانی سڕینەوە ==\nلاپەڕەی مەبەست \"[[:$1]]\" لە پێش‌دا هەیە.\nئایا دەتەوێ ئەوە بسڕیتەوە تا ڕێگە بۆ گواستنەوەی بکەیتەوە؟",
        "delete_and_move_confirm": "بەڵێ، پەڕەکە بسڕەوه",
        "delete_and_move_reason": "سڕایەوە بۆ کردنەوەی ڕیگە بۆ گواستنەوە لە «[[$1]]»ەوە",
        "tooltip-ca-nstab-main": "بینینی پەڕەی ناوەڕۆک",
        "tooltip-ca-nstab-user": "پەڕەی بەکارھێنەر تەماشا بکە",
        "tooltip-ca-nstab-media": "پەڕەی میدیا چاو لێ بکە",
-       "tooltip-ca-nstab-special": "ئەمە پەڕەیەکی تایبەتە، ناتوانی خودی ئەم پەڕە دەستکاری بکەیت",
+       "tooltip-ca-nstab-special": "ئەمە پەڕەیەکی تایبەتە و دەستکاری ناکرێت",
        "tooltip-ca-nstab-project": "بینینی پەڕەی پرۆژە",
        "tooltip-ca-nstab-image": "بینینی پەڕەی پەڕگە",
        "tooltip-ca-nstab-mediawiki": "بینینی پەیامی سیستەم",
index 522ff95..6839396 100644 (file)
@@ -62,6 +62,7 @@
        "tog-watchlisthidebots": "Na seznamu sledovaných stránek skrýt editace botů",
        "tog-watchlisthideminor": "Na seznamu sledovaných stránek skrýt malé editace",
        "tog-watchlisthideliu": "Na seznamu sledovaných stránek skrýt editace přihlášených uživatelů",
+       "tog-watchlistreloadautomatically": "Při změně nastavení automaticky aktualizovat seznam sledovaných stránek (vyžaduje JavaScript)",
        "tog-watchlisthideanons": "Na seznamu sledovaných stránek skrýt editace nepřihlášených uživatelů",
        "tog-watchlisthidepatrolled": "Skrýt patrolované editace ve sledovaných stránkách",
        "tog-watchlisthidecategorization": "Skrýt kategorizaci stránek",
        "morenotlisted": "Tento seznam není úplný.",
        "mypage": "Stránka",
        "mytalk": "Diskuse",
-       "anontalk": "Diskuse k této IP adrese",
+       "anontalk": "Diskuse",
        "navigation": "Navigace",
        "and": "&#32;a",
        "qbfind": "Hledání",
        "databaseerror-query": "Dotaz: $1",
        "databaseerror-function": "Funkce: $1",
        "databaseerror-error": "Chyba: $1",
+       "transaction-duration-limit-exceeded": "Aby nevznikalo velké replikační zpoždění, byla transakce přerušena, protože trvání zápisu ($1) překročilo $2sekundový limit.\nPokud měníte mnoho položek najednou, zkuste místo toho provést několik menších operací.",
        "laggedslavemode": "<strong>Upozornění:</strong> Stránka nemusí být aktuální.",
        "readonly": "Databáze je uzamčena",
        "enterlockreason": "Udejte důvod zamčení, včetně odhadu, za jak dlouho dojde k odemčení",
        "wrongpasswordempty": "Bylo zadáno prázdné heslo. Zkuste to znovu.",
        "passwordtooshort": "Heslo musí být dlouhé nejméně $1 {{PLURAL:$1|znak|znaky|znaků}}.",
        "passwordtoolong": "Hesla nemohou být delší než {{PLURAL:$1|1 znak|$1 znaky|$1 znaků}}.",
+       "passwordtoopopular": "Není možné používat běžně vybíraná hesla. Prosím vyberte si jiné, méně časté heslo.",
        "password-name-match": "Vaše heslo nesmí být stejné jako uživatelské jméno.",
        "password-login-forbidden": "Použití tohoto uživatelského jména a hesla bylo zakázáno.",
        "mailmypassword": "Poslat nové heslo",
        "passwordreset-emailtext-ip": "Někdo (patrně vy, z IP adresy $1) zažádal na {{grammar:6sg|{{SITENAME}}}} ($4) o nastavení nového hesla k vašemu účtu. K této adrese {{PLURAL:$3|je přiřazen následující účet|jsou přiřazeny následující účty}}:\n\n$2\n\n{{PLURAL:$3|Toto dočasné heslo|Tato dočasná hesla}} vyprší za {{PLURAL:$5|jeden den|$5 dny|$5 dnů}}.\nNyní byste se měli přihlásit a zvolit si nové heslo. Pokud tento požadavek poslal někdo jiný nebo jste si na své staré heslo vzpomněli, a nechcete ho tedy změnit, můžete tuto zprávu ignorovat a nadále používat původní heslo.",
        "passwordreset-emailtext-user": "{{gender:$1|Uživatel|Uživatelka}} $1 na {{grammar:6sg|{{SITENAME}}}} {{gender:$1|zažádal|zažádala}} na {{grammar:6sg|{{SITENAME}}}} ($4) o nastavení nového hesla k vašemu\núčtu. K této adrese {{PLURAL:$3|je přiřazen následující účet|jsou přiřazeny následující účty}}:\n\n$2\n\n{{PLURAL:$3|Toto dočasné heslo|Tato dočasná hesla}} vyprší {{PLURAL:$5|za jeden den|za $5 dny|za $5 dnů}}.\nNyní byste se měl(a) přihlásit a zvolit si nové heslo. Pokud tento požadavek\nposlal někdo jiný nebo jste si na své staré heslo vzpomněl(a), a nechcete ho\ntedy změnit, můžete tuto zprávu ignorovat a nadále používat původní heslo.",
        "passwordreset-emailelement": "Uživatelské jméno: \n$1\n\nDočasné heslo: \n$2",
-       "passwordreset-emailsent": "Pokud je to registrovaná emailová adresa k vašemu účtu, tak vám bude odeslán požadavek pro získání nového hesla.",
+       "passwordreset-emailsentemail": "Pokud je to registrovaná emailová adresa k vašemu účtu, tak vám bude odeslán požadavek pro získání nového hesla.",
        "passwordreset-emailsent-capture": "Byl odeslán e-mail pro získání nového hesla, který je zobrazen níže.",
        "passwordreset-emailerror-capture": "Byl vygenerován e-mail pro získání nového hesla, který je zobrazen níže, ale {{GENDER:$2|uživateli|uživatelce}} se ho nepodařilo odeslat: $1",
        "changeemail": "Změna nebo odstranění e-mailové adresy",
        "protectedtitles": "Zamčené názvy stránek",
        "protectedtitles-summary": "Tato stránka obsahuje seznam názvů, které jsou momentálně zamčeny proti založení. Seznam existujících zamčených stránek najdete na stránce [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "S těmito parametry nejsou zamčeny žádné názvy.",
+       "protectedtitles-submit": "Zobrazit názvy",
        "listusers": "Uživatelé",
        "listusers-editsonly": "Zobrazit pouze uživatele s editacemi",
        "listusers-creationsort": "Seřadit podle data registrace",
        "activeusers-hidebots": "Skrýt roboty",
        "activeusers-hidesysops": "Skrýt správce",
        "activeusers-noresult": "Nenalezen žádný uživatel.",
+       "activeusers-submit": "Zobrazit aktivní uživatele",
        "listgrouprights": "Práva skupin uživatelů",
        "listgrouprights-summary": "Toto je seznam uživatelských skupin definovaných na této wiki a&nbsp;jejich přístupových práv.\n\n[[{{MediaWiki:Listgrouprights-helppage}}|Podrobné informace o&nbsp;jednotlivých právech]]",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Udělená práva</span>\n* <span class=\"listgrouprights-revoked\">Odebraná práva</span>",
        "wlheader-showupdated": "Stránky, které se změnily od vaší poslední návštěvy, jsou zobrazeny '''tučně'''.",
        "wlnote": "Níže {{PLURAL:$1|je poslední změna|jsou poslední <strong>$1</strong> změny|je posledních <strong>$1</strong> změn}} za {{PLURAL:$2|poslední hodinu|poslední <strong>$2</strong> hodiny|posledních <strong>$2</strong> hodin}} do $4, $3.",
        "wlshowlast": "Ukázat posledních $1 hodin $2 dnů",
-       "watchlistall2": "všechny",
+       "watchlistall2": "všechno",
        "watchlist-hide": "Skrýt",
-       "wlshowtime": "Ukázat posledních:",
+       "watchlist-submit": "Zobrazit",
+       "wlshowtime": "Zobrazené období:",
        "wlshowhideminor": "malé editace",
        "wlshowhidebots": "boty",
        "wlshowhideliu": "registrované uživatele",
        "contributions": "Příspěvky {{GENDER:$1|uživatele|uživatelky}}",
        "contributions-title": "Příspěvky uživatele $1",
        "mycontris": "Příspěvky",
+       "anoncontribs": "Příspěvky",
        "contribsub2": "{{GENDER:$3|uživatele|uživatelky}} $1 ($2)",
        "contributions-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.",
        "nocontribs": "Nenalezeny žádné změny vyhovující kritériím.",
        "sp-contributions-search": "Zobrazení příspěvků",
        "sp-contributions-username": "IP adresa nebo uživatelské jméno:",
        "sp-contributions-toponly": "Zobrazit pouze editace na aktuální revizi",
-       "sp-contributions-newonly": "Zobrazovat pouze editace zakládající stránku",
+       "sp-contributions-newonly": "Zobrazit pouze editace zakládající stránku",
        "sp-contributions-submit": "Zobrazit",
        "whatlinkshere": "Odkazuje sem",
        "whatlinkshere-title": "Stránky odkazující na „$1“",
        "movenosubpage": "Tato stránka nemá žádné podstránky.",
        "movereason": "Důvod:",
        "revertmove": "vrátit",
-       "delete_and_move": "Smazat a přesunout",
        "delete_and_move_text": "==Je potřeba smazání==\n\nCílová stránka „[[:$1]]“ již existuje. Přejete si ji smazat pro uvolnění místa pro přesun?",
        "delete_and_move_confirm": "Ano, smazat cílovou stránku",
        "delete_and_move_reason": "Smazáno pro umožnění přesunu z „[[$1]]“",
        "tooltip-pt-preferences": "Vaše nastavení",
        "tooltip-pt-watchlist": "Seznam stránek, jejichž změny sledujete",
        "tooltip-pt-mycontris": "Seznam vašich příspěvků",
+       "tooltip-pt-anoncontribs": "Seznam editací provedených z této IP adresy",
        "tooltip-pt-login": "Doporučujeme vám přihlásit se, ovšem není to povinné.",
        "tooltip-pt-logout": "Odhlásit se",
        "tooltip-pt-createaccount": "Doporučujeme vytvořit si účet a přihlásit se, není to však povinné",
        "logentry-suppress-block": "$1 {{GENDER:$2|zablokoval|zablokovala|blokuje}} {{GENDER:$4|uživatele|uživatelku}} „$3“ s časem vypršení $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|změnil|změnila|mění}} nastavení bloku {{GENDER:$4|uživatele|uživatelky}} „$3“ s časem vypršení $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|naimportoval|naimportovala}} $3 načtením souboru",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|naimportoval|naimportovala}} $3 načtením souboru ($4 {{PLURAL:$4|revize|revize|revizí}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|naimportoval|naimportovala}} $3 z jiné wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|naimportoval|naimportovala}} $3 z $5 ($4 {{PLURAL:$4|revize|revize|revizí}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|sloučil|sloučila}} stránku $3 do $4 (revize po $5)",
        "logentry-move-move": "$1 {{GENDER:$2|přesunul|přesunula}} stránku $3 na $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|přesunul|přesunula}} stránku $3 na $4 bez založení přesměrování",
index b48fe02..1da3321 100644 (file)
        "moredotdotdot": "Малалла…",
        "mypage": "Страница",
        "mytalk": "Сӳтсе явни",
-       "anontalk": "Çак IP-адреса сӳтсе явни",
+       "anontalk": "Сӳтсе явни",
        "navigation": "Меню",
        "and": "&#32;тата",
        "qbfind": "Шырани",
        "userloginnocreate": "Кĕмелли",
        "logout": "Сеансне пĕтерни",
        "userlogout": "Тухрăр",
-       "notloggedin": "ЭÑ\81иÑ\80 Ñ\81айÑ\82а Ðºĕмен",
+       "notloggedin": "Ð\9aĕмен",
        "nologin": "Аккаунт çук-и? $1.",
        "nologinlink": "Çĕнĕ хутшăнакана регистрацилесси",
        "createaccount": "Аккаунт ту",
        "recentchangeslinked-page": "Страницă ячĕ:",
        "upload": "Файла кĕртесси",
        "uploadbtn": "Файла кĕрт",
-       "uploadnologin": "ЭÑ\81иÑ\80 Ñ\81айÑ\82а ÐºÄ\95мен.",
+       "uploadnologin": "Ð\9aÄ\95мен",
        "uploadnologintext": "Сирĕн $1 файлсем кĕртес тесен.",
        "uploaderror": "Файла кĕртне чухне йăнăш пулчĕ",
        "uploadlogpage": "Файлсене кĕртнине кăтартакан журнал",
        "contributions": "{{GENDER:$1|Усă куракан}} ӳсĕмĕсем",
        "contributions-title": "Усă куракан $1 хушни",
        "mycontris": "Хушни",
+       "anoncontribs": "Хушни",
        "contribsub2": "{{GENDER:$3|$1}} валли ($2)",
        "uctop": "(хальхи)",
        "month": "Уйăхран (тата маларах):",
        "movetalk": "Статьяна сӳтсе явнă страницăн ятне те улăштармалла",
        "movelogpage": "Ятне улăштарнин логĕ",
        "movereason": "Сăлтавĕ",
-       "delete_and_move": "Кăларса пăрахса куçарасси",
        "delete_and_move_text": "==Кăларса пăрахмалла==\n[[:$1|«$1»]] ятлă страница пур. Урăх ят парас тесе ăна кăларса пăрахмалла-и?",
        "delete_and_move_confirm": "Ку страницăна чăнах та кăларса пăрахмалла",
        "delete_and_move_reason": "Ятне улăштарма кăларса пăрахнă \"[[$1]]\"",
        "importlogpage": "Импорт журналĕ",
        "tooltip-pt-userpage": "Сирĕн хутшăнакан страници",
        "tooltip-pt-mytalk": "Сирĕн канашлу страници",
+       "tooltip-pt-anontalk": "IP адресне сӳтсе явни",
        "tooltip-pt-preferences": "Сирĕн ĕнерлевсем",
        "tooltip-pt-watchlist": "Эсир пăхакан страницисем",
+       "tooltip-pt-anoncontribs": "Ку IP адреспа тӳрлетнисем",
        "tooltip-pt-logout": "Сеансне пĕтер",
        "tooltip-ca-talk": "Статьяна сӳтсе явасси",
        "tooltip-ca-edit": "Эсир ку страницӑна тӳрлетме пултаратӑр. Тархасшӑн ҫырса хӑваричен страницӑ мӗнле пулассине пӑхӑр.",
index f59beea..e914771 100644 (file)
        "passwordreset-emailtext-ip": "Nogen (sandsynligvis dig, fra IP-adressen $1) har anmodet om at få nulstillet din adgangskode til {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brugerkonto er associeret|De følgende brugerkonti er associerede}} med denne e-mailadresse:\n\n$2\n\n{{PLURAL:$3|Denne midlertidige adgangskode|Disse midlertidige adgangskoder}} vil udløbe om {{PLURAL:$5|en dag|$5 dage}}.\nDu bør logge på og vælge en ny adgangskode nu. Hvis en anden end dig har lavet denne anmodning, eller hvis du er kommet i tanke om din oprindelig adgangskode og ikke længere ønsker at ændre den, kan du ignorere denne meddelelse og fortsætte med at bruge din gamle adgangskode.",
        "passwordreset-emailtext-user": "Brugeren $1 på {{SITENAME}} har anmodet om at få nulstillet din adgangskode til {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brugerkonto er associeret|De følgende brugerkonti er associerede}} med denne e-mailadresse:\n\n$2\n\n{{PLURAL:$3|Denne midlertidige adgangskode|Disse midlertidige adgangskoder}} vil udløbe om {{PLURAL:$5|en dag|$5 dage}}.\nDu bør logge på og vælge en ny adgangskode nu. Hvis en anden end dig har lavet denne anmodning, eller hvis du er kommet i tanke om din oprindelig adgangskode og ikke længere ønsker at ændre den, kan du ignorere denne meddelelse og fortsætte med at bruge din gamle adgangskode.",
        "passwordreset-emailelement": "Brugernavn: \n$1\n\nMidlertidig adgangskode: \n$2",
-       "passwordreset-emailsent": "Hvis dettte er en registreret e-mail-adresse til din konto, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
+       "passwordreset-emailsentemail": "Hvis dettte er en registreret e-mail-adresse til din konto, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
        "passwordreset-emailsent-capture": "En e-mail om nulstilling af adgangskode, som vist nedenfor, er blevet sendt.",
        "passwordreset-emailerror-capture": "En mail om nulstilling af adgangskode, som vist nedenfor, blev genereret, men det lykkedes ikke at sende den til {{GENDER:$2|bruger}}: $1",
        "changeemail": "Ændr eller fjern e-mailadresse",
        "wlnote": "Nedenfor ses {{PLURAL:$1|den seneste ændring|de seneste <strong>$1</strong> ændringer}} i {{PLURAL:$2|den sidste time|de sidste <strong>$2</strong> timer}} op til den $3 kl. $4.",
        "wlshowlast": "Vis de seneste $1 timer $2 dage",
        "watchlistall2": "alle",
+       "watchlist-hide": "Skjul",
+       "wlshowtime": "Vis seneste:",
+       "wlshowhideminor": "mindre ændringer",
+       "wlshowhidebots": "robotter",
+       "wlshowhideliu": "registrerede brugere",
+       "wlshowhideanons": "anonyme brugere",
+       "wlshowhidepatr": "patruljerede redigeringer",
+       "wlshowhidemine": "mine redigeringer",
        "watchlist-options": "Indstillinger for overvågningslisten",
        "watching": "Tilføjer overvågning …",
        "unwatching": "Fjerner overvågning …",
        "contributions": "{{GENDER:$1|Brugerbidrag}}",
        "contributions-title": "Brugerbidrag for $1",
        "mycontris": "Bidrag",
+       "anoncontribs": "Bidrag",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Brugerkontoen \"$1\" er ikke registreret.",
        "nocontribs": "Ingen ændringer er fundet som opfylder disse kriterier.",
        "movenosubpage": "Denne side har ingen undersider.",
        "movereason": "Begrundelse:",
        "revertmove": "gendan",
-       "delete_and_move": "Slet og flyt",
        "delete_and_move_text": "==Sletning nødvendig==\n\nArtiklen \"[[:$1]]\" eksisterer allerede. Vil du slette den for at gøre plads til flytningen?",
        "delete_and_move_confirm": "Ja, slet siden",
        "delete_and_move_reason": "Slettet for at gøre plads til flytning fra \"[[$1]]\"",
index 3d7f124..4f207d6 100644 (file)
        "tog-watchlisthidebots": "Bearbeitungen durch Bots in der Beobachtungsliste ausblenden",
        "tog-watchlisthideminor": "Kleine Bearbeitungen in der Beobachtungsliste ausblenden",
        "tog-watchlisthideliu": "Bearbeitungen angemeldeter Benutzer in der Beobachtungsliste ausblenden",
+       "tog-watchlistreloadautomatically": "Die Beobachtungsliste automatisch neu laden, wenn ein Filter geändert wurde (erfordert JavaScript)",
        "tog-watchlisthideanons": "Bearbeitungen anonymer Benutzer (IP-Adressen) in der Beobachtungsliste ausblenden",
        "tog-watchlisthidepatrolled": "Kontrollierte Änderungen in der Beobachtungsliste ausblenden",
        "tog-watchlisthidecategorization": "Kategorisierungen von Seiten ausblenden",
        "morenotlisted": "Diese Liste ist nicht vollständig.",
        "mypage": "Eigene Seite",
        "mytalk": "Diskussion",
-       "anontalk": "Diskussionsseite dieser IP",
+       "anontalk": "Diskussionsseite",
        "navigation": "Navigation",
        "and": "&#32;und",
        "qbfind": "Finden",
        "databaseerror-query": "Abfrage: $1",
        "databaseerror-function": "Funktion: $1",
        "databaseerror-error": "Fehler: $1",
+       "transaction-duration-limit-exceeded": "Um eine hohe Nachbildungsverzögerung zu vermeiden, wurde diese Transaktion abgebrochen, da die Schreibdauer ($1) die zweite Grenze von $2 überschritten hat. Falls du viele Objekte auf einmal änderst, versuche stattdessen, mehrere kleine Operationen auszuführen.",
        "laggedslavemode": "<strong>Achtung:</strong> Die angezeigte Seite könnte unter Umständen nicht die letzten Bearbeitungen enthalten.",
        "readonly": "Datenbank gesperrt",
        "enterlockreason": "Bitte gib einen Grund ein, warum die Datenbank gesperrt werden soll und eine Abschätzung über die Dauer der Sperrung",
        "wrongpasswordempty": "Es wurde kein Passwort eingegeben. Bitte versuche es erneut.",
        "passwordtooshort": "Passwörter müssen mindestens {{PLURAL:$1|1 Zeichen|$1 Zeichen}} lang sein.",
        "passwordtoolong": "Passwörter können nicht länger als {{PLURAL:$1|ein|$1}} Zeichen sein.",
+       "passwordtoopopular": "Häufig ausgewählte Passwörter können nicht verwendet werden. Bitte wähle ein einzigartigeres Passwort aus.",
        "password-name-match": "Dein Passwort muss sich von deinem Benutzernamen unterscheiden.",
        "password-login-forbidden": "Die Verwendung dieses Benutzernamens und Passwortes ist nicht erlaubt.",
        "mailmypassword": "Passwort zurücksetzen",
        "passwordreset-emailtext-ip": "Jemand mit der IP-Adresse $1, wahrscheinlich du selbst, hat eine Zurücksetzung deines Passworts bei {{SITENAME}} angefordert ($4). {{PLURAL:$3|Das folgende Benutzerkonto ist|Die folgenden Benutzerkonten sind}} mit dieser E-Mail-Adresse verknüpft:\n\n$2\n\n{{PLURAL:$3|Dieses temporäre Passwort läuft|Diese temporären Passwörter laufen}} innerhalb von {{PLURAL:$5|einem Tag|$5 Tagen}} ab.\nDu solltest dich anmelden und ein neues Passwort vergeben. Falls jemand anderes diese Anfrage getätigt hat oder du dich wieder an dein ursprüngliches Passwort erinnern kannst und es nicht länger ändern möchtest, kannst du diese Nachricht ignorieren und weiterhin dein altes Passwort benutzen.",
        "passwordreset-emailtext-user": "Benutzer $1 bei {{SITENAME}} hat eine Zurücksetzung deines Passworts bei {{SITENAME}} angefordert ($4). {{PLURAL:$3|Das folgende Benutzerkonto ist|Die folgenden Benutzerkonten sind}} mit dieser E-Mail-Adresse verknüpft:\n\n$2\n\n{{PLURAL:$3|Dieses temporäre Passwort läuft|Diese temporären Passwörter laufen}} innerhalb von {{PLURAL:$5|einem Tag|$5 Tagen}} ab. Du solltest dich anmelden und ein neues Passwort vergeben. Falls jemand anderes diese Anfrage getätigt hat oder du dich wieder an dein ursprüngliches Passwort erinnern kannst und es nicht ändern möchtest, kannst du diese Nachricht ignorieren und weiterhin dein altes Passwort benutzen.",
        "passwordreset-emailelement": "Benutzername: \n$1\n\nTemporäres Passwort: \n$2",
-       "passwordreset-emailsent": "Falls dies eine registrierte E-Mail-Adresse für dein Benutzerkonto ist, wird eine Passwortzurücksetzungs-E-Mail an diese Adresse versandt.",
+       "passwordreset-emailsentemail": "Falls dies eine registrierte E-Mail-Adresse für dein Benutzerkonto ist, wird eine Passwortzurücksetzungs-E-Mail an diese Adresse versandt.",
+       "passwordreset-emailsentusername": "Falls es eine dazugehörige registrierte E-Mail-Adresse gibt, wird eine Passwort-Zurücksetzungs-E-Mail versandt.",
        "passwordreset-emailsent-capture": "Eine Passwortzurücksetzungs-E-Mail wurde versandt, die unten angezeigt wird.",
        "passwordreset-emailerror-capture": "Die unten angezeigte Passwortzurücksetzungs-E-Mail wurde generiert, allerdings ist der Versand an {{GENDER:$2|den Benutzer|die Benutzerin}} gescheitert: $1",
        "changeemail": "E-Mail-Adresse ändern oder entfernen",
        "recentchanges-legend-heading": "'''Legende:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (siehe auch die [[Special:NewPages|Liste neuer Seiten]])",
        "recentchanges-legend-plusminus": "''(±123)''",
+       "recentchanges-submit": "Anzeigen",
        "rcnotefrom": "Angezeigt {{PLURAL:$5|wird die Änderung|werden die Änderungen}} seit <strong>$3, $4</strong> (max. <strong>$1</strong> Einträge).",
        "rclistfrom": "Nur Änderungen seit $3, $2 Uhr zeigen.",
        "rcshowhideminor": "Kleine Änderungen $1",
        "mostrevisions": "Seiten mit den meisten Versionen",
        "prefixindex": "Alle Seiten (mit Präfix)",
        "prefixindex-namespace": "Alle Seiten mit Präfix (Namensraum $1)",
+       "prefixindex-submit": "Anzeigen",
        "prefixindex-strip": "Präfix in der Liste abschneiden",
        "shortpages": "Kurze Seiten",
        "longpages": "Lange Seiten",
        "protectedpages-performer": "Geschützt von",
        "protectedpages-params": "Schutzparameter",
        "protectedpages-reason": "Grund",
+       "protectedpages-submit": "Seiten anzeigen",
        "protectedpages-unknown-timestamp": "Unbekannt",
        "protectedpages-unknown-performer": "Unbekannter Benutzer",
        "protectedtitles": "Geschützte Seitennamen",
        "protectedtitles-summary": "Diese Seite listet Titel auf, die derzeit vor der Erstellung geschützt sind. Für eine Liste vorhandener geschützter Seiten, siehe „[[{{#special:ProtectedPages}}|{{int:protectedpages}}]]“.",
        "protectedtitlesempty": "Zurzeit sind mit den angegebenen Parametern keine Seiten zur Neuerstellung gesperrt.",
+       "protectedtitles-submit": "Titel anzeigen",
        "listusers": "Benutzerverzeichnis",
        "listusers-editsonly": "Zeige nur Benutzer mit Beiträgen",
        "listusers-creationsort": "Nach Erstelldatum sortieren",
        "activeusers-hidebots": "Bots ausblenden",
        "activeusers-hidesysops": "Administratoren ausblenden",
        "activeusers-noresult": "Keine Benutzer gefunden.",
+       "activeusers-submit": "Aktive Benutzer anzeigen",
        "listgrouprights": "Benutzergruppenrechte",
        "listgrouprights-summary": "Dies ist eine Liste der in diesem Wiki definierten Benutzergruppen und der damit verbundenen Rechte.\nZusätzliche Informationen über einzelne Rechte können [[{{MediaWiki:Listgrouprights-helppage}}|hier]] gefunden werden.",
        "listgrouprights-key": "Legende:\n* <span class=\"listgrouprights-granted\">Gewährtes Recht</span>\n* <span class=\"listgrouprights-revoked\">Entzogenes Recht</span>",
        "wlshowlast": "Zeige die Änderungen der letzten $1 Stunden, $2 Tage.",
        "watchlistall2": "alle",
        "watchlist-hide": "Ausblenden",
-       "wlshowtime": "Zeige Änderungen der letzten",
+       "watchlist-submit": "Anzeigen",
+       "wlshowtime": "Anzuzeigende Zeitperiode:",
        "wlshowhideminor": "Kleine Bearbeitungen",
        "wlshowhidebots": "Bots",
        "wlshowhideliu": "Registrierte Benutzer",
        "contributions": "{{GENDER:$1|Benutzerbeiträge}}",
        "contributions-title": "Benutzerbeiträge von „$1“",
        "mycontris": "Beiträge",
+       "anoncontribs": "Beiträge",
        "contribsub2": "Von {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Das Benutzerkonto „$1“ ist nicht vorhanden.",
        "nocontribs": "Es wurden keine Benutzerbeiträge mit diesen Kriterien gefunden.",
        "whatlinkshere-hidelinks": "Links $1",
        "whatlinkshere-hideimages": "Dateilinks $1",
        "whatlinkshere-filters": "Filter",
+       "whatlinkshere-submit": "Los",
        "autoblockid": "Automatische Sperrung #$1",
        "block": "Benutzer sperren",
        "unblock": "Benutzer freigeben",
        "movenosubpage": "Diese Seite hat keine Unterseiten.",
        "movereason": "Grund:",
        "revertmove": "zurück verschieben",
-       "delete_and_move": "Löschen und verschieben",
        "delete_and_move_text": "== Löschung erforderlich ==\n\nDie Seite „[[:$1]]“ existiert bereits. Möchtest du diese löschen, um die Seite verschieben zu können?",
        "delete_and_move_confirm": "Ja, Seite löschen",
        "delete_and_move_reason": "gelöscht, um Platz für die Verschiebung von „[[$1]]“ zu machen",
        "tooltip-pt-preferences": "Deine Einstellungen",
        "tooltip-pt-watchlist": "Liste der von dir beobachteten Seiten",
        "tooltip-pt-mycontris": "Liste eigener Beiträge",
+       "tooltip-pt-anoncontribs": "Eine Liste der Bearbeitungen, die von dieser IP-Adresse gemacht wurden",
        "tooltip-pt-login": "Sich anzumelden wird gerne gesehen, ist jedoch nicht zwingend erforderlich.",
        "tooltip-pt-logout": "Abmelden",
        "tooltip-pt-createaccount": "Wir ermutigen dich dazu, ein Benutzerkonto zu erstellen und dich anzumelden. Es ist jedoch nicht zwingend erforderlich.",
        "exif-compression-4": "CCITT Gruppe 4 Faxcodierung",
        "exif-copyrighted-true": "Geschützt",
        "exif-copyrighted-false": "Urheberrechtsstatus nicht festgelegt",
+       "exif-photometricinterpretation-0": "Schwarzweiß (Weiß ist 0)",
+       "exif-photometricinterpretation-1": "Schwarzweiß (Schwarz ist 0)",
+       "exif-photometricinterpretation-3": "Palette",
+       "exif-photometricinterpretation-4": "Transparenzmaske",
+       "exif-photometricinterpretation-5": "Getrennt (Wahrscheinlich CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC-Kodierung)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU-Kodierung)",
+       "exif-photometricinterpretation-32803": "Farbfilteranordnung",
+       "exif-photometricinterpretation-34892": "Linear roh",
        "exif-unknowndate": "Unbekanntes Datum",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Horizontal gespiegelt",
index d5e79de..c97d34b 100644 (file)
        "october-date": "Tışrino Verên $1",
        "november-date": "Tışrino Peyên $1",
        "december-date": "Kanun $1",
-       "pagecategories": "{{PLURAL:$1|Kategori|Kategoriy}}",
+       "pagecategories": "{{PLURAL:$1|Kategoriye|Kategoriyi}}",
        "category_header": "Pelê ke kategoriya \"$1\" tede derê",
        "subcategories": "Kategoriyê bınêni",
        "category-media-header": "Dosyeyê ke kategoriya \"$1\" derê",
        "broken-file-category": "Peleye ke gıreyê dosyeyanê ğeletan muhtewa kenê",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "Heqa cı de",
-       "article": "Wesiqe",
+       "article": "Pela zerreki",
        "newwindow": "(pençereyê newey de beno a)",
        "cancel": "Bıtexelne",
        "moredotdotdot": "Vêşi...",
        "morenotlisted": "Vêşi lista nêbi...",
-       "mypage": "Per",
+       "mypage": "Pele",
        "mytalk": "Mesac",
-       "anontalk": "Pela werênayışê nê IPy",
+       "anontalk": "Werênayış",
        "navigation": "Pusula",
        "and": "&#32;u",
        "qbfind": "Bıvêne",
        "collapsible-collapse": "Kılm ke",
        "collapsible-expand": "Hera ke",
        "confirmable-confirm": "{{GENDER:$1|Şıma }} do emeli?",
-       "confirmable-yes": "E",
+       "confirmable-yes": "Eya",
        "confirmable-no": "Nê",
        "thisisdeleted": "Bıvêne ya zi $1 peyser biya?",
        "viewdeleted": "$1 bıvêne?",
        "red-link-title": "$1 (pele çıniya)",
        "sort-descending": "Rêzkerdışo kêmbiyaye",
        "sort-ascending": "Rêzkerdışo zêdiyaye",
-       "nstab-main": "Wesiqe",
+       "nstab-main": "Pele",
        "nstab-user": "Pela karberi",
        "nstab-media": "Pela medya",
        "nstab-special": "Pela xase",
        "passwordreset-emailtext-ip": "Jeweri, {{SITENAME}} ra (ma heta şımayê, $1 IP adresi ra) ($4) teferuatê hesabdê şıma  va wa biyaro xo viri. Karbero ke cêrdeyo {{PLURAL:$3|hesaba|eno hesaba}} ena e-posta adresiya aleqey cı esto:\n\n$2\n\n{{PLURAL:$3|ena parola idaretena|ena parola idareten}} {{PLURAL:$5|jew roc|$5  roca}}rêya.\nEna parolaya deqewe de u xorê ju parolaya newi bıweçine. Parolaya şıma emaya şıma viri se  yana  ena e-posta şıma nê weştase u şıma qayıl niye parolaya xo bıvurnese, ena mesacer peygoş bıkerê.",
        "passwordreset-emailtext-user": "$1 enê karberi, {{SITENAME}}  ra ($4) teferuatê hesab dê şıma  va wa biyaro xo viri. Karbero ke cêrdeyo {{PLURAL:$3|hesaba|eno hesaba}} ena e-posta adresiya aleqey cı esto:\n\n$2\n\n{{PLURAL:$3|ena parola idaretena|ena parola idareten}} {{PLURAL:$5|jew roc|$5  roca}}rêya.\nEna parolaya deqewe de u xorê ju parolaya newi bıweçine. Parolaya şıma emaya şıma viri se  yana  ena e-posta şıma nê weştase u şıma qayıl niye parolaya xo bıvurnese, ena mesacer peygoş bıkerê.",
        "passwordreset-emailelement": "Nameyê karberi: \n$1\n\nParolaya vêrdiye: \n$2",
-       "passwordreset-emailsent": "Yew e-posteyê esterıtışê parola rışiya.",
+       "passwordreset-emailsentemail": "Eke na seba hesabê şıma yew adresa e-posteyê qeydına, yew e-posteyê parola nênkerdışi rışiyeno.",
        "passwordreset-emailsent-capture": "Yew e-posteyê esterıtışê parolayo ke rışiya, no cêr mocniyayo.",
        "passwordreset-emailerror-capture": "Yew e-posteyê esterıtışê parolayo ke rışiya, no cêr mocniyayo, ema {{GENDER:$2|karber}}i rê rıştış de mıwefeq nêbi: $1",
        "changeemail": "E-posta adresa xo bıvurnê",
        "nonunicodebrowser": "'''DİQET: Browserê şıma u unicode yewbini nêgeni. Qey izin dayişê vurnayişê pelan: Karakteri ke ASCII niyê; zerreyê qutiyê vurnayişi de kodi (cod) şiyes-şiyes aseni.'''",
        "editingold": "'''İkaz: Şımayé rewizyon da kehan da perer d vırnayış kené.'''\nVanése qeyd k,lakin rewziyoné veréni dé vınibé.",
        "yourdiff": "pêverronayiş",
-       "copyrightwarning": "'''Recayê ikazi:''' Sita da {{SITENAME}} ra iştıraqi pêro umışin da $2 zerredeyo (teferruata rê $1'i bıvinê).\n\nİştıraqê şıma, şıma kayıl niyê ke yewna merdumi kerpeyina bıvurnê yana yewna caya ra vılakerê se, iştıraq mekewê.<br />\nFına zi qayılê ke  iştıraq kewê, Şıma qayılê kê şar vaco eno nuşte felani nuşnayo yana resmi meqeman ra zanayışê cı  u malumatê cı esto/ Xoseri cayan ra groti rê şıma qerenti danê. '''Tiya dı, şıma wêrê telifira mısade nêgroto se eserê cı tiya vıla mekerê! '''",
-       "copyrightwarning2": "Ney bızane ke nuşteyê ke şıma ruşneni (şaweni) keyepelê {{SITENAME}} herkes eşkeno nê nuşteyanê şıma ser kay bıkero. Eke şıma qayil niye kes bıvurno, nuşteyanê xo meerze ita. <br />\nWexta ke şıma nuşte zi erzeni ita; şıma gani taahhud bıde koti ra ardo (qey teferruati referans: $1).",
+       "copyrightwarning": "'''Recaya iqazi:'''Sita {{SITENAME}} ra iştıraqi pêro umışiya $2 zerredeyo (teferuatan rê $1 bıvênê).\n\nİştıraqê şıma, şıma qayıl niyê ke yewna merdumi kerpeyina bıvurnê ya zi yewna cayi ra vıla kerê ke, iştıraq mekewê.<br />\nFına zi qayılê ke iştıraq kewê, şıma qayılê ke şar vaco eno nuşte fılan kesi nusnayo ya zi meqemanê resmiyan ra zanayışê cı û malumatê cı esto / cayanê xoseran ra gırewtışi rê şıma garanti danê. '''Tiya de şıma werê telifi ra ke mısade nêgırewto, eserê cı tiya vıla mekerê! '''",
+       "copyrightwarning2": "Ney bızanê ke nuşteyê ke şıma ruşnenê (şawenê) keyepela {{SITENAME}} herkes eşkeno nê nuşteyanê şıma ser kay bıkero. Eke şıma qayil niyê kes bıvurno, nuşteyanê xo meerzê ita. <br />\nWexto ke şıma nuşteyi zi erzenê ita; şıma gani teahud bıdê koti ra ardo (qandê teferuati ra referans: $1).",
        "longpageerror": "'''Xırab: Dergeya nuşte dê şıma nezdi {{PLURAL:$1|kilobayto|$1 kilobayto}}, feqet {{PLURAL:$2|kilobayt|$2 kilobayt}} ra vêşiyo. Qeyd biyayişê cı nêbeno'''",
        "readonlywarning": "'''Diqet: Semedê mıqayti, database kılit biyo. No sebeb ra vurnayişê şıma qayd nêbeno. Nuşteyanê şıma yewna serkar eşkeno wedaro u pey ra şıma eşkeni reyna ita de qayd bıker'''\n\nSerkar o ke kılit kerdo; no beyanat dayo: $1",
        "protectedpagewarning": "'''Diqet: No pel pawyeno, teyna serkari eşkeni bıvurni.'''\nWexta ke şıma no pel vurneni diqet bıkeri:",
        "revdelete-nooldid-text": "Şıma vıraştışê nê fonksiyoni rê ya yew çımraviyarnayışo waşte diyar nêkerdo, çımraviyarnayışo diyarkerde çıniyo, ya ki şıma wazenê ke çımraviyarnayışê nıkayêni bınımnê.",
        "revdelete-no-file": "Dosya diyarkerdiye çıniya.",
        "revdelete-show-file-confirm": "Şıma eminê ke wazenê çımraviyarnayışê esterıtey na dosya \"<nowiki>$1</nowiki>\" $2 ra $3 de bıvênê?",
-       "revdelete-show-file-submit": "E",
+       "revdelete-show-file-submit": "Eya",
        "logdelete-selected": "{{PLURAL:$1|Qeydbiyayışo weçinıte|Qeydbiyayışê weçinıtey}}:",
        "revdelete-confirm": "Ma rica keno testiq bike ti ena hereket keno u ti zano neticeyanê herketanê xo u ti ena hereket pê ena [[{{MediaWiki:Policy-url}}|polici]] ra keno.",
        "revdelete-suppress-text": "Wedardış gani '''tenya''' nê halanê cêrênan de bıxebıtiyo:\n* Melumatê kıfırio mıhtemel\n* Melumatê şexio bêmınasıb\n*: ''adresa keyey u numreyê têlefoni, numreyê siğorta sosyale, uêb.''",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) bıvênên",
        "searchmenu-exists": "''Ena 'Wikipediya de ser \"[[:$1]]\" yew pel esto'''",
        "searchmenu-new": "<strong>Na wiki de pela \"[[:$1]]\" vıraze!</strong> {{PLURAL:$2|0=|Sewbina pela ke şıma geyrayê cı aye bıvênê.|Yew zi neticanê cıgeyrayışê xo bıvênê.}}",
-       "searchprofile-articles": "Pelê tedeestey",
+       "searchprofile-articles": "Pelê zerreki",
        "searchprofile-images": "Multimedya",
        "searchprofile-everything": "Heme çi",
        "searchprofile-advanced": "Raverşiyaye",
        "listfiles_count": "Versiyoni",
        "listfiles-show-all": "Asayışa versiyonandé verénan",
        "listfiles-latestversion": "Versiyono verin",
-       "listfiles-latestversion-yes": "E",
+       "listfiles-latestversion-yes": "Eya",
        "listfiles-latestversion-no": "Nê",
        "file-anchor-link": "Dosya",
        "filehist": "Ravêrdê dosya",
        "unwatchedpages": "Pelanê seyrnibiyeyî",
        "listredirects": "Listeya Hetenayışan",
        "listduplicatedfiles": "Lista dosyeyanê ke kopyaya cı vêniyena",
-       "unusedtemplates": "Şablonê ke nê xebtênê",
+       "unusedtemplates": "Şablonê ke nêguriyenê",
        "unusedtemplatestext": "no pel, {{ns:template}} pelê ke pelê binan de nêaseni, ninan keno.",
        "unusedtemplateswlh": "linkanê binî",
        "randompage": "Pela raştameyiye",
        "statistics-header-edits": "Îstatistikê vurnayîşî",
        "statistics-header-users": "İstatistikê karberi",
        "statistics-header-hooks": "Îstatistiksê binî",
-       "statistics-articles": "Pelanê tedesteyî",
+       "statistics-articles": "Pelê zerreki",
        "statistics-pages": "Peli",
        "statistics-pages-desc": "Pelanê hemî ke wîkî de estê, pelanê mineqeşeyî, redireksiyon ucb... dehil o.",
        "statistics-files": "Dosyayê bar biye",
        "lonelypagestext": "Ena pelî link nibiyê ya zi pelanê binî {{SITENAME}} de transclude biy.",
        "uncategorizedpages": "Pelê ke kategorize nêbiyê",
        "uncategorizedcategories": "Kategoriyê ke kategorize nêbiyê",
-       "uncategorizedimages": "Dosyayê ke bê kategoriyê",
+       "uncategorizedimages": "Dosyeyê ke bêkategoriyê",
        "uncategorizedtemplates": "Şablonê ke bêkategoriyê",
        "unusedcategories": "Kategoriyê ke nêgureniyê",
-       "unusedimages": "Dosyeyê ke nê xebtênê",
+       "unusedimages": "Dosyeyê ke nêguriyenê",
        "wantedcategories": "Kategoriyê ke waziyayê",
-       "wantedpages": "Peleye ke waştênê",
+       "wantedpages": "Pelê ke waziyayê",
        "wantedpages-badtitle": "sernuşte meqbul niyo: $1",
-       "wantedfiles": "Dosyeyê cıgeyriyayey",
+       "wantedfiles": "Dosyeyê cıgeyriyayeyi",
        "wantedfiletext-cat": "Dosyaya cêrên karvıstedeya lakin çınya. Mewcud dosyayan de xeriba miyan de liste bena. Xırabiya wınisin dana <del>ateber</del>. Zewbi zi, şırê pela da dosyeyê ke çınyaya [[:$1]].",
        "wantedfiletext-nocat": "Dosyeyê cêrêni estê lekin karnêvıstê. Dosyeyê xeribi liste benê. bo babeta dano <del>ateber</del>",
        "wantedtemplates": "Şablonê ke waziyenê",
        "prefixindex-namespace": "Peleyê Veroleyıni ($1 cay nami)",
        "prefixindex-strip": "Listeya réz bıyayışi",
        "shortpages": "Pelê kılmeki",
-       "longpages": "Peleyê dergeki",
+       "longpages": "Pelê dergeki",
        "deadendpages": "Pelê nêgıredayeyi",
        "deadendpagestext": "Ena pelan ke {{SITENAME}} de zerrî ey de link çini yo.",
-       "protectedpages": "Pelê pawıtiyey",
+       "protectedpages": "Pelê pawıteyi",
        "protectedpages-indef": "têna pawıteyê bêmuddeti",
        "protectedpages-summary": "Listeya ena peler newke pawıtiya.Sername de  ena lista rê pawıte vıraştışi rê [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] bıvinê.",
        "protectedpages-cascade": "Kilit biyaye ke teyna cascadiye",
        "protectedpages-reason": "Sebeb",
        "protectedpages-unknown-timestamp": "Nêzanaye",
        "protectedpages-unknown-performer": "Karbero nêzanaye",
-       "protectedtitles": "Sernameyê pawıtiyey",
+       "protectedtitles": "Sernameyê pawıteyi",
        "protectedtitlesempty": "pê ney parametreyan sernuşteyê pawite çinê",
        "listusers": "Listeyê Karberan",
        "listusers-editsonly": "Teyna karberan bimucne ke ey nuştê",
        "usercreated": "$2 de $1 {{GENDER:$3|viraziya}}",
        "newpages": "Pelê newey",
        "newpages-username": "Nameyê karberi:",
-       "ancientpages": "Wesiqeyê ke vurnayışê ciyê peyeni tewr kehani",
+       "ancientpages": "Pelê kehenêri",
        "move": "Bere",
        "movethispage": "Ena pele bere",
        "unusedimagestext": "Enê dosyey estê, feqet zerrey yew pele de wedardey niyê.\nXo vira mekerê ke, sıteyê webiê bini şenê direkt ebe URLi yew dosya ra gırê bê, u wına şenê verba gurênayışo feal de tiya hewna lista bê.",
        "sp-deletedcontributions-contribs": "iştıraqi",
        "linksearch": "Gıreyê teberi cı geyrê",
        "linksearch-pat": "bıgêr motif:",
-       "linksearch-ns": "Heruna namey:",
+       "linksearch-ns": "Heruna nameyi:",
        "linksearch-ok": "Cı geyre",
        "linksearch-text": "Jokeri ê zey \"*.wikipedia.org\"i benê ke bıgureniyê.\nTewr senık yew sewiya serêna cayê tesiri lazıma, mesela \"*.org\".<br />\nQeydeyê {{PLURAL:$2|protoqol|protoqoli}}:destegbiyayey: $1 (qet yew qeydeyo hesabiyaye http:// ke name nêbiyo).",
        "linksearch-line": "$1, $2 ra link biya",
        "deletepage": "Pele bestere",
        "confirm": "Tesdiq ke",
        "excontent": "Zerreko verén: '$1'",
-       "excontentauthor": "zerrekê cı: \"$1\", û iştıraqkerê cı tenya \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]]) bi",
+       "excontentauthor": "Zerreko verên: \"$1\", (teyna \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|vatış]]) iştiraq kerd bı.",
        "exbeforeblank": "behsê verê esteriyayişi: '$1'",
        "delete-confirm": "\"$1\" bestere",
        "delete-legend": "Bestere",
        "undelete-error-short": "Eka dosyayê biyereno feqet yew ğelet biya: $1",
        "undelete-error-long": "hewn a kerdışê na dosyayi wexta tepiya geriyenê xeta vıraziya:\n\n$1",
        "undelete-show-file-confirm": "\"<nowiki>$1</nowiki>\" şıma emin î dosyaya revizyonê no $2 $3 tarixi bıvini?",
-       "undelete-show-file-submit": "E",
-       "namespace": "Heruna namey:",
+       "undelete-show-file-submit": "Eya",
+       "namespace": "Heruna nameyi:",
        "invert": "Weçinıtışi açarne",
        "tooltip-invert": "nameyo ke nışan biyo (u nameyo elekeyın zi nışanyyayo se) vurnayışan  zerrekan nımtışi re ena dore tesdiqi nışan kerê",
        "namespace_association": "Heruna nameyanê elaqedaran",
        "contributions": "İştıraqê {{GENDER:$1|karber}}i",
        "contributions-title": "Dekerdenê karber de $1",
        "mycontris": "İştıraqi",
+       "anoncontribs": "İştıraqi",
        "contribsub2": "Qandê {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Hesabê karberi \"$1\" qeyd nêbiyo.",
        "nocontribs": "Ena kriteriya de vurnayîş çini yo.",
        "ipb-unblock-addr": "$1 a bik",
        "ipb-unblock": "Yew adresê IPî ya zi nameyê karberî blok bike",
        "ipb-blocklist": "Blokî ke hama estê ey bivîne",
-       "ipb-blocklist-contribs": "Ser $1 îştîrakî",
+       "ipb-blocklist-contribs": "Qandê {{GENDER:$1|}} ra iştıraqi",
        "unblockip": "Hesabê karberî a bike",
        "unblockiptext": "Cıreştışê nuştışê IP ya zi karberio ke ver ra gêriyayo, seba peyser barkerdışi dey rê formê cêrêni bıgurenên.",
        "ipusubmit": "Enê kılitkerdışi wedare",
        "movenotallowedfile": "desturê şıma çino, şıma pelan bıkırışi",
        "cant-move-user-page": "desturê şıma çino, şıma pelanê karberani bıkırışi (bê pelê cerıni).",
        "cant-move-to-user-page": "desturê şıma çino, şıma yew peli bıkırışi pelê yew karberi.",
-       "newtitle": "Nameyê newi:",
+       "newtitle": "Sernameyo newe:",
        "move-watch": "Peler seyr ke",
        "movepagebtn": "Pele bere",
        "pagemovedsub": "Berdışi kerd temam",
        "movenosubpage": "pelê bınıni yê no peli çino.",
        "movereason": "Sebeb:",
        "revertmove": "peyser biya",
-       "delete_and_move": "Bestere û bere",
        "delete_and_move_text": "==gani hewn a bıbıo/bıesteriyo==\n\n\" no [[:$1]]\" name de yew pel ca ra esto. şıma wazeni pê hewn a kerdışê ey peli vurnayişê nameyi bıkeri?",
        "delete_and_move_confirm": "Eya, na pele bestere",
        "delete_and_move_reason": "\"[[$1]]\" qande nami re ca akerdışi re besteriyaye",
        "thumbnail_gd-library": "Configurasyonê katalog ê GDî tam niyo:funksiyonê $1î vînî biyo",
        "thumbnail_image-missing": "Dosya vînî biyo: $1",
        "import": "Peleyi import bik",
-       "importinterwiki": "Împortê transwîkî",
+       "importinterwiki": "Zewbina wiki ra ard",
        "import-interwiki-text": "qey kırıştışê zerreyi yew wiki u pel bıvıcinê.\ntarixê revizyon u nameyê nuştoxi pawyene.\nkarê zerredayişê benateyê wikiyani[[Special:Log/import|zerreyê rocaneyê kırıştî de]] qeyd beno.",
        "import-interwiki-history": "Qeydanê pele pêrune kopya ke",
        "import-interwiki-templates": "Şablonan pêro zerre ke",
        "tooltip-t-specialpages": "Yew lista pelanê xasanê pêroyinan",
        "tooltip-t-print": "Hewl versiyona ploğnayışa na perer",
        "tooltip-t-permalink": "Gırêyo daimi be ena versiyonê pele",
-       "tooltip-ca-nstab-main": "Perra muhtevay bıvin",
+       "tooltip-ca-nstab-main": "Pela zerreki bıvêne",
        "tooltip-ca-nstab-user": "Pela karberi bıvêne",
        "tooltip-ca-nstab-media": "Pela medya bıvêne",
        "tooltip-ca-nstab-special": "Na pelaya xas a, şıma nêşenê sero vurnayış bıkerê",
        "pageinfo-redirectsto-info": "melumat",
        "pageinfo-contentpage": "Zey jû pela zerreki hesebiyena",
        "pageinfo-contentpage-yes": "Eya",
-       "pageinfo-protect-cascading": "Sıtarkerdey tiya cı ra yenê war",
+       "pageinfo-protect-cascading": "Sıtarkerdeyi tiya cı ra yenê war",
        "pageinfo-protect-cascading-yes": "Eya",
        "pageinfo-protect-cascading-from": "Sıtarkerdey cı ra yenê war",
        "pageinfo-category-info": "Şınasiya kategoriye",
        "duplicate-defaultsort": "'''Tembe:''' Hesıbyaye sırmey ratnayış de \"$2\" sırmey ratnayış de \"$1\"i nêhesıbneno.",
        "version": "Versiyon",
        "version-extensions": "Ekstensiyonî ke ronaye",
-       "version-skins": "Cıldi",
+       "version-skins": "Bar kerde bejni",
        "version-specialpages": "Pelanê xasiyan",
        "version-parserhooks": "Çengelê Parserî",
        "version-variables": "Vurnayeyî",
        "tags-description-header": "Tam arezekerdışê maneyê cı",
        "tags-active-header": "Activ o?",
        "tags-hitcount-header": "Vurnayîşî ke etiket biyê",
-       "tags-active-yes": "E",
+       "tags-active-yes": "Eya",
        "tags-active-no": "Nê",
        "tags-edit": "bıvurne",
        "tags-hitcount": "$1 {{PLURAL:$1|vurnayış|vurnayışi}}",
index c3a47ae..28ff4b6 100644 (file)
@@ -79,6 +79,7 @@
        "tog-watchlisthidebots": "Απόκρυψη των επεξεργασιών των bot από τη λίστα παρακολούθησης",
        "tog-watchlisthideminor": "Απόκρυψη των επεξεργασιών μικρής σημασίας από τη λίστα παρακολούθησης",
        "tog-watchlisthideliu": "Απόκρυψη επεξεργασιών συνδεδεμένων χρηστών από τη λίστα παρακολούθησης",
+       "tog-watchlistreloadautomatically": "Φορτώσετε εκ νέου η λίστα παρακολούθησής αυτόματα κάθε φορά που ένα φίλτρο έχει αλλάξει (Απαιτείται JavaScript)",
        "tog-watchlisthideanons": "Απόκρυψη επεξεργασιών ανωνύμων χρηστών από τη λίστα παρακολούθησης",
        "tog-watchlisthidepatrolled": "Απόκρυψη ελεγμένων επεξεργασιών από τη λίστα παρακολούθησης",
        "tog-watchlisthidecategorization": "Απόκρυψη κατηγοριοποίησης σελίδων",
        "wrongpasswordempty": "Ο κωδικός πρόσβασης που εισάχθηκε ήταν κενός. Παρακαλούμε προσπαθήστε ξανά.",
        "passwordtooshort": "Οι κωδικοί πρέπει να περιέχουν τουλάχιστον {{PLURAL:$1|1 χαρακτήρα|$1 χαρακτήρες}}.",
        "passwordtoolong": "Οι κωδικοί πρόσβασης δεν μπορούν να υπερβαίνουν {{PLURAL:$1|τον 1 χαρακτήρα|τους $1 χαρακτήρες}}.",
+       "passwordtoopopular": "Συνήθως επιλέγονται οι κωδικοί πρόσβασης δεν μπορούν να χρησιμοποιηθούν. Παρακαλώ επιλέξτε μια πιο μοναδικό κωδικό πρόσβασης.",
        "password-name-match": "Ο κωδικός σου θα πρέπει να είναι διαφορετικός από το όνομα χρήστη σου.",
        "password-login-forbidden": "Η χρήση αυτού του ονόματος χρήστη και συνθηματικού έχουν  απαγορευτεί.",
        "mailmypassword": "Επαναφορά κωδικού",
        "passwordreset-emailtext-ip": "Κάποιος (πιθανώς εσείς, από την διεύθυνση IP $1) ζήτησε την επαναφορά του κωδικού σας σε {{SITENAME}} ($4).  {{PLURAL:$3|Ο ακόλουθος λογαριασμός|Οι ακόλουθοι λογαριασμοί}} χρήστη συνδέονται με αυτή τη διεύθυνση e-mail:\n\n$2\n\n{{PLURAL:$3|Αυτός ο προσωρινός κωδικός πρόσβασης θα λήξει|Αυτοί οι προσωρινοί κωδικοί πρόσβασης θα λήξουν}} σε {{PLURAL:$5|μία ημέρα|$5 ημέρες}}.\nΘα πρέπει να συνδεθείτε τώρα και να επιλέξετε ένα νέο κωδικό. Αν κάποιος άλλος έκανε αυτό το αίτημα ή αν έχετε θυμηθεί τον αρχικό κωδικό πρόσβασής σας, και δεν επιθυμείτε πια να τον αλλάξετε, μπορείτε να αγνοήσετε αυτό το μήνυμα και να συνεχίσετε να χρησιμοποιείτε τον παλιό σας κωδικό πρόσβασης.",
        "passwordreset-emailtext-user": "Ο χρήστης $1 στη {{SITENAME}} ζήτησε μια επαναφορά του κωδικού πρόσβασης σας σε {{SITENAME}} ($4). {{PLURAL:$3|Ο ακόλουθος λογαριασμός|Οι ακόλουθοι λογαριασμοί}} χρήστη συνδέονται με αυτή τη διεύθυνση e-mail:\n\n$2\n\n{{PLURAL:$3|Αυτός ο προσωρινός κωδικός πρόσβασης θα λήξει| Αυτοί οι προσωρινοί κωδικοί πρόσβασης θα λήξουν}} σε {{PLURAL:$5| μία ημέρα| $5 ημέρες}}.\nΘα πρέπει να συνδεθείτε τώρα και να επιλέξετε ένα νέο κωδικό. Αν κάποιος άλλος έκανε αυτό το αίτημα ή αν έχετε θυμηθεί τον αρχικό κωδικό πρόσβασής σας, και δεν επιθυμείτε πια να τον αλλάξετε, μπορείτε να αγνοήσετε αυτό το μήνυμα και να συνεχίσετε να χρησιμοποιείτε τον παλιό σας κωδικό πρόσβασης.",
        "passwordreset-emailelement": "Όνομα χρήστη: \n$1\n\nΠροσωρινός κωδικός πρόσβασης:\n$2",
-       "passwordreset-emailsent": "Αν αυτή είναι η καταχωρυμένη διεύθυνση email για τον λογαριασμό σας, τότε θα σταλεί ένα μήνυμα email αρχικοποίησης κωδικού.",
+       "passwordreset-emailsentemail": "Αν αυτή είναι η καταχωρυμένη διεύθυνση email για τον λογαριασμό σας, τότε θα σταλεί ένα μήνυμα email αρχικοποίησης κωδικού.",
        "passwordreset-emailsent-capture": "Έχει αποσταλεί email επαναφοράς κωδικού, το οποίο φαίνεται πιο κάτω.",
        "passwordreset-emailerror-capture": "Ένα email επαναφοράς κωδικού έχει δημιουργηθεί, το οποίο φαίνεται πιο κάτω, αλλά απέτυχε η αποστολή του στο  {{GENDER:$2|χρήστη}}: $1",
        "changeemail": "Αλλαγή ή αφαίρεση της διεύθυνσης ηλεκτρονικού ταχυδρομείου",
        "revisionasof": "Αναθεώρηση της $1",
        "revision-info": "Αναθεώρηση ως προς $1 από {{GENDER:$6|τον|την}} $2 $7",
        "previousrevision": "← Παλαιότερη αναθεώρηση",
-       "nextrevision": "Î\9dεÏ\8eÏ\84εÏ\81η Î±Î½Î±Î¸ÎµÏ\8eÏ\81ηÏ\83η &rarr;",
+       "nextrevision": "Î\9dεÏ\8cÏ\84εÏ\81η Î±Î½Î±Î¸ÎµÏ\8eÏ\81ηÏ\83η â\86\92",
        "currentrevisionlink": "Τελευταία αναθεώρηση",
        "cur": "τρέχουσα",
        "next": "επόμενη",
        "suppressionlog": "Κατάλογος διαγραφών",
        "suppressionlogtext": "Παρακάτω βρίσκεται μία λίστα με τις διαγραφές και τις φραγές σχετικό  με περιεχόμενο που έχει αποκρυβεί από τους διαχειριστές.\nΔείτε την [[Special:BlockList|λίστα φραγών IP]] για τις τρέχουσες λειτουργικές απαγορεύσεις και φραγές.",
        "mergehistory": "Συγχώνευση ιστορικών σελίδων",
-       "mergehistory-header": "Αυτή η σελίδα σας επιτρέπει να συγχωνεύσετε τις εκδόσεις από το ιστορικό μίας σελίδας πηγής σε μια νεώτερη σελίδα.\nΣιγουρευτείτε ότι αυτή η αλλαγή θα διατηρήσει την συνοχή του ιστορικού της σελίδας.",
+       "mergehistory-header": "Αυτή η σελίδα σας επιτρέπει να συγχωνεύσετε αναθεωρήσεις από το ιστορικό κάποιας σελίδας προέλευσης σε νεότερη σελίδα.\nΣιγουρευτείτε ότι αυτή η αλλαγή θα διατηρήσει τη συνοχή του ιστορικού της σελίδας.",
        "mergehistory-box": "Συγχώνευση εκδόσεων δυο σελίδων:",
        "mergehistory-from": "Σελίδα πηγής:",
        "mergehistory-into": "Σελίδα προορισμού:",
        "notargettext": "Δεν έχετε καθορίσει ένα χρήστη ή μια σελίδα προορισμού για να εκτελεσθεί αυτή η λειτουργία.",
        "nopagetitle": "Δεν υπάρχει τέτοια σελίδα στόχος",
        "nopagetext": "Η σελίδα στόχος που καταχωρίσατε δεν υπάρχει.",
-       "pager-newer-n": "{{PLURAL:$1|1 Î½ÎµÏ\8eÏ\84εÏ\81οÏ\85|$1 Î½ÎµÏ\8eτερων}}",
+       "pager-newer-n": "{{PLURAL:$1|1 Î½ÎµÏ\8cÏ\84εÏ\81οÏ\85|$1 Î½ÎµÏ\8cτερων}}",
        "pager-older-n": "{{PLURAL:$1|1 παλαιότερο|$1 παλαιότερα}}",
        "suppress": "Περιορισμός",
        "querypage-disabled": "Αυτή η ειδική σελίδα είναι απενεργοποιημένη για λόγους απόδοσης.",
        "contributions": "Συνεισφορές {{GENDER:$1|χρήστη}}",
        "contributions-title": "Συνεισφορές χρήστη για {{GENDER:$1|τον|την}} $1",
        "mycontris": "Συνεισφορές",
+       "anoncontribs": "Συνεισφορές",
        "contribsub2": "Για {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Ο λογαριασμός χρήστη «$1» δεν είναι εγγεγραμμένος.",
        "nocontribs": "Δεν βρέθηκαν αλλαγές με αυτά τα κριτήρια.",
        "movenosubpage": "Αυτή η σελίδα δεν έχει υποσελίδες.",
        "movereason": "Αιτία:",
        "revertmove": "επαναφορά",
-       "delete_and_move": "Διαγραφή και μετακίνηση",
        "delete_and_move_text": "==Χρειάζεται διαγραφή.==\n\nΤο άρθρο [[:$1]] υπάρχει ήδη. Θέλετε να το διαγράψετε για να εκτελεσθεί η μετακίνηση;",
        "delete_and_move_confirm": "Ναι, να διαγραφεί η σελίδα.",
        "delete_and_move_reason": "Διαγράφηκε για να δημιουργήσει χώρο για μετακίνηση από το \"[[$1]]\"",
        "filedelete-current-unregistered": "Το συγκεκριμένο αρχείο \"$1\" δεν υπάρχει στη βάση δεδομένων.",
        "filedelete-archive-read-only": "Το αρχείο καταλόγου \"$1\" είναι μη εγγράψιμο από τον διακομιστή.",
        "previousdiff": "← Παλαιότερη επεξεργασία",
-       "nextdiff": "Î\9dεÏ\8eτερη επεξεργασία →",
+       "nextdiff": "Î\9dεÏ\8cτερη επεξεργασία →",
        "mediawarning": "'''Προειδοποίηση''': Το αρχείο αυτό μπορεί να περιέχει κακοπροαίρετο κώδικα.\nΕκτελώντας το, μπορεί να βλάψει το σύστημα του υπολογιστή σας.",
        "imagemaxsize": "Όριο μεγέθους εικόνων:<br />''(στις σελίδες περιγραφής εικόνων)''",
        "thumbsize": "Μέγεθος μικρογραφίας:",
index 4bec8e2..38347bf 100644 (file)
@@ -35,6 +35,7 @@
        "tog-watchlisthidebots": "Hide bot edits from the watchlist",
        "tog-watchlisthideminor": "Hide minor edits from the watchlist",
        "tog-watchlisthideliu": "Hide edits by logged in users from the watchlist",
+       "tog-watchlistreloadautomatically": "Reload the watchlist automatically whenever a filter is changed (JavaScript required)",
        "tog-watchlisthideanons": "Hide edits by anonymous users from the watchlist",
        "tog-watchlisthidepatrolled": "Hide patrolled edits from the watchlist",
        "tog-watchlisthidecategorization": "Hide categorization of pages",
        "morenotlisted": "This list is not complete.",
        "mypage": "Page",
        "mytalk": "Talk",
-       "anontalk": "Talk for this IP address",
+       "anontalk": "Talk",
        "navigation": "Navigation",
        "and": "&#32;and",
        "qbfind": "Find",
        "databaseerror-query": "Query: $1",
        "databaseerror-function": "Function: $1",
        "databaseerror-error": "Error: $1",
+       "transaction-duration-limit-exceeded": "In order to avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, trying doing multiple smaller operations instead.",
        "laggedslavemode": "<strong>Warning:</strong> Page may not contain recent updates.",
        "readonly": "Database locked",
        "enterlockreason": "Enter a reason for the lock, including an estimate of when the lock will be released",
        "wrongpasswordempty": "Password entered was blank.\nPlease try again.",
        "passwordtooshort": "Passwords must be at least {{PLURAL:$1|1 character|$1 characters}}.",
        "passwordtoolong": "Passwords cannot be longer than {{PLURAL:$1|1 character|$1 characters}}.",
+       "passwordtoopopular": "Commonly chosen passwords cannot be used. Please choose a more unique password.",
        "password-name-match": "Your password must be different from your username.",
        "password-login-forbidden": "The use of this username and password has been forbidden.",
        "mailmypassword": "Reset password",
        "passwordreset-emailtext-ip": "Someone (probably you, from IP address $1) requested a reset of your\npassword for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}\nassociated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
        "passwordreset-emailtext-user": "User $1 on {{SITENAME}} requested a reset of your password for {{SITENAME}}\n($4). The following user {{PLURAL:$3|account is|accounts are}} associated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
        "passwordreset-emailelement": "Username:\n$1\n\nTemporary password:\n$2",
-       "passwordreset-emailsent": "If this is a registered email address for your account, then a password reset email will be sent.",
+       "passwordreset-emailsentemail": "If this is a registered email address for your account, then a password reset email will be sent.",
+       "passwordreset-emailsentusername": "If there is a corresponding registered email address, then a password reset email will be sent.",
        "passwordreset-emailsent-capture": "A password reset email has been sent, which is shown below.",
        "passwordreset-emailerror-capture": "A password reset email was generated, which is shown below, but sending it to the {{GENDER:$2|user}} failed: $1",
        "changeemail": "Change or remove email address",
        "recentchanges-legend-bot": "{{int:recentchanges-label-bot}}",
        "recentchanges-legend-unpatrolled": "{{int:recentchanges-label-unpatrolled}}",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
+       "recentchanges-submit": "Show",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfrom": "Show new changes starting from $2, $3",
        "rcshowhideminor": "$1 minor edits",
        "prefixindex": "All pages with prefix",
        "prefixindex-namespace": "All pages with prefix ($1 namespace)",
        "prefixindex-summary": "",
+       "prefixindex-submit": "Show",
        "prefixindex-strip": "Strip prefix in list",
        "shortpages": "Short pages",
        "shortpages-summary": "",
        "protectedpages-performer": "Protecting user",
        "protectedpages-params": "Protection parameters",
        "protectedpages-reason": "Reason",
+       "protectedpages-submit": "Display pages",
        "protectedpages-unknown-timestamp": "Unknown",
        "protectedpages-unknown-performer": "Unknown user",
        "protectedpages-unknown-reason": "—",
        "protectedtitles": "Protected titles",
        "protectedtitles-summary": "This page lists titles that are currently protected from creation. For a list of existing pages that are protected, see [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "No titles are currently protected with these parameters.",
+       "protectedtitles-submit": "Display titles",
        "listusers": "User list",
        "listusers-summary": "",
        "listusers-editsonly": "Show only users with edits",
        "usercreated": "{{GENDER:$3|Created}} on $1 at $2",
        "newpages": "New pages",
        "newpages-summary": "",
+       "newpages-submit": "Show",
        "newpages-username": "Username:",
        "ancientpages": "Oldest pages",
        "ancientpages-summary": "",
        "specialloguserlabel": "Performer:",
        "speciallogtitlelabel": "Target (title or {{ns:user}}:username for user):",
        "log": "Logs",
+       "logeventslist-submit": "Show",
        "all-logs-page": "All public logs",
        "alllogstext": "Combined display of all available logs of {{SITENAME}}.\nYou can narrow down the view by selecting a log type, the username (case-sensitive), or the affected page (also case-sensitive).",
        "logempty": "No matching items in log.",
        "cachedspecial-refresh-now": "View latest.",
        "categories": "Categories",
        "categories-summary": "",
+       "categories-submit": "Show",
        "categoriespagetext": "The following {{PLURAL:$1|category contains|categories contain}} pages or media.\n[[Special:UnusedCategories|Unused categories]] are not shown here.\nAlso see [[Special:WantedCategories|wanted categories]].",
        "categoriesfrom": "Display categories starting at:",
        "special-categories-sort-count": "sort by count",
        "activeusers-hidebots": "Hide bots",
        "activeusers-hidesysops": "Hide administrators",
        "activeusers-noresult": "No users found.",
+       "activeusers-submit": "Display active users",
        "listgrouprights": "User group rights",
        "listgrouprights-summary": "The following is a list of user groups defined on this wiki, with their associated access rights.\nThere may be [[{{MediaWiki:Listgrouprights-helppage}}|additional information]] about individual rights.",
        "listgrouprights-key": "Legend:\n* <span class=\"listgrouprights-granted\">Granted right</span>\n* <span class=\"listgrouprights-revoked\">Revoked right</span>",
        "wlshowlast": "Show last $1 hours $2 days",
        "watchlistall2": "all",
        "watchlist-hide": "Hide",
-       "wlshowtime": "Show last:",
+       "watchlist-submit": "Show",
+       "wlshowtime": "Period of time to display:",
        "wlshowhideminor": "minor edits",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "registered users",
        "delete-confirm": "Delete \"$1\"",
        "delete-legend": "Delete",
        "historywarning": "<strong>Warning:</strong> The page you are about to delete has a history with $1 {{PLURAL:$1|revision|revisions}}:",
+       "historyaction-submit": "Show",
        "confirmdeletetext": "You are about to delete a page along with all of its history.\nPlease confirm that you intend to do this, that you understand the consequences, and that you are doing this in accordance with [[{{MediaWiki:Policy-url}}|the policy]].",
        "actioncomplete": "Action complete",
        "actionfailed": "Action failed",
        "contributions-summary": "",
        "contributions-title": "User contributions for $1",
        "mycontris": "Contributions",
+       "anoncontribs": "Contributions",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "User account \"$1\" is not registered.",
        "nocontribs": "No changes were found matching these criteria.",
        "whatlinkshere-hidelinks": "$1 links",
        "whatlinkshere-hideimages": "$1 file links",
        "whatlinkshere-filters": "Filters",
+       "whatlinkshere-submit": "Go",
        "autoblockid": "Autoblock #$1",
        "block": "Block user",
        "unblock": "Unblock user",
        "accesskey-pt-preferences": "",
        "accesskey-pt-watchlist": "l",
        "accesskey-pt-mycontris": "y",
+       "accesskey-pt-anoncontribs": "y",
        "accesskey-pt-login": "o",
        "accesskey-pt-logout": "",
        "accesskey-pt-createaccount": "",
        "tooltip-pt-preferences": "Your preferences",
        "tooltip-pt-watchlist": "A list of pages you are monitoring for changes",
        "tooltip-pt-mycontris": "A list of your contributions",
+       "tooltip-pt-anoncontribs": "A list of edits made from this IP address",
        "tooltip-pt-login": "You are encouraged to log in; however, it is not mandatory",
        "tooltip-pt-logout": "Log out",
        "tooltip-pt-createaccount": "You are encouraged to create an account and log in; however, it is not mandatory",
        "spam_blanking": "All revisions contained links to $1, blanking",
        "spam_deleting": "All revisions contained links to $1, deleting",
        "simpleantispam-label": "Anti-spam check.\nDo <strong>not</strong> fill this in!",
-       "autochange-username": "MediaWiki automatic change",
        "pageinfo-header": "-",
        "pageinfo-title": "Information for \"$1\"",
        "pageinfo-not-current": "Sorry, it's impossible to provide this information for old revisions.",
        "exif-compression-34712": "JPEG2000",
        "exif-copyrighted-true": "Copyrighted",
        "exif-copyrighted-false": "Copyright status not set",
+       "exif-photometricinterpretation-0": "Black and white (White is 0)",
+       "exif-photometricinterpretation-1": "Black and white (Black is 0)",
        "exif-photometricinterpretation-2": "RGB",
+       "exif-photometricinterpretation-3": "Palette",
+       "exif-photometricinterpretation-4": "Transparency mask",
+       "exif-photometricinterpretation-5": "Separated (Probably CMYK)",
        "exif-photometricinterpretation-6": "YCbCr",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC encoding)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU encoding)",
+       "exif-photometricinterpretation-32803": "Color Filter Array",
+       "exif-photometricinterpretation-34892": "Linear raw",
        "exif-unknowndate": "Unknown date",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Flipped horizontally",
        "mw-widgets-titleinput-description-redirect": "redirect to $1",
        "api-error-blacklisted": "Please choose a different, descriptive title."
 }
+
+
index 56f0320..2d58c9b 100644 (file)
@@ -43,7 +43,8 @@
                        "Ochilov",
                        "Macofe",
                        "Matma Rex",
-                       "Xð"
+                       "Xð",
+                       "Robin van der Vliet"
                ]
        },
        "tog-underline": "Substreki ligilojn",
        "morenotlisted": "Ĉi tiu listo ne estas kompleta.",
        "mypage": "Paĝo",
        "mytalk": "Diskuto",
-       "anontalk": "Diskutpaĝo por tiu ĉi IP-adreso",
+       "anontalk": "Diskuto",
        "navigation": "Navigado",
        "and": "&#32;kaj",
        "qbfind": "Trovi",
        "passwordreset-emailtext-ip": "Iu (verŝajne vi, de IP-adreso $1) petis restarigon de via pasvorto por {{SITENAME}} ($4). La {{PLURAL:$3|jena uzanto-konto estas asociita|jenaj uzanto-kontoj estas asociitaj}} kun ĉi tiu retpoŝtadreso:\n\n$2\n\nĈi {{PLURAL:$3|tiu provizora pasvorto|tiuj provizoraj pasvortoj}} findatiĝos {{PLURAL:$5|unu tagon|$5 tagojn}}.\nVi ensalutu kaj elektu novan pasvorton nun. Se iu alia petis ĉi tion,\naŭ se vi memoris vian originalan pasvorton, kaj vi ne plu volas\nŝanĝi ĝin, vi povas ignori ĉi tiun mesaĝon kaj plu uzi vian \nmalnovan pasvorton.",
        "passwordreset-emailtext-user": "Uzanto $1 de {{SITENAME}} petis restarigo de via pasvorto por {{SITENAME}}\n($4). La {{PLURAL:$3|jena uzanto-konto estas asociita|jenaj uzanto-kontoj estas asociitaj}} kun ĉi tiu retpoŝtadreso:\n\n$2\n\nĈi {{PLURAL:$3|tiu provizora pasvorto|tiuj provizoraj pasvortoj}} findatiĝos {{PLURAL:$5|unu tagon|$5 tagojn}}.\nVi devas ensaluti kaj elekti novan pasvorton nun. Se iu alia petis ĉi tion,\naŭ se vi memoris vian originalan pasvorton, kaj vi ne plu volas ŝanĝi\nĝin, vi povas ignori ĉi tiun mesaĝon kaj uzi vian malnovan pasvorton.",
        "passwordreset-emailelement": "Salutnomo: \n$1\n\nProvizora pasvorto: \n$2",
-       "passwordreset-emailsent": "Se tio estas registrita retpoŝta adreso por via konto, tiam retpoŝto por renovigita pasvorto estos sendata al ĉi tiu adreso.",
+       "passwordreset-emailsentemail": "Se tio estas registrita retpoŝta adreso por via konto, tiam retpoŝto por renovigita pasvorto estos sendata al ĉi tiu adreso.",
        "passwordreset-emailsent-capture": "Retpoŝto kun renovigita pasvorto estis sendita, kiu estas montrata malsupre.",
        "passwordreset-emailerror-capture": "Retpoŝto kun renovigita pasvorto estis generita, montrata sube, sed sendado al la {{GENDER:$2|uzanto}} malsukcesis: $1",
        "changeemail": "Ŝanĝi aŭ forigi retpoŝtadreson",
        "sig_tip": "Via subskribo kun tempindiko",
        "hr_tip": "Horizontala linio (uzu ŝpareme)",
        "summary": "Resumo:",
-       "subject": "Temo/subtitolo:",
+       "subject": "Temo:",
        "minoredit": "Ĉi tiu ŝanĝo estas redakteto",
        "watchthis": "Atenti ĉi tiun paĝon",
        "savearticle": "Konservi ŝanĝojn",
        "columns": "Kolumnoj:",
        "searchresultshead": "Serĉi",
        "stub-threshold": "Ligilformatigo de ĝermoj ($1):",
+       "stub-threshold-sample-link": "specimeno",
        "stub-threshold-disabled": "Malebligita",
        "recentchangesdays": "Tagoj montrendaj en lastaj ŝanĝoj:",
        "recentchangesdays-max": "(maksimume $1 {{PLURAL:$1|tago|tagoj}})",
        "badsig": "Via kaŝnomo (por subskriboj) malvalidas. Bv. kontroli la HTML-etikedojn!",
        "badsiglength": "La subskribo estas tro longa.\nĜi devas esti sub $1 {{PLURAL:$1|signo|signoj}}.",
        "yourgender": "Sekso:",
-       "gender-unknown": "Nespecifita",
+       "gender-unknown": "En mencii vin, la programaro uzos vortojn de neŭtra genro, ĉiam ol estu ebla",
        "gender-male": "Vira",
        "gender-female": "Ina",
        "prefs-help-gender": "Nedeviga: uzita por sekseca salutado de la programaro. Ĉi tiu informo montriĝos publike.",
        "rcshowhidemine": "$1 miajn redaktojn",
        "rcshowhidemine-show": "Montri",
        "rcshowhidemine-hide": "Kaŝi",
+       "rcshowhidecategorization-show": "Montri",
+       "rcshowhidecategorization-hide": "Kaŝi",
        "rclinks": "Montri $1 lastajn ŝanĝojn dum la $2 lastaj tagoj.<br />$3",
        "diff": "malsamoj",
        "hist": "historio",
        "upload-too-many-redirects": "La URL-o enhavis tro multajn alidirektilojn",
        "upload-http-error": "HTTP-eraro okazis: $1",
        "upload-copy-upload-invalid-domain": "Kopio-alŝutoj ne disponiĝas el ĉi tiu domajno.",
+       "upload-dialog-title": "Alŝuti dosieron",
+       "upload-dialog-button-cancel": "Nuligi",
+       "upload-dialog-button-done": "Farite",
+       "upload-dialog-button-save": "Konservi",
+       "upload-dialog-button-upload": "Alŝuti",
+       "upload-form-label-select-file": "Elekti dosieron",
+       "upload-form-label-infoform-title": "Detaloj",
+       "upload-form-label-infoform-name": "Nomo",
+       "upload-form-label-infoform-description": "Priskribo",
+       "upload-form-label-usage-title": "Uzo",
+       "upload-form-label-usage-filename": "Dosiernomo",
+       "foreign-structured-upload-form-label-own-work": "Tio estas mia propra laboro",
+       "foreign-structured-upload-form-label-infoform-categories": "Kategorioj",
+       "foreign-structured-upload-form-label-infoform-date": "Dato",
        "backend-fail-stream": "Ne povis fluigi dosieron $1.",
        "backend-fail-backup": "Ne povis enarkivigi dosieron $1.",
        "backend-fail-notexists": "La dosiero $1 ne ekzistas.",
        "wlnote": "Jen la {{PLURAL:$1|lasta redakto|lastaj <strong>$1</strong> redaktoj}} dum la {{PLURAL:$2|lasta horo|lastaj <strong>$2</strong> horoj}}, ekde $3, $4.",
        "wlshowlast": "Montri el lastaj $1 horoj $2 tagoj",
        "watchlistall2": "ĉiuj",
+       "watchlist-hide": "Kaŝi",
+       "wlshowhideminor": "Etaj redaktoj",
+       "wlshowhidebots": "robotoj",
+       "wlshowhideliu": "registritaj uzantoj",
+       "wlshowhideanons": "anonimaj uzantoj",
+       "wlshowhidepatr": "patrolitaj redaktoj",
+       "wlshowhidemine": "miaj redaktoj",
        "watchlist-options": "Opcioj por atentaro",
        "watching": "Aldonata al la atentaro...",
        "unwatching": "Malatentante...",
        "contributions": "Kontribuoj de {{GENDER:$1|uzanto|uzantino}}",
        "contributions-title": "Kontribuoj de uzanto $1",
        "mycontris": "Kontribuoj",
+       "anoncontribs": "Kontribuoj",
        "contribsub2": "De {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Uzanto-konto \"$1\" ne estas registrita.",
        "nocontribs": "Trovis neniajn redaktojn laŭ tiu kriterio.",
        "cant-move-to-user-page": "Vi ne rajtas movi paĝon al uzantopaĝo (krom al uzantosubpaĝo).",
        "cant-move-category-page": "Vi ne rajtas movi kategoriajn paĝojn.",
        "cant-move-to-category-page": "Vi ne rajtas movi paĝon al kategoria paĝo.",
-       "newtitle": "Al nova titolo",
+       "newtitle": "Nova titolo:",
        "move-watch": "Atenti ĉi tiun paĝon",
        "movepagebtn": "Alinomi paĝon",
        "pagemovedsub": "Sukcesis alinomigo",
        "movenosubpage": "Ĉi tiu paĝo havas neniujn subpaĝojn.",
        "movereason": "Kialo:",
        "revertmove": "restarigi",
-       "delete_and_move": "Forigi kaj alinomi",
        "delete_and_move_text": "==Forigo nepras==\n\nLa celartikolo \"[[:$1]]\" jam ekzistas. Ĉu vi volas forigi ĝin por krei spacon por la movo?",
        "delete_and_move_confirm": "Jes, forigu la paĝon",
        "delete_and_move_reason": "Forigita por ebligi movadon de \"[[$1]]\"",
index 695d5b4..695b15f 100644 (file)
                        "Tusca",
                        "Tadol",
                        "Nelson6e65",
-                       "Matiia"
+                       "Matiia",
+                       "SinNovedades"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "tog-watchlisthidebots": "Ocultar las ediciones de bots de la lista de seguimiento",
        "tog-watchlisthideminor": "Ocultar las ediciones menores de la lista de seguimiento",
        "tog-watchlisthideliu": "Ocultar las ediciones de los usuarios registrados de la lista de seguimiento",
+       "tog-watchlistreloadautomatically": "Recargar la lista de seguimiento automáticamente cuando se modifica un filtro (requiere JavaScript)",
        "tog-watchlisthideanons": "Ocultar las ediciones de los usuarios anónimos de la lista de seguimiento",
        "tog-watchlisthidepatrolled": "Ocultar las ediciones verificadas de la lista de seguimiento",
        "tog-watchlisthidecategorization": "Ocultar la categorización de páginas",
        "morenotlisted": "Esta lista no está completa.",
        "mypage": "Página",
        "mytalk": "Discusión",
-       "anontalk": "Discusión para esta IP",
+       "anontalk": "Discusión",
        "navigation": "Navegación",
        "and": "&#32;y",
        "qbfind": "Buscar",
        "qbpageoptions": "Opciones de página",
        "qbmyoptions": "Mis páginas",
        "faq": "Preguntas frecuentes",
-       "faqpage": "Project:PP. FF.",
+       "faqpage": "Project:Preguntas frecuentes",
        "actions": "Acciones",
        "namespaces": "Espacios de nombres",
        "variants": "Variantes",
        "virus-scanfailed": "ha fallado el análisis (código $1)",
        "virus-unknownscanner": "antivirus desconocido:",
        "logouttext": "<strong>Tu sesión ha finalizado.</strong>\n\nPuede que algunas páginas continúen mostrándose como si la sesión estuviera iniciada hasta que actualices la caché de tu navegador.",
-       "welcomeuser": "¡Bienvenido, $1!",
+       "welcomeuser": "¡Bienvenido/a, $1!",
        "welcomecreation-msg": "Se ha creado tu cuenta.\nSi lo deseas, puedes cambiar tus [[Special:Preferences|preferencias]] para {{SITENAME}}.",
        "yourname": "Usuario:",
        "userlogin-yourname": "Usuario",
        "passwordreset-emailtext-ip": "Alguien (probablemente tú, desde la dirección IP $1) ha solicitado el restablecimiento de tu contraseña en {{SITENAME}} ($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}}\na esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} caducarán en {{PLURAL:$5|un día|$5 días}}.\nAhora puedes iniciar sesión y establecer una nueva contraseña. Si fue otra persona la que realizó esta solicitud, o si ya recuerdas tu contraseña original y, por tanto, no deseas cambiarla, puedes ignorar este mensaje y continuar usando tu contraseña anterior.",
        "passwordreset-emailtext-user": "El usuario $1 de {{SITENAME}} solicitó el restablecimiento de tu contraseña en {{SITENAME}}\n($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}} a esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} caducarán en {{PLURAL:$5|un día|$5 días}}.\nAhora puedes iniciar sesión y establecer una nueva contraseña. Si fue otra persona la que realizó esta solicitud, o si ya recuerdas tu contraseña original y, por tanto, no deseas cambiarla, puedes ignorar este mensaje y continuar usando tu contraseña anterior.",
        "passwordreset-emailelement": "Nombre de {{GENDER:$1|usuario|usuaria}}: \n$1\n\nContraseña temporal: \n$2",
-       "passwordreset-emailsent": "Si esta es una dirección de correo electrónico registrada para tu cuenta, entonces se enviará un correo electrónico para el restablecimiento de tu contraseña.",
+       "passwordreset-emailsentemail": "Si esta es una dirección de correo electrónico registrada para tu cuenta, entonces se enviará un correo electrónico para el restablecimiento de tu contraseña.",
        "passwordreset-emailsent-capture": "Se ha enviado un correo para el restablecimiento de la contraseña, el cual se muestra a continuación.",
        "passwordreset-emailerror-capture": "Se ha generado un correo electrónico de restablecimiento de contraseña, que se muestra a continuación, pero ha fallado el envío {{GENDER:$2|al usuario|a la usuaria}}: $1",
        "changeemail": "Cambiar o eliminar la dirección de correo electrónico",
        "recentchanges-label-plusminus": "El tamaño de la página cambió esta cantidad de bytes",
        "recentchanges-legend-heading": "'''Leyenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (véase también la [[Special:NewPages|lista de páginas nuevas]])",
+       "recentchanges-submit": "Mostrar",
        "rcnotefrom": "Debajo aparece{{PLURAL:$5| el cambio|n los cambios}} desde <strong>$3, $4</strong> (se muestran hasta <strong>$1</strong>).",
        "rclistfrom": "Mostrar cambios nuevos desde las $2 del $3",
        "rcshowhideminor": "$1 ediciones menores",
        "mostrevisions": "Artículos con más ediciones",
        "prefixindex": "Todas las páginas con prefijo",
        "prefixindex-namespace": "Todas las páginas con el prefijo (espacio de nombres $1)",
+       "prefixindex-submit": "Mostrar",
        "prefixindex-strip": "Quitar prefijos en la lista",
        "shortpages": "Páginas cortas",
        "longpages": "Páginas largas",
        "protectedpages-performer": "Protección de usuario",
        "protectedpages-params": "Parámetros de protección",
        "protectedpages-reason": "Motivo",
+       "protectedpages-submit": "Mostrar páginas",
        "protectedpages-unknown-timestamp": "Desconocido",
        "protectedpages-unknown-performer": "Usuario desconocido",
        "protectedtitles": "Títulos protegidos",
        "protectedtitles-summary": "Esta página enumera títulos que actualmente están protegidos desde su creación. Para una lista de las páginas existentes que están protegidas, véase [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Actualmente no existen entradas protegidas con esos parámetros.",
+       "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Lista de usuarios",
        "listusers-editsonly": "Muestra sólo usuarios con ediciones",
        "listusers-creationsort": "Ordenado por fecha de creación",
        "activeusers-hidebots": "Ocultar robots",
        "activeusers-hidesysops": "Ocultar administradores",
        "activeusers-noresult": "No se encontraron usuarios.",
+       "activeusers-submit": "Mostrar usuarios activos",
        "listgrouprights": "Permisos del grupo de usuarios",
        "listgrouprights-summary": "La siguiente es una lista de los grupos de usuario definidos en esta wiki y de sus privilegios de acceso asociados.\nPuede haber información adicional sobre privilegios individuales en [[{{MediaWiki:Listgrouprights-helppage}}]]",
        "listgrouprights-key": "Leyenda:\n* <span class=\"listgrouprights-granted\">Derecho concedido</span>\n* <span class=\"listgrouprights-revoked\">Derecho revocado</span>",
        "wlshowlast": "Ver los cambios de las últimas $1 horas, $2 días",
        "watchlistall2": "todos",
        "watchlist-hide": "Ocultar",
+       "watchlist-submit": "Mostrar",
        "wlshowtime": "Mostrar cambios desde hace:",
        "wlshowhideminor": "ediciones menores",
        "wlshowhidebots": "bots",
        "contributions": "Contribuciones {{GENDER:$1|del usuario|de la usuaria}}",
        "contributions-title": "Contribuciones {{GENDER:$1|del usuario|de la usuaria}} $1",
        "mycontris": "Contribuciones",
+       "anoncontribs": "Contribuciones",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "La cuenta de usuario «$1» no está registrada.",
        "nocontribs": "No se encontraron cambios que cumplieran estos criterios.",
        "whatlinkshere-hidelinks": "$1 enlaces",
        "whatlinkshere-hideimages": "$1 enlaces a archivos",
        "whatlinkshere-filters": "Filtros",
+       "whatlinkshere-submit": "Ir",
        "autoblockid": "Bloqueo automático #$1",
        "block": "Bloquear usuario",
        "unblock": "Desbloquear usuario",
        "movenosubpage": "Esta página no tiene subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "revertir",
-       "delete_and_move": "Borrar y trasladar",
        "delete_and_move_text": "==Se necesita borrado==\n\nLa página de destino (\"[[:$1]]\") ya existe. ¿Quiere borrarla para permitir al traslado?",
        "delete_and_move_confirm": "Sí, borrar la página",
        "delete_and_move_reason": "Borrada para permitir el traslado de \"[[$1]]\"",
        "tooltip-pt-preferences": "Tus preferencias",
        "tooltip-pt-watchlist": "Lista de páginas cuyos cambios vigilas",
        "tooltip-pt-mycontris": "Lista de tus contribuciones",
+       "tooltip-pt-anoncontribs": "Una lista de modificaciones hechas desde esta dirección IP",
        "tooltip-pt-login": "Te recomendamos iniciar sesión, aunque no es obligatorio",
        "tooltip-pt-logout": "Salir de la sesión",
        "tooltip-pt-createaccount": "Te recomendamos crear una cuenta e iniciar sesión; sin embargo, no es obligatorio",
index 76ef032..50b1565 100644 (file)
@@ -61,6 +61,7 @@
        "tog-watchlisthidebots": "Peida robotid jälgimisloendist",
        "tog-watchlisthideminor": "Peida pisiparandused jälgimisloendist",
        "tog-watchlisthideliu": "Peida sisselogitud kasutajate muudatused jälgimisloendist",
+       "tog-watchlistreloadautomatically": "Laadi jälgimisloend mõne filtri muutmise järel koheselt uuesti (nõutav JavaScript)",
        "tog-watchlisthideanons": "Peida anonüümsete kasutajate muudatused jälgimisloendist",
        "tog-watchlisthidepatrolled": "Peida kontrollitud muudatused jälgimisloendist",
        "tog-watchlisthidecategorization": "Peida lehekülgede kategoriseerimine",
@@ -72,7 +73,7 @@
        "tog-prefershttps": "Kasuta sisselogimisel alati turvalist ühendust",
        "underline-always": "Alati",
        "underline-never": "Mitte kunagi",
-       "underline-default": "Kujunduse või brauseri vaikeväärtus",
+       "underline-default": "Kujunduse või veebilehitseja vaikeväärtus",
        "editfont-style": "Redigeerimisala kirjatüüp:",
        "editfont-default": "Veebilehitseja vaikesäte",
        "editfont-monospace": "Püsisammuga font",
        "morenotlisted": "See loend pole täielik.",
        "mypage": "Minu lehekülg",
        "mytalk": "Arutelu",
-       "anontalk": "Selle IP-aadressi arutelu",
+       "anontalk": "Arutelu",
        "navigation": "Navigeerimine",
        "and": "&#32;ja",
        "qbfind": "Otsi",
        "databaseerror-query": "Päring: $1",
        "databaseerror-function": "Funktsioon: $1",
        "databaseerror-error": "Tõrge: $1",
+       "transaction-duration-limit-exceeded": "Selleks et vältida tiražeerimise suurt mahajäämust, on see tehing katkestatud, kuna kirjutamise kestus ($1) ületas $2 sekundi piirangut.\nKui muudad korraga palju üksusi, siis proovi selle asemel teha mitu väiksemat toimingut.",
        "laggedslavemode": "Hoiatus: Leheküljel võivad puududa viimased uuendused.",
        "readonly": "Andmebaas on hetkel kirjutuskaitse all",
        "enterlockreason": "Sisesta lukustamise põhjus ning juurdepääsu taastamise ligikaudne aeg",
        "wrongpasswordempty": "Parool jäi sisestamata. Palun proovi uuesti.",
        "passwordtooshort": "Parool peab koosnema vähemalt {{PLURAL:$1|ühest|$1}} tähemärgist.",
        "passwordtoolong": "Parool ei saa olla pikem kui {{PLURAL:$1|üks märk|$1 märk}}.",
+       "passwordtoopopular": "Liigi levinud parooli ei saa kasutada. Palun vali haruldasem parool.",
        "password-name-match": "Parool peab kasutajanimest erinema.",
        "password-login-forbidden": "Selle kasutajanime ja parooli kasutamine on keelatud.",
        "mailmypassword": "Lähtesta parool",
        "passwordreset-emailtext-ip": "Keegi, arvatavasti sina ise, IP-aadressilt $1 palus lähtestada sinu {{GRAMMAR:genitive|{{SITENAME}}}} ($4) parooli. Selle e-posti aadressiga on seotud {{PLURAL:$3|järgmine konto|järgmised kontod}}:\n\n$2\n\n{{PLURAL:$3|See ajutine parool aegub|Need ajutised paroolid aeguvad}} {{PLURAL:$5|ühe|$5}} päeva pärast.\nPeaksid nüüd sisse logima ja uue parooli valima. Kui selle palve esitas keegi teine või kui sulle meenus su parool ja sa ei soovi seda enam muuta, võid teadet eirata ja jätkata vana parooli kasutamist.",
        "passwordreset-emailtext-user": "{{GRAMMAR:genitive|{{SITENAME}}}} kasutaja $1 palus lähtestada sinu {{GRAMMAR:genitive|{{SITENAME}}}} ($4) parooli. Selle e-posti aadressiga on seotud {{PLURAL:$3|järgmine konto|järgmised kontod}}:\n\n$2\n\n{{PLURAL:$3|See ajutine parool aegub|Need ajutised paroolid aeguvad}} {{PLURAL:$5|ühe|$5}} päeva pärast.\nPeaksid nüüd sisse logima ja uue parooli valima. Kui selle palve esitas keegi teine või kui sulle meenus su parool ja sa ei soovi seda enam muuta, võid teadet eirata ja jätkata vana parooli kasutamist.",
        "passwordreset-emailelement": "Kasutajanimi: \n$1\n\nAjutine parool: \n$2",
-       "passwordreset-emailsent": "Kui oled sidunud konto selle e-posti aadressiga, siis saadetakse sulle parooli lähtestamise e-kiri.",
+       "passwordreset-emailsentemail": "Kui oled sidunud konto selle e-posti aadressiga, siis saadetakse sulle parooli lähtestamise e-kiri.",
        "passwordreset-emailsent-capture": "E-kirjatsi on saadetud allpool näidatav parooli lähtestuskiri.",
        "passwordreset-emailerror-capture": "Koostati allpool näidatav parooli lähtestuskiri, aga selle e-kirjatsi {{GENDER:$2|kasutajale}} saatmine ebaõnnestus: $1",
        "changeemail": "E-posti aadressi muutmine või eemaldamine",
        "timezoneuseserverdefault": "Kasuta serveri vaikesätet ($1)",
        "timezoneuseoffset": "Muu (määra ajavahe)",
        "servertime": "Serveri aeg:",
-       "guesstimezone": "Loe aeg brauserist",
+       "guesstimezone": "Loe aeg veebilehitsejast",
        "timezoneregion-africa": "Aafrika",
        "timezoneregion-america": "Ameerika",
        "timezoneregion-antarctica": "Antarktika",
        "prefs-dateformat": "Kuupäeva vorming",
        "prefs-timeoffset": "Ajavahe",
        "prefs-advancedediting": "Üldsuvandid",
-       "prefs-editor": "Redaktor",
+       "prefs-editor": "Toimeti",
        "prefs-preview": "Eelvaade",
        "prefs-advancedrc": "Täpsemad eelistused",
        "prefs-advancedrendering": "Täpsemad eelistused",
        "upload-dialog-button-done": "Valmis",
        "upload-dialog-button-save": "Salvesta",
        "upload-dialog-button-upload": "Laadi üles",
-       "upload-form-label-select-file": "Vali fail",
+       "upload-form-label-select-file": "Faili valimine",
        "upload-form-label-infoform-title": "Üksikasjad",
        "upload-form-label-infoform-name": "Pealkiri",
        "upload-form-label-infoform-description": "Kirjeldus",
        "contributions": "{{GENDER:$1|Kasutaja}} kaastöö",
        "contributions-title": "Kasutaja $1 kaastöö",
        "mycontris": "Kaastöö",
+       "anoncontribs": "Kaastöö",
        "contribsub2": "Kasutaja {{GENDER:$3|$1}} ($2) jaoks",
        "contributions-userdoesnotexist": "Kasutajakonto \"$1\" pole registreeritud.",
        "nocontribs": "Antud kriteeriumitele vastavaid muudatusi ei leitud.",
        "movenosubpage": "Sellel leheküljel pole alamlehekülgi.",
        "movereason": "Põhjus:",
        "revertmove": "taasta",
-       "delete_and_move": "Kustuta ja teisalda",
        "delete_and_move_text": "== Vajalik kustutamine ==\nSihtlehekülg \"[[:$1]]\" on juba olemas.\nKas kustutad selle, et luua võimalus teisaldamiseks?",
        "delete_and_move_confirm": "Jah, kustuta lehekülg",
        "delete_and_move_reason": "Kustutatud, et tõsta asemele lehekülg \"[[$1]]\"",
        "tooltip-pt-preferences": "Sinu eelistused",
        "tooltip-pt-watchlist": "Loend lehekülgedest, mille muudatusi jälgid",
        "tooltip-pt-mycontris": "Sinu kaastööde loend",
+       "tooltip-pt-anoncontribs": "Sellelt IP-aadressilt tehtud muudatuste loend",
        "tooltip-pt-login": "See pole küll kohustuslik, aga sul tasub sisse logida.",
        "tooltip-pt-logout": "Logi välja",
        "tooltip-pt-createaccount": "See pole küll kohustuslik, aga sul tasub konto luua ja sisse logida.",
index f095677..d0854ce 100644 (file)
                        "Joxemai",
                        "Arkaitz Barnetik",
                        "Sator",
-                       "Macofe"
+                       "Macofe",
+                       "Xð"
                ]
        },
        "tog-underline": "Azpimarratu loturak:",
        "tog-hideminor": "Ezkutatu azken aldaketetan aldaketa txikiak",
        "tog-hidepatrolled": "Ezkutatu patruilatutako aldaketa azken aldaketetan",
        "tog-newpageshidepatrolled": "Ezkutatu patruilatutako orriak, orri-zerrenda berritik",
-       "tog-hidecategorization": "Orrialdeen kategorizazioa ezkutatu",
+       "tog-hidecategorization": "Ezkutatu orrien kategorizazioa",
        "tog-extendwatchlist": "Jarraipen-zerrenda zabaldu aldaketa guztiak ikusteko, ez bakarrik azken aldaketak",
        "tog-usenewrc": "Azken aldaketetan eta jarraipen-zerrendan aldaketak orrialdearen arabera taldekatu",
-       "tog-numberheadings": "Goiburukoak automatikoki zenbakitu",
+       "tog-numberheadings": "Zenbakitu automatikoki goiburuak",
        "tog-showtoolbar": "Aldaketen tresna-barra erakutsi",
        "tog-editondblclick": "Klik bikoitzaren bitartez orrialdeak aldatu",
        "tog-editsectiononrightclick": "Atalen izenburuetan eskuin klik eginez aldatzea gaitu",
        "morenotlisted": "Zerrenda hau ez dago osorik.",
        "mypage": "Orrialdea",
        "mytalk": "Eztabaida",
-       "anontalk": "IP honen eztabaida",
+       "anontalk": "Eztabaida",
        "navigation": "Nabigazioa",
        "and": "&#32;eta",
        "qbfind": "Aurkitu",
        "viewhelppage": "Laguntza orrialdea ikusi",
        "categorypage": "Kategoria orrialdea ikusi",
        "viewtalkpage": "Eztabaida ikusi",
-       "otherlanguages": "Erdaretan",
+       "otherlanguages": "Beste hizkuntza batzuetan",
        "redirectedfrom": "($1(e)tik birzuzenduta)",
        "redirectpagesub": "Birbideratze orria",
        "redirectto": "Hona birzuzentzen du:",
        "passwordreset-email": "E-mail helbidea:",
        "passwordreset-emailtitle": "{{SITENAME}}-rako kontuaren xehetasunak",
        "passwordreset-emailelement": "Erabiltzaile izena: \n$1\n\nBehin-behineko pasahitza: \n$2",
-       "passwordreset-emailsent": "Pasahitza berrezartzeko e-posta bidali da.",
+       "passwordreset-emailsent": "Hau zure konturako erregistratuta dagoen helbide elektronikoa baldin bada, mezu elektronikoa bidaliko da zure pasahitza berrezartzeko.",
        "passwordreset-emailsent-capture": "Pasahitza berrezartzeko e-posta bat bidali dizugu, behean erakusten dena.",
        "changeemail": "Aldatu edo kendu e-mail helbidea",
-       "changeemail-header": "Aldatu kontuko e-posta helbidea",
+       "changeemail-header": "Bete ezazu inprimaki hau, zure helbide elektronikoa aldatzeko. Zure kontuari helbide elektronikorik elkartuta ez izatea nahi baduzu, utz ezazu hutsik helbide elektroniko berria, inprimakia bidaltzen duzunean.",
        "changeemail-no-info": "Orrialde honetara zuzenean sartzeko izena eman behar duzu.",
        "changeemail-oldemail": "Egungo e-mail helbidea:",
        "changeemail-newemail": "E-posta helbide berria:",
        "anonpreviewwarning": "''Ez duzu saioa hasi. Gordez gero, zure IP helbidea grabatuko da orri honen edizio historian.''",
        "missingsummary": "'''Gogorarazpena:''' Ez duzu aldaketa laburpen bat zehaztu. Berriz ere gordetzeko aukeratzen baduzu, laburpen mezurik gordeko da.",
        "missingcommenttext": "Mesedez, iruzkin bat idatzi jarraian.",
-       "missingcommentheader": "'''Oharra:''' Ez duzu iruzkin honetarako gairik edo goiburukorik ezarri. «{{int:Savearticle}}» klikatzen baduzu, hutsune horrekin gordeko da.",
+       "missingcommentheader": "<strong>Oharra:</strong> Ez duzu iruzkin honetarako gairik ezarri. «{{int:Savearticle}}» berriro klikatzen baduzu, gairik gabe gordeko da zure edizioa.",
        "summary-preview": "Laburpenaren aurreikuspena:",
        "subject-preview": "Gaiaren aurrebista:",
        "blockedtitle": "Erabiltzailea blokeatuta dago",
        "creating": "«$1» sortzen",
        "editingsection": "«$1» aldatzen (atala)",
        "editingcomment": "«$1» aldatzen (atal berria)",
-       "editconflict": "Zure aldaketak ezin izan dira gorde, edizio gatazka bat izan delako. Gatazka eskuz konpondu nahi {{GENDER:|duzu}}?",
+       "editconflict": "Edizio gatazka: $1",
        "explainconflict": "Zu orrialdea aldatzen hasi ondoren beste norbaitek ere aldaketak egin ditu.\nGoiko testu koadroan ikus daiteke orrialdeak uneotan duen edukia.\nZure aldaketak beheko testu koadroan ikus daitezke.\nZure testua dagoenarekin elkartu beharko duzu.\nOrrialdea gordetzeko erabakitzen duzun unean goiko koadroko edukia '''bakarrik''' gordeko da.",
        "yourtext": "Zure testua",
        "storedversion": "Gordetako bertsioa",
        "parser-template-recursion-depth-warning": "Txantiloaren rekurtsio sakoneraren muga gainditu da ($1)",
        "language-converter-depth-warning": "Hizkuntza-bihurgailuaren sakonerak ($1) muga gainditu du",
        "node-count-exceeded-category": "Nodo-zenbaketa gainditu den orrialdeak",
-       "node-count-exceeded-warning": "Orrialdeak nodo-zenbaketa gainditu du",
+       "node-count-exceeded-warning": "Orriak nodo-kopuruaren muga gainditu du",
        "expansion-depth-exceeded-category": "Orrialdearen espantsio sakonera gainditu da",
        "expansion-depth-exceeded-warning": "Espantsio sakonera gainditu duten orrialdeak",
        "parser-unstrip-loop-warning": "Loop unstrip bat aurkitu da",
        "rev-deleted-user": "(erabiltzailea ezabatu da)",
        "rev-deleted-event": "(log xehetasunak ezabatu dira)",
        "rev-deleted-user-contribs": "[lankide izena edo Ip helbidea ezabatua - aldatu ezkutapena ekarpenetatik]",
-       "rev-deleted-text-permission": "Orrialdearen berrikuspen hau '''ezabatua''' izan da.\nXehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus daitezke.",
+       "rev-deleted-text-permission": "Orrialdearen berrikuspen hau <strong>ezabatua</strong> izan da.\nXehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus daitezke.",
        "rev-deleted-text-unhide": "Orriaren bertsio hau '''ezabatu''' da.\nXehetasunak ikusgai daude [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabatze erregistroan].\nAdministratzailea zarenez, oraindik [$1 bertsio hau ikus dezakezu], nahi izanez gero.",
        "rev-suppressed-text-unhide": "Orriaren bertsio hau '''ezeztatu''' da.\nXehetasunak ikusgai daude [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ezeztatze erregistroan].\nAdministratzailea zarenez, oraindik [$1 bertsio hau ikus dezakezu], nahi izanez gero.",
        "rev-deleted-text-view": "Orriaren berrikuspen hau '''ezabatua''' izan da.\nZuk ikusteko aukera daukazu; xehetasunak [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ezabaketa erregistroan] ikus ditzakezu.",
        "rev-showdeleted": "erakutsi",
        "revisiondelete": "Berrikuspenak ezabatu/leheneratu",
        "revdelete-nooldid-title": "Helburu berrikuspenik ez",
-       "revdelete-nooldid-text": "Ez d(it)uzu eragiketa hau burutzeko helburu berrikuspena(k) zehaztu.",
+       "revdelete-nooldid-text": "Ez duzu eragiketa hau burutzeko helburu berrikuspenik zehaztu, edo berrikuspen hori ez da existitzen, edo oraingo berrikuspena ezkutatzen ari zara.",
        "revdelete-no-file": "Zehazturiko fitxategia ez da existitzen.",
        "revdelete-show-file-confirm": "\"<nowiki>$1</nowiki>\" fitxategiaren bertsio ezabatua (eguna: $2; ordua: $3) ikusi nahi duzu?",
        "revdelete-show-file-submit": "Bai",
        "logdelete-selected": "{{PLURAL:$1|Aukeratutako log gertakaria|Aukeratutako log gertakariak}}:",
        "revdelete-confirm": "Baiezta ezazu hori dela zure asmoa, ulertzen dituzula ondorioak, eta [[{{MediaWiki:Policy-url}}|irizpideak]] errespetatuz egiten ari zarela hau.",
-       "revdelete-suppress-text": "Ezabaketa '''bakarrik''' arrazoi hauek direla eta erabili beharko litzateke:\n* Informazio pertsonal desegokia\n*: ''etxeko helbideak eta telefono zenbakiak, segurtasun sozial zenbakiak, etab.''",
+       "revdelete-suppress-text": "Ezabaketa <strong>bakarrik</strong> arrazoi hauek direla eta erabili beharko litzateke:\n* Iraingarria izan daiteken informazioa\n* Informazio pertsonal desegokia\n*: <em>etxeko helbideak eta telefono zenbakiak, nortasun zenbaki nazionalak, etab.</em>",
        "revdelete-legend": "Berrikuspen mugapenak ezarri:",
        "revdelete-hide-text": "Berrikuspenaren testua ezkutatu",
        "revdelete-hide-image": "Fitxategiaren edukia ezkutatu",
        "search-relatedarticle": "Erlazionatua",
        "searchrelated": "erlazionatua",
        "searchall": "guztia",
-       "showingresults": "Jarraian {{PLURAL:$1|emaitza '''1''' ikus daiteke|'''$1''' emaitza ikus daitezke}}, #'''$2'''.etik hasita.",
-       "showingresultsinrange": "Jarraian {{PLURAL:$1|emaitza '''1''' ikus daiteke|'''$1''' emaitza ikus daitezke}}, #'''$2'''.etik hasi eta #<strong>$3</strong>.eraino.",
+       "showingresults": "Jarraian {{PLURAL:$1|emaitza <strong>bat</strong> ageri da.|<strong>$1</strong> emaitza ageri dira, #'''$2'''.etik hasita.}}",
+       "showingresultsinrange": "Jarraian {{PLURAL:$1|emaitza <strong>bat</strong> ageri da.|<strong>$1</strong> emaitza ageri dira, </strong>$2</strong>.etik hasi eta <strong>$3</strong>.eraino.}}",
        "search-showingresults": "{{PLURAL:$4|<strong>$1.</strong> emaitza (guztira <strong>$3</strong> dira)|<strong>$1 - $2.</strong> emaitzak (guztira <strong>$3</strong> dira)}}",
        "search-nonefound": "Ez dago eskaerarekin bat egiten duten emaitzarik.",
        "powersearch-legend": "Bilaketa aurreratua",
        "listgrouprights-addgroup-self-all": "Talde guztiak norbere kontura gehitu",
        "listgrouprights-removegroup-self-all": "Talde guztiak norbere kontutik ezabatu",
        "listgrouprights-namespaceprotection-namespace": "Izen-tartea",
+       "trackingcategories-name": "Mezuaren izena",
        "trackingcategories-nodesc": "Ez dago deskribapenik eskuragarri.",
        "trackingcategories-disabled": "Kategoria desgaitua dago",
        "mailnologin": "Bidalketa helbiderik ez",
        "wlheader-showupdated": "Bisitatu zenituen azken alditik aldaketak izan dituzten orrialdeak '''beltzez''' nabarmenduta daude.",
        "wlnote": "Jarraian {{PLURAL:$2|ikus daiteke azken orduko|ikus daitezke azken '''$2''' orduetako}} azken {{PLURAL:$1|aldaketa|'''$1''' aldaketak}}, $3, $4 gisa.",
        "wlshowlast": "Erakutsi azken $1 orduak, azken $2 egunak",
-       "watchlistall2": "guztiak",
+       "watchlistall2": "guztia",
        "watchlist-hide": "Ezkutatu",
        "wlshowtime": "Erakutsi azkenak:",
        "wlshowhideminor": "aldaketa txikiak",
        "wlshowhidebots": "bot-ak",
+       "wlshowhideliu": "Erregistratutako erabiltzaileak",
        "wlshowhideanons": "erabiltzaile anonimoak",
+       "wlshowhidepatr": "Patruilatutako aldaketak",
        "wlshowhidemine": "nire edizioak",
        "watchlist-options": "Jarraitze-zerrendaren aukerak",
        "watching": "Zerrendan gehitzen...",
        "contributions": "{{GENDER:$1|Lankidearen}} ekarpenak",
        "contributions-title": "$1(r)entzat lankidearen ekarpenak",
        "mycontris": "Ekarpenak",
+       "anoncontribs": "Ekarpenak",
        "contribsub2": "{{GENDER:$3|$1(r)entzat}} ($2)",
+       "contributions-userdoesnotexist": "\"$1\" erabiltzaile-kontua ez dago erregistraturik.",
        "nocontribs": "Ez da ezaugarri horiekin bat datorren aldaketarik aurkitu.",
        "uctop": "(azken aldaketa)",
        "month": "Hilabetea (eta lehenagokoak):",
        "sp-contributions-newbies-sub": "Hasiberrientzako",
        "sp-contributions-newbies-title": "Lankideen ekarpenak lankide berrietn",
        "sp-contributions-blocklog": "Blokeaketa erregistroa",
+       "sp-contributions-suppresslog": "lankide-ekarpen ezabatuak",
        "sp-contributions-deleted": "lankide-ekarpen ezabatuak",
        "sp-contributions-uploads": "igoerak",
        "sp-contributions-logs": "erregistroak",
        "sp-contributions-talk": "eztabaida",
        "sp-contributions-userrights": "erabiltzaile-baimenen kudeaketa",
        "sp-contributions-blocked-notice": "Lankide hau une honetan blokeatuta dago.\nBlokeo erregistroa azken sarrera ematen da azpian erreferentziarako:",
+       "sp-contributions-blocked-notice-anon": "Erabiltzaile hau blokeatuta dago une honetan.\nAzken blokeoaren erregistroa ageri da behean, erreferentzia gisa:",
        "sp-contributions-search": "Ekarpenentzako bilaketa",
        "sp-contributions-username": "IP helbidea edo erabiltzaile izena:",
        "sp-contributions-toponly": "Azken aldaketak direnak soilik erakutsi",
        "unblocked": "[[User:$1|$1]] desblokeatu egin da",
        "unblocked-range": "$1 desblokeatuta izan da.",
        "unblocked-id": "$1 blokeaketa ezabatu da",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] desblokeatua izan da.",
        "blocklist": "Blokeatutako erabiltzaileak",
        "ipblocklist": "Blokeatutako erabiltzaileak",
        "ipblocklist-legend": "Blokeatutako erabiltzaile bat bilatu",
        "movenosubpage": "Orrialde honek ez du azpiorrialderik.",
        "movereason": "Arrazoia:",
        "revertmove": "desegin",
-       "delete_and_move": "Ezabatu eta mugitu",
        "delete_and_move_text": "== Ezabatzeko beharra ==\n\n\"[[:$1]]\" helburua existitzen da. Lekua egiteko ezabatu nahi al duzu?",
        "delete_and_move_confirm": "Bai, orrialdea ezabatu",
        "delete_and_move_reason": "[[$1]] mugitzeko ezabatu da",
        "thumbnail_gd-library": "GD liburutegiaren konfigurazio osagabea: $1 funtzioa falta da",
        "thumbnail_image-missing": "Fitxategirik ez dagoela dirudi: $1",
        "import": "Orrialdeak inportatu",
-       "importinterwiki": "Wikien arteko inportazioa",
+       "importinterwiki": "Beste wiki batetik inportatu",
        "import-interwiki-text": "Aukeratu inportatzeko wiki eta orrialde izenburu bat. Berrikuspenen datak eta egileak gorde egingo dira. Inportazio ekintza guzti hauek [[Special:Log/import|inportazio erregistroan]] gordetzen dira.",
        "import-interwiki-sourcewiki": "Jatorrizko wikia:",
        "import-interwiki-sourcepage": "Jatorrizko orria:",
        "tooltip-pt-preferences": "Nire hobespenak",
        "tooltip-pt-watchlist": "Jarraitzen dituzun orrialdeen zerrenda.",
        "tooltip-pt-mycontris": "Nire ekarpenen zerrenda",
+       "tooltip-pt-anoncontribs": "IP helbide honetatik egindako aldaketen zerrenda",
        "tooltip-pt-login": "Izen ematera gonbidatzen zaitugu.",
        "tooltip-pt-logout": "Saioa itxi",
        "tooltip-pt-createaccount": "Kontu bat sortu eta horrekin saioa hastea eskatu nahi genizuke; ez da ezinbestekoa, ordea.",
        "pageinfo-protect-cascading-yes": "Bai",
        "pageinfo-protect-cascading-from": "Serieko babesak aktibatuta. Sorburua:",
        "pageinfo-category-info": "Kategoria informazioa",
+       "pageinfo-category-total": "Erabiltzaile kopurua, guztira",
        "pageinfo-category-pages": "Orrialde kopurua",
        "pageinfo-category-subcats": "Azpikategorien zenbakia",
        "pageinfo-category-files": "Fitxategi kopurua",
        "patrol-log-page": "Patrullatze loga",
        "patrol-log-header": "Hau patruliatutako aldaketen log bat da.",
        "log-show-hide-patrol": "$1 patruilatze loga",
+       "log-show-hide-tag": "$1 etiketa erregistroa",
        "deletedrevision": "$1 berrikuspen zaharra ezabatu da",
        "filedeleteerror-short": "Errorea fitxategia ezabatzerakoan: $1",
        "filedeleteerror-long": "Erroreak gertatu dira fitxategia ezabatzerakoan:\n\n$1",
        "file-info-size-pages": "$1 × $2 pixel, fitxategi tamaina: $3, MIME mota: $4, {{PLURAL:$5|orrialde $5|$5 orrialde}}",
        "file-nohires": "Ez dago bereizmen handiagorik.",
        "svg-long-desc": "SVG fitxategia, nominaldi $1 × $2 pixel, fitxategiaren tamaina: $3",
+       "svg-long-desc-animated": "SVG fitxategi animatua, nominalki $1 × $2 pixel, fitxategiaren tamaina: $3",
        "svg-long-error": "SVG fitxategi ez baliagarria: $1",
        "show-big-image": "Jatorrizko fitxategia",
        "show-big-image-preview": "Aurreikuspen honen neurria: $1.",
        "autosumm-replace": "Orriaren edukiaren ordez, «$1» jarri da",
        "autoredircomment": "[[$1]] orrialdera birzuzentzentzen",
        "autosumm-new": "Orria sortu da. Edukia: $1",
+       "autosumm-newblank": "Orrialde zuria sortu da",
        "lag-warn-normal": "{{PLURAL:$1|segundu $1|$1 segundu}} baino berriagoak diren aldaketak ez dira zerrenda honetan agertuko.",
        "lag-warn-high": "Zerbitzariaren atzerapen handia dela eta, {{PLURAL:$1|segundu $1|$1 segundu}} baino berriagoak diren aldaketak baliteke zerrenda honetan ez azaltzea.",
        "watchlistedit-normal-title": "Jarraitze zerrenda aldatu",
        "watchlistedit-clear-submit": "Garbitu jarraipen zerrenda (Behin betiko da!)",
        "watchlistedit-clear-done": "Zure jarraipen-zerrenda garbitu da.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Izenburu 1 kendu da|$1 izenburu kendu dira}}:",
+       "watchlistedit-too-many": " Orrialde gehiegi, hemen erakusteko.",
        "watchlisttools-clear": "Garbitu jarraipen-zerrenda",
        "watchlisttools-view": "Aldaketa garrantzitsuak ikusi",
        "watchlisttools-edit": "Zerrenda ikusi eta aldatu",
        "version-ext-colheader-license": "Lizentzia",
        "version-ext-colheader-description": "Deskribapena",
        "version-ext-colheader-credits": "Egileak",
+       "version-license-title": "$1-entzako lizentzia",
+       "version-credits-title": "$1-entzako aitorpena",
        "version-poweredby-credits": "Wiki hau '''[https://www.mediawiki.org/ MediaWiki]'''k sustatzen du (copyright © 2001-$1 $2).",
        "version-poweredby-others": "beste batzuk",
        "version-poweredby-translators": "translatewiki.net itzultzaileak",
        "version-entrypoints": "Sarrera puntuko URLa",
        "version-entrypoints-header-entrypoint": "Sarrera puntua",
        "version-entrypoints-header-url": "URL",
+       "version-libraries": "Instalatutako bibliotekak",
        "version-libraries-library": "Liburutegia",
        "version-libraries-version": "Bertsioa",
        "version-libraries-license": "Lizentzia",
        "tags-actions-header": "Ekintzak",
        "tags-active-yes": "Bai",
        "tags-active-no": "Ez",
+       "tags-source-extension": "Luzapenak definitua",
+       "tags-source-none": "Ez da gehiago erabiltzen",
        "tags-edit": "aldatu",
        "tags-delete": "ezabatu",
        "tags-activate": "aktibatu",
        "tags-deactivate": "desaktibatu",
        "tags-hitcount": "$1 {{PLURAL:$1|aldaketa|aldaketa}}",
+       "tags-manage-no-permission": "Ez duzu etiketa aldaketak kudeatzeko baimenik.",
        "tags-create-heading": "Etiketa berria sortu",
        "tags-create-tag-name": "Etiketaren izena:",
        "tags-create-reason": "Arrazoia:",
        "tags-create-submit": "Sortu",
+       "tags-create-already-exists": "\"$1\" etiketa badago.",
+       "tags-create-warnings-below": "Etiketaren sorrerarekin jarraitu nahi duzu?",
        "tags-delete-title": "Etiketa ezabatu",
+       "tags-delete-explanation-initial": "Datu-basetik \"$1\" etiketa ezabatzera zoaz",
        "tags-delete-reason": "Arrazoia:",
        "tags-delete-not-found": "\"$1\" etiketa  ez da existitzen.",
        "tags-activate-title": "Etiketa aktibatu",
        "compare-revision-not-exists": "Zehazturiko berrikuspena ez da existitzen.",
        "dberr-problems": "Barkatu! Webgune honek zailtasun teknikoak jasaten ari da.",
        "dberr-again": "Saiatu pare bat minutu itxaroten edo kargatu ezazu orrialdea berriro.",
-       "dberr-info": "($1: Ezin da datu-base zerbitzariarekin konektatu)",
-       "dberr-info-hidden": "(Ezin da konektatu datubasearen zerbitzariarekin)",
+       "dberr-info": "($1: Ezin da datu-basera konektatu)",
+       "dberr-info-hidden": "(Ezin da konektatu datu-basera)",
        "dberr-usegoogle": "Bitartean Google bidez bilatzen saiatu zintezke.",
        "dberr-outofdate": "Eduki hauek aurkibideak eguneratu gabe egon daitezke.",
        "dberr-cachederror": "Ondorengoa eskatutako orriaren katxedun kopia da, eta eguneratu gabe egon daiteke.",
        "logentry-newusers-create": "$1 erabiltzaile kontua {{GENDER:$2|sortu da}}",
        "logentry-newusers-create2": "$1 wikilariak $3 erabiltzaile kontua sortu du",
        "logentry-upload-upload": "$1(e)k $3 {{GENDER:$2|igo du}}",
+       "log-name-tag": "Etiketen erregistroa",
        "rightsnone": "(bat ere ez)",
        "revdelete-summary": "aldaketaren laburpena",
        "feedback-adding": "Orriari feedbacka gehitzen...",
        "feedback-bugnew": "Txekeatu dut. Bug berria bidaliko",
        "feedback-cancel": "Utzi",
        "feedback-close": "Egina",
+       "feedback-dialog-title": "Feedbacka bidali",
        "feedback-error-title": "Errorea",
        "feedback-error1": "Akatsa: APIaren emaitza ez ezagunak",
        "feedback-error2": "Akatsa: Aldaketa ez da egin",
        "expand_templates_remove_comments": "Iruzkinak kendu",
        "expand_templates_remove_nowiki": "Ezabatu <nowiki> etiketen emaitzak",
        "expand_templates_generate_xml": "Erakutsi XML parse zuhaitza",
+       "expand_templates_generate_rawhtml": "Erakutsi HTML gordina",
        "expand_templates_preview": "Aurreikusi",
        "pagelanguage": "Orriaren hizkuntza aukeratu",
        "pagelang-name": "Orria",
        "special-characters-title-emdash": "em lerroa",
        "special-characters-title-minus": "minus zeinua",
        "mw-widgets-dateinput-no-date": "Ez duzu datarik aukeratu",
-       "mw-widgets-titleinput-description-new-page": "orrialde hori oraindik ez da existitzen",
+       "mw-widgets-titleinput-description-new-page": "orri hori oraindik ez da existitzen",
        "mw-widgets-titleinput-description-redirect": "$1ra birzuzendu",
        "api-error-blacklisted": "Aukera ezazu, mesedez, izenburu ezberdin eta deskriptiboago bat."
 }
index e6381ff..0757ce6 100644 (file)
        "passwordreset-emailtext-ip": "یک نفر (احتمالاً شما، با نشانی آی‌پی $1) درخواست بازنشانی گذرواژه‌تان در {{SITENAME}} ($4) را کرده‌است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این آدرس ایمیل مرتبط هستند:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} پس از {{PLURAL:$5|یک روز|$5 روز}} باطل خواهند شد.\nشما باید هم‌اکنون ثبت ورود کنید و گذرواژه‌ای جدید برگزینید. اگر فکر می‌کنید شخص دیگری این درخواست را داده است یا اگر گذرواژهٔ اصلی‌تان را به یاد آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
        "passwordreset-emailtext-user": "کاربر $1 از {{SITENAME}} درخواست بازنشانی گذرواژهٔ شما در {{SITENAME}} ($4) را کرده است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این آدرس ایمیل مرتبط است:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} تا {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\nشما باید هم‌اکنون وارد شده و یک گذرواژهٔ جدید برگزینید. اگر شخص دیگری این درخواست را داده است، یا اگر گذرواژهٔ اصلی‌تان را به خاطر آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
        "passwordreset-emailelement": "نام کاربری: \n$1\n\nگذرواژهٔ موقت: \n$2",
-       "passwordreset-emailsent": "اگر ایمیلی را برای حساب کاربریتان مشخص کرده باشید، یک نامهٔ بازنشانی گذرواژه فرستاده شده‌است.",
+       "passwordreset-emailsentemail": "اگر ایمیلی را برای حساب کاربریتان مشخص کرده باشید، یک نامهٔ بازنشانی گذرواژه فرستاده شده‌است.",
        "passwordreset-emailsent-capture": "یک ایمیل بازنشانی که در پایین نمایش داده شده، فرستاده شده است.",
        "passwordreset-emailerror-capture": "ایمیل بازنشانی، که در زیر نمایش داده شده، ایجاد شد، ولی ارسال آن به {{GENDER:$2|کاربر}} موفقیت‌آمیز نبود: $1",
        "changeemail": "تغییر یا حذف نشانی ایمیل",
        "contributions": "مشارکت‌های {{GENDER:$1|کاربر}}",
        "contributions-title": "مشارکت‌های کاربری $1",
        "mycontris": "مشارکت‌ها",
+       "anoncontribs": "مشارکت‌ها",
        "contribsub2": "برای {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
        "nocontribs": "هیچ تغییری با این مشخصات یافت نشد.",
        "movenosubpage": "این صفحه هیچ زیرصفحه‌ای ندارد.",
        "movereason": "دلیل:",
        "revertmove": "واگردانی",
-       "delete_and_move": "حذف و انتقال",
        "delete_and_move_text": "== نیاز به حذف ==\n\nمقالهٔ مقصد «[[:$1]]» وجود دارد. آیا می‌خواهید آن را حذف کنید تا انتقال ممکن شود؟",
        "delete_and_move_confirm": "بله، صفحه حذف شود",
        "delete_and_move_reason": "حذف برای ممکن‌شدن انتقال  «[[$1]]»",
        "tooltip-pt-preferences": "ترجیحات من",
        "tooltip-pt-watchlist": "فهرست صفحه‌هایی که شما تغییرات آن‌ها را پی‌گیری می‌کنید",
        "tooltip-pt-mycontris": "فهرست مشارکت‌های شما",
+       "tooltip-pt-anoncontribs": "فهرست ویرایش‌ها انجام شده از این نشانی آی‌پی",
        "tooltip-pt-login": "توصیه می‌شود که به سامانه وارد شوید، گرچه اجباری نیست",
        "tooltip-pt-logout": "خروج از سامانه",
        "tooltip-pt-createaccount": "از شما دعوت می‌شود که حساب کاربری بسازید و به سامانه وارد شوید؛ هرچند که ساخت حساب کاربری اختیاری است.",
        "tags-edit": "ویرایش",
        "tags-delete": "حذف",
        "tags-activate": "فعال‌سازی",
-       "tags-deactivate": "غیرفعال‌سازی",
+       "tags-deactivate": "غیرفعال کردن/إکار کةتن",
        "tags-hitcount": "$1 {{PLURAL:$1|تغییر|تغییر}}",
        "tags-manage-no-permission": "شما اجازه مدیریت تغییر تگ‌ها را ندارید.",
        "tags-create-heading": "ایجاد یک برچسب جدید",
index dd02823..00b854c 100644 (file)
@@ -82,6 +82,7 @@
        "tog-watchlisthidebots": "Piilota bottien muokkaukset tarkkailulistalta",
        "tog-watchlisthideminor": "Piilota pienet muokkaukset tarkkailulistalta",
        "tog-watchlisthideliu": "Piilota kirjautuneiden käyttäjien muokkaukset tarkkailulistalta",
+       "tog-watchlistreloadautomatically": "Päivitä tarkkailulista automaattisesti aina kun jotakin suodatinta on muutettu (vaatii JavaScriptiä)",
        "tog-watchlisthideanons": "Piilota rekisteröitymättömien käyttäjien muokkaukset tarkkailulistalta",
        "tog-watchlisthidepatrolled": "Piilota muutostentarkastajien hyväksymät muokkaukset tarkkailulistalta",
        "tog-watchlisthidecategorization": "Piilota muutokset, jotka koskevat sivujeen lisäämistä tai poistamista luokkiin",
        "morenotlisted": "Tämä luettelo ei ole täydellinen.",
        "mypage": "Käyttäjäsivu",
        "mytalk": "Keskustelu",
-       "anontalk": "Keskustelusivu tälle IP-muokkaajalle",
+       "anontalk": "Keskustelu",
        "navigation": "Valikko",
        "and": "&#32;ja",
        "qbfind": "Etsi",
        "wrongpasswordempty": "Et voi antaa tyhjää salasanaa.",
        "passwordtooshort": "Salasanan täytyy olla vähintään {{PLURAL:$1|yhden merkin pituinen|$1 merkkiä pitkä}}.",
        "passwordtoolong": "Salasanat saavat olla enintään $1 {{PLURAL:$1|merkin}} pituisia.",
+       "passwordtoopopular": "Tavanomaisen kaltaisia salasanoja ei saa käyttää. Valitse parempi ja yksilöllisempi salasana.",
        "password-name-match": "Salasanasi täytyy olla eri kuin käyttäjätunnuksesi.",
        "password-login-forbidden": "Tämän käyttäjänimen ja salasanan käyttö on estetty.",
        "mailmypassword": "Uudista salasana",
        "passwordreset-emailtext-ip": "Joku (todennäköisesti sinä, IP-osoitteesta $1) pyysi salasanasi\nvaihtamista sivustolla {{SITENAME}} ($4). {{PLURAL:$3|Seuraava käyttäjätunnus on|Seuraavat käyttäjätunnukset ovat}}\nyhdistettynä tähän sähköpostiosoitteeseen:\n\n$2\n\n{{PLURAL:$3|Tämä väliaikainen salasana vanhentuu|Nämä väliaikaiset salasanat vanhentuvat}} {{PLURAL:$5|yhden päivän|$5 päivän}} kuluttua.\nKirjaudu sisään nyt ja valitse uusi salasana heti. Jos joku toinen teki tämän pyynnön \ntai jos muistitkin vanhan salasanasi etkä halua enää muuttaa sitä,\nvoit jättää tämän viestin huomiotta ja jatkaa vanhan salasanasi käyttämistä.",
        "passwordreset-emailtext-user": "Käyttäjä $1 pyysi muistutusta tunnuksesi tiedoista sivustolla {{SITENAME}} ($4).\n{{PLURAL:$3|Seuraava käyttäjätunnus on|Seuraavat käyttäjätunnukset ovat}} liitetty tähän sähköpostiosoitteeseen:\n\n$2\n\n{{PLURAL:$3|Tämä väliaikainen salasana vanhentuu|Nämä väliaikaiset salasanat vanhentuvat}} {{PLURAL:$5|yhden päivän|$5 päivän}} kuluttua.\nSinun kannattaa kirjautua sisään ja valita uusi salasana. Jos joku toinen teki tämän\npyynnön, tai muistat sittenkin vanhan salasanasi, etkä halua muuttaa sitä,\nvoit jättää tämän viestin huomiotta ja jatkaa vanhan salasanan käyttöä.",
        "passwordreset-emailelement": "Käyttäjätunnus: \n$1\n\nVäliaikainen salasana: \n$2",
-       "passwordreset-emailsent": "Jos tämä on sinun tunnuksellesi rekisteröity sähköpostiosoite, siihen lähetetään salasanan uudistamisesta kertova viesti.",
+       "passwordreset-emailsentemail": "Jos tämä on sinun tunnuksellesi rekisteröity sähköpostiosoite, siihen lähetetään salasanan uudistamisesta kertova viesti.",
        "passwordreset-emailsent-capture": "Salasanan uudistamisesta kertova sähköpostiviesti on lähetetty, ja se näkyy myös alla.",
        "passwordreset-emailerror-capture": "Allaoleva sähköpostiviesti luotiin, mutta sen lähettäminen {{GENDER:$2|käyttäjälle}} epäonnistui: $1",
        "changeemail": "Muuta tai poista sähköpostiosoite",
        "recentchanges-legend-heading": "'''Selitys:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (katso myös [[Special:NewPages|lista uusista sivuista]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Näytä",
        "rcnotefrom": "Alla ovat muutokset <strong>$3, $4</strong> lähtien. (Enintään <strong>$1</strong> näytetään.)",
        "rclistfrom": "Näytä uudet muutokset $3 $2 alkaen",
        "rcshowhideminor": "$1 pienet muutokset",
        "mostrevisions": "Muokatuimmat sivut",
        "prefixindex": "Kaikki sivut katkaisuhaulla",
        "prefixindex-namespace": "Kaikki sivut etuliitteellä (nimiavaruus $1)",
+       "prefixindex-submit": "Näytä",
        "prefixindex-strip": "Älä näytä etuliitteitä listauksessa",
        "shortpages": "Lyhyet sivut",
        "longpages": "Pitkät sivut",
        "protectedpages-performer": "Suojauksen asettanut",
        "protectedpages-params": "Suojauksen asetukset",
        "protectedpages-reason": "Syy",
+       "protectedpages-submit": "Hae sivut",
        "protectedpages-unknown-timestamp": "Tuntematon",
        "protectedpages-unknown-performer": "Tuntematon käyttäjä",
        "protectedtitles": "Suojatut sivunimet",
        "protectedtitles-summary": "Tällä sivulla on lueteltu ne sivut, jotka on tällä hetkellä suojattu uudelleenluonnilta. Nähdäksesi luettelon olemassaolevista suojatuista sivuista katso [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Ei suojattuja sivunimiä näillä hakuehdoilla.",
+       "protectedtitles-submit": "Hae sivunimet",
        "listusers": "Käyttäjien luettelo",
        "listusers-editsonly": "Näytä vain käyttäjät, joilla on muokkauksia",
        "listusers-creationsort": "Lajittele tunnuksen luontipäivämäärän mukaan",
        "activeusers-hidebots": "Piilota botit",
        "activeusers-hidesysops": "Piilota ylläpitäjät",
        "activeusers-noresult": "Käyttäjiä ei löytynyt.",
+       "activeusers-submit": "Hae aktiiviset käyttäjät",
        "listgrouprights": "Käyttäjäryhmien oikeudet",
        "listgrouprights-summary": "Tämä lista sisältää tämän wikin käyttäjäryhmät sekä ryhmiin liitetyt käyttöoikeudet.\nLisätietoa yksittäisistä käyttäjäoikeuksista saattaa löytyä [[{{MediaWiki:Listgrouprights-helppage}}|erilliseltä ohjesivulta]].",
        "listgrouprights-key": "Selite:\n* <span class=\"listgrouprights-granted\">Myönnetyt oikeudet</span>\n* <span class=\"listgrouprights-revoked\">Kumotut oikeudet</span>",
        "wlshowlast": "Näytä edelliset $1 tuntia tai $2 päivää",
        "watchlistall2": "kaikki",
        "watchlist-hide": "Piilota",
-       "wlshowtime": "Näytä viimeiset:",
+       "watchlist-submit": "Näytä",
+       "wlshowtime": "Näytettävä aikajakso:",
        "wlshowhideminor": "pienet muutokset",
        "wlshowhidebots": "botit",
        "wlshowhideliu": "rekisteröityneet käyttäjät",
        "deletepage": "Poista sivu",
        "confirm": "Toteuta",
        "excontent": "sisälsi: ”$1”",
-       "excontentauthor": "sisältö oli: \"$1\", ja ainoa muokkaaja oli \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|keskustelu]])",
+       "excontentauthor": "sisältö oli: \"$1\", ja ainoa muokkaaja oli \"[[Special:Contributions/$2|$2]]\"",
        "exbeforeblank": "ennen tyhjentämistä sisälsi: ”$1”",
        "delete-confirm": "Poista ”$1”",
        "delete-legend": "Sivun poisto",
        "blanknamespace": "(pääavaruus)",
        "contributions": "{{GENDER:$1|Käyttäjän}} muokkaukset",
        "contributions-title": "Käyttäjän $1 muokkaukset",
-       "mycontris": "Omat muokkaukset",
+       "mycontris": "Muokkaukset",
+       "anoncontribs": "Muokkaukset",
        "contribsub2": "Käyttäjän {{GENDER:$3|$1}} ($2) muokkaukset",
        "contributions-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
        "nocontribs": "Näihin ehtoihin sopivia muokkauksia ei löytynyt.",
        "whatlinkshere-hidelinks": "$1 linkit",
        "whatlinkshere-hideimages": "$1 tiedostolinkit",
        "whatlinkshere-filters": "Suotimet",
+       "whatlinkshere-submit": "Siirry",
        "autoblockid": "Automaattinen esto #$1",
        "block": "Estä käyttäjä",
        "unblock": "Poista käyttäjän esto",
        "movenosubpage": "Tällä sivulla ei ole alasivuja.",
        "movereason": "Syy:",
        "revertmove": "kumoa siirto",
-       "delete_and_move": "Poista kohdesivu ja siirrä",
        "delete_and_move_text": "==Poistamista edellyttävä siirto==\nKohdesivu [[:$1]] on jo olemassa. \nHaluatko poistaa sen, jotta nykyinen sivu voitaisiin siirtää?",
        "delete_and_move_confirm": "Kyllä, poista kohdesivu",
        "delete_and_move_reason": "Sivu on sivun [[$1]] siirron tiellä.",
        "tooltip-pt-preferences": "Omat asetukset",
        "tooltip-pt-watchlist": "Lista sivuista, joiden muokkauksia tarkkailet",
        "tooltip-pt-mycontris": "Lista omista muokkauksista",
+       "tooltip-pt-anoncontribs": "Luettelo tästä IP-osoitteesta tehdyistä muokkauksista",
        "tooltip-pt-login": "Kirjaudu sisään tai luo tunnus",
        "tooltip-pt-logout": "Kirjaudu ulos",
        "tooltip-pt-createaccount": "On suositeltavaa luoda käyttäjätunnus ja kirjautua sisään. Se ei kuitenkaan ole pakollista.",
index fdc460e..002b6a0 100644 (file)
        },
        "tog-underline": "Soulignement des liens :",
        "tog-hideminor": "Masquer les modifications mineures dans les changements récents",
-       "tog-hidepatrolled": "Masquer les modifications surveillées dans les modifications récentes",
-       "tog-newpageshidepatrolled": "Masquer les pages surveillées dans la liste des nouvelles pages",
+       "tog-hidepatrolled": "Masquer les modifications relues dans les modifications récentes",
+       "tog-newpageshidepatrolled": "Masquer les pages relues dans la liste des nouvelles pages",
        "tog-hidecategorization": "Masquer la catégorisation des pages",
        "tog-extendwatchlist": "Étendre la liste de suivi pour afficher toutes les modifications et pas uniquement les plus récentes",
        "tog-usenewrc": "Grouper les changements par page dans les modifications récentes et la liste de suivi",
        "tog-watchlisthidebots": "Masquer les modifications faites par des robots dans la liste de suivi",
        "tog-watchlisthideminor": "Masquer les modifications mineures dans la liste de suivi",
        "tog-watchlisthideliu": "Masquer les modifications faites par des utilisateurs inscrits dans la liste de suivi",
+       "tog-watchlistreloadautomatically": "Recharger automatiquement la liste de suivi lorsque les options de filtrage sont modifiées (JavaScript requis)",
        "tog-watchlisthideanons": "Masquer les modifications d'utilisateurs anonymes dans la liste de suivi",
-       "tog-watchlisthidepatrolled": "Masquer les modifications surveillées dans la liste de suivi",
+       "tog-watchlisthidepatrolled": "Masquer les modifications relues dans la liste de suivi",
        "tog-watchlisthidecategorization": "Masquer la catégorisation des pages",
        "tog-ccmeonemails": "M'envoyer une copie des courriels que j'envoie aux autres utilisateurs",
        "tog-diffonly": "Ne pas afficher le contenu des pages sous les diffs",
        "morenotlisted": "Cette liste n’est pas complète.",
        "mypage": "Page",
        "mytalk": "Discussion",
-       "anontalk": "Discussion avec cette adresse IP",
+       "anontalk": "Discussion",
        "navigation": "Navigation",
        "and": "&#32;et",
        "qbfind": "Rechercher",
        "databaseerror-query": "Requête : $1",
        "databaseerror-function": "Fonction : $1",
        "databaseerror-error": "Erreur : $1",
+       "transaction-duration-limit-exceeded": "Pour éviter une trop forte augmentation du délai de réplication, cette transaction a été annulée car la durée d’écriture ($1) a dépassé la limite de $2 secondes. Si vous cherchez à modifier un grand nombre d’éléments simultanément, essayez plutôt d’effectuer l’opération en plusieurs étapes.",
        "laggedslavemode": "Attention, cette page peut ne pas contenir les toutes dernières modifications effectuées",
        "readonly": "Base de données verrouillée",
        "enterlockreason": "Indiquez la raison du verrouillage ainsi qu'une estimation de sa durée",
        "wrongpasswordempty": "Vous n'avez pas entré de mot de passe. Veuillez essayer à nouveau.",
        "passwordtooshort": "Votre mot de passe doit contenir au moins $1 caractère{{PLURAL:$1||s}}.",
        "passwordtoolong": "Les mots de passe ne peuvent pas dépasser {{PLURAL:$1|1 caractère|$1 caractères}}.",
+       "passwordtoopopular": "Les mots de passe trop courants ne peuvent pas être utilisés. Veuillez choisir un mot de passe plus original.",
        "password-name-match": "Votre mot de passe doit être différent de votre nom d'utilisateur.",
        "password-login-forbidden": "L'utilisation de ce nom d'utilisateur et/ou de ce mot de passe a été interdite.",
        "mailmypassword": "Réinitialiser le mot de passe",
        "passwordreset-emailtext-ip": "Quelqu'un (probablement vous, depuis l'adresse IP $1) a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
        "passwordreset-emailtext-user": "L'utilisateur $1 sur {{SITENAME}} a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
        "passwordreset-emailelement": "Nom d'utilisateur : \n$1\n\nMot de passe temporaire : \n$2",
-       "passwordreset-emailsent": "Si c’est une adresse de courriel enregistrée pour votre compte, alors un courriel de réinitialisation de mot de passe sera envoyé.",
+       "passwordreset-emailsentemail": "Si c’est une adresse de courriel enregistrée pour votre compte, alors un courriel de réinitialisation de mot de passe sera envoyé.",
+       "passwordreset-emailsentusername": "S’il y a une adresse de courriel enregistrée pour ce compte, alors un courriel de réinitialisation de mot de passe sera envoyé.",
        "passwordreset-emailsent-capture": "Un courriel de réinitialisation de mot de passe a été envoyé, qui est affiché ci-dessous.",
        "passwordreset-emailerror-capture": "Un courriel de réinitialisation de mot de passe a été généré, qui est affiché ci-dessous, mais l'envoi à l'{{GENDER:$2|utilisateur|utilisatrice}} a échoué : $1",
        "changeemail": "Changer ou supprimer l’adresse de courriel",
        "rev-deleted-user": "(nom d'utilisateur retiré)",
        "rev-deleted-event": "(détails de l’entrée retirée)",
        "rev-deleted-user-contribs": "[nom d'utilisateur ou adresse IP retiré - modification masquée sur les contributions]",
-       "rev-deleted-text-permission": "Cette version de la page a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
-       "rev-suppressed-text-permission": "Cette version de la page a été <strong>supprimée</strong>.\nLes détails se trouvent dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-       "rev-deleted-text-unhide": "Cette version de la page a été '''effacée'''.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} le journal des effacements].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
-       "rev-suppressed-text-unhide": "Cette version de la page a été '''supprimée'''.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} le journal des suppression].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
-       "rev-deleted-text-view": "Cette version de la page a été '''effacée'''.\nVous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
-       "rev-suppressed-text-view": "Cette version de la page a été '''supprimée'''.\nVous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-       "rev-deleted-no-diff": "Vous ne pouvez pas voir ce diff parce qu'une des versions a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].",
+       "rev-deleted-text-permission": "Cette version de la page a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
+       "rev-suppressed-text-permission": "Cette version de la page a été <strong>supprimée</strong>.\nLes détails se trouvent dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des masquages].",
+       "rev-deleted-text-unhide": "Cette version de la page a été '''effacée'''.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} le journal des suppressions].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
+       "rev-suppressed-text-unhide": "Cette version de la page a été '''supprimée'''.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} le journal des masquages].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
+       "rev-deleted-text-view": "Cette version de la page a été '''effacée'''.\nVous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
+       "rev-suppressed-text-view": "Cette version de la page a été '''supprimée'''.\nVous pouvez la visualiser ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des masquages].",
+       "rev-deleted-no-diff": "Vous ne pouvez pas voir ce diff parce qu'une des versions a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
        "rev-suppressed-no-diff": "Vous ne pouvez pas voir cette différence car une des révisions a été '''supprimée'''.",
-       "rev-deleted-unhide-diff": "Une des révisions de cette différence a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des effacements].\nVous pouvez toujours [$1 voir cette différence] si vous le voulez.",
-       "rev-suppressed-unhide-diff": "L'une des révisions de ce diff a été '''supprimée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des suppressions].\nVous pouvez toujours [$1 voir ce diff] si vous souhaitez poursuivre.",
-       "rev-deleted-diff-view": "Une des révisions de ce diff a été '''supprimée'''.\nVous pouvez voir ce diff ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-       "rev-suppressed-diff-view": "Une des révisions de ce diff a été '''effacée'''.\nVous pouvez voir ce diff ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des effacements].",
+       "rev-deleted-unhide-diff": "Une des révisions de cette différence a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].\nVous pouvez toujours [$1 voir cette différence] si vous le voulez.",
+       "rev-suppressed-unhide-diff": "L'une des révisions de ce diff a été '''supprimée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des masquages].\nVous pouvez toujours [$1 voir ce diff] si vous souhaitez poursuivre.",
+       "rev-deleted-diff-view": "Une des révisions de ce diff a été '''effacée'''.\nVous pouvez voir ce diff ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
+       "rev-suppressed-diff-view": "Une des révisions de ce diff a été '''supprimée'''.\nVous pouvez voir ce diff ; des détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des masquages].",
        "rev-delundel": "afficher/masquer",
        "rev-showdeleted": "afficher",
        "revisiondelete": "Supprimer ou restaurer des événements",
        "userrights-removed-self": "Vous avez bien supprimé vos propres droits. Du coup, vous ne pouvez plus accéder à cette page.",
        "group": "Groupe :",
        "group-user": "Utilisateurs",
-       "group-autoconfirmed": "Utilisateurs enregistrés",
+       "group-autoconfirmed": "Utilisateurs autoconfirmés",
        "group-bot": "Robots",
        "group-sysop": "Administrateurs",
        "group-bureaucrat": "Bureaucrates",
        "group-suppress": "Limitateurs",
        "group-all": "(tous)",
        "group-user-member": "{{GENDER:$1|utilisateur|utilisatrice}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|utilisateur enregistré|utilisatrice enregistrée}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|utilisateur autoconfirmé|utilisatrice autoconfirmée}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administrateur|administratrice}}",
        "group-bureaucrat-member": "{{GENDER:$1|bureaucrate}}",
        "group-suppress-member": "{{GENDER:$1|limitateur|limitatrice}}",
        "grouppage-user": "{{ns:project}}:Utilisateurs",
-       "grouppage-autoconfirmed": "{{ns:project}}:Utilisateurs enregistrés",
+       "grouppage-autoconfirmed": "{{ns:project}}:Utilisateurs autoconfirmés",
        "grouppage-bot": "{{ns:project}}:Robots",
        "grouppage-sysop": "{{ns:project}}:Administrateurs",
        "grouppage-bureaucrat": "{{ns:project}}:Bureaucrates",
        "right-import": "Importer des pages depuis d'autres wikis",
        "right-importupload": "Importer des pages depuis un fichier",
        "right-patrol": "Marquer des modifications des autres comme relues",
-       "right-autopatrol": "Avoir ses modifications automatiquement marquées comme surveillées",
-       "right-patrolmarks": "Voir les marquages de surveillance dans les modifications récentes",
+       "right-autopatrol": "Avoir ses modifications automatiquement marquées comme relues",
+       "right-patrolmarks": "Voir les marquages de relecture dans les modifications récentes",
        "right-unwatchedpages": "Voir la liste des pages non suivies",
        "right-mergehistory": "Fusionner les historiques des pages",
        "right-userrights": "Modifier tous les droits d'un utilisateur",
        "recentchanges-legend-heading": "'''Légende :'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (voir aussi la [[Special:NewPages|liste des nouvelles pages]]).",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Lister",
        "rcnotefrom": "Ci-dessous {{PLURAL:$5|la modification effectuée|les modifications effectuées}} depuis le <strong>$3, $4</strong> (affichées jusqu’à <strong>$1</strong>).",
        "rclistfrom": "Afficher les nouvelles modifications depuis le $3 à $2",
        "rcshowhideminor": "$1 les modifications mineures",
        "mostrevisions": "Pages les plus modifiées",
        "prefixindex": "Toutes les pages commençant par…",
        "prefixindex-namespace": "Toutes les pages avec préfixe (espace de noms $1)",
+       "prefixindex-submit": "Lister",
        "prefixindex-strip": "Enlever le préfixe dans la liste",
        "shortpages": "Pages courtes",
        "longpages": "Pages longues",
        "protectedpages-performer": "Protection de l’utilisateur",
        "protectedpages-params": "Paramètres de protection",
        "protectedpages-reason": "Motif",
+       "protectedpages-submit": "Afficher les pages",
        "protectedpages-unknown-timestamp": "Inconnu",
        "protectedpages-unknown-performer": "Utilisateur inconnu",
        "protectedtitles": "Titres protégés",
        "protectedtitles-summary": "Cette page liste les titres actuellement protégés contre la création. Pour une liste des pages protégées existantes, voir [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Aucun titre n'est actuellement protégé avec ces paramètres.",
+       "protectedtitles-submit": "Afficher les titres",
        "listusers": "Liste des utilisateurs",
        "listusers-editsonly": "Ne montrer que les utilisateurs ayant au moins une contribution",
        "listusers-creationsort": "Trier par date de création",
        "activeusers-hidebots": "Masquer les robots",
        "activeusers-hidesysops": "Masquer les administrateurs",
        "activeusers-noresult": "Aucun utilisateur trouvé.",
+       "activeusers-submit": "Afficher les utilisateurs actifs",
        "listgrouprights": "Droits des groupes d'utilisateurs",
        "listgrouprights-summary": "Cette page contient une liste des groupes définis sur ce wiki ainsi que les droits d'accès qui leur sont associés.\nDes [[{{MediaWiki:Listgrouprights-helppage}}|informations additionnelles]] peuvent exister au sujet des droits individuels.",
        "listgrouprights-key": "Légende :\n*<span class=\"listgrouprights-granted\">Droit octroyé</span>\n*<span class=\"listgrouprights-revoked\">Droit révoqué</span>",
        "wlshowlast": "Montrer les dernières $1 heures, les derniers $2 jours",
        "watchlistall2": "tout",
        "watchlist-hide": "Masquer",
+       "watchlist-submit": "Lister",
        "wlshowtime": "Période affichée :",
        "wlshowhideminor": "modifications mineures",
        "wlshowhidebots": "robots",
        "actioncomplete": "Action effectuée",
        "actionfailed": "L'action a échoué",
        "deletedtext": "« $1 » a été supprimée.\nVoir $2 pour une liste des suppressions récentes.",
-       "dellogpage": "Journal des suppressions de page",
+       "dellogpage": "Journal des suppressions",
        "dellogpagetext": "Voici la liste des suppressions les plus récentes.",
        "deletionlog": "journal des suppressions",
        "reverted": "Version précédente rétablie",
        "protect-cascadeon": "Cette page est protégée car elle est transcluse dans {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l'option « protection en cascade » activée.\nLa modification du niveau de protection de cette page n'affectera pas la protection en cascade.",
        "protect-default": "Autoriser tous les utilisateurs",
        "protect-fallback": "Autoriser uniquement les utilisateurs avec le droit « $1 »",
-       "protect-level-autoconfirmed": "Autoriser uniquement les utilisateurs auto-confirmés",
+       "protect-level-autoconfirmed": "Autoriser uniquement les utilisateurs autoconfirmés",
        "protect-level-sysop": "Autoriser uniquement les administrateurs",
        "protect-summary-cascade": "protection en cascade",
        "protect-expiring": "expire le $1 (UTC)",
        "contributions": "Contributions de l’{{GENDER:$1|utilisateur|utilisatrice}}",
        "contributions-title": "Liste des contributions de l’utilisat{{GENDER:$1|eur|rice|eur}} $1",
        "mycontris": "Contributions",
+       "anoncontribs": "Contributions",
        "contribsub2": "Pour {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Le compte utilisateur « $1 » n’est pas enregistré.",
        "nocontribs": "Aucune modification correspondant à ces critères n'a été trouvée.",
        "whatlinkshere-hidelinks": "$1 les liens",
        "whatlinkshere-hideimages": "$1 les liens vers le fichier",
        "whatlinkshere-filters": "Filtres",
+       "whatlinkshere-submit": "Lister",
        "autoblockid": "Blocage automatique #$1",
        "block": "Bloquer l’utilisateur",
        "unblock": "Débloquer l’utilisateur",
        "autoblocker": "Vous avez été bloqué automatiquement parce que votre adresse IP a été récemment utilisée par « [[User:$1|$1]] ».\nLe motif fourni pour le blocage de $1 est « $2 »",
        "blocklogpage": "Journal des blocages",
        "blocklog-showlog": "Cet utilisateur a été bloqué précédemment. Le journal des blocages est disponible ci-dessous :",
-       "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et caché précédemment. Le journal des suppressions est disponible ci-dessous :",
+       "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et masqué précédemment. Le journal des masquages est disponible ci-dessous :",
        "blocklogentry": "a bloqué [[$1]] ; expiration : $2 $3",
        "reblock-logentry": "a modifié les paramètres du blocage de [[$1]] avec une expiration au $2 $3",
        "blocklogtext": "Ceci est le journal des actions de blocage et déblocage d’utilisateurs.\nLes adresses IP automatiquement bloquées ne sont pas listées.\nConsultez la [[Special:BlockList|liste des blocages]] pour voir les bannissements et blocages effectivement en cours.",
        "movenosubpage": "Cette page n'a aucune sous-page.",
        "movereason": "Motif :",
        "revertmove": "rétablir",
-       "delete_and_move": "Supprimer et renommer",
        "delete_and_move_text": "== Suppression requise ==\nLa page de destination « [[:$1]] » existe déjà.\nÊtes-vous certain{{GENDER:||e|}} de vouloir la supprimer pour permettre ce renommage ?",
        "delete_and_move_confirm": "Oui, supprimer la page de destination",
        "delete_and_move_reason": "Page supprimée pour permettre le renommage depuis « [[$1]] »",
        "tooltip-pt-preferences": "Vos préférences",
        "tooltip-pt-watchlist": "La liste des pages dont vous suivez les modifications",
        "tooltip-pt-mycontris": "La liste de vos contributions",
+       "tooltip-pt-anoncontribs": "Une liste des modifications effectuées depuis cette adresse IP",
        "tooltip-pt-login": "Il est recommandé de vous identifier ; ce n'est cependant pas obligatoire.",
        "tooltip-pt-logout": "Se déconnecter",
        "tooltip-pt-createaccount": "Il vous est conseillé de créer un compte et de vous connecter ; cependant, ce n’est pas obligatoire",
        "common.css": "/* Le CSS placé ici sera appliqué à tous les habillages. */",
        "print.css": "/* Le CSS placé ici affectera les impressions */",
        "noscript.css": "/* Le CSS placé ici affectera les utilisateurs ayant désactivé Javascript. */",
-       "group-autoconfirmed.css": "/* Le CSS placé ici affectera les utilisateurs auto-confirmés seulement. */",
+       "group-autoconfirmed.css": "/* Le CSS placé ici n’affectera que les utilisateurs autoconfirmés. */",
        "group-user.css": "/* Le CSS placé ici n’affectera que les utilisateurs enregistrés. */",
        "group-bot.css": "/* Le CSS placé ici affectera les robots seulement. */",
        "group-sysop.css": "/* Le CSS inclus ici n’affectera que les administrateurs */",
        "group-bureaucrat.css": "/* Le CSS inclus ici n’affectera que les bureaucrates */",
        "common.js": "/* Tout JavaScript ici sera chargé avec chaque page accédée par n’importe quel utilisateur. */",
-       "group-autoconfirmed.js": "/* Le JavaScript inclus ici n’affectera que les utilisateurs auto-confirmés */",
+       "group-autoconfirmed.js": "/* Le JavaScript inclus ici n’affectera que les utilisateurs autoconfirmés */",
        "group-user.js": "/* Le JavaScript placé ici ne sera chargé que pour les utilisateurs enregistrés. */",
        "group-bot.js": "/* Le JavaScript inclus ici n’affectera que les robots */",
        "group-sysop.js": "/* Le JavaScript inclus ici n’affectera que les administrateurs */",
        "markedaspatrollederrortext": "Vous devez sélectionner une version pour pouvoir la marquer comme relue.",
        "markedaspatrollederror-noautopatrol": "Vous n'avez pas le droit de marquer vos propres modifications comme relues.",
        "markedaspatrollednotify": "Cette modification de $1 a été marquée comme relue.",
-       "markedaspatrollederrornotify": "Échec du marquage comme contrôlé.",
+       "markedaspatrollederrornotify": "Échec du marquage de la modification comme relue.",
        "patrol-log-page": "Journal des relectures",
        "patrol-log-header": "Voici l’historique des versions relues.",
        "log-show-hide-patrol": "$1 l’historique des relectures",
index 42b050f..be92a64 100644 (file)
        "rcshowhidemine-hide": "Cacher",
        "diff": "diff",
        "hist": "hist",
+       "hide": "Cacher",
        "show": "Afficher",
        "minoreditletter": "m",
        "newpageletter": "N",
        "filehist-current": "Courant",
        "filehist-datetime": "Date et heure",
        "filehist-user": "Useur",
+       "filehist-dimensions": "Dimensions",
        "filehist-comment": "Commentaire",
        "imagelinks": "Utilisation du fichier",
        "nolinkstoimage": "Aucune page uses ce fichier.",
        "unusedimages": "Fichiers orphelins",
        "protectedpages-page": "Page",
        "protectedpages-reason": "Raison",
+       "newpages": "Nouvelles pages",
        "newpages-username": "Nom d'useur:",
        "ancientpages": "Pages les plus anciennement changées",
        "move": "Renommer",
        "namespace": "Espace de noms:",
        "invert": "Inverser la sélection",
        "blanknamespace": "(Principal)",
-       "contributions": "Changements de l'useur",
+       "contributions": "Contributions de l’{{GENDER:$1|useur|useuse}}",
        "mycontris": "Contributions",
        "uctop": "(actuel)",
        "sp-contributions-talk": "Discuter",
        "whatlinkshere": "Pages liées",
        "whatlinkshere-title": "Pages qui connectent vers \"$1\"",
        "whatlinkshere-page": "Page:",
+       "isimage": "lien vers le fichier",
+       "whatlinkshere-next": "{{PLURAL:$1|suivante|$1 suivantes}}",
        "whatlinkshere-links": "← liens",
        "whatlinkshere-hidelinks": "$1 les liens",
        "whatlinkshere-filters": "Filtres",
        "tooltip-t-specialpages": "Liste de tout les pages speciales",
        "tooltip-t-print": "Version imprimable de cette page",
        "tooltip-ca-nstab-user": "Voir la page d'useur",
-       "tooltip-ca-nstab-special": "Ceci est une page spéciale, vous ne pouvez pas la changer.",
+       "tooltip-ca-nstab-special": "Ceci est une page spéciale, et elle ne peut pas être changée.",
        "pageinfo-toolboxlink": "Information sur la page",
        "bad_image_list": "Le format est le suivant :\n\nSeules les listes d’énumération (commençant par *) sont prises en compte. Le premier lien d’une ligne doit être celui d’une mauvaise image.\nLes autres liens sur la même ligne sont considérés comme des exceptions, par exemple des pages sur lesquelles l’image peut apparaître.",
        "metadata": "Métadonnées",
+       "exif-orientation": "Orientation",
        "exif-colorspace": "Espace des couleurs",
        "exif-orientation-1": "Normale",
        "namespacesall": "Tous",
+       "monthsall": "tous",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussion]])",
        "redirect-file": "Nom du fichier",
        "specialpages": "Pages spéciales",
index 36f0758..2876ef2 100644 (file)
        "movelogpagetext": "Dit is in list fan feroare titels.",
        "movereason": "Reden:",
        "revertmove": "werom sette",
-       "delete_and_move": "Fuortsmite en omneame",
        "delete_and_move_text": "== Wiskjen nedich ==\nDe doelside \"[[:$1]]\" is der al.\nMoat dy wiske wurde om plak te meitsjen foar it werneamen?",
        "delete_and_move_confirm": "Ja, wiskje de side",
        "delete_and_move_reason": "Wiske om plak te meitsjen foar in werneamde side",
index 62e26de..fce4d42 100644 (file)
        "movenosubpage": "Chan eil fo-dhuilleag aig an duilleag seo.",
        "movereason": "Adhbhar:",
        "revertmove": "till",
-       "delete_and_move": "Sguab às agus gluais",
        "delete_and_move_text": "== Tha sguabadh às a dhìth ==\nTha an duilleag-uidhe \"[[:$1]]\" ann mar-thà.\nA bheil thu airson a sguabadh às ach am bidh rum airson a' ghluasaid ann?",
        "delete_and_move_confirm": "Siuthad, sguab às an duilleag",
        "delete_and_move_reason": "Chaidh a sguabadh às gus rum a airson a' ghluasaid o \"[[$1]]\" a chruthachadh",
index ae43f1e..756f957 100644 (file)
@@ -56,6 +56,7 @@
        "tog-watchlisthidebots": "Agochar as edicións dos bots na lista de vixilancia",
        "tog-watchlisthideminor": "Agochar as edicións pequenas na lista de vixilancia",
        "tog-watchlisthideliu": "Agochar as edicións dos usuarios rexistrados na lista de vixilancia",
+       "tog-watchlistreloadautomatically": "Recargar a lista de vixilancia automáticamente cando se produce un cambio nun filtro (require JavaScript)",
        "tog-watchlisthideanons": "Agochar as edicións dos usuarios anónimos na lista de vixilancia",
        "tog-watchlisthidepatrolled": "Agochar as edicións patrulladas na lista de vixilancia",
        "tog-watchlisthidecategorization": "Agochar a categorización das páxinas",
        "morenotlisted": "Esta lista non está completa.",
        "mypage": "Páxina",
        "mytalk": "Conversa",
-       "anontalk": "Conversa con este enderezo IP",
+       "anontalk": "Conversa",
        "navigation": "Navegación",
        "and": "&#32;e",
        "qbfind": "Procurar",
        "databaseerror-query": "Pescuda: $1",
        "databaseerror-function": "Función: $1",
        "databaseerror-error": "Erro: $1",
+       "transaction-duration-limit-exceeded": "Para evitar crear un gran atraso na replicación, esta transacción abortouse xa que a duración de escritura ($1) excedeu o límite de $2 segundos.\nSe estás a cambiar moitos obxectos ao mesmo tempo, procura facer operacións múltiples máis pequenas no seu lugar.",
        "laggedslavemode": "'''Aviso:''' A páxina pode non conter as actualizacións recentes.",
        "readonly": "Base de datos pechada",
        "enterlockreason": "Dea unha razón para o peche, incluíndo unha estimación de até cando se manterá",
        "wrongpasswordempty": "O campo do contrasinal estaba en branco.\nPor favor, inténteo de novo.",
        "passwordtooshort": "Os contrasinais deben conter, como mínimo, {{PLURAL:$1|1 carácter|$1 caracteres}}.",
        "passwordtoolong": "Os contrasinais non deben ser máis longo de {{PLURAL:$1|1 carácter|$1 caracteres}}.",
+       "passwordtoopopular": "Os contrasinais escollidos máis habitualmente non poden usarse. Por favor, escolle un contrasinal máis único.",
        "password-name-match": "O seu contrasinal debe ser diferente do seu nome de usuario.",
        "password-login-forbidden": "O uso deste nome de usuario e contrasinal foi prohibido.",
        "mailmypassword": "Restablecer o contrasinal",
        "passwordreset-emailtext-ip": "Alguén (probablemente vostede, desde o enderezo IP $1) solicitou o restablecemento do seu\ncontrasinal de {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de usuario está asociada|As seguintes contas de usuarios están asociadas}}\na este enderezo de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Este contrasinal temporal caducará|Estes contrasinais temporais caducarán}} {{PLURAL:$5|nun día|en $5 días}}.\nDebería acceder ao sistema e elixir un novo contrasinal agora. Se outra persoa fixo esta\nsolicitude ou se lembrou o seu contrasinal orixinal e xa non o quere cambiar,\nignore esta mensaxe e continúe empregando o seu contrasinal vello.",
        "passwordreset-emailtext-user": "O usuario $1 solicitou o restablecemento do contrasinal de {{SITENAME}}\n($4). {{PLURAL:$3|A seguinte conta de usuario está asociada|As seguintes contas de usuarios están asociadas}}\na este enderezo de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Este contrasinal temporal caducará|Estes contrasinais temporais caducarán}} {{PLURAL:$5|nun día|en $5 días}}.\nDebería acceder ao sistema e elixir un novo contrasinal agora. Se outra persoa fixo esta\nsolicitude ou se lembrou o seu contrasinal orixinal e xa non o quere cambiar,\nignore esta mensaxe e continúe empregando o seu contrasinal vello.",
        "passwordreset-emailelement": "Nome de usuario: \n$1\n\nContrasinal temporal: \n$2",
-       "passwordreset-emailsent": "Se esta é unha dirección de correo electrónico rexistrada para a túa conta, entón enviarase un correo electrónico para o restablecemento do teu contrasinal.",
+       "passwordreset-emailsentemail": "Se esta é unha dirección de correo electrónico rexistrada para a túa conta, entón enviarase un correo electrónico para o restablecemento do teu contrasinal.",
        "passwordreset-emailsent-capture": "Enviouse un correo electrónico de restablecemento do contrasinal, mostrado a continuación.",
        "passwordreset-emailerror-capture": "Xerouse un correo electrónico de restablecemento do contrasinal, mostrado a continuación, pero o envío {{GENDER:$2|ao usuario|á usuaria}} fallou: $1",
        "changeemail": "Cambiar ou eliminar o enderezo de correo electrónico",
        "wlshowlast": "Mostrar as últimas $1 horas e os últimos $2 días",
        "watchlistall2": "todo",
        "watchlist-hide": "Agochar",
-       "wlshowtime": "Mostrar último:",
+       "wlshowtime": "Periodo de tempo a amosar:",
        "wlshowhideminor": "edicións menores",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "usuarios rexistrados",
        "contributions": "Contribucións {{GENDER:$1|do usuario|da usuaria}}",
        "contributions-title": "Contribucións de $1",
        "mycontris": "Contribucións",
+       "anoncontribs": "Contribucións",
        "contribsub2": "De {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "A conta de usuario \"$1\" non está rexistrada.",
        "nocontribs": "Non se deron atopado cambios con eses criterios.",
        "movenosubpage": "Esta páxina non ten subpáxinas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
-       "delete_and_move": "Borrar e mover",
        "delete_and_move_text": "== Cómpre borrar ==\nA páxina de destino, chamada \"[[:$1]]\", xa existe.\nQuérea borrar para deixar sitio para facer o traslado?",
        "delete_and_move_confirm": "Si, borrar a páxina",
        "delete_and_move_reason": "Eliminado para facer sitio para mover \"[[$1]]\"",
        "tooltip-pt-preferences": "As miñas preferencias",
        "tooltip-pt-watchlist": "A lista de páxinas cuxas modificacións está a seguir",
        "tooltip-pt-mycontris": "Lista das súas contribucións",
+       "tooltip-pt-anoncontribs": "Unha lista de modificacións feitas desde esta dirección IP",
        "tooltip-pt-login": "Recoméndaselle rexistrarse, se ben non é obrigatorio",
        "tooltip-pt-logout": "Saír ao anonimato",
        "tooltip-pt-createaccount": "Recoméndaselle crear unha conta e acceder ao sistema, se ben non é obrigatorio",
index 4daf258..41f1ec9 100644 (file)
        "passwordreset-emailtext-ip": "Eber mit dr IP-Adresse $1, wahrschyns Du sälber, het e Erinnerig an Dyyni Benutzerkonteninformatione fir {{SITENAME}} aagforderet ($4). \n\n{{PLURAL:$3|Des Benutzerkonto isch|Die Benutzerkonte sin}} mit däre E-Mail-Adräss verchnipft: \n\n$2 \n\n{{PLURAL:$3|Des temporär Passwort lauft|Die temporäre Passwerter laufe}} in {{PLURAL:$5|eim Tag|$5 Täg}} ab.\nDu sottsch di aamälden un e nej Passwort vergee. Wänn eber ander die Aafrog gstellt het oder Du di wider an Dyy alt Passwort chasch erinnere un s nimi wettsch ändere, chasch die Nochricht ignorieren un alsfurt Dyy alt Passwort bruche.",
        "passwordreset-emailtext-user": "Dr Benutzer $1 bi {{SITENAME}} het e Zrucksetzig vu Dym Passwort bi {{SITENAME}} aagforderet ($4). \n\n{{PLURAL:$3|Des Benutzerkonto isch|Die Benutzerkonte sin}} mit däre E-Mail-Adräss verchnipft: \n\n$2 \n\n{{PLURAL:$3|Des temporär Passwort lauft|Die temporäre Passwerter laufe}} in {{PLURAL:$5|eim Tag|$5 Täg}} ab.\nDu sottsch di aamälden un e nej Passwort vergee. Wänn eber ander die Aafrog gstellt het oder Du di wider an Dyy alt Passwort chasch erinnere un s nimi wettsch ändere, chasch die Nochricht ignorieren un alsfurt Dyy alt Passwort bruche.",
        "passwordreset-emailelement": "Benutzername: \n$1\n\nTemporär Passwort: \n$2",
-       "passwordreset-emailsent": "We das di bestätigti E-Mail-Adrässen vo dym Wiki-Konto isch, de wird es E-Mail verschickt, für ds Passwort zrüggzsetze.",
+       "passwordreset-emailsentemail": "We das di bestätigti E-Mail-Adrässen vo dym Wiki-Konto isch, de wird es E-Mail verschickt, für ds Passwort zrüggzsetze.",
        "passwordreset-emailsent-capture": "E Passwort-Zrucksetzigs-Mail isch vergschickt worde, un isch unte aazeigt.",
        "passwordreset-emailerror-capture": "Die unten angezeigte Passwortzrucksetzigsmail, wu unten aazeigt wird, isch generiert wore, aber dr Versand an {{GENDER:$2|dr Benutzer|d Benutzeri}} het nit funktioniert: $1",
        "changeemail": "E-Mail-Adrässen änderen oder lösche",
        "movenosubpage": "Die Syte het kei Untersyte.",
        "movereason": "Grund:",
        "revertmove": "Zrugg verschiebe",
-       "delete_and_move": "Lösche un Verschiebe",
        "delete_and_move_text": "== D Ziilsyte isch scho vorhande, lösche?==\n\nD Syte „[[:$1]]“ gits scho. Wottsch du si lösche, zume Platz zum verschiebe mache?",
        "delete_and_move_confirm": "D Ziilsyte für d Verschiebig lösche",
        "delete_and_move_reason": "glöscht, zume Platz für s Verschiebe vo „[[$1]]“ z mache",
        "tooltip-pt-mycontris": "Lischt vu Dyyne Byyträg",
        "tooltip-pt-login": "Aamälde",
        "tooltip-pt-logout": "Abmälde",
-       "tooltip-pt-createaccount": "Du chasch gärn e Bentuzerkonto aalege un Di aamälde. Du muesch s aber nit",
+       "tooltip-pt-createaccount": "Du chasch gärn e Benutzerkonto aalege un Di aamälde. Du muesch s aber nit",
        "tooltip-ca-talk": "Diskussion zum Artikelinhalt",
        "tooltip-ca-edit": "Die Syte bearbeite",
        "tooltip-ca-addsection": "Neje Abschnitt aafange",
index 773448b..ef0713e 100644 (file)
        "createaccountreason": "કારણ:",
        "createacct-reason": "કારણ",
        "createacct-reason-ph": "તમે કેમ બીજું ખાતું બનાવો છો",
-       "createacct-captcha": "સલામતી ચકાસણી",
-       "createacct-imgcaptcha-ph": "તમે જે લખાણ જુઓ છો તે દાખલ કરો",
        "createacct-submit": "તમારું ખાતું બનાવો",
        "createacct-another-submit": "બીજું ખાતું બનાવો",
        "createacct-benefit-heading": "{{SITENAME}} એ તમારા જેવા લોકોએ બનાવેલ છે.",
        "passwordreset-emailtext-ip": "કોઈકે (કદાચ તમોએ , $1 IP એડ્રેસ થી) તમારી વેબસાઈટ {{SITENAME}}  ($4) નો પાસવર્ડ રિસેટ કરવાની રજૂઆત કરી છે. આ ઈમેઈલ એડ્રેસ સાથે {{PLURAL:$3|નું ખાતું|ના ખાતા}} જોડાયેલા છે.\n.\n.\n\n$2\n\n{{PLURAL:$3|આ કામચલાઉ પાસવર્ડ|આ બધા કામચલાઉ પાસવર્ડ}} {{PLURAL:$5|એક દિવસ|$5 દિવસો}} માં નષ્ટ થઇ જશે. તમારે અત્યારે જ ખાતું ખોલીને નવો પાસવર્ડ સેટ કરી લેવો જોઈએ .જો કોઈ બીજા એ આ રજૂઆત કરી હોય, અથવા જો તમને પોતાનો અસલ પાસવર્ડ યાદ હોય, અને તેને બદલવા નથી માગતા, તો આ સંદેશાને જતો કરીને પોતાના અસલ પાસવર્ડ ને વાપરી શકો છો.",
        "passwordreset-emailtext-user": "વેબસાઈટ  {{SITENAME}} ના વપરાશકર્તા $1 એ તમારા {{SITENAME}} ($4) નો પાસવર્ડ રિસેટ કરવાની રજૂઆત કરી છે. આ ઈમેઈલ એડ્રેસ સાથે {{PLURAL:$3|નું ખાતું|ના ખાતા}} જોડાયેલ છે.\n\n$2\n\n{{PLURAL:$3|આ કામચલાઉ પાસવર્ડ|આ બધા કામચલાઉ પાસવર્ડ}} {{PLURAL:$5|એક દિવસ|$5 દિવસ}} માં નષ્ટ થઇ જશે. તમારે અત્યારે જ ખાતું ખોલીને નવો પાસવર્ડ સેટ કરી લેવો જોઈએ .જો કોઈ બીજા એ આ રજૂઆત કરી હોય, અથવા જો તમને પોતાનો અસલ પાસવર્ડ યાદ હોય, અને તેને બદલવા નથી માગતા, તો આ સંદેશાને જતો કરીને પોતાના અસલ પાસવર્ડ ને વાપરી શકો છો..",
        "passwordreset-emailelement": "વપરાશકર્તા નામ: \n$1\n\nકામચલાઉ પાસવર્ડ: \n$2",
-       "passwordreset-emailsent": "પાસવર્ડ બદલવાનો ઇમેલ મોકલવામાં આવ્યો છે.",
+       "passwordreset-emailsentemail": "પાસવર્ડ બદલવાનો ઇમેલ મોકલવામાં આવ્યો છે.",
        "passwordreset-emailsent-capture": "પાસવર્ડ બદલવાનો ઇમેલ મોકલવામાં આવ્યો છે, જે નીચે પ્રમાણે છે.",
        "passwordreset-emailerror-capture": "પાસવર્ડ ફરી ગોઠવવા માટેનો ઇમેલ બનાવવામાં આવ્યો છે, જે નીચે પ્રમાણે છે, પરંતુ તે {{GENDER:$2|સભ્ય}}ને મોકલવામાં નિષ્ફળ થયો છે: $1",
        "changeemail": "ઇમેલ સરનામું બદલો",
        "userrights-editusergroup": "સભ્ય સમુહો સંપાદીત કરો",
        "saveusergroups": "સભ્ય સમુહો સાચવો",
        "userrights-groupsmember": "સભ્યપદ:",
-       "userrights-groupsmember-auto": "àª\86નà«\8b અભિપ્રેત સભ્ય:",
+       "userrights-groupsmember-auto": "સામà«\87 àª¦àª°à«\8dશાવà«\87લા {{PLURAL:$1|àª\9cà«\82થ|àª\9cà«\82થà«\8b}}{{GENDER:$2|નà«\8b|નà«\80|ના}} અભિપ્રેત સભ્ય:",
        "userrights-groupsmember-type": " $1",
-       "userrights-groups-help": "àª\85 àª¸à«\8dભà«\8dય àª\9cà«\87નà«\8b àª¸àª­à«\8dય àª\9bà«\87 àª¤à«\87 àª¸àª®à«\8dહà«\82હનà«\87 àª¬àª¦àª²à«\80 àª¶àª\95à«\8b àª\9bà«\8b:\n* àª\85àª\82àª\95િત àª\95રà«\87લà«\81àª\82 àª\96ાનà«\81àª\82 àª¬àª¤àª¾àªµà«\87 àª\9bà«\87 àª¸àª­à«\8dય àª¤à«\87નà«\8b àª¸àª®à«\82હમાàª\82 àª¶àª¾àª®àª¿àª² àª\9bà«\87.\n* àª\9cà«\8b àª\96ાનà«\81àª\82 àª\85àª\82àª\95િત àª¨ àª¹à«\8bય àª¤à«\8b àª¸àª­à«\8dય àª¤à«\87 àª¸àª®à«\82હમાàª\82 àª¶àª¾àª®àª¿àª² àª¨àª¥à«\80.\n* àª\8fàª\95  *દરà«\8dશાવà«\87 àª\9bà«\87 àª¤àª®à«\87 àª\89મà«\87રà«\8dયા àªªàª\9bà«\80 àª¸àª®à«\82હ àª¹àª\9fાવà«\80 àª¨ àª¶àª\95à«\8b àª\85થવા àª¤à«\87થà«\80 àª\89લàª\9fà«\81àª\82.",
+       "userrights-groups-help": "àª\86 àª¸àª­à«\8dય àª\9cà«\87 àª\9cà«\82થà«\8bનà«\8b àª¸àª­à«\8dય àª\9bà«\87 àª¤à«\87 àª¤àª®à«\87 àª¬àª¦àª²à«\80 àª¶àª\95à«\8b àª\9bà«\8b:\n* àª\85àª\82àª\95િત àª\95રà«\87લà«\81àª\82 àª\96ાનà«\81àª\82 àª¦àª°à«\8dશાવà«\87 àª\9bà«\87 àª\95à«\87 àª¸àª­à«\8dય àª¤à«\87 àª\9cà«\82થમાàª\82 àª\9bà«\87.\n* àª\9cà«\8b àª\96ાનà«\81àª\82 àª\85àª\82àª\95િત àª¨ àª¹à«\8bય àª¤à«\8b àª¤à«\87નà«\8b àª\85રà«\8dથ àª\8fમ àª\9bà«\87 àª\95à«\87 àª¸àª­à«\8dય àª¤à«\87 àª\9cà«\82થમાàª\82 àª¨àª¥à«\80.\n* àª«à«\81દડà«\80 (*) àª¦àª°à«\8dશાવà«\87 àª\9bà«\87 àª\95à«\87 àª¤àª®à«\87 àª\8fàª\95 àªµàª\96ત àª\89મà«\87રà«\8dયા àªªàª\9bà«\80 àª¤à«\87 àª\9cà«\82થ àª¹àª\9fાવà«\80 àª¨àª¹à«\80 àª¶àª\95à«\8b àª\85થવા àª¹àª\9fાવà«\8dયા àªªàª\9bà«\80 àª\89મà«\87રà«\80 àª¨àª¹à«\80 àª¶àª\95à«\8b.",
        "userrights-reason": "કારણ:",
        "userrights-no-interwiki": "અન્ય વિકિ પર અન્ય સભ્યો ના અધિકારો માં પરિવર્તન કરવાની તમને પરવાનગી નથી",
        "userrights-nodatabase": "માહિતીસંચ $1 અસ્તિત્વમાં નથી કે તે સ્થાનીય નથી.",
        "userrights-unchangeable-col": "તમે બદલી ન શકો તેવા જૂથ",
        "group": "સમુહ",
        "group-user": "સભ્ય",
-       "group-autoconfirmed": "સà«\8dવયàª\82àª\9aલિત àª®àª¾àª¨à«\8dય àª¸àª­à«\8dયà«\8b",
+       "group-autoconfirmed": "સà«\8dવàª\9aાલિત àª®àª\82àª\9cà«\82ર àª¸àª­à«\8dય",
        "group-bot": "બૉટો",
        "group-sysop": "સાઇસૉપ/પ્રબંધકો",
        "group-bureaucrat": "રાજનૈતિકો",
-       "group-suppress": "દà«\81રà«\8dલàª\95à«\8dષ",
+       "group-suppress": "નાબà«\82દàª\95રà«\8dતા",
        "group-all": "(બધા)",
        "group-user-member": "{{GENDER:$1|સભ્ય}}",
        "group-autoconfirmed-member": "{{GENDER:$1|સ્વચાલિત મંજૂર સભ્ય}}",
        "group-bot-member": "{{GENDER:$1|બૉટ}}",
        "group-sysop-member": "{{GENDER:$1|પ્રબંધક}}",
        "group-bureaucrat-member": "{{GENDER:$1|રાજનૈતિક}}",
-       "group-suppress-member": "{{GENDER:$1|દà«\81રà«\8dલàª\95à«\8dષ}}",
+       "group-suppress-member": "{{GENDER:$1|નાબà«\82દàª\95રà«\8dતા}}",
        "grouppage-user": "{{ns:project}}:સભ્યો",
-       "grouppage-autoconfirmed": "{{ns:project}}:સà«\8dવયàª\82àª\9aલિત àª®àª¾àª¨à«\8dય સભ્યો",
+       "grouppage-autoconfirmed": "{{ns:project}}:સà«\8dવàª\9aાલિત àª®àª\82àª\9cà«\82ર સભ્યો",
        "grouppage-bot": "{{ns:project}}:બૉટો",
        "grouppage-sysop": "{{ns:project}}:પ્રબંધકો",
        "grouppage-bureaucrat": "{{ns:project}}: રાજનૈતિક",
-       "grouppage-suppress": "{{ns:project}}:દà«\81રà«\8dલàª\95à«\8dષ",
+       "grouppage-suppress": "{{ns:project}}:નાબà«\82દ",
        "right-read": " પાના વાંચો",
        "right-edit": "પાના બદલો",
        "right-createpage": "પાના બનાવો ( જે ચર્ચા પાના ન હોય)",
        "nopagetext": "તમે લખેલ પાનું અસ્તિત્વમાં નથી",
        "pager-newer-n": "{{PLURAL:$1|નવું 1|નવા $1}}",
        "pager-older-n": "{{PLURAL:$1|જૂનું 1|જૂનાં $1}}",
-       "suppress": "દà«\81રà«\8dલàª\95à«\8dષ",
+       "suppress": "નાબà«\82દ",
        "querypage-disabled": "કાર્યક્ષમતાના કારણે આ ખાસ પાનું નિષ્ક્રિ કરાયું છે.",
        "apihelp": "API મદદ",
        "apihelp-no-such-module": "સાધન જૂથ \"$1\" ન મળ્યું.",
        "wlheader-showupdated": "તમારી છેલ્લી મુલાકાત પછી બદલાયેલાં પાના  '''ઘાટા''' અક્ષરો વડે દર્શાવ્યાં છે.",
        "wlnote": "નીચે $3, $4 વાગ્યા સુધીના છેલ્લા {{PLURAL:$2|એક કલાક|'''$2''' કલાક}}માં થયેલા {{PLURAL:$1|ફેરફાર|'''$1''' ફેરફારો }} દર્શાવ્યા છે.",
        "wlshowlast": "છેલ્લા $1 કલાકો $2 દિવસો બતાવો",
+       "watchlistall2": "બધા",
        "watchlist-options": "ધ્યાનસૂચિના વિકલ્પો",
        "watching": "નજર રાખી રહ્યાં છો...",
        "unwatching": "નજર રાખવાની બંધ કરી છે...",
        "movenosubpage": "આ પાનાના કોઈ ઉપ-પાના નથી",
        "movereason": "કારણ:",
        "revertmove": "પૂર્વવત",
-       "delete_and_move": "હટાવો અને નામ બદલો",
        "delete_and_move_text": "== પાનું દૂર કરવાની જરૂર છે  ==\nલક્ષ્ય પાનું  \"[[:$1]]\" પહેલેથી અસ્તિત્વમાં છે.\nશું તમે આને હટાવીને સ્થળાંતર કરવાનો માર્ગ મોકળો કરવા માંગો છો?",
        "delete_and_move_confirm": "હા, આ પાનું હટાવો",
        "delete_and_move_reason": "હટાવવાનું કામ આગળ વધાવવા ભૂંસી દેવાયુ \"[[$1]]\"",
index a69a693..1519aee 100644 (file)
@@ -66,6 +66,7 @@
        "tog-watchlisthidebots": "הסתרת עריכות של בוטים ברשימת המעקב",
        "tog-watchlisthideminor": "הסתרת עריכות משניות ברשימת המעקב",
        "tog-watchlisthideliu": "הסתרת עריכות של משתמשים רשומים ברשימת המעקב",
+       "tog-watchlistreloadautomatically": "רענון אוטומטי של רשימת המעקב בכל פעם שמסנן משתנה (נדרש JavaScript)",
        "tog-watchlisthideanons": "הסתרת עריכות של משתמשים אנונימיים ברשימת המעקב",
        "tog-watchlisthidepatrolled": "הסתרת עריכות בדוקות ברשימת המעקב",
        "tog-watchlisthidecategorization": "הסתרת הוספות והסרות של דפים מקטגוריות",
        "morenotlisted": "רשימה זו אינה מלאה.",
        "mypage": "דף משתמש",
        "mytalk": "שיחה",
-       "anontalk": "×\93×£ ×\94ש×\99×\97×\94 ×¢×\91×\95ר ×\9bת×\95×\91ת IP ×\96×\95",
+       "anontalk": "ש×\99×\97×\94",
        "navigation": "ניווט",
        "and": "&#32;וגם",
        "qbfind": "חיפוש",
        "databaseerror-query": "שאילתה: $1",
        "databaseerror-function": "פונקציה: $1",
        "databaseerror-error": "שגיאה: $1",
+       "transaction-duration-limit-exceeded": "כדי למנוע עיכובי העתקה גדולים, פעולה זו הופסקה כיוון שמשך הכתיבה ($1) עבר את המגבלה של $2 שניות.\nאם הפעולה דורשת שינוי של פריטים רבים בו־זמנית, ניתן לנסות לבצע מספר פעולות קטנות יותר.",
        "laggedslavemode": "'''אזהרה:''' הדף עשוי שלא להכיל עדכונים אחרונים.",
        "readonly": "בסיס הנתונים נעול",
        "enterlockreason": "יש להקליד סיבה לנעילה, כולל הערכה למועד שחרור הנעילה",
        "wrongpasswordempty": "הסיסמה שהקלדתם ריקה.\nאנא נסו שוב.",
        "passwordtooshort": "סיסמאות חייבות להיות באורך {{PLURAL:$1|תו אחד|$1 תווים}} לפחות.",
        "passwordtoolong": "סיסמאות אינן יכולות להיות ארוכות {{PLURAL:$1|מתו אחד|מ־$1 תווים}}.",
+       "passwordtoopopular": "לא ניתן להשתמש בסיסמאות נפוצות. יש לבחור סיסמה ייחודית יותר.",
        "password-name-match": "סיסמתך חייבת להיות שונה משם המשתמש שלך.",
        "password-login-forbidden": "השימוש בשם המשתמש והסיסמה האלה נאסר.",
        "mailmypassword": "איפוס סיסמה",
        "passwordreset-emailtext-ip": "מישהו (ככל הנראה אתם, מכתובת ה־IP מספר $1) ביקש איפוס של\nהסיסמה שלכם ב{{grammar:תחילית|{{SITENAME}}}} ($4). {{PLURAL:$3|חשבון המשתמש הבא שייך|חשבונות המשתמש הבאים שייכים}}\nלכתובת הדואר האלקטרוני הזאת:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו תפקע|סיסמאות זמניות אלה יפקעו}} תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
        "passwordreset-emailtext-user": "{{GENDER:$1|המשתמש|המשתמשת}} $1 ב{{GRAMMAR:תחילית|{{SITENAME}}}} {{GENDER:$1|ביקש|ביקשה}} איפוס של הסיסמה שלכם ב{{GRAMMAR:תחילית|{{SITENAME}}}}\n($4). {{PLURAL:$3|חשבון המשתמש הבא שייך|חשבונות המשתמש הבאים שייכים}} לכתובת הדואר האלקטרוני הזאת:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו תפקע|סיסמאות זמניות אלה יפקעו}} תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
        "passwordreset-emailelement": "שם משתמש:\n$1\n\nסיסמה זמנית:\n$2",
-       "passwordreset-emailsent": "אם זוהי כתובת דואר אלקטרוני רשומה עבור החשבון שלך, אז יישלח דואר אלקטרוני לאיפוס הסיסמה.",
+       "passwordreset-emailsentemail": "אם זוהי כתובת דואר אלקטרוני רשומה עבור החשבון שלך, אז יישלח דואר אלקטרוני לאיפוס הסיסמה.",
+       "passwordreset-emailsentusername": "אם רשומה כתובת דואר אלקטרוני מתאימה, אז יישלח דואר אלקטרוני לאיפוס הסיסמה.",
        "passwordreset-emailsent-capture": "נשלח דואר אלקטרוני לאיפוס הסיסמה, והוא מוצג להלן.",
        "passwordreset-emailerror-capture": "נוצר דואר אלקטרוני לאיפוס הסיסמה, והוא מוצג להלן, אך שליחתו ל{{GENDER:$2|משתמש|משתמשת}} נכשלה: $1",
        "changeemail": "שינוי או הסרת כתובת דוא\"ל",
        "recentchanges-legend-heading": "'''מקרא:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ראו גם [[Special:NewPages|רשימת דפים חדשים]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "הצגה",
        "rcnotefrom": "להלן {{PLURAL:$5|השינוי שבוצע|השינויים שבוצעו}} החל מ‏‏֫־<b>$2</b> (עד <b>$1</b> מוצגים).",
        "rclistfrom": "הצגת שינויים חדשים החל מ־$2, $3",
        "rcshowhideminor": "$1 שינויים משניים",
        "mostrevisions": "הדפים עם מספר העריכות הגבוה ביותר",
        "prefixindex": "רשימת הדפים המתחילים ב…",
        "prefixindex-namespace": "רשימת הדפים המתחילים ב… (במרחב השם $1)",
+       "prefixindex-submit": "הצגה",
        "prefixindex-strip": "הסתרת התחילית ברשימה",
        "shortpages": "דפים קצרים",
        "longpages": "דפים ארוכים",
        "protectedpages-performer": "הוגן על־ידי",
        "protectedpages-params": "פרמטרים להגנה",
        "protectedpages-reason": "סיבה",
+       "protectedpages-submit": "הצגת דפים",
        "protectedpages-unknown-timestamp": "לא ידוע",
        "protectedpages-unknown-performer": "משתמש לא ידוע",
        "protectedtitles": "כותרות מוגנות",
        "protectedtitles-summary": "בדף זה רשומות הכותרות שמוגנות כעת מפני יצירה. לרשימת הדפים הקיימים שמוגנים, ראו [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "אין כרגע כותרות מוגנות עם הפרמטרים האלה.",
+       "protectedtitles-submit": "הצגת כותרות",
        "listusers": "רשימת משתמשים",
        "listusers-editsonly": "הצגת משתמשים עם עריכות בלבד",
        "listusers-creationsort": "מיון לפי תאריך היצירה",
        "activeusers-hidebots": "הסתרת בוטים",
        "activeusers-hidesysops": "הסתרת מפעילי מערכת",
        "activeusers-noresult": "לא נמצאו משתמשים.",
+       "activeusers-submit": "הצגת משתמשים פעילים",
        "listgrouprights": "רשימת הרשאות לקבוצה",
        "listgrouprights-summary": "זוהי רשימה של קבוצות המשתמש המוגדרות באתר זה, עם ההרשאות של כל אחת.\nמידע נוסף על ההרשאות ניתן למצוא [[{{MediaWiki:Listgrouprights-helppage}}|כאן]].",
        "listgrouprights-key": "מקרא:\n* <span class=\"listgrouprights-granted\">הרשאה שהוענקה</span>\n* <span class=\"listgrouprights-revoked\">הרשאה שהוסרה</span>",
        "wlshowlast": "הצגת $1 שעות אחרונות $2 ימים אחרונים",
        "watchlistall2": "הכול",
        "watchlist-hide": "הסתרה",
-       "wlshowtime": "להציג מאז:",
+       "watchlist-submit": "הצגה",
+       "wlshowtime": "תקופת זמן לצפייה:",
        "wlshowhideminor": "עריכות משניות",
        "wlshowhidebots": "בוטים",
        "wlshowhideliu": "משתמשים רשומים",
        "contributions": "תרומות {{GENDER:$1|המשתמש|המשתמשת}}",
        "contributions-title": "תרומות של ה{{GENDER:$1|משתמש|משתמשת}} $1",
        "mycontris": "תרומות",
+       "anoncontribs": "תרומות",
        "contribsub2": "עבור {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "החשבון \"$1\" אינו רשום.",
        "nocontribs": "לא נמצאו שינויים המתאימים לקריטריונים אלו.",
        "whatlinkshere-hidelinks": "$1 קישורים",
        "whatlinkshere-hideimages": "$1 קישורים לקובץ",
        "whatlinkshere-filters": "מסננים",
+       "whatlinkshere-submit": "הצגה",
        "autoblockid": "חסימה אוטומטית #$1",
        "block": "חסימת משתמש",
        "unblock": "שחרור משתמש",
        "movenosubpage": "לדף זה אין דפי משנה.",
        "movereason": "סיבה:",
        "revertmove": "החזרה",
-       "delete_and_move": "מחיקה והעברה",
        "delete_and_move_text": "== בקשת מחיקה ==\nדף היעד, \"[[:$1]]\", כבר קיים.\nהאם ברצונך למחוק אותו כדי לאפשר את ההעברה?",
        "delete_and_move_confirm": "אישור מחיקת הדף",
        "delete_and_move_reason": "מחיקה כדי לאפשר העברה מהשם \"[[$1]]\"",
        "tooltip-pt-preferences": "ההעדפות שלך",
        "tooltip-pt-watchlist": "רשימת הדפים שאתם עוקבים אחרי השינויים בהם",
        "tooltip-pt-mycontris": "רשימת התרומות שלך",
+       "tooltip-pt-anoncontribs": "רשימת העריכות שנעשו מכתובת ה־IP הזאת",
        "tooltip-pt-login": "מומלץ להירשם, אך אין חובה לעשות כן",
        "tooltip-pt-logout": "יציאה מהחשבון",
        "tooltip-pt-createaccount": "מומלץ ליצור חשבון ולהיכנס אליו; עם זאת, זו אינה חובה",
        "exif-compression-32946": "Deflate (של PKZIP)",
        "exif-copyrighted-true": "מוגן בזכויות יוצרים",
        "exif-copyrighted-false": "מצב זכויות היוצרים לא הוגדר",
+       "exif-photometricinterpretation-0": "שחור־לבן (לבן זה 0)",
+       "exif-photometricinterpretation-1": "שחור־לבן (שחור זה 0)",
+       "exif-photometricinterpretation-3": "לוח צבעים",
+       "exif-photometricinterpretation-4": "מסכת שקיפות",
+       "exif-photometricinterpretation-5": "מופרד (כנראה CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*‎",
+       "exif-photometricinterpretation-9": "CIE L*a*b*‎ (קידוד ICC)",
+       "exif-photometricinterpretation-10": "CIE L*a*b*‎ (קידוד ITU)",
+       "exif-photometricinterpretation-32803": "מערך סינון צבע",
+       "exif-photometricinterpretation-34892": "גולמי קווי",
        "exif-unknowndate": "תאריך בלתי ידוע",
        "exif-orientation-1": "רגילה",
        "exif-orientation-2": "הפוך אופקית",
index 51d6fa1..319a29f 100644 (file)
        "movenosubpage": "Ii panna me koi subpages nai hai.",
        "movereason": "Kaaran:",
        "revertmove": "purana copy pe lae jao",
-       "delete_and_move": "Mitao aur hatao",
        "delete_and_move_text": "== Mitae ke jaruri hai ==\nDestination panna \"[[:$1]]\" abhi hai.\nKa aap mangta hai ki iske mitae dewa jaae, jisse ki ii naam se duusra paana ke save karaa jaae sake?",
        "delete_and_move_confirm": "Haan, panna ke mitao",
        "delete_and_move_reason": "\"[[$1]]\" se move kare ke khatir isk mitaya",
index 2a2f2f7..6bd7777 100644 (file)
        "morenotlisted": "Ovaj popis nije potpun.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
-       "anontalk": "Razgovor za ovu IP adresu",
+       "anontalk": "Razgovor",
        "navigation": "Orijentacija",
        "and": "&#32;i",
        "qbfind": "Nađi",
        "passwordreset-emailtext-ip": "Netko (vjerojatno Vi, s IP adrese $1) zatražio je podsjetnik za Vaše detalje računa\nza {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}}\npovezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste sjeti Vaše izvorne lozinke, a vi je više ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru lozinku.",
        "passwordreset-emailtext-user": "Suradnik $1 na {{SITENAME}} zatražio podsjetnik o pojedinostima vašeg računa za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste sjeti Vaše izvorne lozinke, a vi je više ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru lozinku.",
        "passwordreset-emailelement": "Suradničko ime: \n$1\n\nPrivremena lozinka: \n$2",
-       "passwordreset-emailsent": "E-mail podsjetnik zaporke je poslan.",
+       "passwordreset-emailsentemail": "E-mail podsjetnik zaporke je poslan.",
        "passwordreset-emailsent-capture": "Poslan Vam je podsjetnik kao e-pošta (tekst je prikazan dolje).",
        "passwordreset-emailerror-capture": "Napravljena je e-poruka za ponovno postavljanje zaporke (prikazana ispod), ali njeno slanje suradniku nije uspjelo: $1",
        "changeemail": "Promijeni e-mail adresu",
        "showingresultsinrange": "Dolje {{PLURAL:$1|je prikazan '''$1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}}, u rasponu od '''$2''' do '''$3'''.",
        "search-showingresults": "{{PLURAL:$4|Rezultat <strong>$1</strong> od <strong>$3</strong>|Rezultati <strong>$1 - $2</strong> od <strong>$3</strong>}}",
        "search-nonefound": "Ne postoje rezultati koji se podudaraju s upitom.",
+       "search-nonefound-thiswiki": "Nema rezultata na ovim stranicama koji se podudaraju s upitom.",
        "powersearch-legend": "Napredno pretraživanje",
        "powersearch-ns": "Traži u imenskom prostoru:",
        "powersearch-togglelabel": "Uključi:",
        "mostrevisions": "Popis članaka po broju uređivanja",
        "prefixindex": "Sve stranice prema početku naslova",
        "prefixindex-namespace": "Sve stranice s predmetkom (imenski prostor $1)",
+       "prefixindex-strip": "Ne prikazuj predmetak u popisu",
        "shortpages": "Kratke stranice",
        "longpages": "Duge stranice",
        "deadendpages": "Slijepe ulice",
        "wlnote": "Ovdje {{PLURAL:$1|je posljednja $1 promjena|su posljednje $1 promjene|je posljednjih $1 promjena}} u {{PLURAL:$2|posljednjem <strong>$2</strong> satu|posljednja '''$2''' sata|posljednjih <strong>$2</strong> sati}}, od $3, $4.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
        "watchlistall2": "sve",
+       "watchlist-hide": "Sakrij",
+       "wlshowtime": "Prikaži posljednjih:",
+       "wlshowhideminor": "manje promjene",
+       "wlshowhidebots": "botove",
+       "wlshowhideliu": "prijavljene suradnike",
+       "wlshowhideanons": "neprijavljene suradnike",
+       "wlshowhidepatr": "ophođena uređivanja",
+       "wlshowhidemine": "moje promjene",
        "watchlist-options": "Izbornik popisa praćenja",
        "watching": "Pratim...",
        "unwatching": "Prestajem pratiti...",
        "contributions": "Doprinosi {{GENDER:$1|suradnika|suradnice}}",
        "contributions-title": "Suradnički doprinosi za $1",
        "mycontris": "Doprinosi",
+       "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Suradnički račun \"$1\" nije registriran.",
        "nocontribs": "Nema promjena koje udovoljavaju ovim kriterijima.",
        "movenosubpage": "Ova stranica nema podstranica.",
        "movereason": "Razlog:",
        "revertmove": "vrati",
-       "delete_and_move": "Izbriši i premjesti",
        "delete_and_move_text": "==Nužno brisanje==\n\nOdredišni članak \"[[:$1]]\" već postoji. Želite li ga obrisati da biste napravili mjesto za premještaj?",
        "delete_and_move_confirm": "Da, izbriši stranicu",
        "delete_and_move_reason": "obrisano kako bi se napravilo mjesto za premještaj, stari naziv \"[[$1]]\"",
index ef6cdfa..0c35967 100644 (file)
        "shown-title": "$1 {{PLURAL:$1|wuslědk|wuslědkaj|wuslědki|wuslědkow}} na stronu pokazać",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) pokazać",
        "searchmenu-exists": "'''Je strona z mjenom \"[[$1]]\" na tutym wikiju'''",
-       "searchmenu-new": "<strong>Wutwor stronu \"[[:$1]]\" na tutym wikiju!</strong> {{PLURAL:$2|0=|Hlej tež stronu namakanu z twojim pytanjom.|Hlej tež namakane pytanske wuslědki.}}",
+       "searchmenu-new": "<strong>Wutwor stronu \"[[:$1]]\" na tutym wikiju!</strong> {{PLURAL:$2|0=|Hlej tež stronu namakanu z twojim pytanjom.|Dźiwaj tež na namakane pytanske wuslědki.}}",
        "searchprofile-articles": "Wobsahowe strony",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything": "Wšitko",
        "movenosubpage": "Tuta strona podstrony nima.",
        "movereason": "Přičina:",
        "revertmove": "wróćo přesunyć",
-       "delete_and_move": "wušmórnyć a přesunyć",
        "delete_and_move_text": "== Wušmórnjenje trěbne ==\n\nCilowa strona „[[:$1]]” hižo eksistuje. Chceš ju wušmórnyć, zo by so přesunjenje zmóžniło?",
        "delete_and_move_confirm": "Haj, stronu wušmórnyć.",
        "delete_and_move_reason": "Wušmórnjena, zo by so rum za přesunjenje z \"[[$1]]\" wutworił.",
index f902c75..af537da 100644 (file)
        "passwordreset-emailtext-ip": "Valaki (vélhetően Te, a $1 IP-címről) a jelszavad visszaállítását kérte a {{SITENAME}} ($4) oldalon felvett {{PLURAL:$3|fiókban|fiókokban}}. A következő felhasználói {{PLURAL:$3|fiók van|fiókok vannak}} hozzárendelve ehhez az e-mail címhez:\n\n$2\n\n{{PLURAL:$3|Ez az ideiglenes jelszó|Ezek az ideiglenes jelszavak}} $5 nap múlva {{PLURAL:$3|jár|járnak}} le. Jelentkezz be, és cseréld le a jelszavadat. Ha valaki más kérte az emlékeztetőt, vagy eszedbe jutott a régi jelszó, és nem akarod lecserélni a jelszavadat, hagyd figyelmen kívül ezt az üzenetet, és használd a régi jelszavadat.",
        "passwordreset-emailtext-user": "$1 felhasználó jelszó-visszaállítást kért a {{SITENAME}} ($4) oldalon felvett {{PLURAL:$3|fiókban|fiókokban}}. A következő felhasználói {{PLURAL:$3|fiók van|fiókok vannak}} hozzárendelve ehhez az e-mail címhez:\n\n$2\n\n{{PLURAL:$3|Ez az ideiglenes jelszó|Ezek az ideiglenes jelszavak}} $5 nap múlva {{PLURAL:$3|jár|járnak}} le. Jelentkezz be, és cseréld le a jelszavadat. Ha valaki más kérte az emlékeztetőt, vagy eszedbe jutott a régi jelszó, és nem akarod lecserélni a jelszavadat, hagyd figyelmen kívül ezt az üzenetet, és használd a régi jelszavadat.",
        "passwordreset-emailelement": "Felhasználónév: \n$1\n\nIdeiglenes jelszó: \n$2",
-       "passwordreset-emailsent": "Ha ez egy regisztrált e-mail cím a fiókodhoz, egy jelszó-visszaállító e-mailt küldünk.",
+       "passwordreset-emailsentemail": "Ha ez egy regisztrált e-mail-cím a fiókodhoz, egy jelszó-visszaállító e-mailt küldünk.",
        "passwordreset-emailsent-capture": "Az alább látható jelszó-visszaállító e-mail lett elküldve.",
        "passwordreset-emailerror-capture": "A jelszó-visszaállító e-mail generálása megtörtént, mint az alább látszik, de elküldése a {{GENDER:$2|szerkesztőnek}} nem sikerült: $1",
        "changeemail": "E-mail cím megváltoztatása vagy eltávolítása",
        "contributions": "{{GENDER:$1|Szerkesztő}} közreműködései",
        "contributions-title": "$1 közreműködései",
        "mycontris": "Közreműködések",
+       "anoncontribs": "Közreműködések",
        "contribsub2": "$1 ($2)",
        "contributions-userdoesnotexist": "Nincs regisztrálva „$1” szerkesztői azonosító.",
        "nocontribs": "Nem található a feltételeknek megfelelő változtatás.",
        "movenosubpage": "Ez a lap nem rendelkezik allapokkal.",
        "movereason": "Indoklás:",
        "revertmove": "visszaállítás",
-       "delete_and_move": "Törlés és átnevezés",
        "delete_and_move_text": "== Törlés szükséges ==\n\nAz átnevezés céljaként megadott „[[:$1]]” szócikk már létezik.  Ha az átnevezést végre akarod hajtani, ezt a lapot törölni kell.  Valóban ezt szeretnéd?",
        "delete_and_move_confirm": "Igen, töröld a lapot",
        "delete_and_move_reason": "átnevezendő lap célneve felszabadítva „[[$1]]” számára",
        "tooltip-pt-preferences": "A beállításaid",
        "tooltip-pt-watchlist": "Az általad figyelemmel kísért oldalak utolsó változtatásai",
        "tooltip-pt-mycontris": "A közreműködéseid listája",
+       "tooltip-pt-anoncontribs": "Erről az IP-címről végrehajtott szerkesztések listája",
        "tooltip-pt-login": "Bejelentkezni javasolt, de nem kötelező.",
        "tooltip-pt-logout": "Kijelentkezés",
        "tooltip-pt-createaccount": "Arra bíztatunk, hogy hozz létre egy fiókot, és jelentkezz be, azonban ez nem kötelező",
index 9862dfe..b741e06 100644 (file)
        "passwordreset-email": "Էլ-փոստի հասցեն՝",
        "passwordreset-emailtitle": "{{SITENAME}} հաշվի մանրամասները",
        "passwordreset-emailelement": "Մասնակցային անունը՝ \n$1\n\nԺամանակավոր գաղտնաբառը՝ \n$2",
-       "passwordreset-emailsent": "Ուղարկվեց հիշեցնող էլ․ նամակ։",
+       "passwordreset-emailsentemail": "Ուղարկվեց հիշեցնող էլ․ նամակ։",
        "passwordreset-emailsent-capture": "Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։",
        "passwordreset-emailerror-capture": "Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։ Սակայն մասնակցին ուղարկելը չհաջողվեց․",
        "changeemail": "Փոխել էլ. հասցեն",
        "recentchanges-label-plusminus": "Էջի չափսը փոփոխվեց այսքան բայթով",
        "recentchanges-legend-heading": "'''Լեգենդ՝'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (տես նաև՝  [[Special:NewPages|նոր էջերի ցանկ]])",
+       "recentchanges-submit": "Ցույց տալ",
        "rcnotefrom": "Ստորև բերված են փոփոխությունները սկսած՝ '''$2''' (մինչև՝ '''$1''')։",
        "rclistfrom": "Ցույց տալ նոր փոփոխությունները սկսած $3 $2",
        "rcshowhideminor": "$1 չնչին խմբագրումները",
        "mostinterwikis": "Ամենաշատ միջլեզվային հղումներով էջեր",
        "mostrevisions": "Ամենաշատ վերափոխումներով հոդվածներ",
        "prefixindex": "Բոլոր էջերը ըստ սկզբնատառի",
+       "prefixindex-submit": "Ցույց տալ",
        "shortpages": "Կարճ էջեր",
        "longpages": "Երկար էջեր",
        "deadendpages": "Հղումներ չպարունակող էջեր",
        "deadendpagestext": "Հետևյալ էջերը չունեն հղումներ վիքիի այլ էջերին։",
        "protectedpages": "Պաշտպանված էջեր",
        "protectedpagesempty": "Ներկայումս չկան պաշտպանված էջեր նշված պարամետրերով։",
+       "protectedpages-submit": "Ցույց տալ էջերը",
        "protectedtitles": "Պաշտպանված անվանումներ",
+       "protectedtitles-submit": "Ցույց տալ վերնագրերը",
        "listusers": "Մասնակիցների ցանկ",
        "usereditcount": " \n$1 {{PLURAL:$1|խմբագրում|խմբագրումներ}}",
        "usercreated": "{{GENDER:$3|Ստեղծվել է}} $1-ին, ժամը $2-ին",
        "listusers-blocked": "(արգելափակված)",
        "activeusers": "Ակտիվ մասնակիցների ցանկ",
        "activeusers-noresult": "Այդպիսի մասնակիցներ չեն գտնվել։",
+       "activeusers-submit": "Ցույց տալ ակտիվ մասնակիցներին",
        "listgrouprights-members": "(անդամների ցանկ)",
        "listgrouprights-addgroup": "Ավելացնեել {{PLURAL:$2|խումբ|խմբեր}}՝  $1",
        "mailnologin": "Ուղարկման հասցե չկա",
        "wlnote": "Ստորև բերված {{PLURAL:$1|է վերջին փոփոխությունը|են վերջին '''$1''' փոփոխությունները}} վերջին <strong>$2</strong> ժամվա ընթացքում։",
        "wlshowlast": "Ցուցադրել վերջին $1 ժամերը $2 օրերը",
        "watchlistall2": "բոլոր",
+       "watchlist-submit": "Ցույց տալ",
        "watchlist-options": "Հսկացանկի նախընտրություններ",
        "watching": "Հսկվում է...",
        "unwatching": "Հանվում է հսկումից...",
        "whatlinkshere-hidelinks": "$1 հղում",
        "whatlinkshere-hideimages": "$1 նիշքային հղումներ",
        "whatlinkshere-filters": "Զտիչներ",
+       "whatlinkshere-submit": "Գնալ առաջ",
        "autoblockid": "Ավտոմատ արգելափակում #$1",
        "block": "Արգելափակել մասնակցին",
        "unblock": "Արգելափակումից հանել",
        "movenosubpage": "Այս էջը ենթաէջեր չունի",
        "movereason": "Պատճառ.",
        "revertmove": "հետ շրջել",
-       "delete_and_move": "Ջնջել և տեղափոխել",
        "delete_and_move_text": "==Պահանջվում է ջնջում==\n\n«[[:$1]]» անվանմամբ էջ արդեն գոյություն ունի։ Ուզո՞ւմ եք այն ջնջել՝ տեղափոխումը իրականացնելու համար։",
        "delete_and_move_confirm": "Այո, ջնջել էջը",
        "delete_and_move_reason": "Ջնջված է՝ տեղափոխման տեղ ազատելու համար",
index 5be6bd8..bd16123 100644 (file)
@@ -49,6 +49,7 @@
        "tog-watchlisthidebots": "Celar le modificationes de robots in le observatorio",
        "tog-watchlisthideminor": "Celar modificationes minor in le observatorio",
        "tog-watchlisthideliu": "Celar modificationes de usatores registrate in le observatorio",
+       "tog-watchlistreloadautomatically": "Recargar automaticamente le observatorio quando un filtro es cambiate (JavaScript requirite)",
        "tog-watchlisthideanons": "Celar modificationes de usatores anonyme in le observatorio",
        "tog-watchlisthidepatrolled": "Celar le modificationes patruliate in le observatorio",
        "tog-watchlisthidecategorization": "Celar le categorisation de paginas",
        "morenotlisted": "Iste lista non es complete.",
        "mypage": "Pagina",
        "mytalk": "Discussion",
-       "anontalk": "Discussion pro iste adresse IP",
+       "anontalk": "Discussion",
        "navigation": "Navigation",
        "and": "&#32;e",
        "qbfind": "Cercar",
        "databaseerror-query": "Consulta: $1",
        "databaseerror-function": "Function: $1",
        "databaseerror-error": "Error: $1",
+       "transaction-duration-limit-exceeded": "A fin de evitar un grande retardo de replication, iste transaction ha essite abortate perque le duration de scriptura ($1) excedeva le limite de $2 secundas.\nSi tu modifica multe elementos insimul, tenta facer plure operationes minor in loco de un grande.",
        "laggedslavemode": "Attention: Es possibile que le pagina non contine actualisationes recente.",
        "readonly": "Base de datos blocate",
        "enterlockreason": "Describe le motivo del blocada, includente un estimation\nde quando illo essera terminate",
        "wrongpasswordempty": "Tu non entrava un contrasigno. Per favor reprova.",
        "passwordtooshort": "Le contrasignos debe continer al minus {{PLURAL:$1|1 character|$1 characteres}}.",
        "passwordtoolong": "Le contrasignos non pote esser plus longe de {{PLURAL:$1|1 character|$1 characteres}}.",
+       "passwordtoopopular": "Contrasignos habitual non pote esser usate. Per favor, elige un contrasigno plus unic.",
        "password-name-match": "Tu contrasigno debe esser differente de tu nomine de usator.",
        "password-login-forbidden": "Le uso de iste nomine de usator e contrasigno ha essite prohibite.",
        "mailmypassword": "Reinitialisar contrasigno",
        "passwordreset-emailtext-ip": "Un persona (probabilemente tu, ab le adresse IP $1) requestava le reinitialisation de tu\ncontrasigno de {{SITENAME}} ($4). Le {{PLURAL:$3|conto|contos}} de usator sequente es\nassociate con iste adresse de e-mail:\n\n$2\n\nIste {{PLURAL:$3|contrasigno|contrasignos}} temporari expirara post {{PLURAL:$5|un die|$5 dies}}.\nTu deberea ora aperir session e eliger un nove contrasigno. Si un altere persona faceva iste\nrequesta, o si tu te ha rememorate tu contrasigno original e non plus\nvole cambiar lo, tu pote ignorar iste message e continuar a usar le ancian\ncontrasigno.",
        "passwordreset-emailtext-user": "Le usator $1 in {{SITENAME}} requestava un reinitialisation de tu contrasigno in {{SITENAME}}\n($4). Le {{PLURAL:$3|conto|contos}} de usator sequente es associate con iste adresse de e-mail:\n\n$2\n\nIste {{PLURAL:$3|contrasigno|contrasignos}} temporari expirara post {{PLURAL:$5|un die|$5 dies}}.\nTu deberea ora aperir session e eliger un nove contrasigno. Si un altere persona faceva iste\nrequesta, o si tu te ha rememorate tu contrasigno original e non plus\nvole cambiar lo, tu pote ignorar iste message e continuar a usar le ancian\ncontrasigno.",
        "passwordreset-emailelement": "Nomine de usator: \n$1\n\nContrasigno temporari: \n$2",
-       "passwordreset-emailsent": "Si iste es le adresse de e-mail registrate pro tu conto, alora un message de e-mail pro le reinitialisation del contrasigno essera inviate.",
+       "passwordreset-emailsentemail": "Si iste es le adresse de e-mail registrate pro tu conto, alora un message de e-mail pro le reinitialisation del contrasigno essera inviate.",
        "passwordreset-emailsent-capture": "Un message de e-mail pro le reinitialisation del contrasigno ha essite inviate; iste message es monstrate hic infra.",
        "passwordreset-emailerror-capture": "Un e-mail pro le reinitialisation del contrasigno ha essite generate; iste message es monstrate hic infra, ma le invio al {{GENDER:$2|usator}} ha fallite: $1",
        "changeemail": "Cambiar o remover adresse de e-mail",
        "wlshowlast": "Monstrar le ultime $1 horas $2 dies",
        "watchlistall2": "toto",
        "watchlist-hide": "Celar",
-       "wlshowtime": "Monstrar le ultime:",
+       "wlshowtime": "Periodo de tempore a monstrar:",
        "wlshowhideminor": "modificationes minor",
        "wlshowhidebots": "robots",
        "wlshowhideliu": "usatores registrate",
        "contributions": "Contributiones del {{GENDER:$1|usator}}",
        "contributions-title": "Contributiones del usator $1",
        "mycontris": "Contributiones",
+       "anoncontribs": "Contributiones",
        "contribsub2": "Pro {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Le conto de usator \"$1\" non es registrate.",
        "nocontribs": "Necun modification ha essite trovate secundo iste criterios.",
        "movenosubpage": "Iste pagina non ha subpaginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
-       "delete_and_move": "Deler e renominar",
        "delete_and_move_text": "==Deletion requirite==\nLe pagina de destination \"[[:$1]]\" existe ja.\nEsque tu vole deler lo pro permitter le renomination?",
        "delete_and_move_confirm": "Si, deler le pagina",
        "delete_and_move_reason": "Delite pro permitter le renomination de \"[[$1]]\"",
        "tooltip-pt-preferences": "Mi preferentias",
        "tooltip-pt-watchlist": "Le lista de paginas del quales tu seque le modificationes",
        "tooltip-pt-mycontris": "Lista de tu contributiones",
+       "tooltip-pt-anoncontribs": "Un lista de modificationes facite per iste adresse IP",
        "tooltip-pt-login": "Nos recommenda que tu te authentica, ma non es obligatori.",
        "tooltip-pt-logout": "Clauder session",
        "tooltip-pt-createaccount": "Tu es incoragiate a crear un conto e aperir session; totevia, non es obligatori",
        "logentry-suppress-block": "$1 {{GENDER:$2|blocava}} {{GENDER:$4|$3}} con un tempore de expiration de $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|cambiava}} le configuration del blocada de {{GENDER:$4|$3}} con un tempore de expiration de $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importava}} $3 per incargamento de file",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|importava}} $3 per incargamento de file ($4 {{PLURAL:$4|version|versiones}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|importava}} $3 ab un altere wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|importava}} $3 ab $5 ($4 {{PLURAL:$4|version|versiones}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|fusionava}} $3 in $4 (versiones usque a $5)",
        "logentry-move-move": "$1 {{GENDER:$2|renominava}} le pagina $3 a $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|renominava}} le pagina $3 a $4 sin lassar un redirection",
index a147dc9..54d78c3 100644 (file)
        "morenotlisted": "Daytoy a listaan ket saan a kompleto.",
        "mypage": "Panid",
        "mytalk": "Tungtungan",
-       "anontalk": "Tungtungan para iti daytoy a pagtaengan ti IP",
+       "anontalk": "Tungtungan",
        "navigation": "Pagdaliasatan",
        "and": "&#32;ken",
        "qbfind": "Biruken",
        "viewsource": "Kitaen ti taudan",
        "viewsource-title": "Kitaen ti taudan para iti $1",
        "actionthrottled": "Napabuntog ti aramid",
-       "actionthrottledtext": "Para iti pagkontra ti spam, naipatinggaka nga agramid iti daytoy a tignay iti adu unay a beses iti nasiket nga oras, ken nalabsamon daytoy a patingga.\nPangngaasi nga ipadasmo manen no madamdama.",
+       "actionthrottledtext": "Kas pangkontra iti spam, naipatinggaka nga agaramid iti daytoy a tignay iti adu unay a beses iti nabiit a panawen, ken nalabsamon daytoy a patingga.\nPangngaasi nga ipadasmo manen intono madamdama.",
        "protectedpagetext": "Nasalakniban daytoy a panid tapno mapawilan ti panagurnos wenno dagiti dadduma pay a tignay.",
        "viewsourcetext": "Mabalinmo a kitaen ken tuladen ti taudan daytoy a panid.",
        "viewyourtext": "Mabalinmo a makita ken tuladen ti taudan dagiti <strong>inurnosmo</strong> iti daytoy panid.",
        "passwordreset-emailtext-ip": "Adda (baka sika, ti naggapuan ti IP a pagtaengan $1) a nagkiddaw ti maysa a panangisaad manen ti kontrasenias para iti {{SITNAME}} ($4) . {{PLURAL:$3|Ti |Dagiti}} sumaganad a pakabilangan ti agar-aramat ket\nmainaig iti daytoy nga esurat a pagtaengan:\n\n$2\n\n{{PLURAL:$3|Daytoy temporario a kontrasenias|Dagitoy temporario a kontrasenias}} ket agpaso {{PLURAL:$5|iti maysa nga aldaw|kadagiti $5 nga aldaw}}.\nSumrekka koman tapno agpilika ti baro a kontraseniasmo tattan. No adda met sabali a nagaramid daytoy a \npanagkiddaw, wenno malagipmo ti dati a kontraseniasmo, ket saanmo a kayaten a sukatan, saanmo nga ikaskaso daytoy a mensahe ken \nagtuloyka nga agusar ti daan a kontrasenias.",
        "passwordreset-emailtext-user": "Daytoy nga agar-aramat $1 iti {{SITENAME}} ket nagkiddaw ti maysa a panangisaad manen ti bukod a kontrasenias para iti {{SITENAME}}\n($4) . {{PLURAL:$3|Ti|Dagiti}} sumaganad a pakabilangan ti agar-aramat ket\nmainaig iti daytoy nga esurat a pagtaengan:\n\n$2\n\n{{PLURAL:$3|Daytoy temporario a kontrasenias|Dagitoy temporario a kontrasenias}} ket agpaso {{PLURAL:$5|iti maysa nga aldaw|kadagiti $5 nga aldaw}}.\nSumrekka koman tapno agpilika ti baro a kontraseniasmo tattan. No adda met sabali a nagaramid daytoy a \npanagkiddaw, wenno malagipmo ti dati a kontraseniasmo, ken saanmo a kayaten a sukatan, saanmo nga ikaskaso daytoy a mensahe ken \nagtuloykan nga agusar ti daan a kontraseniasmo.",
        "passwordreset-emailelement": "Nagan ti agar-aramat: \n$1\n\nTemporario a kontrasenias: \n$2",
-       "passwordreset-emailsent": "Ti maysa nga esurat ti panangisaad manen ti kontrasenias ket naipatuloden.",
+       "passwordreset-emailsent": "No daytoy ket nairehistro nga adres ti esurat para iti pakabilangam, maipatulodto ti maysa nga esurat iti panangisaad manen ti kontrasenias.",
        "passwordreset-emailsent-capture": "Ti maysa nga esurat ti panangisaad manen ti kontrasenias ket naipatuloden, a naipakita dita baba.",
        "passwordreset-emailerror-capture": "Naaramid ti maysa nga esurat a panangisaad manen ti kontrasenias, a napaikita dita baba, ngem ti panangitulod kenni {{GENDER:$2|agar-aramat}} ket napaay: $1",
-       "changeemail": "Sukatan ti esurat a pagtaengan",
-       "changeemail-header": "Sukatan ti esurat a pagtaengan ti pakabilangan",
+       "changeemail": "Sukatan wenno ikkaten ti adres ti esurat",
+       "changeemail-header": "Kompletuen daytoy a porma tapno masukatan ti adres ti esuratmo. No kayatmo a maikkat ti pannakainaig iti ania man nga adres ti esurat manipud iti pakabilangam, ibati a blanko ti baro nga adres ti esurat no ited ti porma.",
+       "changeemail-passwordrequired": "Masapulmonto nga ikabil ti kontraseniasmo tapno mapasingkedan daytoy a panagbaliw.",
        "changeemail-no-info": "Masapul a nakastrekka tapno dagus a makapan iti ditoy a panid.",
        "changeemail-oldemail": "Agdama nga esurat a pagtaengan:",
        "changeemail-newemail": "Baro nga esurat a pagtaengan:",
+       "changeemail-newemail-help": "Daytoy a pagikabilan ket nasken a blanko no kayatmo a maikkat ti adres ti esuratmo. Saanmonto a mabalin ti mangisaad manen ti nalipatan a kontrasenias ken saankanto a makaawat kadagiti esurat manipud iti daytoy a wiki no maikkat ti adres ti esurat.",
        "changeemail-none": "(awan)",
        "changeemail-password": "Ti bukodmo a kontrasenias ti {{SITENAME}}:",
        "changeemail-submit": "Sukatan ti esurat",
        "sig_tip": "Ti pirmam nga addaan iti oras ken petsa",
        "hr_tip": "Horisontal a linia (manmano laeng nga aramaten)",
        "summary": "Pakabuklan:",
-       "subject": "Suheto/paulo:",
+       "subject": "Suheto:",
        "minoredit": "Daytoy ket bassit a panagurnos",
        "watchthis": "Bantayan daytoy a panid",
        "savearticle": "Idulin ti panid",
        "missingsummary": "<strong>Palagip:</strong> Saanka a nakaited iti pakabuklan ti panagurnos.\nNo pindutem manen ti \"{{int:savearticle}}\", maidulin ti inurnosmo nga awan ti pakabuklanna.",
        "selfredirect": "<strong>Ballaag:</strong> Ibawbaw-ingmo daytoy a panid iti isu met laeng a panid.\nMabalinmo nga innaganan ti kamali a puntaan para iti baw-ing, wenno mabalin nga ur-urnosem ti kamali a panid.\nNo pindutem manen ti \"{{int:savearticle}}\" , mapartuatto lattan ti baw-ing.",
        "missingcommenttext": "Pangngaasi nga agikabil ti komentario dita baba.",
-       "missingcommentheader": "<strong>Palagip:</strong> Saanka a nakaited iti suheto/paulo para iti daytoy a komentario.\nNo pindutem manen ti \"{{int:savearticle}}\", maidulin ti inurnosmo nga awan ti pakabuklanna.",
+       "missingcommentheader": "<strong>Palagip:</strong> Saanka pay a nakaited iti suheto para iti daytoy a komentario.\nNo pindutem manen ti \"{{int:savearticle}}\", maidulinto ti inurnosmo nga awan ti pakabuklanna.",
        "summary-preview": "Naipadas a pakabuklan:",
-       "subject-preview": "Suheto/naipadas a paulo:",
+       "subject-preview": "Naipadas a suheto:",
        "previewerrortext": "Adda napasamak a maysa a biddut bayat a nagpadpadas kadagiti binawbaliwam.",
        "blockedtitle": "Naseraan ti agar-aramat",
        "blockedtext": "<strong>Naseraan ti naganmo nga agar-aramat wenno ti IP a pagtaengam.</strong>\n\nTi serra ket inaramid babaen ni $1. \nTi rason a naited ket <em>$2</em>.\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddeng a serraanna: $7\n\nMabalinmo a kontaken ni $1 wenno sabali pay nga [[{{MediaWiki:Grouppage-sysop}}|administrador]] no kayatmo a maipalawag daytoy a panagserra.\nDimo mabalin nga aramaten ti ramit nga esuratan daytoy nga agar-aramat malaksid no adda napudno nga esurat a pagtaengan a nainaganan iti [[Special:Preferences|pakabilangan ti kakaykayatm]] ken no saanka a naparitan nga agaramat iti daytoy.\nTi agdama nga IP a pagtaengam ket $3, ti naserraan nga ID ket #$5. \nPangngaasi nga iramanmo amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
        "permissionserrors": "Biddut ti pammalubos",
        "permissionserrorstext": "Awan ti pammalubosmo nga agaramid iti dayta, gapu ti sumaganad {{PLURAL:$1|a rason|a rasrason}}:",
        "permissionserrorstext-withaction": "Awan ti pammalubosmo nga $2, gapu ti sumaganad a {{PLURAL:$1|rason|rasrason}}:",
+       "contentmodelediterror": "Saanmo a maurnos daytoy a rebision gapu ta ti modelo ti linaon ket <code>$1</code>, ken ti agdama a linaon ti panid ket <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Ballaag: Agparpartuatka manen ti dati a naikkat a panid.</strong>\n\nUsigem koma no maitutop ti agtuloy nga agurnos iti daytoy a panid.\nTi listaan ti pannakaikkat ken pannakaiyalis para iti daytoy a panid ket naited ditoy para iti pakainugotan:",
        "moveddeleted-notice": "Naikkaten daytoy a panid.\nTi listaan ti pannakaikkat ken pannakaiyalis para iti panid ket naited dita baba para iti reperensia.",
        "moveddeleted-notice-recent": "Pasensian, daytoy a panid ket kaik-ikkat idi (iti kaunegan dagiti 24 nga oras).\nTi listaan ti pannakaikkat ken pannakaiyalis para iti panid ket naited dita baba para iti reperensia.",
        "mergehistory-go": "Ipakita dagiti mabalin a maitipon a panagurnos",
        "mergehistory-submit": "Pagtitiponen dagiti rebision",
        "mergehistory-empty": "Awan dagiti rebision ti mabalin nga itipon.",
-       "mergehistory-done": "$3 {{PLURAL:$3|a rebision|dagiti rebision}} iti $1 ket nagballigi a naitipon iti [[:$2]].",
+       "mergehistory-done": "$3 {{PLURAL:$3|a rebision|dagiti rebision}} iti $1 ket {{PLURAL:$3|naitipon|naitiponda}} iti [[:$2]].",
        "mergehistory-fail": "Saan a nakaaramid ti panagtipon ti pakasaritaan, pangngaasi a kitaen ti panid ken dagiti parametro ti oras.",
        "mergehistory-fail-toobig": "Di naaramid ti panagtipon ti pakasaritaan gapu ta ad-adu ti patingga ti $1 {{PLURAL:$1|a rebision|kadagiti rebision}} ti maiyalisto.",
        "mergehistory-no-source": "Awan ti taudan ti panid ti $1.",
        "showingresultsinrange": "Mangipakpakita aginggana {{PLURAL:$1|iti <strong>1</strong> a resulta|dagiti <strong>$1</strong> a resulta}} iti sakop ti #<strong>$2</strong> aginggana iti #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Nagbanagan a <strong>$1</strong> iti <strong>$3</strong>|Dagiti nagbanagan a <strong>$1 - $2</strong> iti <strong>$3</strong>}}",
        "search-nonefound": "Awan dagiti nagbanagan a maipada iti usisa.",
+       "search-nonefound-thiswiki": "Awan dagiti resulta a maipada iti panagusisa iti daytoy a sitio.",
        "powersearch-legend": "Napasayat a panagbiruk",
        "powersearch-ns": "Agbiruk kadagiti nagan ti espasio:",
        "powersearch-togglelabel": "Markaan:",
        "prefs-watchlist-token": "Tandaan ti listaan ti bambantayan:",
        "prefs-misc": "Sabsabali",
        "prefs-resetpass": "Sukatan ti kontrasenias",
-       "prefs-changeemail": "Sukatan ti esurat a pagtaengan",
+       "prefs-changeemail": "Sukatan wenno ikkaten ti adres ti esurat",
        "prefs-setemail": "Isaad ti esurat a pagtaengan",
        "prefs-email": "Dagiti pagpilian ti esurat",
        "prefs-rendering": "Tabas",
        "prefs-help-recentchangescount": "Daytoy ket mangiraman iti kaudian a balbaliw, dagiti pakasaritaan ti panid, ken dagiti listaan.",
        "prefs-help-watchlist-token2": "Daytoy ti sekreto a tulbek iti pakan ti web iti listaan ti bambantayam.\nTi sinoman a makaammo daytoy ket mabalinda a basaen ti listaan ti bambantayam, isu a saanmo nga ipabingay.\nNo masapulmo, [[Special:ResetTokens|mabalinmo nga isaad manen]].",
        "savedprefs": "Naidulinen dagiti kakaykayatam.",
+       "savedrights": "Naidulinen dagiti karbengan ti agar-aramat ni {{GENDER:$1|$1}}.",
        "timezonelegend": "Sona ti oras:",
        "localtime": "Lokal nga oras:",
        "timezoneuseserverdefault": "Usaren ti kasisigud ti wiki ($1)",
        "recentchanges-page-added-to-category-bundled": "nainayon ti [[:$1]] ken {{PLURAL:$2|maysa a panid|$2 a pampanid}} iti kategoria",
        "recentchanges-page-removed-from-category": "naikkat ti [[:$1]] manipud iti kategoria",
        "recentchanges-page-removed-from-category-bundled": "Naikkat ti [[:$1]] ken {{PLURAL:$2|maysa a panid|$2 a pampanid}} manipud iti kategoria",
+       "autochange-username": "Automatiko a panagbaliw iti MediaWiki",
        "upload": "Agikarga iti papeles",
        "uploadbtn": "Agikarga iti papeles",
        "reuploaddesc": "Ukasen ti panagikarga ken agsubli idiay porma ti panagikarga",
        "upload-form-label-infoform-description": "Deskripsion",
        "upload-form-label-usage-title": "Panagusar",
        "upload-form-label-usage-filename": "Nagan ti papeles",
+       "foreign-structured-upload-form-label-own-work": "Daytoy ket bukodko nga obra",
+       "foreign-structured-upload-form-label-infoform-categories": "Katkategoria",
+       "foreign-structured-upload-form-label-infoform-date": "Petsa",
        "backend-fail-stream": "Saan a maipan ti papeles $1.",
        "backend-fail-backup": "Saan a makaidulin ti kapada ti papeles ti $1.",
        "backend-fail-notexists": "Awan ti papeles ti $1.",
        "wlnote": "Dita baba ket {{PLURAL:$1|naudi a sinukatan|dagiti naudi a <strong>$1</strong> a sinukatan}} iti napalabas {{PLURAL:$2|nga oras|a <strong>$2</strong> nga or-oras}}, manipud idi $3, $4.",
        "wlshowlast": "Ipakita dagiti naudi a $1 nga or-oras $2 nga al-aldaw",
        "watchlistall2": "amin",
+       "watchlist-hide": "Ilemmeng",
+       "wlshowtime": "Ipakita ti naudi:",
+       "wlshowhideminor": "dagiti bassit a panagurnos",
+       "wlshowhidebots": "dagiti bot",
+       "wlshowhideliu": "dagiti nakarehistro nga agar-aramat",
+       "wlshowhideanons": "dagiti di ammo nga agar-aramat",
+       "wlshowhidepatr": "dagiti napatrulian a panagurnos",
+       "wlshowhidemine": "dagiti inurnosko",
        "watchlist-options": "Dagiti pagpilian ti listaan a bambantayan",
        "watching": "Bambantayan...",
        "unwatching": "Saanen a bantayan...",
        "contributions": "Dagiti kontribusion ti {{GENDER:$1|agar-aramat}}",
        "contributions-title": "Kontribusion ti agar-aramat para kenni $1",
        "mycontris": "Inar-aramid",
+       "anoncontribs": "Inar-aramid",
        "contribsub2": "Para kenni {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Ti pakabilangan ti agar-aramat ni \"$1\" ket saan a nakarehistro.",
        "nocontribs": "Awan ti nasarakan a nasukatan a kapada dagitoy a kriteria.",
        "cant-move-to-user-page": "Awan ti pammalubosmo nga agiyalis ti panid iti panid ti agar-aramat (malaksid kadagiti subpanid ti agar-aramat).",
        "cant-move-category-page": "Awan ti pammalubosmo nga agiyalis kadagiti panid ti kategoria.",
        "cant-move-to-category-page": "Awan ti pammalubosmo nga agiyalis ti panid iti panid ti kategoria.",
-       "newtitle": "Iti baro a titulo:",
+       "newtitle": "Baro a titulo:",
        "move-watch": "Bantayan ti taudan a panid ken puntaan a panid",
        "movepagebtn": "Iyalis ti panid",
        "pagemovedsub": "Balligi ti panangiyalis",
        "movenosubpage": "Daytoy a panid ket awan ti subpanidna.",
        "movereason": "Rason:",
        "revertmove": "isubli",
-       "delete_and_move": "Ikkaten ken iyalis",
        "delete_and_move_text": "== Masapul nga ikkaten ==\nTi pangipanan ti panid ket \"[[:$1]]\" addan.\nKayatmo nga ikkaten tapno makaiyaliska?",
        "delete_and_move_confirm": "Wen, ikkaten ti panid",
        "delete_and_move_reason": "Naikkat tapno mawayaan ti pannaka-iyalis manipud ti \"[[$1]]\"",
        "tooltip-pt-userpage": "Panidmo nga agar-aramat",
        "tooltip-pt-anonuserpage": "Ti panid ti agar-aramat para iti daytoy nga IP a pagtaengan a kas ur-urnosem",
        "tooltip-pt-mytalk": "Tungtungam a panid",
-       "tooltip-pt-anontalk": "Pakitungtungan a maipanggep kadagiti panagurnos manipud ti daytoy nga IP a pagtaengan",
+       "tooltip-pt-anontalk": "Pakitungtungan a maipanggep kadagiti panagurnos manipud iti daytoy nga adres ti IP",
        "tooltip-pt-preferences": "Dagiti kakaykayatam",
        "tooltip-pt-watchlist": "Listaan dagiti panid a sipsiputem para iti pannakabalbaliw",
        "tooltip-pt-mycontris": "Ti listaan dagiti kontribusionmo",
+       "tooltip-pt-anoncontribs": "Ti listaan dagiti panagurnos manipud iti daytoy nga adres ti IP",
        "tooltip-pt-login": "Maaw-awis a sumrekka; nupay kasta, daytoy ket saan a nasken",
        "tooltip-pt-logout": "Rummuar",
        "tooltip-pt-createaccount": "Maaw-awis nga agpartuatka iti pakabilangan ken sumrek; nupay kasta, daytoy ket saan a nasken",
index 8e93778..2ae8f63 100644 (file)
        "movenosubpage": "Þessi síða hefur engar undirsíður.",
        "movereason": "Ástæða:",
        "revertmove": "taka til baka",
-       "delete_and_move": "Eyða og flytja",
        "delete_and_move_text": "==Beiðni um eyðingu==\n\nSíðan „[[:$1]]“ er þegar til. Viltu eyða henni til þess að rýma til fyrir flutningi?",
        "delete_and_move_confirm": "Já, eyða síðunni",
        "delete_and_move_reason": "Eytt til að rýma til fyrir flutning frá \"[[$1]]\"",
index 8694ca5..ea2e22b 100644 (file)
        "tog-watchlisthidebots": "Nascondi le modifiche dei bot negli osservati speciali",
        "tog-watchlisthideminor": "Nascondi le modifiche minori negli osservati speciali",
        "tog-watchlisthideliu": "Nascondi le modifiche degli utenti registrati negli osservati speciali",
+       "tog-watchlistreloadautomatically": "Ricarica automaticamente l'elenco degli osservati speciali ogni volta che si modifica una filtro (richiede JavaScript)",
        "tog-watchlisthideanons": "Nascondi le modifiche degli utenti anonimi negli osservati speciali",
        "tog-watchlisthidepatrolled": "Nascondi le modifiche verificate negli osservati speciali",
        "tog-watchlisthidecategorization": "Nascondi la categorizzazione delle pagine",
        "tog-prefershttps": "Usa sempre una connessione sicura quando si effettua l'accesso",
        "underline-always": "Sempre",
        "underline-never": "Mai",
-       "underline-default": "Impostazioni predefinite del browser o della skin",
+       "underline-default": "Impostazioni predefinite del browser o del tema",
        "editfont-style": "Stile del carattere nella casella di modifica:",
        "editfont-default": "Predefinito del browser",
        "editfont-monospace": "Carattere a larghezza fissa",
        "morenotlisted": "Questo elenco non è completo.",
        "mypage": "Pagina",
        "mytalk": "discussioni",
-       "anontalk": "Discussioni per questo IP",
+       "anontalk": "discussioni",
        "navigation": "Navigazione",
        "and": "&#32;e",
        "qbfind": "Trova",
        "databaseerror-query": "Query: $1",
        "databaseerror-function": "Funzione: $1",
        "databaseerror-error": "Errore: $1",
+       "transaction-duration-limit-exceeded": "Al fine di evitare un alto ritardo di replica, questa operazione è stata interrotta perché la durata di scrittura ($1) ha superato il limite di $2 secondi.\nSe si stanno modificando molti elementi alla volta, prova a fare più operazioni più piccole.",
        "laggedslavemode": "'''Attenzione:''' la pagina potrebbe non riportare gli aggiornamenti più recenti.",
        "readonly": "Database bloccato",
        "enterlockreason": "Indicare il motivo del blocco, specificando il momento in cui è presumibile che venga rimosso",
        "wrongpasswordempty": "Non è stata inserita alcuna password. Riprovare.",
        "passwordtooshort": "Le password devono contenere almeno {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoolong": "La password non può contenere più di {{PLURAL:$1|1 carattere|$1 caratteri}}.",
+       "passwordtoopopular": "Password comuni non possono essere usate. Scegli una password più originale.",
        "password-name-match": "La password deve essere diversa dal nome utente.",
        "password-login-forbidden": "L'uso di questo nome utente e password è stato proibito.",
        "mailmypassword": "Reimposta password",
        "passwordreset-emailtext-ip": "Qualcuno (probabilmente tu, con indirizzo IP $1) ha richiesto l'invio di una nuova password per l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associato|Gli utenti associati}} a questo indirizzo email sono:\n\n$2\n\n{{PLURAL:$3|Questa password temporanea scadrà|Queste password temporanee scadranno}} dopo {{PLURAL:$5|un giorno|$5 giorni}}.\nDovresti accedere e scegliere una nuova password ora. \n\nSe non sei stato tu a fare la richiesta, o se ti sei ricordato la password originale e non vuoi più cambiarla, puoi ignorare questo messaggio e continuare ad utilizzare la tua vecchia password.",
        "passwordreset-emailtext-user": "L'utente $1 di {{SITENAME}} ha richiesto l'invio di una nuova password per l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associato|Gli utenti associati}} a questo indirizzo email sono:\n\n$2\n\n{{PLURAL:$3|Questa password temporanea scadrà|Queste password temporanee scadranno}} dopo {{PLURAL:$5|un giorno|$5 giorni}}.\nDovresti accedere e scegliere una nuova password ora. \n\nSe non sei stato tu a fare la richiesta, o se ti sei ricordato la password originale e non vuoi più cambiarla, puoi ignorare questo messaggio e continuare al utilizzare la tua vecchia password.",
        "passwordreset-emailelement": "Nome utente: \n$1\n\nPassword temporanea: \n$2",
-       "passwordreset-emailsent": "Se questo è un indirizzo di posta elettronica registrato per la tua utenza, allora verrà inviata una email per reimpostare la password.",
+       "passwordreset-emailsentemail": "Se questo è un indirizzo di posta elettronica registrato per la tua utenza, allora verrà inviata una email per reimpostare la password.",
        "passwordreset-emailsent-capture": "È stata inviata una email di reimpostazione della password, il contenuto è riportato di seguito.",
        "passwordreset-emailerror-capture": "È stata generata una email di reimpostazione della password, riportata di seguito. L'invio {{GENDER:$2|all'utente}} non è riuscito: $1",
        "changeemail": "Modifica o rimuovi indirizzo email",
        "userjspreview": "'''Questa è solo un'anteprima per provare il proprio JavaScript personale; le modifiche non sono ancora state salvate!'''",
        "sitecsspreview": "Questa è solo un'anteprima del CSS. Le modifiche non sono ancora state salvate!'''",
        "sitejspreview": "Questa è solo un'anteprima per provare il JavaScript; le modifiche non sono ancora state salvate!'''",
-       "userinvalidcssjstitle": "'''Attenzione:'''  Non esiste alcuna skin con nome \"$1\". Si noti che le pagine per i .css e .js personalizzati hanno l'iniziale del titolo minuscola, ad esempio {{ns:user}}:Esempio/vector.css e non {{ns:user}}:Esempio/Vector.css.",
+       "userinvalidcssjstitle": "<strong>Attenzione:</strong> non esiste alcun tema con nome \"$1\". Si noti che le pagine per i .css e .js personalizzati hanno l'iniziale del titolo minuscola, ad esempio {{ns:user}}:Esempio/vector.css e non {{ns:user}}:Esempio/Vector.css.",
        "updated": "(Aggiornato)",
        "note": "'''Nota:'''",
        "previewnote": "'''Ricorda che questa è solo un'anteprima.'''\nLe tue modifiche NON sono ancora state salvate!",
        "mypreferences": "preferenze",
        "prefs-edits": "Modifiche effettuate:",
        "prefsnologintext2": "Per modificare le tue preferenze è necessario effettuare l'accesso.",
-       "prefs-skin": "Aspetto grafico (skin)",
+       "prefs-skin": "Tema",
        "skin-preview": "Anteprima",
        "datedefault": "Nessuna preferenza",
        "prefs-labs": "Funzionalità sperimentali",
        "prefs-files": "File",
        "prefs-custom-css": "CSS personalizzato",
        "prefs-custom-js": "JavaScript personalizzato",
-       "prefs-common-css-js": "CSS/JavaScript condiviso per tutte le skin:",
+       "prefs-common-css-js": "CSS/JavaScript condiviso per tutti i temi:",
        "prefs-reset-intro": "È possibile usare questa pagina per reimpostare le proprie preferenze a quelle predefinite del sito.\nL'operazione non può essere annullata.",
        "prefs-emailconfirm-label": "Conferma dell'e-mail:",
        "youremail": "Indirizzo email:",
        "wlshowlast": "Mostra le ultime $1 ore $2 giorni",
        "watchlistall2": "tutte",
        "watchlist-hide": "Nascondi",
-       "wlshowtime": "Mostra ultime:",
+       "wlshowtime": "Periodo di tempo da visualizzare:",
        "wlshowhideminor": "modifiche minori",
        "wlshowhidebots": "bot",
        "wlshowhideliu": "utenti registrati",
        "contributions": "Contributi {{GENDER:$1|utente}}",
        "contributions-title": "Contributi di $1",
        "mycontris": "contributi",
+       "anoncontribs": "contributi",
        "contribsub2": "Per {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "L'utenza \"$1\" non è registrata.",
        "nocontribs": "Non sono state trovate modifiche che soddisfino i criteri di ricerca.",
        "movenosubpage": "Questa pagina non ha sottopagine.",
        "movereason": "Motivo:",
        "revertmove": "ripristina",
-       "delete_and_move": "Cancella e sposta",
        "delete_and_move_text": "==Cancellazione richiesta==\n\nLa pagina specificata come destinazione \"[[:$1]]\" esiste già. Vuoi cancellarla per proseguire con lo spostamento?",
        "delete_and_move_confirm": "Sì, sovrascrivi la pagina esistente",
        "delete_and_move_reason": "Cancellata per rendere possibile lo spostamento da \"[[$1]]\"",
        "javascripttest-pagetext-unknownframework": "Framework di test sconosciuto \"$1\".",
        "javascripttest-pagetext-unknownaction": "Azione sconosciuta \"$1\".",
        "javascripttest-pagetext-frameworks": "Per cortesia, scegli uno dei seguenti framework per i test: $1",
-       "javascripttest-pagetext-skins": "Scegli una skin con cui eseguire i test:",
+       "javascripttest-pagetext-skins": "Scegli un tema con cui eseguire i test:",
        "javascripttest-qunit-intro": "Vedi su mediawiki.org la [$1 documentazione riguardante i test].",
        "tooltip-pt-userpage": "La tua pagina utente",
        "tooltip-pt-anonuserpage": "La pagina utente di questo indirizzo IP",
        "tooltip-pt-preferences": "Le tue preferenze",
        "tooltip-pt-watchlist": "La lista delle pagine che stai tenendo sotto osservazione",
        "tooltip-pt-mycontris": "La lista dei tuoi contributi",
+       "tooltip-pt-anoncontribs": "Un elenco delle modifiche fatte da questo indirizzo IP",
        "tooltip-pt-login": "Si consiglia di effettuare l'accesso, anche se non è obbligatorio",
        "tooltip-pt-logout": "Uscita (logout)",
        "tooltip-pt-createaccount": "Si consiglia di registrarsi e di effettuare l'accesso, anche se non è obbligatorio",
        "tooltip-preferences-save": "Salva le preferenze",
        "tooltip-summary": "Inserire una breve sintesi",
        "interlanguage-link-title": "$1 - $2",
-       "common.css": "/* Gli stili CSS inseriti qui si applicano a tutte le skin */",
+       "common.css": "/* Gli stili CSS inseriti qui si applicano a tutti i temi */",
        "print.css": "/* Gli stili CSS inseriti qui si applicano all'output in stampa */",
        "noscript.css": "/ * Gli stili CSS inseriti qui si applicano agli utenti che hanno JavaScript disabilitato * /",
        "group-autoconfirmed.css": "/ * Gli stili CSS inseriti qui si applicheranno solo ad utenti autoconvalidati * /",
        "exif-datetimeexpires": "Non utilizzare dopo",
        "exif-datetimereleased": "Rilasciato il",
        "exif-originaltransmissionref": "Codice del luogo di trasmissione originaria",
-       "exif-identifier": "Identificativo",
+       "exif-identifier": "Identificatore",
        "exif-lens": "Obiettivo utilizzato",
        "exif-serialnumber": "Numero di serie della fotocamera",
        "exif-cameraownername": "Proprietario della macchina fotografica",
        "invalid-indicator-name": "<strong>Errore:</strong> attributo <code>name</code> degli indicatori dello stato della pagina non può essere vuoto.",
        "version": "Versione",
        "version-extensions": "Estensioni installate",
-       "version-skins": "Skin installate",
+       "version-skins": "Temi installati",
        "version-specialpages": "Pagine speciali",
        "version-parserhooks": "Hook del parser",
        "version-variables": "Variabili",
        "version-license": "Licenza MediaWiki",
        "version-ext-license": "Licenza",
        "version-ext-colheader-name": "Estensione",
-       "version-skin-colheader-name": "Skin",
+       "version-skin-colheader-name": "Tema",
        "version-ext-colheader-version": "Versione",
        "version-ext-colheader-license": "Licenza",
        "version-ext-colheader-description": "Descrizione",
        "log-name-pagelang": "Modifiche lingua",
        "log-description-pagelang": "Questo è un registro delle modifiche alla lingua delle pagine.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ha modificato}} la lingua della pagina $3 da $4 a $5.",
-       "default-skin-not-found": "Oops! La skin predefinita per il tuo wiki, definita in <code dir=\"ltr\">$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nLa tua installazione sembra includere {{PLURAL:$4|la seguente|le seguenti}} skin. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitar{{PLURAL:$4|la|le e scegliere quella predefinita}}.\n\n$2\n\n; Se hai appena installato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code dir=\"ltr\">skins/</code> da lì.\n:* Scaricando tarball di singole skin da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git per scaricare le skin].\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki.\n\n; Se hai appena aggiornato MediaWiki:\n: MediaWiki 1.24 e versioni successive non abilitano più automaticamente le skin installate (vedi [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automatico skin]). Puoi copiare {{PLURAL:$5|la seguente linea|le seguenti linee}} nel <code>LocalSettings.php</code> per abilitare {{PLURAL:$5|la|tutte le}} skin {{PLURAL:$5|installata|installate}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Se hai appena modificato <code>LocalSettings.php</code>:\n: Ricontrolla i nomi delle skin per errori di battitura.",
-       "default-skin-not-found-no-skins": "Oops! La skin predefinita per il tuo wiki, definita in <code>$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nNon hai skin installate.\n\n; Se hai appena installato o aggiornato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. MediaWiki 1.24 e versioni successive non include alcuna skin nel repository principale. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code>skins/</code> da lì.\n:* Scaricando tarball di singole skin da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git per scaricare le skin].\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitarle e scegliere quella predefinita.",
+       "default-skin-not-found": "Oops! Il tema predefinito per il tuo wiki, definito in <code dir=\"ltr\">$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nLa tua installazione sembra includere {{PLURAL:$4|il seguente|i seguenti}} temi. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione tema] per informazioni su come {{PLURAL:$4|abilitarlo|abilitarli e scegliere quello predefinito}}.\n\n$2\n\n; Se hai appena installato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. Prova ad installare alcuni temi dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diversi temi ed estensioni. Puoi fare copia ed incolla della directory <code dir=\"ltr\">skins/</code> da lì.\n:* Scaricando tarball di singoli temi da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git per scaricare i temi].\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki.\n\n; Se hai appena aggiornato MediaWiki:\n: MediaWiki 1.24 e versioni successive non abilitano più automaticamente i temi installati (vedi [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automatico temi]). Puoi copiare {{PLURAL:$5|la seguente linea|le seguenti linee}} nel <code>LocalSettings.php</code> per abilitare {{PLURAL:$5|il tema installato|tutti i temi installati}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Se hai appena modificato <code>LocalSettings.php</code>:\n: Ricontrolla i nomi dei temi per errori di battitura.",
+       "default-skin-not-found-no-skins": "Oops! Il tema predefinito per il tuo wiki, definito in <code>$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nNon hai temi installati.\n\n; Se hai appena installato o aggiornato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. MediaWiki 1.24 e versioni successive non include alcun tema nel repository principale. Prova ad installare alcuni temi dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diversi temi ed estensioni. Puoi fare copia ed incolla della directory <code>skins/</code> da lì.\n:* Scaricando tarball di singoli temi da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git per scaricare i temi].\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione temi] per informazioni su come abilitarle e scegliere quello predefinito.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (abilitata)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disabilitata''')",
        "mediastatistics": "Statistiche relative ai file multimediali",
index 7d17c1e..2f5e695 100644 (file)
@@ -68,7 +68,8 @@
                        "赤城。",
                        "Sujiniku",
                        "Azeha",
-                       "Kana Higashikawa"
+                       "Kana Higashikawa",
+                       "Shield-9"
                ]
        },
        "tog-underline": "リンクの下線:",
@@ -86,7 +87,7 @@
        "tog-watchdefault": "自分が編集したページやファイルをウォッチリストに追加",
        "tog-watchmoves": "自分が移動したページやファイルをウォッチリストに追加",
        "tog-watchdeletion": "自分が削除したページやファイルをウォッチリストに追加",
-       "tog-watchrollback": "巻き戻したページを、ウォッチリストに追加",
+       "tog-watchrollback": "自分が巻き戻したページを、ウォッチリストに追加",
        "tog-minordefault": "編集をすべて既定で細部の編集とする",
        "tog-previewontop": "プレビューを編集ボックスの前に配置",
        "tog-previewonfirst": "編集開始時にもプレビューを表示",
        "morenotlisted": "この一覧は完全ではありません。",
        "mypage": "ページ",
        "mytalk": "トーク",
-       "anontalk": "このIPアドレスについての議論",
+       "anontalk": "議論",
        "navigation": "案内",
        "and": "&#32;と",
        "qbfind": "検索",
        "throttled-mailpassword": "パスワード再設定メールを過去 {{PLURAL:$1|$1 時間}}に送信済みです。\n悪用防止のため、パスワードの再設定は {{PLURAL:$1|$1 時間}}に 1 回のみです。",
        "mailerror": "メールを送信する際にエラーが発生しました: $1",
        "acct_creation_throttle_hit": "あなたと同じ IP アドレスでこのウィキに訪れた人が、最近 24 時間で {{PLURAL:$1|$1 アカウント}}を作成しており、これはこの期間で作成が許可されている最大数です。\nそのため、現在この IP アドレスではアカウントをこれ以上作成できません。",
-       "emailauthenticated": "メールアドレスは$2 $3に確認済みです。",
+       "emailauthenticated": "メールアドレスは$2 $3に確認済みです。",
        "emailnotauthenticated": "メールアドレスが確認されていません。\n確認されるまで、以下のいかなる機能でもメールは送信されません。",
        "noemailprefs": "これらの機能を有効にするには、個人設定でメールアドレスを登録してください。",
        "emailconfirmlink": "あなたのメールアドレスを確認",
        "login-abort-generic": "ログインに失敗しました - 中止",
        "login-migrated-generic": "あなたのアカウントは移行が完了しており、その利用者名はこのウィキにはもう存在しません。",
        "loginlanguagelabel": "言語: $1",
-       "suspicious-userlogout": "å£\8aã\82\8cã\81\9fã\83\96ã\83©ã\82¦ã\82¶ã\83¼ã\81¾ã\81\9fã\81¯ã\82­ã\83£ã\83\83ã\82·ã\83¥ã\83\97ã\83­ã\82­ã\82·ã\81«ã\82\88ã\81£ã\81¦é\80\81ä¿¡ã\81\95ã\82\8cã\81\9få\8f¯è\83½æ\80§ã\81\8cã\81\82ã\82\8bã\81\9fã\82\81ã\80\81ã\83­ã\82°ã\82¢ã\82¦ã\83\88è¦\81æ±\82ã\81¯æ\8b\92å\90¦ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fã\80\82",
+       "suspicious-userlogout": "壊れたブラウザまたはキャッシュプロキシによって送信された可能性があるため、ログアウト要求は拒否されました。",
        "createacct-another-realname-tip": "本名は省略できます。\n入力すると、その利用者の著作物の帰属表示に使われます。",
        "pt-login": "ログイン",
        "pt-login-button": "ログイン",
        "passwordreset-emailtext-ip": "誰か (おそらくあなた、IP アドレス $1) が {{SITENAME}} ($4)\nでのパスワードを再設定するよう申請しました。\n以下の利用者{{PLURAL:$3|アカウント|アカウント群}}がこのメールアドレスと紐付けられています。\n\n$2\n\n{{PLURAL:$3|この仮パスワード|これらの仮パスワード}}は {{PLURAL:$5|$5 日|$5 日間}}で有効期限が切れます。\nあなたはすぐにログインして新しいパスワードを設定する必要があります。\nこれが他の誰かによる申請である場合、あるいはあなたが自分の元のパスワードを\n覚えていてそれを変更したくない場合には、このメッセージを無視して以前のパスワードを\n使用し続けることができます。",
        "passwordreset-emailtext-user": "{{SITENAME}} の利用者 $1 があなたの {{SITENAME}} ($4)\nでのパスワードを再設定するよう申請しました。\n以下の利用者{{PLURAL:$3|アカウント|アカウント群}}がこのメールアドレスと紐付けられています。\n\n$2\n\n{{PLURAL:$3|この仮パスワード|これらの仮パスワード}}は{{PLURAL:$5|$5日}}で有効期限が切れます。\nあなたは、すぐにログインして新しいパスワードを設定する必要があります。\nこの申請が他の誰かによるものの場合、あるいはあなたが自分の元のパスワードを\n覚えていて、変更したくない場合は、このメッセージを無視して\n以前のパスワードを使い続けることができます。",
        "passwordreset-emailelement": "利用者名: \n$1\n\n仮パスワード: \n$2",
-       "passwordreset-emailsent": "もし、これがあなたのアカウントのために登録されたメールアドレスである場合、これからパスワードリセットのメールが送信されます。",
+       "passwordreset-emailsentemail": "もし、これがあなたのアカウントのために登録されたメールアドレスである場合、これからパスワードリセットのメールが送信されます。",
+       "passwordreset-emailsentusername": "メールアドレスが登録されている場合は、パスワードリセットのメールが送信されます。",
        "passwordreset-emailsent-capture": "下記の内容の、パスワード再設定メールをお送りしました。",
        "passwordreset-emailerror-capture": "以下の内容のパスワード再設定メールを生成しましたが、{{GENDER:$2|利用者}}への送信に失敗しました: $1",
        "changeemail": "メールアドレスを変更または除去",
        "rev-suppressed-unhide-diff": "この差分の一方の版は<strong>秘匿されています</strong>。\n[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 秘匿記録]に詳細情報があるかもしれません。\nこのまま[$1 この差分を閲覧]できます。",
        "rev-deleted-diff-view": "この差分の一方の版は<strong>削除されています</strong>。\nこの差分を閲覧できます。[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 削除記録]に詳細情報があるかもしれません。",
        "rev-suppressed-diff-view": "この差分の一方の版は<strong>秘匿されています</strong>。\nこの差分を閲覧できます。[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 秘匿記録]に詳細情報があるかもしれません。",
-       "rev-delundel": "表示/非表示 の変更",
+       "rev-delundel": "閲覧レベルの変更",
        "rev-showdeleted": "表示",
        "revisiondelete": "版の削除と復元",
        "revdelete-nooldid-title": "無効な対象の版",
        "right-changetags": "個々の版と記録項目の任意の[[Special:Tags|タグ]]の追加と削除",
        "newuserlogpage": "アカウント作成記録",
        "newuserlogpagetext": "以下はアカウント作成の記録です。",
-       "rightslog": "利用者権限変更記録",
+       "rightslog": "利用者権限変更記録",
        "rightslogtext": "以下は利用者権限の変更記録です。",
        "action-read": "このページの閲覧",
        "action-edit": "このページの編集",
        "recentchanges-legend-heading": "'''凡例:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|新しいページ一覧]]も参照)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
+       "recentchanges-submit": "表示",
        "rcnotefrom": "以下は<strong>$3 $4</strong>以降の{{PLURAL:$5|更新です}} (最大 <strong>$1</strong> 件)。",
        "rclistfrom": "$3の$2以降の更新を表示する",
        "rcshowhideminor": "細部の編集を$1",
        "mostrevisions": "版の多いページ",
        "prefixindex": "先頭が同じ全ページ",
        "prefixindex-namespace": "先頭が同じ全ページ ($1名前空間)",
+       "prefixindex-submit": "表示",
        "prefixindex-strip": "一覧で接頭辞を省略",
        "shortpages": "短いページ",
        "longpages": "長いページ",
        "protectedpages-performer": "保護の実行者",
        "protectedpages-params": "保護のパラメーター",
        "protectedpages-reason": "理由",
+       "protectedpages-submit": "ページを表示",
        "protectedpages-unknown-timestamp": "不明",
        "protectedpages-unknown-performer": "不明な利用者",
        "protectedtitles": "作成保護されているページ名",
        "protectedtitles-summary": "このページでは、現時点で新規作成が禁止されているページ名を列挙します。保護されている既存のページの一覧は、[[{{#special:ProtectedPages}}|{{int:protectedpages}}]] を参照してください。",
        "protectedtitlesempty": "これらの引数で現在保護されているページはありません。",
+       "protectedtitles-submit": "タイトルを表示",
        "listusers": "利用者一覧",
        "listusers-editsonly": "投稿記録のある利用者のみを表示",
        "listusers-creationsort": "作成日順に並べ替え",
        "activeusers-hidebots": "ボットを隠す",
        "activeusers-hidesysops": "管理者を隠す",
        "activeusers-noresult": "利用者が見つかりませんでした。",
+       "activeusers-submit": "活動中の利用者を表示",
        "listgrouprights": "利用者グループの権限",
        "listgrouprights-summary": "以下は、このウィキに登録されている利用者グループと、それぞれに割り当てられている権限の一覧です。\n個々の権限に関する更なる情報は[[{{MediaWiki:Listgrouprights-helppage}}|追加情報]]を見てください。",
        "listgrouprights-key": "凡例:\n* <span class=\"listgrouprights-granted\">与えられた権限</span>\n* <span class=\"listgrouprights-revoked\">取り消された権限</span>",
        "wlshowlast": "表示する期間: $1時間、$2日間",
        "watchlistall2": "すべて",
        "watchlist-hide": "非表示",
-       "wlshowtime": "表示範囲:直近",
+       "watchlist-submit": "表示",
+       "wlshowtime": "表示範囲:",
        "wlshowhideminor": "細部の編集",
        "wlshowhidebots": "ボット",
        "wlshowhideliu": "登録利用者",
        "contributions": "{{GENDER:$1|利用者}}の投稿記録",
        "contributions-title": "$1の投稿記録",
        "mycontris": "投稿記録",
+       "anoncontribs": "投稿記録",
        "contribsub2": "利用者: {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "利用者アカウント「$1」は登録されていません。",
        "nocontribs": "これらの条件に一致する変更は見つかりませんでした。",
        "whatlinkshere-hidelinks": "リンクを$1",
        "whatlinkshere-hideimages": "ファイルへのリンクを$1",
        "whatlinkshere-filters": "絞り込み",
+       "whatlinkshere-submit": "実行",
        "autoblockid": "自動ブロック #$1",
        "block": "利用者をブロック",
        "unblock": "利用者のブロックを解除",
        "movenosubpage": "このページに下位ページはありません。",
        "movereason": "理由:",
        "revertmove": "差し戻し",
-       "delete_and_move": "削除して移動",
        "delete_and_move_text": "== 削除が必要です ==\n移動先「[[:$1]]」は既に存在します。\n移動のためにこのページを削除しますか?",
        "delete_and_move_confirm": "はい、ページを削除します",
        "delete_and_move_reason": "「[[$1]]」からの移動のために削除",
        "tooltip-pt-preferences": "個人設定",
        "tooltip-pt-watchlist": "変更をウォッチしているページの一覧",
        "tooltip-pt-mycontris": "自分の投稿の一覧",
+       "tooltip-pt-anoncontribs": "このIPアドレスからなされた編集の一覧",
        "tooltip-pt-login": "ログインすることを推奨します。ただし、必須ではありません。",
        "tooltip-pt-logout": "ログアウト",
        "tooltip-pt-createaccount": "アカウントを作成してログインすることをお勧めしますが、必須ではありません",
        "tags-create-warnings-below": "このタグの作成を続けますか?",
        "tags-delete-title": "タグを削除",
        "tags-delete-explanation-initial": "あなたはタグ「$1」をデータベースから削除しようとしています。",
-       "tags-delete-explanation-in-use": "ç\8f¾å\9c¨é\81©ç\94¨ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8b{{PLURAL:$2|ç\89\88ã\82\84è¨\98é\8c²é \85ç\9b® $2 ä»¶}}ã\82\92å\89\8aé\99¤ã\81\97ます。",
+       "tags-delete-explanation-in-use": "ç\8f¾å\9c¨é\81©ç\94¨ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8b{{PLURAL:$2|ç\89\88ã\82\84è¨\98é\8c²é \85ç\9b® $2 ä»¶}}ã\81\8bã\82\89å\89\8aé\99¤ã\81\95ã\82\8cます。",
        "tags-delete-explanation-warning": "この操作は<strong>元に戻せず</strong>、データベース管理者をもってしても<strong>取り消しは不可能</strong>です。削除するタグとして間違いがないことをもう一度しっかり確認してください。",
        "tags-delete-explanation-active": "<strong>タグ「$1」はまだ有効であり、今後も付与され続けます。</strong>これを止めるには、タグが付与されるよう設定されているところに行き、そこで無効化してください。",
        "tags-delete-reason": "理由:",
        "logentry-suppress-reblock": "$1 が {{GENDER:$4|$3}} のブロックの期限を$5に{{GENDER:$2|変更しました}} $6",
        "logentry-import-upload": "$1 がファイルをアップロードして $3 を{{GENDER:$2|インポートしました}}",
        "logentry-import-interwiki": "$1 が他のウィキから $3 を{{GENDER:$2|インポートしました}}",
+       "logentry-import-interwiki-details": "$1 が $3 を $5 から{{GENDER:$2|取り込み}}ました ($4 {{PLURAL:$4|版}})",
        "logentry-merge-merge": "$1{{GENDER:$2|統合元}} と$3を$4に統合(改訂版を$5に掲載)",
        "logentry-move-move": "$1 がページ「$3」を「$4」に{{GENDER:$2|移動しました}}",
        "logentry-move-move-noredirect": "$1 がページ「$3」を「$4」に、リダイレクトを残さずに{{GENDER:$2|移動しました}}",
        "logentry-managetags-activate": "$1 がタグ \"$4\" の利用者およびボットによる使用を{{GENDER:$2|有効化しました}}。",
        "logentry-managetags-deactivate": "$1 がタグ \"$4\" の利用者およびボットによる使用を{{GENDER:$2|無効化しました}}。",
        "log-name-tag": "タグ記録",
-       "log-description-tag": "このページには、個々の版またはエントリーの記録から、利用者を追加または削除した[[Special:Tags|タグ]]が表示されます。編集の一部、削除、同様の操作として発生したときの操作はタグ付けされず、記録には表示されません。",
+       "log-description-tag": "このページには、個々の版または記録項目から、いつ利用者が[[Special:Tags|タグ]]を追加または削除したかが記録されます。編集、削除、または同様の操作の一部として発生したタグ付けは記録には表示されません。",
        "logentry-tag-update-add-revision": "$1 がページ $3 の版 $4 に{{PLURAL:$7|タグ}} $6 を{{GENDER:$2|追加しました}}",
        "logentry-tag-update-add-logentry": "$1 がページ $3 の記録項目 $5 に{{PLURAL:$7|タグ}} $6 を{{GENDER:$2|追加しました}}",
        "logentry-tag-update-remove-revision": "$1 がページ $3 の版 $4 から{{PLURAL:$9|タグ}} $8 を{{GENDER:$2|除去しました}}",
        "logentry-tag-update-remove-logentry": "$1 がページ $3 の記録項目 $5 から{{PLURAL:$9|タグ}} $8 を{{GENDER:$2|除去しました}}",
        "logentry-tag-update-revision": "$1 がページ「$3」の版 $4 でのタグを{{GENDER:$2|更新しました}} ($6 が{{PLURAL:$7|追加}}、$8 が{{PLURAL:$9|削除}})",
-       "logentry-tag-update-logentry": "$1 がページ「$3」のエントリー $5 での記録のタグを{{GENDER:$2|更新しました}} ($6 が{{PLURAL:$7|追加}}、$8 が{{PLURAL:$9|削除}})",
+       "logentry-tag-update-logentry": "$1 がページ「$3」の記録項目 $5 のタグを{{GENDER:$2|更新しました}} ($6 を{{PLURAL:$7|追加}}、$8 を{{PLURAL:$9|削除}})",
        "rightsnone": "(なし)",
        "revdelete-summary": "編集内容の要約",
        "feedback-adding": "ページへのフィードバックの追加...",
index 8108835..b232c9b 100644 (file)
        "passwordreset-emailtext-ip": "ვიღაცამ (შესაძლოა თქვენ, ამ IP-მისამართიდან $1) მოითხოვა თქვენი \nპაროლის თავიდან დაყენება საიტისათვის {{SITENAME}} ($4).\n{{PLURAL:$3|შემდეგი ანგარიში მიბმულია|შემდეგი ანგარიშები მიბმულია}} ამ ელ.ფოსტის მისამართზე:\n\n$2\n\n{{PLURAL:$3|ეს დროებითი პაროლი|ეს დროებითი პაროლები}} იმოქმედებს {{PLURAL:$5|ერთი დღე|$5 დღე}}.\nთქვენ უნდა შეხვიდეთ სისტემაში და აირჩიოთ ახალი პაროლი.\nთუ თქვენ არ გაგიკეთებიათ აღნიშნული მოთხოვნა, ან გაიხსენეთ თქვენი პაროლი\nდა აღარ გსურთ მისი შეცვლა, მაშინ შეგიძლიათ იგნორირება გაუკეთოთ ამ შეტყობინებას\nდა გააგრძელოთ თქვენი ძველი პაროლის გამოყენება.",
        "passwordreset-emailtext-user": "მომხმარებელმა $1 პროექტიდან {{SITENAME}} მოითხოვა თქვენი \nპაროლის თავიდან დაყენება საიტისათვის {{SITENAME}} ($4).\n{{PLURAL:$3|შემდეგი ანგარიში მიბმულია|შემდეგი ანგარიშები მიბმულია}} ამ ელ.ფოსტის მისამართზე:\n\n$2\n\n{{PLURAL:$3|ეს დროებითი პაროლი|ეს დროებითი პაროლები}} იმოქმედებს {{PLURAL:$5|ერთი დღე|$5 დღე}}.\nთქვენ უნდა შეხვიდეთ სისტემაში და აირჩიოთ ახალი პაროლი.\nთუ თქვენ არ გაგიკეთებიათ აღნიშნული მოთხოვნა, ან გაიხსენეთ თქვენი პაროლი\nდა აღარ გსურთ მისი შეცვლა, მაშინ შეგიძლიათ იგნორირება გაუკეთოთ ამ შეტყობინებას\nდა გააგრძელოთ თქვენი ძველი პაროლის გამოყენება.",
        "passwordreset-emailelement": "მომხმარებლის სახელი: \n$1\n\nდროებითი პაროლი: \n$2",
-       "passwordreset-emailsent": "პაროლის თავიდან დასაყენებელი ელ.ფოსტა გაიგზავნა.",
+       "passwordreset-emailsentemail": "პაროლის თავიდან დასაყენებელი ელ.ფოსტა გაიგზავნა.",
        "passwordreset-emailsent-capture": "ქვემოთ ნაჩვენები პაროლის თავიდან დასაყენებელი წერილი გაიგზავნა.",
        "passwordreset-emailerror-capture": "ქვემოთ მოცემულია შექმნილი პაროლის დასაყენებელი წერილი, რომლის გაგზავნაც {{GENDER:$2|მომხმარებელთან}} ვერ მოხერხდა: $1 გამო",
        "changeemail": "ელ-ფოსტის მისამართის შეცვლა ან წაშლა",
        "prefs-help-recentchangescount": "შეიცავს ახალ შესწორებებს, გვერდების ისტორიებს, ჟურნალებს.",
        "prefs-help-watchlist-token2": "ეს არის საიდუმლო გასაღები თქვენი კონტროლის სიის ვებ-არხისთვის. ნებისმიერს, ვინც იცის ის, შეუძლია წაიკითხოს თქვენი კონტროლის სია, ამიტომ არ გაუზიაროთ იგი სხვებს. [[Special:ResetTokens|თქვენ შეგიძლიათ ჩამოყაროთ ის]].",
        "savedprefs": "თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.",
+       "savedrights": "მომხმარებლის {{GENDER:$1|$1}} უფლებები შენახულია",
        "timezonelegend": "სასაათო სარტყელი:",
        "localtime": "ადგილობრივი დრო:",
        "timezoneuseserverdefault": "გამოიყენე ნაგულისხმევი პარამეტრები ($1)",
        "wlnote": "ქვემოთ {{PLURAL:$1|ნაჩვენებია ბოლო ცვლილება|ნაჩვენებია ბოლო '''$1''' ცვლილება}} უკანასკნელი {{PLURAL:$2|საათის|'''$2''' საათის}} მანძილზე, $3, $4 მდგომარეობით.",
        "wlshowlast": "ბოლო $1 საათის $2 დღის ჩვენება",
        "watchlistall2": "ყველა",
+       "wlshowtime": "აჩვენე უკანასკნელი:",
+       "wlshowhideminor": "მცირე რედაქტირების",
+       "wlshowhidebots": "რობოტების",
+       "wlshowhideliu": "რეგისტრირებული მომხმარებლების",
+       "wlshowhideanons": "ანონიმური მომხმარებლების",
        "wlshowhidemine": "ჩემი რედაქტირება",
        "watchlist-options": "კონტროლის სიის პარამეტრები",
        "watching": "კონტროლებადი...",
        "logentry-contentmodel-change-revert": "დაბრუნება",
        "protectlogpage": "დაცვის ისტორია",
        "protectlogtext": "ქვემოთ წარმოდგენილია გვერდის დაცვის დონის ცვლილებების სია. \nიხილეთ ასევე [[Special:ProtectedPages|დაცული გვერდების სია]] ამ მომენტისთვის.",
-       "protectedarticle": "დაცულია გვერდი: „[[$1]]“",
+       "protectedarticle": "დაცულია გვერდი „[[$1]]“",
        "modifiedarticleprotection": "შეცვლილია დაცვის დონე გვერდისთვის „[[$1]]“",
        "unprotectedarticle": "„[[$1]]“-დან დაცვა მოხსნილია",
        "movedarticleprotection": "დაცვის პარამეტრების გადატანა გვერდიდან „[[$2]]“ გვერდზე „[[$1]]“",
        "contributions": "{{GENDER:$1|მომხმარებლის}} წვლილი",
        "contributions-title": "მომხმარებლის წვლილი $1",
        "mycontris": "წვლილი",
+       "anoncontribs": "წვლილი",
        "contribsub2": "მომხმარებელი {{GENDER:$3|$1}} წვლილი ($2)",
        "contributions-userdoesnotexist": "მომხმარებლის ანგარიში „$1“ არ არის რეგისტრირებული.",
        "nocontribs": "ძებნისას მითითებული პარამეტრების შესაბამისი არც ერთი ცვლილება ნაპოვნი არ არის",
        "movenosubpage": "ამ გვერდს არა აქვს ქვეგვერდები",
        "movereason": "მიზეზი:",
        "revertmove": "გაუქმება",
-       "delete_and_move": "წაშლა და გადატანა",
        "delete_and_move_text": "==საჭიროა წაშლა==\n\nსტატია დასახელებით „[[:$1]]“ უკვე არსებობს. გსურთ მისი წაშლა გადატანისთვის ადგილის დასათმობად?",
        "delete_and_move_confirm": "დიახ, წაშალეთ ეს გვერდი",
        "delete_and_move_reason": "წაშლილია „[[$1]]“-დან გადატანისთვის ადგილის დასათმობად",
        "tooltip-pt-preferences": "თქვენი კონფიგურაცია",
        "tooltip-pt-watchlist": "გვერდების სია, რომელთა ცვლილებებს თქვენ უთვალთვალებთ",
        "tooltip-pt-mycontris": "თქვენი წვლილის სია",
+       "tooltip-pt-anoncontribs": "რედაქტირებების სია შესრულებული ამ IP მისამართიდან",
        "tooltip-pt-login": "სასურველია დარეგისტრირდეთ, თუმცა აუცილებელია არაა.",
        "tooltip-pt-logout": "გასვლა",
        "tooltip-pt-createaccount": "ჩვენ გთავაზობთ, შექმნათ ანგარიში და შეხვიდეთ სისტემაში; თუმცა ეს არ არის აუცილებელი",
index 50e9fb7..4b97c43 100644 (file)
        "contributions": " $1 صارفو حصہ",
        "contributions-title": "$1 صارفو حصہ",
        "mycontris": "مہ حصہ",
+       "anoncontribs": "آرٹیکلز",
        "contribsub2": "براۓ $1 ($2)",
        "uctop": "(ٹیکہ)",
        "month": "مس (وا ھیغاری پروشٹی):",
index ba934cd..ca6843b 100644 (file)
        "newwindow": "(zerrê pençerê dê newey de beno ra)",
        "cancel": "Bıtexelne",
        "moredotdotdot": "Jêde...",
-       "mypage": "Pela mı",
+       "mypage": "Pele",
        "mytalk": "Hurênayişê mı",
        "anontalk": "Pela hurênaisê ni ''IP''y",
        "navigation": "Pusula",
index 72d4d0a..cf9a06a 100644 (file)
@@ -20,6 +20,7 @@
        "tog-hideminor": "Жуықтағы өзгерістерден шағын өңдемелерді жасыру",
        "tog-hidepatrolled": "Тексерілген өңдеулерді жуықтағы өзгерістер тізімінде көрсетпеу",
        "tog-newpageshidepatrolled": "Тексерілген беттерді жаңа беттер тізімінде жасыру",
+       "tog-hidecategorization": "Беттерді санаттауларды жасыру",
        "tog-extendwatchlist": "Бақылау тізімді ұлғайтып барлық өзгерістерді көрсету, ең соңғыларды ғана емес",
        "tog-usenewrc": "Жуықтағы өзгерістер және бақылау тізімінде беті бойынша өзгерістерді топтау",
        "tog-numberheadings": "Мазмұн тақырыптарын автоматты нөмірлеу",
@@ -49,6 +50,7 @@
        "tog-watchlisthideliu": "Бақылау тізіміндегі кірген қатысушылардың өңдеулерін көрсетпеу",
        "tog-watchlisthideanons": "Бақылау тізіміндегі аноним қатысушылардың өңдеулерін көрсетпеу",
        "tog-watchlisthidepatrolled": "Бақылау тізімінде тексерілген өңдеулерді көрсетпеу",
+       "tog-watchlisthidecategorization": "Беттерді санаттауларды жасыру",
        "tog-ccmeonemails": "Басқа қатысушыға жіберген хатымның есесін өзіме жөнелту",
        "tog-diffonly": "Нұсқалар айырмашылықтарының астында бет мағлұматын көрсетпеу",
        "tog-showhiddencats": "Жасырын санаттарды көрсету",
        "morenotlisted": "Бұл тізім толық емес.",
        "mypage": "Жеке бет",
        "mytalk": "Талқылау",
-       "anontalk": "IP талқылауы",
+       "anontalk": "Талқылау",
        "navigation": "Бағыттау",
        "and": "&#32;және",
        "qbfind": "Табу",
        "passwordreset-emailtext-ip": "Әлде кім (мүмкін сіз болуыңыз, $1 IP адресінен) {{SITENAME}} сайтында ($4) құпия сөзді өзгертуге өтініш білдірді. Мына қатысушы {{PLURAL:$3|аккаунты|аккаунттары}} осы электронды почта қатысты:\n\n$2\n\n{{PLURAL:$3|Бұл уақытша құпия сөз|Бұл уақытша құпия сөздер}} {{PLURAL:$5|бір күнде|$5 күнде}}уақыты аяқталады.\nСіз кіруіңіз және жаңа құпия сөзді таңдауыңыз керек. Егер бұл өтінішті басқа біреу жасаса, немесе сіз  бұрынғы құпия сөзіңізді еске түсірсеңіз және құпия сөзді ауыстыруды қаламасаңыз, сіз бұл хабарламаны ескермей және бұрынғы құпия сөзді қолдана беруіңізге болады.",
        "passwordreset-emailtext-user": "$1 есімді қатысушы {{SITENAME}} сайтында ($4) құпия сөзді өзгертуге өтініш білдірді. Мына қатысушы {{PLURAL:$3|аккаунт|аккаунттар}} осы електронды почта қатысты:\n\n$2\n\n{{PLURAL:$3|Бұл уақытша құпия сөз|Бұл уақытша құпия сөздер}} {{PLURAL:$5|бір күнде|$5 күнде}}уақыты аяқталады.\nСіз кіруіңіз және жаңа құпия сөзді таңдауыңыз керек. Егер бұл өтінішті басқа біреу жасаса, немесе сіз  бұрынғы құпия сөзіңізді еске түсірсеңіз, және құпия сөзді ауыстыруды қаламасаңыз, сіз бұл хабарламаны ескермей және бұрыңғы құпия сөзді қолдана беруіңізге болады.",
        "passwordreset-emailelement": "Қатысушы есімі: \n$1\n\nУақытша құпия сөз: \n$2",
-       "passwordreset-emailsent": "Құпия сөзді өзгерту электронды пошта арқылы жөнелтілді.",
+       "passwordreset-emailsentemail": "Құпия сөзді өзгерту электронды пошта арқылы жөнелтілді.",
        "passwordreset-emailsent-capture": "Құпия сөзді өзгерту электронды пошта арқылы жөнелтілді, ол төменде көрсетілген.",
        "passwordreset-emailerror-capture": "Құпиясөзді өзгерту электрон хаты жасалды, ол төменде көрсетілген, бірақ ол {{GENDER:$2|қатысушыға}} жөнелтілмеді: $1",
        "changeemail": "Е-пошта мекенжайын өзгерту немесе аластау",
        "changeemail-password": "{{SITENAME}} жобасындағы құпия сөзіңіз:",
        "changeemail-submit": "Е-поштаны өзгерту",
        "changeemail-throttled": "Сіз жақында кіруге тым көп әрекет жасадыңыз.\nҚайта байқап көру үшін $1 уақыт күте тұрыңыз.",
+       "changeemail-nochange": "Басқа жаңа email мекенжайын енгізіңіз.",
        "resettokens": "Байрақшаны ысыру",
        "resettokens-text": "Мұнда сіз құпия дерекке қатысты тіркелгіңізге қатынауға рұқсат ететін байрақшаны ысыра аласыз.\n\nЕгер сіздің тіркелгіңіз бұзылған болса, егер сіз абайсызда қандай да біреумен бөліссеңіз, сіз мұны істеуіңіз керек.",
        "resettokens-no-tokens": "Мұнда ысыруға байрақша жоқ.",
        "session_fail_preview_html": "<strong>Кешіріңіз! Сессия деректері жоғалуы салдарынан өңдемеңізді бітіре алмаймыз.</strong>\n\n<em>Сондықтан {{SITENAME}} жобасында қам HTML қосылған, JavaScript шабуылдардан қорғану үшін алдын ала қарап шығу жасырылған.</em>\n\n<strong>Егер бұл өңдеме адал ниетті әрекет болса қайта байқап көріңіз.</strong> \nЕгер бұл әлі істемесе [[Special:UserLogout|шығуды]] және қайта кіруді байқап көріңіз.",
        "token_suffix_mismatch": "<strong>Өңдемеңіз тайдырылды, себебі тұтынғышыңыз өңдеме деректер бумасындағы тыныс белгілерін бүлдіртті.\nБет мәтіні бүлінбеу үшін өңдемеңіз тайдырылады.</strong>\nБұл кей уақытта қатесі толған веб-негізінде тіркелуі жоқ прокси-серверді пайдаланған болуы мүмкін.",
        "edit_form_incomplete": "<strong>Өңдеу пішінінің кейбір бөліктері серверге жетпеді; өңдемелеріңіздің бұзылмағандығына екі рет бақылау жүргізіңіз және қайта байқап көріңіз.</strong>",
-       "editing": "Өңделуде: $1",
+       "editing": "$1 бетін өңдеп жатырсыз",
        "creating": "Жаңадан бастау: $1",
-       "editingsection": "Өңделуде: $1 (бөлімі)",
-       "editingcomment": "Өңделуде: $1 (жаңа бөлім)",
+       "editingsection": "$1 бетінің бөлімін өңдеп жатырсыз",
+       "editingcomment": "$1 бетін өңдеп жатырсыз (жаңа бөлім)",
        "editconflict": "Өңдемелер қақтығысы: $1",
        "explainconflict": "Осы бетті сіз өңдей бастағанда басқа біреу бетті өзгерткен.\nЖоғарғы мәтін аумағында қазіргі уақытта бар бет мәтінінен тұрады.\nТөменгі мәтін аумағында сіздің өзгертулеріңіз көрсетіледі.\nӨзгертуіңізді бар мәтінге біріктіруге тура келеді.\n«{{int:savearticle}}» батырмасын басқанда </strong>тек</strong> жоғарғы мәтін аумағы сақталады.",
        "yourtext": "Мәтініңіз",
        "prefs-watchlist-token": "Бақылау тізімінің белгісі:",
        "prefs-misc": "Әрқилы",
        "prefs-resetpass": "Құпия сөзді өзгерту",
-       "prefs-changeemail": "E-mail мекен-жайын өзгерту",
+       "prefs-changeemail": "E-mail мекенжайын өзгерту немесе алып тастау",
        "prefs-setemail": "E-mail мекен-жайын жөндеу",
        "prefs-email": "Е-пошта баптаулары",
        "prefs-rendering": "Сырт көрініс",
        "rows": "Жолдар:",
        "columns": "Бағандар:",
        "searchresultshead": "Іздеу",
-       "stub-threshold": "<a href=\"#\" class=\"stub\">Бастама сілтемесін</a> пішімдеу табалдырығы (байт):",
+       "stub-threshold": "Бастама сілтемесін пішімдеу табалдырығы ($1):",
        "stub-threshold-sample-link": "қарапайым",
        "stub-threshold-disabled": "Ажыратылған",
        "recentchangesdays": "Жуықтағы өзгерістерде көрсетілетін күн саны:",
        "group-bot": "Боттар",
        "group-sysop": "Әкімшілер",
        "group-bureaucrat": "Бітікшілер",
-       "group-suppress": "ШеÑ\82Ñ\82еÑ\82Ñ\83Ñ\88Ñ\96леÑ\80",
+       "group-suppress": "Ð\91аÑ\81Ñ\82Ñ\8bÑ\80Ñ\83Ñ\88Ñ\8b",
        "group-all": "(барлық)",
        "group-user-member": "{{GENDER:$1|қатысушы}}",
        "group-autoconfirmed-member": "{{GENDER:$1|өздіктіқұпталған қатысушы}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|әкімші}}",
        "group-bureaucrat-member": "{{GENDER:$1|бітікші}}",
-       "group-suppress-member": "{{GENDER:$1|шеттетуші}}",
+       "group-suppress-member": "{{GENDER:$1|бастырушы}}",
        "grouppage-user": "{{ns:project}}:Қатысушылар",
        "grouppage-autoconfirmed": "{{ns:project}}:Өздіктіқұпталған қатысушылар",
        "grouppage-bot": "{{ns:project}}:Боттар",
        "grouppage-sysop": "{{ns:project}}:Әкімшілер",
        "grouppage-bureaucrat": "{{ns:project}}:Бітікшілер",
-       "grouppage-suppress": "{{ns:project}}:ШеÑ\82Ñ\82еÑ\82Ñ\83Ñ\88Ñ\96леÑ\80",
+       "grouppage-suppress": "{{ns:project}}:Ð\91аÑ\81Ñ\82Ñ\8bÑ\80Ñ\83",
        "right-read": "Беттерді оқу",
        "right-edit": "Беттерді өңдеу",
        "right-createpage": "Беттерді бастау (талқылау емес беттерді бастау)",
        "rcshowhidemine": "Өңдемелерімді $1",
        "rcshowhidemine-show": "көрсету",
        "rcshowhidemine-hide": "жасыру",
+       "rcshowhidecategorization": "Бет санаттауларын $1",
+       "rcshowhidecategorization-show": "Көрсету",
+       "rcshowhidecategorization-hide": "Жасыру",
        "rclinks": "Соңғы $2 күнде болған соңғы $1 өзгерісті көрсет<br />$3",
        "diff": "айырм",
        "hist": "тарихы",
        "recentchangeslinked-page": "Бет атауы:",
        "recentchangeslinked-to": "Керісінше, келтірілген бетке сілтейтін беттердегі өзгерістерді көрсет",
        "recentchanges-page-added-to-category": "[[:$1]] бетіне санат қосты",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] және {{PLURAL:$2|бір бет|$2 бет}} санатқа қосылды",
+       "recentchanges-page-removed-from-category": "[[:$1]] санаттан алынды",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] және {{PLURAL:$2|бір бет|$2 бет}} санаттан алынды",
+       "autochange-username": "МедиаУики өздікті өзгерісі",
        "upload": "Файл жүктеу",
        "uploadbtn": "Файлды жүктеу",
        "reuploaddesc": "Жүктеу пішініне қайта келу.",
        "filerevert-legend": "Файлды қайтару",
        "filerevert-intro": "Сіз  '''[[Media:$1|$1]]''' дегенді [$3, $2 кезіндегі $4 нұсқасына] қайтарудасыз.",
        "filerevert-comment": "Себебі:",
-       "filerevert-defaultcomment": "$2, $1 кезіндегі нұсқасына қайтарылды",
+       "filerevert-defaultcomment": "$2, $1 ($3) кезіндегі нұсқасына қайтарылды",
        "filerevert-submit": "Қайтару",
        "filerevert-success": "'''[[Media:$1|$1]]''' деген [$3, $2 кезіндегі $4 нұсқасына] қайтарылды.",
        "filerevert-badversion": "Келтірілген уақыт белгісімен бұл файлдың алдыңғы жергілікті нұсқасы жоқ.",
        "unusedimages": "Пайдаланылмаған файлдар",
        "wantedcategories": "Басталмаған санаттар",
        "wantedpages": "Басталмаған беттер",
-       "wantedpages-summary": "Оларға тек бағыттап сілтейтін беттерді қоспағанда, өте көп сілтенген жоқ беттер тізімі. Оларға бағыттап жоқ беттерге сілтейтін тізім үшін келесі бетті қараңыз: [[{{#special:BrokenRedirects}}]].",
+       "wantedpages-summary": "Оларға тек бағыттап сілтейтін беттерді қоспағанда, өте көп сілтенген әзірге басталмаған беттер тізімі. Жойылған беттерге сілтейтін тізім үшін келесі бетті қараңыз: [[{{#special:BrokenRedirects}}|жарамсыз айдағыштар тізімі]].",
        "wantedpages-badtitle": "Нәтиже жиынындағы жарамсыз атау: $1",
        "wantedfiles": "Басталмаған файлдар",
        "wantedfiletext-cat": "Келесі файлдар қолданылған бірақ жоқ. Бар болғанына қарамастан файлдар сыртқы қорларда тізімделген болуы мүмкін. Кез келген осындай жарамсыз боямалар <del>үстінен сызылып</del> белгіленеді. Сонымен қатар, бар емес файлдарды ендіру беттері [[:$1]] бетінде тізімделген.",
        "listusers-noresult": "Қатысушы табылған жоқ.",
        "listusers-blocked": "(бұғатталған)",
        "activeusers": "Белсенді қатысушылар тізімі",
-       "activeusers-intro": "Ð\91ұл Ñ\82Ñ\96зÑ\96м Ñ\81оңÒ\93Ñ\8b $1 {{PLURAL:$1|күнде|күнде}} Ò\9bандай Ð´Ð° Ð±Ñ\96Ñ\80 Ñ\96Ñ\81\99Ñ\80екеÑ\82 Ð¶Ð°Ñ\81аÒ\93ан Ò\9bаÑ\82Ñ\8bÑ\81Ñ\83Ñ\88Ñ\8bлаÑ\80 Ñ\82Ñ\96зÑ\96мÑ\96.",
+       "activeusers-intro": "Бұл соңғы $1 {{PLURAL:$1|күнде|күнде}} қандай да бір іс-әрекет жасаған қатысушылар тізімі.",
        "activeusers-count": "соңғы {{PLURAL:$3|күнде|$3 күнде}} $1 {{PLURAL:$1|әрекет|әрекет}}",
        "activeusers-from": "Мынадан басталатын қатысушыларды көрсет:",
        "activeusers-hidebots": "Боттарды жасыру",
        "wlnote": "Төменде $3, $4 кезіне дейінгі соңғы {{PLURAL:$2|сағатта|<strong>$2</strong>  сағатта}} болған, {{PLURAL:$1|жуықтағы өзгеріс|жуықтағы <strong>$1</strong>  өзгеріс}} көрсетіледі.",
        "wlshowlast": "Соңғы $1 сағаттағы, $2 күндегіні көрсету",
        "watchlistall2": "барлық",
+       "watchlist-hide": "Жасыру",
+       "wlshowtime": "Соңғысын көрсету:",
+       "wlshowhideminor": "шағын өңдемелер",
+       "wlshowhidebots": "боттар",
+       "wlshowhideliu": "тіркелген қатысушылар",
+       "wlshowhideanons": "анонимді қатысушылар",
+       "wlshowhidepatr": "тексерілген өңдемелер",
+       "wlshowhidemine": "өңдемелерім",
        "watchlist-options": "Бақылау тізімінің баптаулары",
        "watching": "Бақылауда…",
        "unwatching": "Бақыламауда…",
        "deletepage": "Бетті жою",
        "confirm": "Құптау",
        "excontent": "болған мағлұматы: $1",
-       "excontentauthor": "болған мағлұматы (тек «[[Special:Contributions/$2|$2]]» үлесі): $1",
+       "excontentauthor": "болған мағлұматы: «$1» және тек «[[Special:Contributions/$2|$2]]» ([[User talk:$2|талқ]]) үлесі",
        "exbeforeblank": "тазарту алдындағы болған мағлұматы: $1",
        "delete-confirm": "«$1» дегенді жою",
        "delete-legend": "Жою",
        "contributions": "{{GENDER:$1|Қатысушы}} үлестері",
        "contributions-title": "$1 есімді қатысушының үлесі",
        "mycontris": "Үлесім",
+       "anoncontribs": "Үлесім",
        "contribsub2": "{{GENDER:$3|$1}} ($2) үлесі",
        "contributions-userdoesnotexist": "«$1» қатысушы акаунты тіркелмеді.",
        "nocontribs": "Осы іздеу шартына сәйкес өзгерістер табылған жоқ.",
        "cant-move-to-user-page": "Бетті қатысушы бетіне жылжытуға рұқсатыңыз жоқ (төменгі беттерін қоспағанда).",
        "cant-move-category-page": "Сізде санат беттерінің атауын өзгертуге рұқсатыңыз жоқ.",
        "cant-move-to-category-page": "Сізде бетті санат бетіне жылжытуға рұқсатыңыз жоқ.",
-       "newtitle": "Ð\96аңа Ð±ÐµÑ\82 Ð°Ñ\82аÑ\83Ñ\8b:",
+       "newtitle": "Жаңа атауы:",
        "move-watch": "Бұл бетті бақылау",
        "movepagebtn": "Бетті жылжыту",
        "pagemovedsub": "Бет жылжытылды",
        "movenosubpage": "Бұл бетте төменгі беттері жоқ.",
        "movereason": "Жылжытудың себебі:",
        "revertmove": "қайтару",
-       "delete_and_move": "Жою және жылжыту",
        "delete_and_move_text": "== Жоюды қажет етеді ==\nТағайындалған «[[:$1]]» беті әлдеқашан бар.\nЖылжытуға жол беру үшін бұны жойғыңыз келе ме?",
        "delete_and_move_confirm": "Иә, бұл бетті жой",
        "delete_and_move_reason": "«[[$1]]» дегеннен жылжытуға жол беру үшін жойылған",
        "tooltip-pt-preferences": "Бапталымдарым",
        "tooltip-pt-watchlist": "Өзгерістерін бақылап тұрған беттер тізімім.",
        "tooltip-pt-mycontris": "Өңдеулеріңіздің тізімі",
+       "tooltip-pt-anoncontribs": "Бұл IP мекенжаймен жасаған өңдемелер тізімі",
        "tooltip-pt-login": "Кіруіңізді ұсынамыз, ол міндетті емес.",
        "tooltip-pt-logout": "Шығу",
        "tooltip-pt-createaccount": "Біз сізге есептік жазба бастауды және кіруді ұсынамыз,ол міндетті емес.",
        "tooltip-ca-nstab-main": "Мағлұмат бетін қарау",
        "tooltip-ca-nstab-user": "Қатысушы бетін қарау",
        "tooltip-ca-nstab-media": "Медиа бетін қарау",
-       "tooltip-ca-nstab-special": "Ð\91ұл Ð°Ñ\80найÑ\8b Ð±ÐµÑ\82, Ð±ÐµÑ\82Ñ\82Ñ\96Ò£ Ó©Ð·Ñ\96 Ó©Ò£Ð´ÐµÐ»Ñ\96нбейді.",
+       "tooltip-ca-nstab-special": "Ð\91ұл Ð°Ñ\80найÑ\8b Ð±ÐµÑ\82, Ð¾Ð» Ó©Ò£Ð´ÐµÐ»Ð¼ейді.",
        "tooltip-ca-nstab-project": "Жоба бетін қарау",
        "tooltip-ca-nstab-image": "Файл бетін қарау",
        "tooltip-ca-nstab-mediawiki": "Жүйе хабарын қарау",
        "logentry-newusers-byemail": "$1 $3 деген аккаунт {{GENDER:$2|тіркеді}} және құпия сөзі е-пошта арқылы жіберілді",
        "logentry-newusers-autocreate": "$1 қатысушы аккаунтын автоматты түрде {{GENDER:$2|тіркеді}}",
        "logentry-protect-move_prot": "$1 protection settings from $4 дегеннен $3 дегенге қорғалу баптауларын {{GENDER:$2|жылжытты}}",
+       "logentry-protect-protect": "$1 $3 бетін {{GENDER:$2|қорғады}}  $4",
        "logentry-rights-rights": "$1 $3 үшін топ мүшелігін $4 дегеннен $5 дегенге {{GENDER:$2|өзгертті}}",
        "logentry-rights-rights-legacy": "$1 $3 үшін топ мүшелігін {{GENDER:$2|өзгертті}}",
        "logentry-rights-autopromote": "$1 $4 дегенен $5 дегенге автоматты түрде {{GENDER:$2|деңгейі көтерілген}}",
index 757e294..19e3a20 100644 (file)
        "nstab-template": "ಟೆಂಪ್ಲೇಟು",
        "nstab-help": "ಸಹಾಯ",
        "nstab-category": "ವರ್ಗ",
+       "mainpage-nstab": "ಮುಖ್ಯ ಪುಟ",
        "nosuchaction": "ಆ ರೀತಿಯ ಕೃತ್ಯ ಯಾವುದೂ ಇಲ್ಲ",
        "nosuchactiontext": "ಈ URL ನೇಮಿಸಿದ ಕೃತ್ಯವು ಈ ವಿಕಿಯಿಂದ ಗುರುತಿಸಬಲ್ಲದಲ್ಲ",
        "nosuchspecialpage": "ಆ ಹೆಸರಿನ ವಿಶೇಷ ಪುಟ ಇಲ್ಲ",
        "passwordreset-username": "ಬಳಕೆದಾರ ಹೆಸರು:",
        "passwordreset-domain": "ಕ್ಷೇತ್ರ:",
        "passwordreset-email": "ಇ-ಮೇಲ್ ವಿಳಾಸ:",
-       "passwordreset-emailsent": "ಪ್ರವೇಶಪದವನ್ನು ಪುನಃಸ್ಥಾಪಿಸಿದ ಮಿಂಚಂಚೆಯನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.",
+       "passwordreset-emailsentemail": "ಪ್ರವೇಶಪದವನ್ನು ಪುನಃಸ್ಥಾಪಿಸಿದ ಮಿಂಚಂಚೆಯನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.",
        "passwordreset-emailsent-capture": "ಪ್ರವೇಶಪದವನ್ನು ಪುನಃಸ್ಥಾಪಿಸಿದ ಮಿಂಚಂಚೆಯನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ,ಇದನ್ನು ಈ ಕೆಳಗೆ ತೋರಿಸಲಾಗಿದೆ.",
        "changeemail": "ಮಿಂಚಂಚೆ ವಿಳಾಸವನ್ನು ಬದಲಾಯಿಸಿ",
        "changeemail-no-info": "ನೀವು ಈ ಪುಟವನ್ನು ನೇರತಲುಪಲು ಲಾಗಿನ್ ಆಗಿರುವುದು ಆವಶ್ಯಕ.",
        "movelogpagetext": "ಸ್ಥಳಾಂತರಿಸಲಾಗಿರುವ ಪುಟಗಳ ಪಟ್ಟಿ ಕೆಳಗಿದೆ.",
        "movereason": "ಕಾರಣ:",
        "revertmove": "ಹಿಂದಿನಂತಾಗಿಸು",
-       "delete_and_move": "ಅಳಿಸು ಮತ್ತು ಸ್ಥಳಾಂತರಿಸು",
        "delete_and_move_text": "==ಅಳಿಸುವಿಕೆ ಬೇಕಾಗಿದೆ==\nಸ್ಥಳಾಂತರಿಬೇಕೆಂದಿರುವ ಪುಟ \"[[:$1]]\" ಆಗಲೆ ಅಸ್ಥಿತ್ವದಲ್ಲಿ ಇದೆ.\nಸ್ಥಳಾಂತರಿಕೆಗೆ ಜಾಗ ಮಾಡಲು ಆ ಪುಟವನ್ನು ಅಳಿಸಬೇಕೆ?",
        "delete_and_move_confirm": "ಹೌದು, ಪುಟವನ್ನು ಅಳಿಸಿ",
        "delete_and_move_reason": "ಸ್ಥಳಾಂತರಿಕೆಗೆ ಜಾಗ ಮಾಡಲು ಪುಟವನ್ನು ಅಳಿಸಲಾಯಿತು",
index 7530cd4..6bb04e9 100644 (file)
@@ -54,7 +54,8 @@
                        "Hwangjy9",
                        "Kurousagi",
                        "Macofe",
-                       "Yearning"
+                       "Yearning",
+                       "고솜"
                ]
        },
        "tog-underline": "링크에 밑줄:",
        "morenotlisted": "이 목록은 완성되지 않았습니다.",
        "mypage": "문서",
        "mytalk": "토론",
-       "anontalk": "이 IP 주소의 사용자와 토론",
+       "anontalk": "토론",
        "navigation": "둘러보기",
        "and": ",",
        "qbfind": "찾기",
        "missing-article": "데이터베이스에서 \"$1\" 문서의 $2 텍스트를 찾지 못했습니다.\n\n삭제된 문서의 오래된 차이나 역사 링크를 보려고 시도할 때 이러한 문제가 발생할 수 있습니다.\n\n그렇지 않다면, 소프트웨어에 버그가 발생했을 수도 있습니다.\n[[Special:ListUsers/sysop|관리자]]에게 URL을 참조하여 알려주세요.",
        "missingarticle-rev": "(판번호: $1)",
        "missingarticle-diff": "(차이: $1, $2)",
-       "readonly_lag": "슬레이브 데이터베이스가 마스터 서버의 자료를 새로 고치는 중입니다. 데이터베이스가 자동으로 잠겨 있습니다.",
+       "readonly_lag": "슬레이브 데이터베이스가 마스터 서버의 자료를 새로 고치는 중입니다. 데이터베이스가 자동으로 잠겨져 있습니다",
        "internalerror": "내부 오류",
        "internalerror_info": "내부 오류: $1",
        "internalerror-fatal-exception": "종류 \"$1\"에서 심각한 오류",
        "passwordreset-emailtext-ip": "$1 IP 주소를 사용하는 누군가가 아마 자신이 {{SITENAME}} ($4)의 비밀번호 재설정을 요청하였습니다.\n이 이메일 주소와 연관된 {{PLURAL:$3|계정}}의 목록입니다:\n\n$2\n\n{{PLURAL:$3|이 임시 비밀번호}}는 {{PLURAL:$5|$5일}} 후에 만료됩니다.\n이 비밀번호로 로그인한 후 비밀번호를 바꾸십시오. 만약 당신이 아닌 다른 사람이 요청하였거나,\n원래의 비밀번호를 기억해냈다면, 이 메시지를 무시하고\n이전의 비밀번호를 계속 사용할 수 있습니다.",
        "passwordreset-emailtext-user": "{{SITENAME}} ($4)의 사용자 $1이 비밀번호 재설정을 요청하였습니다.\n이 이메일 주소와 연관된 {{PLURAL:$3|계정}}의 목록입니다:\n\n$2\n\n{{PLURAL:$3|이 임시 비밀번호}}는 {{PLURAL:$5|$5일}} 후에 만료됩니다.\n이 비밀번호로 로그인한 후 비밀번호를 바꾸십시오. 만약 당신이 아닌 다른 사람이 요청하였거나,\n원래의 비밀번호를 기억해냈다면, 이 메시지를 무시하고\n이전의 비밀번호를 계속 사용할 수 있습니다.",
        "passwordreset-emailelement": "사용자 이름: \n$1\n\n임시 비밀번호: \n$2",
-       "passwordreset-emailsent": "당신의 계정에 등록된 이메일 주소가 있다면, 비밀번호 재설정 메일이 전해질 것입니다.",
+       "passwordreset-emailsentemail": "당신의 계정에 등록된 이메일 주소가 있다면, 비밀번호 재설정 메일이 전해질 것입니다.",
        "passwordreset-emailsent-capture": "비밀번호 재설정 이메일이 발송되었으며, 아래에 나타나 있습니다.",
        "passwordreset-emailerror-capture": "비밀번호 재설정 이메일이 생성되어 아래에 보여져 있지만, {{GENDER:$2|사용자}}에게 발송하는 데에는 실패했습니다: $1",
        "changeemail": "이메일 주소를 바꾸거나 제거하기",
        "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: $2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "autoblockedtext": "당신의 IP 주소는 $1 사용자가 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:$2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "blockednoreason": "이유를 입력하지 않음",
-       "whitelistedittext": "문서를 편집하기 전에  $1해야 합니다.",
+       "whitelistedittext": "문서를 편집하기 전에 $1해야 합니다.",
        "confirmedittext": "문서를 고치려면 이메일 인증 절차가 필요합니다.\n[[Special:Preferences|사용자 환경 설정]]에서 이메일 주소를 입력하고 이메일 주소 인증을 해주시기 바랍니다.",
        "nosuchsectiontitle": "문단을 찾을 수 없음",
        "nosuchsectiontext": "존재하지 않는 문단을 편집하려 했습니다.\n이 문서를 보는 동안 문단이 이동되었거나 삭제되었을 수 있습니다.",
        "copyrightwarning2": "{{SITENAME}}에서의 모든 기여는 다른 사용자가 편집, 수정, 삭제할 수 있다는 점을 유의해 주세요.\n만약 여기에 동의하지 않는다면, 문서를 저장하지 말아 주세요.<br />\n또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다 (자세한 내용에 대해서는 $1 문서를 읽어 주세요).\n'''저작권이 있는 내용을 허가 없이 저장하지 마세요!'''",
        "editpage-cannot-use-custom-model": "이 문서의 콘텐츠 모델은 변경될 수 없습니다.",
        "longpageerror": "'''오류: 문서의 크기가 {{PLURAL:$1|$1킬로바이트}}로 최대 크기인 {{PLURAL:$2|$2킬로바이트}}보다 큽니다.'''\n저장할 수 없습니다.",
-       "readonlywarning": "'''경고: 데이터베이스가 관리를 위해 잠겨 있습니다. 따라서 문서를 편집한 내용을 지금 저장할 수 없습니다.'''\n편집 내용을 복사하여 붙여넣기 등을 사용하여 일단 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.\n\n잠근 관리자가 남긴 설명은 다음과 같습니다: $1",
+       "readonlywarning": "<strong>경고: 데이터베이스가 관리를 위해 잠겨 있습니다. 따라서 문서를 편집한 내용을 지금 저장할 수 없습니다.</strong>\n편집 내용을 복사하여 붙여넣기 등을 사용하여 일단 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.\n\n잠근 관리자가 남긴 설명은 다음과 같습니다: $1",
        "protectedpagewarning": "<strong>경고: 이 문서는 관리자 권한이 있는 사용자만 편집할 수 있도록 보호되어 있습니다.</strong>\n이 문서의 최근 기록을 참조하십시오:",
-       "semiprotectedpagewarning": "<strong>참고:</strong> 이 문서는 계정을 등록한 사용자만이 편집할 수 있도록 잠겨 있습니다.\n이 문서의 최근 기록을 참조하십시오:",
-       "cascadeprotectedwarning": "<strong>경고:</strong> 이 문서는 잠겨 있어 관리자만 편집할 수 있습니다. 연쇄적 보호가 걸린 다음 {{PLURAL:$1|문서}}에서 이 문서를 사용하고 있습니다:",
-       "titleprotectedwarning": "<strong>경고: 이 문서는 잠겨 있어, 문서를 만드려면 [[Special:ListGroupRights|특정 권한]]이 필요합니다.</strong>\n아래 문서의 최근 기록을 참조하십시오:",
+       "semiprotectedpagewarning": "<strong>참고:</strong> 이 문서는 계정을 등록한 사용자만이 편집할 수 있도록 보호되어 있습니다.\n이 문서의 최근 기록을 참조하십시오:",
+       "cascadeprotectedwarning": "<strong>경고:</strong> 이 문서는 보호되어 있어 관리자만 편집할 수 있습니다. 연쇄적 보호가 걸린 다음 {{PLURAL:$1|문서}}에서 이 문서를 사용하고 있습니다:",
+       "titleprotectedwarning": "<strong>경고: 이 문서는 보호되어 있어, 문서를 만드려면 [[Special:ListGroupRights|특정한 권한]]이 필요합니다.</strong>\n아래 문서의 최근 기록을 참조하십시오:",
        "templatesused": "이 문서에서 사용한 {{PLURAL:$1|틀}}:",
        "templatesusedpreview": "이 미리 보기에서 사용하고 있는 {{PLURAL:$1|틀}}:",
        "templatesusedsection": "이 문단에서 사용하고 있는 {{PLURAL:$1|틀}}:",
        "permissionserrors": "권한 오류",
        "permissionserrorstext": "해당 명령을 수행할 권한이 없습니다. 다음 {{PLURAL:$1|이유}}를 확인해보세요:",
        "permissionserrorstext-withaction": "$2 권한이 없습니다. 다음 {{PLURAL:$1|이유}}를 확인해주세요:",
-       "recreate-moveddeleted-warn": "<strong>경고: ì\82­ì \9cë\90\9c ë¬¸ì\84\9c를 ë\8b¤ì\8b\9c ë§\8cë\93¤ê³  ì\9e\88ì\8aµë\8b\88ë\8b¤.</strong>\n\nì\9d´ ë¬¸ì\84\9c를 ê³\84ì\86\8d í\8e¸ì§\91í\95\98ë\8a\94 ê²\83ì\9d´ ì \81í\95©í\95\9c ê²\83ì\9d¸ì§\80 í\99\95ì\9d¸í\95´ì£¼ì\84¸ì\9a\94.\ní\8e¸ì\9d\98를 ì\9c\84í\95´ ì\82­ì \9cì\99\80 ì\98®ê¸°ê¸° 기록을 다음과 같이 제공합니다:",
+       "recreate-moveddeleted-warn": "<strong>경고: ì\82­ì \9cë\90\9c ë¬¸ì\84\9c를 ë\8b¤ì\8b\9c ë§\8cë\93¤ê³  ì\9e\88ì\8aµë\8b\88ë\8b¤.</strong>\n\nì\9d´ ë¬¸ì\84\9c를 ê³\84ì\86\8d í\8e¸ì§\91í\95\98ë\8a\94 ê²\83ì\9d´ ì \81í\95©í\95\9c ê²\83ì\9d¸ì§\80 í\99\95ì\9d¸í\95´ì£¼ì\84¸ì\9a\94.\ní\8e¸ì\9d\98를 ì\9c\84í\95´ ì\82­ì \9cì\99\80 ì\9d´ë\8f\99 기록을 다음과 같이 제공합니다:",
        "moveddeleted-notice": "이 문서는 삭제되었습니다.\n이 문서의 삭제 및 이동 기록은 다음과 같습니다.",
        "moveddeleted-notice-recent": "죄송합니다, 이 문서는 최근 (24시간 내)에 삭제된 적이 있습니다.\n삭제와 이동 기록이 참고를 위해 남겨져 있습니다.",
        "log-fulllog": "전체 기록 보기",
        "powersearch-togglenone": "모두 제외",
        "powersearch-remember": "향후 검색에 선택 기억하기",
        "search-external": "바깥 검색",
-       "searchdisabled": "{{SITENAME}} 검색이 비활성화되어 있습니다.\n검색이 작동하지 않는 동안에는 Google을 통해 검색할 수 있습니다.\n검색 엔진의 내용은 최신이 아닐 수 있다는 점을 참고하세요.",
+       "searchdisabled": "{{SITENAME}} 검색이 비활성화되어 있습니다.\n검색이 작동하지 않는 동안 Google을 통해 검색할 수 있습니다.\n검색 엔진의 내용은 최신이 아닐 수 있다는 점을 참고하세요.",
        "search-error": "검색하는 동안 오류가 발생했습니다: $1",
        "preferences": "사용자 환경 설정",
        "mypreferences": "환경 설정",
        "right-createtalk": "토론 문서 만들기",
        "right-createaccount": "새 사용자 계정 만들기",
        "right-minoredit": "사소한 편집으로 표시",
-       "right-move": "문ì\84\9c ì\98®ê¸°ê¸°",
-       "right-move-subpages": "문ì\84\9cì\99\80 í\95\98ì\9c\84 ë¬¸ì\84\9c ì\98®ê¸°기",
-       "right-move-rootuserpages": "ìµ\9cì\83\81ì\9c\84 ì\82¬ì\9a©ì\9e\90 ë¬¸ì\84\9c ì\98®ê¸°ê¸°",
-       "right-move-categorypages": "ë¶\84ë¥\98 ë¬¸ì\84\9c ì\98®ê¸°ê¸°",
+       "right-move": "문ì\84\9c ì\9d´ë\8f\99",
+       "right-move-subpages": "문ì\84\9cì\99\80 í\95\98ì\9c\84 ë¬¸ì\84\9c ì\9d´ë\8f\99í\95\98기",
+       "right-move-rootuserpages": "ìµ\9cì\83\81ì\9c\84 ì\82¬ì\9a©ì\9e\90 ë¬¸ì\84\9c ì\9d´ë\8f\99",
+       "right-move-categorypages": "ë¶\84ë¥\98 ë¬¸ì\84\9c ì\9d´ë\8f\99",
        "right-movefile": "파일 옮기기",
        "right-suppressredirect": "문서을 옮길 때 원래 문서 이름으로 된 넘겨주기를 만들지 않기",
        "right-upload": "파일 올리기",
        "action-history": "이 문서의 역사 보기",
        "action-minoredit": "이 편집을 사소한 편집으로 표시하기",
        "action-move": "이 문서 옮기기",
-       "action-move-subpages": "ì\9d´ ë¬¸ì\84\9cì\99\80 í\95\98ì\9c\84 ë¬¸ì\84\9c를 í\95¨ê»\98 ì\98®ê¸°기",
+       "action-move-subpages": "ì\9d´ ë¬¸ì\84\9cì\99\80 í\95\98ì\9c\84 ë¬¸ì\84\9c를 í\95¨ê»\98 ì\9d´ë\8f\99í\95\98기",
        "action-move-rootuserpages": "최상위 사용자 문서를 이동할",
        "action-move-categorypages": "분류 문서 옮기기",
        "action-movefile": "이 파일을 옮기기",
        "upload_directory_missing": "파일 올리기용 디렉터리($1)가 없고 웹 서버가 만들지 못했습니다.",
        "upload_directory_read_only": "파일 저장 디렉터리($1)에 쓰기 권한이 없습니다.",
        "uploaderror": "올리기 오류",
-       "upload-recreate-warning": "<strong>경고: í\95´ë\8b¹ ì\9d´ë¦\84ì\9c¼ë¡\9c ë\90\9c í\8c\8cì\9d¼ì\9d´ ì\82­ì \9cë\90\98ì\97\88ê±°ë\82\98 ì\98®ê²¨ì¡\8cì\8aµë\8b\88ë\8b¤.</strong>\n\ní\8e¸ì\9d\98를 ì\9c\84í\95´ ì\9d´ ë¬¸ì\84\9cì\97\90 ë\8c\80í\95\9c ì\82­ì \9cì\99\80 ì\98®ê¸°ê¸° 기록을 다음과 같이 제공합니다:",
+       "upload-recreate-warning": "<strong>경고: í\95´ë\8b¹ ì\9d´ë¦\84ì\9c¼ë¡\9c ë\90\9c í\8c\8cì\9d¼ì\9d´ ì\82­ì \9cë\90\98ì\97\88ê±°ë\82\98 ì\9d´ë\8f\99ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤.</strong>\n\ní\8e¸ì\9d\98를 ì\9c\84í\95´ ì\9d´ ë¬¸ì\84\9cì\97\90 ë\8c\80í\95\9c ì\82­ì \9cì\99\80 ì\9d´ë\8f\99 기록을 다음과 같이 제공합니다:",
        "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
        "upload-permitted": "허용된 파일 {{PLURAL:$2|형식}}: $1",
        "upload-preferred": "권장 파일 {{PLURAL:$2|형식}}: $1",
        "newpages-username": "사용자 이름:",
        "ancientpages": "오래된 문서 목록",
        "move": "이동",
-       "movethispage": "ì\9d´ ë¬¸ì\84\9c ì\98®ê¸°기",
+       "movethispage": "ì\9d´ ë¬¸ì\84\9c ì\9d´ë\8f\99í\95\98기",
        "unusedimagestext": "다음은 어떠한 문서도 사용하지 않는 파일의 목록입니다.\n다른 사이트에서 URL 접근을 통해 파일을 사용할 수 있기 때문에, 아래 목록에 있는 파일도 실제로 사용 중일 가능성이 있다는 점을 주의해주세요.",
        "unusedcategoriestext": "사용하지 않는 분류 문서의 목록입니다.",
        "notargettitle": "해당하는 문서 없음",
        "delete-edit-reasonlist": "삭제 이유 편집",
        "delete-toobig": "이 문서에는 {{PLURAL:$1|편집 역사}}가 $1개 이상 있습니다.\n{{SITENAME}}에 의도하지 않은 혼란을 줄 수 있기 때문에 이런 문서의 삭제는 제한됩니다.",
        "delete-warning-toobig": "이 문서에는 {{PLURAL:$1|편집 역사}}가 $1개 있습니다.\n편집 역사가 긴 문서를 삭제하면 {{SITENAME}} 데이터베이스 동작에 큰 영향을 줄 수 있습니다.\n주의해 주세요.",
-       "deleteprotected": "이 문서가 잠겨 있기 때문에 삭제할 수 없습니다.",
+       "deleteprotected": "이 문서가 보호되어 있기 때문에 삭제할 수 없습니다.",
        "deleting-backlinks-warning": "'''경고:''' 삭제하려는 문서가 [[Special:WhatLinksHere/{{FULLPAGENAME}}|다른 문서]]에 링크되어 있거나 끼워져 있습니다.",
        "rollback": "편집 되돌리기",
        "rollbacklink": "되돌리기",
        "maximum-size": "최대 크기:",
        "pagesize": "(바이트)",
        "restriction-edit": "편집",
-       "restriction-move": "ì\98®ê¸°ê¸°",
+       "restriction-move": "ì\9d´ë\8f\99",
        "restriction-create": "만들기",
        "restriction-upload": "올리기",
        "restriction-level-sysop": "보호됨",
        "contributions": "{{GENDER:$1|사용자}} 기여",
        "contributions-title": "$1 사용자의 기여",
        "mycontris": "기여",
+       "anoncontribs": "기여",
        "contribsub2": "{{GENDER:$3|$1}}($2)의 기여",
        "contributions-userdoesnotexist": "\"$1\" 사용자 계정은 등록되어 있지 않습니다.",
        "nocontribs": "지정한 조건과 일치하는 바뀜을 찾을 수 없습니다.",
        "lockfilenotwritable": "데이터베이스 잠금 파일에 쓰기 권한이 없습니다.\n데이터베이스를 잠그거나 잠금 해제하려면, 웹 서버에서 이 파일의 쓰기 권한을 설정해야 합니다.",
        "databasenotlocked": "데이터베이스가 잠겨 있지 않습니다.",
        "lockedbyandtime": "({{GENDER:$1|$1}} 사용자가 $2 $3에 잠금)",
-       "move-page": "$1 ì\98®ê¸°ê¸°",
-       "move-page-legend": "문ì\84\9c ì\98®ê¸°ê¸°",
+       "move-page": "$1 ì\9d´ë\8f\99",
+       "move-page-legend": "문ì\84\9c ì\9d´ë\8f\99",
        "movepagetext": "아래 양식을 채워 문서의 이름을 바꾸고 모든 역사를 새 이름으로 된 문서로 옮길 수 있습니다.\n원래의 문서는 새 문서로 넘겨주는 링크로만 남게 되고,\n원래 이름을 가리키는 넘겨주기는 자동으로 갱신됩니다.\n만약 이 설정을 선택하지 않았다면 [[Special:DoubleRedirects|이중 넘겨주기]]와 [[Special:BrokenRedirects|끊긴 넘겨주기]]를 확인해주세요.\n당신은 링크와 가리키는 대상이 서로 일치하도록 해야 할 책임이 있습니다.\n\n만약 이미 있는 문서의 이름을 새 이름으로 입력했을 때는 그 문서가 넘겨주기 문서이고 문서 역사가 없어야만 이동이 됩니다. 그렇지 않을 경우에는 이동되지 <strong>않습니다</strong>.\n이것은 실수로 이동한 문서를 되돌릴 수는 있지만, 이미 존재하는 문서 위에 덮어씌울 수는 없다는 것을 의미합니다.\n\n<strong>주의!</strong>\n자주 사용하는 문서를 이동하면 해결하기 어려운 문제를 일으킬 수도 있습니다.\n이동하기 전에 반드시 이 문서를 이동해도 문제가 없는지 확인해주세요.",
        "movepagetext-noredirectfixer": "아래 양식을 채워 문서의 이름을 바꾸고 모든 역사를 새 이름으로 된 문서로 옮길 수 있습니다.\n원래의 문서는 새 문서로 넘겨주는 링크로만 남게 됩니다.\n[[Special:DoubleRedirects|이중 넘겨주기]]와 [[Special:BrokenRedirects|끊긴 넘겨주기]]를 확인해주세요.\n당신은 링크와 가리키는 대상이 서로 일치하도록 해야 할 책임이 있습니다.\n\n만약 이미 있는 문서의 이름을 새 이름으로 입력했을 때는 그 문서가 넘겨주기 문서이고 문서 역사가 없어야만 이동이 됩니다. 그렇지 않을 경우에는 이동되지 <strong>않습니다</strong>.\n이것은 실수로 옮긴 문서를 되돌릴 수는 있지만, 이미 존재하는 문서 위에 덮어씌울 수는 없다는 것을 의미합니다.\n\n<strong>주의!</strong>\n자주 사용하는 문서를 이동하면 해결하기 어려운 문제를 일으킬 수도 있습니다.\n이동하기 전에 반드시 이 문서를 이동해도 문제가 없는지 확인해주세요.",
        "movepagetalktext": "체크하면, 딸린 토론 문서가 자동으로 옮겨집니다. 다만, 비어있지 않은 토론 문서가 있다면 옮겨지지 않습니다.\n\n이러한 경우에는, 수동으로 옮기거나 합쳐야 합니다.",
        "cant-move-to-category-page": "문서를 분류 문서로 옮길 권한이 없습니다.",
        "newtitle": "새 제목:",
        "move-watch": "원래 문서와 대상 문서를 주시하기",
-       "movepagebtn": "문ì\84\9c ì\98®ê¸°ê¸°",
-       "pagemovedsub": "ì\98®ê¸°ê¸° 성공",
+       "movepagebtn": "문ì\84\9c ì\9d´ë\8f\99",
+       "pagemovedsub": "ì\9d´ë\8f\99 성공",
        "movepage-moved": "'''\"$1\" 문서를 \"$2\" 문서로 옮겼습니다.'''",
        "movepage-moved-redirect": "넘겨주기 문서를 만들었습니다.",
        "movepage-moved-noredirect": "넘겨주기 문서를 남기지 않았습니다.",
        "articleexists": "문서가 이미 존재하거나 이름이 올바르지 않습니다.\n다른 이름을 선택하세요.",
        "cantmove-titleprotected": "새로운 제목으로 문서를 만드는 것이 금지되어 있어 문서를 옮길 수 없습니다",
-       "movetalk": "ë\94¸ë¦° í\86 ë¡  ë¬¸ì\84\9cë\8f\84 ì\98®ê¸°기",
+       "movetalk": "ë\94¸ë¦° í\86 ë¡  ë¬¸ì\84\9cë\8f\84 ì\9d´ë\8f\99í\95\98기",
        "move-subpages": "하위 문서도 옮기기 ($1개까지)",
-       "move-talk-subpages": "í\86 ë¡  ë¬¸ì\84\9cì\9d\98 í\95\98ì\9c\84 ë¬¸ì\84\9cë\8f\84 ì\98®ê¸°기 ($1개까지)",
+       "move-talk-subpages": "í\86 ë¡  ë¬¸ì\84\9cì\9d\98 í\95\98ì\9c\84 ë¬¸ì\84\9cë\8f\84 ì\9d´ë\8f\99í\95\98기 ($1개까지)",
        "movepage-page-exists": "$1 문서가 이미 존재하므로 자동으로 덮어쓸 수 없습니다.",
        "movepage-page-moved": "\"$1\" 문서를 \"$2\" 문서로 옮겼습니다.",
        "movepage-page-unmoved": "$1 문서를 $2 문서로 옮길 수 없습니다.",
        "movenosubpage": "이 문서에는 하위 문서가 존재하지 않습니다.",
        "movereason": "이유:",
        "revertmove": "되돌리기",
-       "delete_and_move": "삭제하고 옮기기",
        "delete_and_move_text": "== 삭제 필요 ==\n이동하려는 제목으로 된 \"[[:$1]]\" 문서가 이미 존재합니다.\n삭제하고 이동할까요?",
        "delete_and_move_confirm": "네. 문서를 삭제합니다",
        "delete_and_move_reason": "\"[[$1]]\"에서 문서를 이동하기 위해 삭제함",
        "imageinvalidfilename": "새 파일 이름이 잘못되었습니다.",
        "fix-double-redirects": "원래 제목을 가리키는 넘겨주기를 새로 고침",
        "move-leave-redirect": "옮긴 뒤 넘겨주기를 남기기",
-       "protectedpagemovewarning": "<strong>경고:</strong> 이 문서는 관리자만 이동할 수 있도록 잠겨 있습니다.\n최근 기록을 참조를 위해 아래에 제공합니다:",
-       "semiprotectedpagemovewarning": "<strong>참고:</strong> 이 문서는 등록된 사용자만이 이동할 수 있도록 ì\9e ê²¨ ì\9e\88ì\8aµë\8b\88ë\8b¤.\nìµ\9cê·¼ ê¸°ë¡\9d ë\82´ì\9a©ì\9d\84 ì°¸ì¡°ë¥¼ ì\9c\84í\95´ ì\95\84ë\9e\98ì\97\90 ì \9cê³µí\95©ë\8b\88ë\8b¤:",
+       "protectedpagemovewarning": "<strong>경고:</strong> 이 문서는 관리자만 이동할 수 있도록 보호되어 있습니다.\n최근 기록을 참조를 위해 아래에 제공합니다:",
+       "semiprotectedpagemovewarning": "<strong>참고:</strong> 이 문서는 등록된 사용자만이 이동할 수 있도록 ë³´í\98¸ë\90\98ì\96´ ì\9e\88ì\8aµë\8b\88ë\8b¤.\nìµ\9cê·¼ ê¸°ë¡\9d ë\82´ì\9a©ì\9d´ ì°¸ì¡°ë¥¼ ì\9c\84í\95´ ì\95\84ë\9e\98ì\97\90 ì \9cê³µë\90©ë\8b\88ë\8b¤:",
        "move-over-sharedrepo": "== 파일이 존재함 ==\n[[:$1]] 파일이 공용 저장소에 있습니다. 이 이름으로 파일을 옮기면 공용의 파일을 덮어쓰게 될 것입니다.",
        "file-exists-sharedrepo": "선택한 파일 이름은 공용 저장소에서 사용 중입니다.\n다른 이름을 선택하세요.",
        "export": "문서 내보내기",
        "tooltip-pt-preferences": "사용자 환경 설정",
        "tooltip-pt-watchlist": "주시문서에 대한 바뀜 목록",
        "tooltip-pt-mycontris": "내 기여의 목록",
+       "tooltip-pt-anoncontribs": "이 IP 주소의 편집 목록",
        "tooltip-pt-login": "꼭 로그인해야 하는 것은 아니지만, 로그인을 권장합니다.",
        "tooltip-pt-logout": "로그아웃",
        "tooltip-pt-createaccount": "계정을 만들고 로그인하는 것이 좋습니다; 하지만, 필수는 아닙니다",
        "tooltip-ca-talk": "문서의 내용에 대한 토론 문서",
        "tooltip-ca-edit": "이 문서 편집하기",
        "tooltip-ca-addsection": "문단 추가하기",
-       "tooltip-ca-viewsource": "이 문서가 잠겨 있습니다.\n문서의 원본을 볼 수 있습니다.",
+       "tooltip-ca-viewsource": "이 문서가 보호되어 있습니다.\n문서의 원본을 볼 수 있습니다.",
        "tooltip-ca-history": "문서의 과거 판",
        "tooltip-ca-protect": "문서 보호하기",
        "tooltip-ca-unprotect": "이 문서의 보호 설정을 바꾸기",
index d5c037a..81ed4e7 100644 (file)
@@ -16,6 +16,7 @@
        "tog-hideminor": "Dun de klein Mini-Änderonge (<strong>M</strong>) en de Leß met de „{{lcfirst:{{int:Recentchanges}}}}“ <strong>nit</strong> aanzeije",
        "tog-hidepatrolled": "Dun de nohjeloorte Änderunge en de „{{int:recentchanges}}“ eez ens <strong>nit</strong> aanzeije",
        "tog-newpageshidepatrolled": "Dun de nohjeloorte Änderunge en de Leß „{{int:newpages}}“ eez ens <strong>nit</strong> aanzeije",
+       "tog-hidecategorization": "Donn de Sigge nit ennohdene",
        "tog-extendwatchlist": "Verjrößer de Oppaßleß för jede Aat vun müjjeliche Ännderonge ze zeije, nit alleijns  de neuste.",
        "tog-usenewrc": "De Änderonge en de „{{int:Recentchanges}}“ un en de Oppaßleß en Jroppe zesammevaße.",
        "tog-numberheadings": "Dun de Üvverschrefte automatisch nummereere",
        "tog-watchlisthidebots": "Dun jedes Mohl dä Bots ehr Änderonge <strong>nit</strong> en minger Oppaßleß zeije",
        "tog-watchlisthideminor": "Donn jehdes Mohl de klein Mini-Ännderonge <strong>nit</strong> en minger Oppaßleß zeije",
        "tog-watchlisthideliu": "Enjeloggte Metmaacher ier Änderonge jehdesmohl <strong>nit</strong> en minger Oppaßleß aanzeije",
+       "tog-watchlistreloadautomatically": "Don de Oppaßleß automattesch neu lahde, wann ene Flter verändert wohd (bruch JavaSkrepp)",
        "tog-watchlisthideanons": "Nahmelohse Metmaacher ier Änderonge jehdesmohl <strong>nit</strong> en minger Oppaßleß aanzeije.",
        "tog-watchlisthidepatrolled": "Donn de nohjelohrte Oppaßleß et eez ens <strong>nit</strong> en minger Oppaßleß aanzeije.",
+       "tog-watchlisthidecategorization": "Donn de Sigge nit ennohdene",
        "tog-ccmeonemails": "Scheck mer en Kopie, wann ich en <i lang=\"en\">e-mail</i> an ene andere Metmaacher scheck",
        "tog-diffonly": "Zeich beim Versione Verjliche nur de Ungerscheide aan (ävver pack nit noch de janze Sigg dodronger)",
        "tog-showhiddencats": "Donn de verschtoche Saachjroppe aanzeije",
        "morenotlisted": "Et jeiht noch wigger&nbsp;…",
        "mypage": "Metmaachersigg",
        "mytalk": "Klaafsigg",
-       "anontalk": "Klaaf för de IP-Adress",
+       "anontalk": "Klaaf för ene nahmelohse Metmaacher",
        "navigation": "Jangk noh de",
        "and": ", un",
        "qbfind": "Fingk",
        "mypreferencesprotected": "Do häs nit dat Rääsch, Ding Enschtällonge ze verändere.",
        "ns-specialprotected": "{{int:nstab-special}}e künne mer nit ändere.",
        "titleprotected": "Di Övverschreff för en Sigg eß fum [[User:$1]] verbodde woode, un der Jrond wohr: ''„$2“''",
-       "filereadonlyerror": "Mer künne di Dattei „$1“ nit ändere, weil dä Dateijebeshtand „$2“ bloß för ze Lässe doh es.\n\nDä Wiki_Köbes dovun hät beim Deeschmaache als Jrond aanjejovve: „$3“",
+       "filereadonlyerror": "Mer künne di Dattei „$1“ nit ändere, weil dä Dateijebeshtand „$2“ bloß för ze Lässe doh es.\n\nDä Verantwootlesche doför hät beim Deeschmaache als Jrond aanjejovve: „$3“",
        "invalidtitle-knownnamespace": "„$3“ es en onjöltijje Övverschreff för em Appachtemang „$2“",
        "invalidtitle-unknownnamespace": "„$2“ es sn onjöltijje Övverschreff em onbikannte Appachtemang met dä Nommer $1",
        "exception-nologin": "Nit enjelogg",
        "wrongpasswordempty": "Dat Passwood ka'mer nit fottlooße. Jetz muss De et noch ens versöke.",
        "passwordtooshort": "En Paßwööter {{PLURAL:$1|moß|möße|moß}} winnichstens {{PLURAL:$1|ei|$1|kei}} Zeiche, {{PLURAL:$1|Zeffer|Zeffere|Zeffere}}, udder Bochstave dren sin.",
        "passwordtoolong": "Paßwööter künnne nit länge sin wi {{PLURAL:$1|ein|$1|Noll}} Zeische.",
+       "passwordtoopopular": "Esu en jewöhnejje Paßwööter nämme mer nit aan. Söhk Der jädd uß, wat nit jehder_ein alle nahßlangs nemmp.",
        "password-name-match": "Ding Poßwoot moß anders wi Dinge Name als ene Metmaacher sin.",
        "password-login-forbidden": "Dä Zohjang met däm Metmaacher-Name un däm Paßwoot es verbodde.",
        "mailmypassword": "Lohß jonn!",
        "passwordreset-emailtext-ip": "Do künns et sällver jewääse sin, öhnswää em Internet hät vun dä IP-Adräß $1 öm\ne neu Paßwoot jefrooch, för Dinge Zohjäng op {{GRAMMAR:Akkusativ|{{SITENAME}}}}\n$4\nHeh {{PLURAL:$3|dä Metmaacher hät|di Metmaacher han|hät keine Metmaacher}} Ding e-mail Addräß:\n\n$2\n\n{{PLURAL:$3|Dat Zweschepaßwoot leuf|Di Zweschepaßwööter loufe|Kein Zweschepaßwoot leuf}} en {{PLURAL:$5|enem Daach|$5 Dääsch|keinem Daach}} uß.\nDonn Desch jäz enlogge, un e neu Paßwoot faßlääje. Wann ene Andere wi\nDo dat heh aanjestüßße hät, udder wann De Desch widder aan Ding Paßwoot\nentsenne kanns, un et nimmih ändere wells, udder es suwwisu weiß, dann\nmoß De jäz jaa nix donn, un kanns Ding Paßwoot wigger bruche.",
        "passwordreset-emailtext-user": "Dä Metmaacher $1 vun {{GRAMMAR:Dativ|{{SITENAME}}}} hät öm e neu Paßwoot jefrooch,\nför Dinge Zohjäng op {{GRAMMAR:Akkusativ|{{SITENAME}}}}\n$4\nHeh {{PLURAL:$3|dä Metmaacher hät|di Metmaacher han|hät keine Metmaacher}} Ding e-mail Addräß:\n\n$2\n\n{{PLURAL:$3|Dat Zweschepaßwoot leuf|Di Zweschepaßwööter loufe|Kein Zweschepaßwoot leuf}} en {{PLURAL:$5|enem Daach|$5 Dääsch|keinem Daach}} uß.\nDonn Desch jäz enlogge, un e neu Paßwoot faßlääje. Wann ene Andere wi\nDo dat heh aanjestüßße hät, udder wann De Desch widder aan Ding Paßwoot\nentsenne kanns, un et nimmih ändere wells, udder es suwwisu weiß, dann\nmoß De jäz jaa nix donn, un kanns Ding Paßwoot wigger bruche.",
        "passwordreset-emailelement": "Metmaacher Name: \n$1\n\nEijmohl-Paßwoot: \n$2",
-       "passwordreset-emailsent": "Wann dat en ennjedrahre <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>-Adräß vun Der es, dann weed en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> för der Zohjang heh verschek, öm e neu Paßwoot ze krijje.",
+       "passwordreset-emailsentemail": "Wann dat en ennjedrahre <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>-Adräß vun Der es, dann weed en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> för der Zohjang heh verschek, öm e neu Paßwoot ze krijje.",
        "passwordreset-emailsent-capture": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> met Aanjahbe zom neue Paßwoot för der Zohjang heh es verschek woode. Heh dronger kanns De se lässe.",
        "passwordreset-emailerror-capture": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> met Aanjahbe zom neue Paßwoot för der Zohjang heh sullt verschek wääde, ävver dat Verscheke aan {{GENDER:$2|dä|dat|dä Metmaacher|de|dat}} $2 hät nit jeflup: $1",
        "changeemail": "Donn en Adräß för de <i lang=\"en\">e-mail</i> ändere udder fott schmiiße",
        "rcshowhidemine": "ming eije Änderonge $1",
        "rcshowhidemine-show": "aanzeije",
        "rcshowhidemine-hide": "verschteihsche",
+       "rcshowhidecategorization": "De Sigge ier Ennohdenong $1",
        "rcshowhidecategorization-show": "Aanzeije!",
        "rcshowhidecategorization-hide": "Verschteische!",
        "rclinks": "Zeisch de läzde {{int:pipe-separator}}$1{{int:pipe-separator}} Änderonge us de läzde {{int:pipe-separator}}$2{{int:pipe-separator}} Däch, un dun {{int:pipe-separator}} $3.",
        "foreign-structured-upload-form-label-not-own-work-local-local": "Do künnts edd och ens met dä [[Special:Upload|Schtandatt-Sigg zom Huhlahde]] versöhke welle.",
        "foreign-structured-upload-form-label-own-work-message-default": "Esch verschtonn, dadd esch en en jemeinsamme Sammlong huh aam lahde ben un dadd sesch dat met dä Bedengonge un de Lezänzbedengonge heh verdräht.",
        "foreign-structured-upload-form-label-not-own-work-message-default": "Wann De di Dattei nit en de jemeinsamme Sammlong vun Datteule huh lahde kanns un derbei de Rähjelle ennhalde, dann maach heh nit wigger, un probehr ene anndere Wähsch.",
+       "foreign-structured-upload-form-label-not-own-work-local-default": "Wann dat noh dä Rähjelle doh jeiht, kanns De och probehre, [[Special:Upload|di Dattei {{GRAMMAR:em|{{ucfirst:{{SITENAME}}}}}} huhzelahde]]",
        "backend-fail-stream": "Mer kunnte di Dattei $1 nit övverdraare.",
        "backend-fail-backup": "Mer kunnte kein Sescherongskopih vun dä Dattei $1 maache.",
        "backend-fail-notexists": "En Dattei $1 jidd et nit.",
        "wlnote": "{{PLURAL:$1|Hee es de läzde Änderong uß|Hee sin de läzde <strong>$1</strong> Änderonge uß|Mer han kein Änderonge en}} de läzde {{PLURAL:$2|Stund|<strong>$2</strong> Stunde|<strong>noll</strong> Stunde}} zigg em $3 öm $4 Uhr.",
        "wlshowlast": "Zeisch de läzde $1 Schtunde, $2 Dähsch aan.",
        "watchlistall2": "all",
+       "watchlist-hide": "Verschtisch",
+       "wlshowhideminor": "klein Minni-Änderonge",
+       "wlshowhidebots": "de Bots ehr Änderonge",
+       "wlshowhideliu": "de ennjeloggte Metmaacher ier Änderonge",
+       "wlshowhideanons": "de nahmelohse Metmaacher ier Änderonge",
+       "wlshowhidepatr": "de nohjelohrte Änderonge",
+       "wlshowhidemine": "ming eije Änderonge",
        "watchlist-options": "Eijeschaffte fun de Oppassless",
        "watching": "Drobb oppaßße…",
        "unwatching": "Nimmih drobb oppaßße",
        "contributions": "{{GENDER:$1|Däm Metmaacher|Däm|Däm Metmaacher|Dä Metmaacherėn|Däm}} $1 {{GENDER:$1|singe|singe|singe|iere|singe}} Beijdrähsch",
        "contributions-title": "Beijdrähsch fum $1",
        "mycontris": "Beijdrähsch",
+       "anoncontribs": "Beijdrähsch",
        "contribsub2": "För {{GENDER:$3|dä|et|dä Metmaacher|de|dat}} $1: $1 ($2)",
        "contributions-userdoesnotexist": "Ene Metmaacher mem Nahme „$1“ ham_mer nit.",
        "nocontribs": "Mer han kein Änderunge jefonge, en de Logböcher, di do paße dähte.",
        "movenosubpage": "Di Sigg hät kei Ongersigge.",
        "movereason": "Aanlass:",
        "revertmove": "Et Ömnänne zerök_nämme",
-       "delete_and_move": "Fottschmieße un Ömnenne",
        "delete_and_move_text": "== Dä! Dubbelte Name ==\nDi Sigg „[[:$1]]“ jitt et ald. Wollts De se fottschmieße, öm heh di Sigg ömnenne ze künne?",
        "delete_and_move_confirm": "Jo, dun di Sigg fottschmieße.",
        "delete_and_move_reason": "Fottjeschmeße, öm di Sigg „[[$1]]“ ömbenänne ze künne.",
index dda2c8f..a07b59b 100644 (file)
        "userloginnocreate": "Têkeve",
        "logout": "Derkeve",
        "userlogout": "Derkeve",
-       "notloggedin": "Xwe tomar nekir",
+       "notloggedin": "Te xwe tomar nekir",
        "userlogin-noaccount": "Hesabekî te nîne?",
        "userlogin-joinproject": "Tevlî {{SITENAME}} bibe",
        "nologin": "Hesabê te nîne? $1.",
        "passwordreset-email": "Navnîşana e-nameyê:",
        "passwordreset-emailtitle": "Hûragahiyên hesab li ser {{SITENAME}}",
        "passwordreset-emailelement": "Navê bikarhêner:\n$1\n\nŞîfreya niha:\n$2",
-       "passwordreset-emailsent": "E-nameyeke bibîrxistinê hate şandin.",
+       "passwordreset-emailsentemail": "E-nameyeke bibîrxistinê hate şandin.",
        "changeemail": "Navnîşana enameya xwe biguherîne an rabike",
        "changeemail-oldemail": "Navnîşana E-nameya niha:",
        "changeemail-newemail": "Navnîşana e-nameya nû:",
        "movenosubpage": "Binrûpelên vê rûpelê tune ne.",
        "movereason": "Sedem:",
        "revertmove": "şûnde vegerîne",
-       "delete_and_move": "Jêbibe û nav biguherîne",
        "delete_and_move_text": "== Jêbirin gireke ==\n\nRûpela \"[[:$1]]\" berê heye. Tu rast dixazê wê jêbibê ji bo navguherandinê ra?",
        "delete_and_move_confirm": "Erê, rûpelê jê bibe",
        "delete_and_move_reason": "Jêbir ji bo navguherandinê",
index 2c28b08..abcf0d0 100644 (file)
@@ -24,7 +24,8 @@
                        "아라",
                        "Lesgles",
                        "StevenJ81",
-                       "Macofe"
+                       "Macofe",
+                       "Xð"
                ]
        },
        "tog-underline": "Versores linea denotandi:",
        "viewhelppage": "Videre auxilium",
        "categorypage": "Videre categoriam",
        "viewtalkpage": "Videre disputationem",
-       "otherlanguages": "Linguis aliis",
+       "otherlanguages": "In aliis linguis",
        "redirectedfrom": "(Redirectum de $1)",
        "redirectpagesub": "Pagina redirectionis",
        "lastmodifiedat": "Ultima mutatio: $2, $1.",
        "movenosubpage": "Huic paginae non sunt subpaginae.",
        "movereason": "Causa:",
        "revertmove": "reverti",
-       "delete_and_move": "Delere et movere",
        "delete_and_move_text": "==Deletio necesse est==\nPaginae nomen petitum \"[[:$1]]\" iam existit. Vin tu eam delere ut pagina illic moveatur?",
        "delete_and_move_confirm": "Ita, paginam delere",
        "delete_and_move_reason": "Deleta ut moveatur ex \"[[$1]]\"",
index 6a32ae1..d61d298 100644 (file)
        "morenotlisted": "Dës Lëscht ass net komplett.",
        "mypage": "Säit",
        "mytalk": "Diskussioun",
-       "anontalk": "Diskussioun fir dës IP Adress",
+       "anontalk": "Diskussioun",
        "navigation": "Navigatioun",
        "and": "&#32;a(n)",
        "qbfind": "Fannen",
        "passwordreset-emailtext-ip": "Iergendee mat der IP-Adress $1, wahrscheinlech Dir selwer, huet d'Zrécksetze vun Ärem Passwuert op {{SITENAME}} gefrot ($4). {{PLURAL:$3|De Benotzerkont ass|D'Benutzerkonte si}} mat dëser E-Mail-Adress verbonn:\n\n$2\n\n{{PLURAL:$3|Dëst temporärt Passwuert leeft|Dës temporär Passwierder lafe}} bannent {{PLURAL:$5|engem Dag|$5 Deeg}} of.\nDir sollt Iech aloggen an een neit Passwuert festleeën. Wann een Aneren déi Ufro gemaach huet oder Dir Iech erëm un Äert Passwuert erënnere kënnt an et net ännere wëllt, kënnt Dir dës Noriicht ignoréieren an Äert aalt Passwuert weider benotzen.",
        "passwordreset-emailtext-user": "De Benotzer $1 vu(n) {{SITENAME}} huet d'Zrécksetze vun Ärem Passwuert op {{SITENAME}} gefrot ($4). {{PLURAL:$3|De Benotzerkont|D'Benutzerkonte}} \n\n$2\n\n{{PLURAL:$3|ass|si}} mat dëser E-Mail-Adress verbonn.\n\n{{PLURAL:$3|Dëst temporärt Passwuert leeft|Dës temporär Passwierder lafe}} bannent {{PLURAL:$5|engem Dag|$5 Deeg}} of.\nDir sollt Iech aloggen an een neit Passwuert festleeën. Wann een Aneren déi Ufro gemaach huet oder Dir Iech erëm un Äert Passwuert erënnere kënnt an et net ännere wëllt, kënnt Dir dës Noriicht ignoréieren an Äert aalt Passwuert weider benotzen.",
        "passwordreset-emailelement": "Benotzernumm: \n$1\n\nTemporärt Passwuert: \n$2",
-       "passwordreset-emailsent": "Wann dëst eng registréiert E-Mailadress vun Ärem benotzerkont ass da gëtt Eng E-Mail fir d'Passwuert zréckzesetze geschéckt.",
+       "passwordreset-emailsentemail": "Wann dëst eng registréiert E-Mailadress vun Ärem benotzerkont ass da gëtt Eng E-Mail fir d'Passwuert zréckzesetze geschéckt.",
        "passwordreset-emailsent-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner.",
        "passwordreset-emailerror-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner, awer de {{GENDER:$2|Benotzer}} konnt se net kréien: $1",
        "changeemail": "E-Mail-Adress änneren oder ewechhuelen",
        "recentchanges-legend-heading": "'''Legend:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (kuckt och [[Special:NewPages|Lëscht vun den neie Säiten]])",
        "recentchanges-legend-plusminus": "''(±123)''",
+       "recentchanges-submit": "Weisen",
        "rcnotefrom": "Hei drënner {{PLURAL:$5|gëtt d'Ännerung|ginn d'Ännerungen}} zanter <strong>$3, $4</strong> (maximal <strong>$1</strong> Ännerunge gi gewisen).",
        "rclistfrom": "Nei Ännerunge vum $3 $2 u weisen",
        "rcshowhideminor": "Kleng Ännerunge $1",
        "mostrevisions": "Säite mat de meeschte Versiounen",
        "prefixindex": "All Säite mat Prefix",
        "prefixindex-namespace": "All Säite mat Prefix (Nummraum $1)",
+       "prefixindex-submit": "Weisen",
        "prefixindex-strip": "Prefix an der Lëscht ewechhuelen",
        "shortpages": "Kuerz Säiten",
        "longpages": "Laang Säiten",
        "protectedpages-performer": "Spär duerch de Benotzer",
        "protectedpages-params": "Parameter vun der Spär",
        "protectedpages-reason": "Grond",
+       "protectedpages-submit": "Säite weisen",
        "protectedpages-unknown-timestamp": "Onbekannt",
        "protectedpages-unknown-performer": "Onbekannte Benotzer",
        "protectedtitles": "Gespaarten Titel",
        "protectedtitles-summary": "Op dëser Säit stinn all déi Säiten déi elo gespaart si fir ugefaang ze ginn. D'Lëscht vun de Säiten déi gespaart sinn: [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Elo si mat de Parameteren déi Dir uginn hutt keng Säite fir neit Uleeë gespaart.",
+       "protectedtitles-submit": "Titele weisen",
        "listusers": "Benotzerlëscht",
        "listusers-editsonly": "Nëmme Benotzer mat Ännerunge weisen",
        "listusers-creationsort": "Nom Datum vum Uleeën zortéieren",
        "activeusers-hidebots": "Botte verstoppen",
        "activeusers-hidesysops": "Administrateure verstoppen",
        "activeusers-noresult": "Keng Benotzer fonnt.",
+       "activeusers-submit": "Aktiv Benotzer weisen",
        "listgrouprights": "Rechter vun de Benotzergruppen",
        "listgrouprights-summary": "Dëst ass eng Lëscht vun den op dëser Wiki definéierte Benotzergruppen an den domat verbonnene Rechter.\nEt ginn [[{{MediaWiki:Listgrouprights-helppage}}|zousätzlech Informatiounen]] iwwer individuell Benotzerrechter.",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Recht dat zouerkannt gouf</span>\n* <span class=\"listgrouprights-revoked\">Recht dat ofgeholl gouf</span>",
        "wlshowlast": "Déi lescht $1 Stonnen $2 Deeg weisen",
        "watchlistall2": "all",
        "watchlist-hide": "Verstoppen",
-       "wlshowtime": "Lëscht weisen",
+       "watchlist-submit": "Weisen",
+       "wlshowtime": "Zäitraum dee gewise gëtt:",
        "wlshowhideminor": "kleng Ännerungen",
        "wlshowhidebots": "Botten",
        "wlshowhideliu": "registréiert Benotzer",
        "contributions": "{{GENDER:$1|Benotzer}}kontributiounen",
        "contributions-title": "Kontributioune vum $1",
        "mycontris": "Kontributiounen",
+       "anoncontribs": "Kontributiounen",
        "contribsub2": "Fir {{GENDER:$3|den $1|d'$1|de Benotzer $1}} ($2)",
        "contributions-userdoesnotexist": "De Benotzerkont \"$1\" ass net registréiert.",
        "nocontribs": "Et goufe keng Ännerunge fonnt, déi dëse Kritèren entspriechen.",
        "whatlinkshere-hidelinks": "Linken $1",
        "whatlinkshere-hideimages": "Linken op Fichiere $1",
        "whatlinkshere-filters": "Filteren",
+       "whatlinkshere-submit": "Lass",
        "autoblockid": "Automatesch Spär #$1",
        "block": "Benotzer spären",
        "unblock": "D'Spär vum Benotzer ophiewen",
        "movenosubpage": "Dës Säit huet keng Ënnersäiten.",
        "movereason": "Grond:",
        "revertmove": "zréck réckelen",
-       "delete_and_move": "Läschen a réckelen",
        "delete_and_move_text": "== Läsche vun der Destinatiounssäit néideg ==\nD'Säit \"[[:$1]]\" existéiert schonn. \nWëll Dir se läsche fir d'Réckelen ze erméiglechen?",
        "delete_and_move_confirm": "Jo, läsch d'Säit",
        "delete_and_move_reason": "Geläscht fir Plaz ze maache fir \"[[$1]]\" heihin ze réckelen",
index ae6865a..c8e8015 100644 (file)
@@ -45,6 +45,7 @@
        "tog-watchlisthidebots": "Ascondi e modiffiche di bot da-a lista che tegno d'oeuggio",
        "tog-watchlisthideminor": "Ascondi e modiffiche menoî da-a lista che tegno d'oeuggio",
        "tog-watchlisthideliu": "Ascondi e modiffiche di utenti intræ da-a lista che tegno d'oeuggio",
+       "tog-watchlistreloadautomatically": "Recarrega aotomaticamente a lista di oservæ quande vegne cangiòu un filtro (ghe veu o JavaScript)",
        "tog-watchlisthideanons": "Ascondi e modiffiche di utenti anonnimi da-a lista che tegno d'oeuggio",
        "tog-watchlisthidepatrolled": "Ascondi e modiffiche za controllæ da-a lista che tegno d'oeuggio",
        "tog-watchlisthidecategorization": "Ascondi a categorizzassion de paggine",
        "morenotlisted": "Questa lista a no l'è completa.",
        "mypage": "Paggina",
        "mytalk": "Discuscioin",
-       "anontalk": "Discuscion pe questo indirisso IP",
+       "anontalk": "Discuscion pe questo addresso IP",
        "navigation": "Navegaçión",
        "and": "&#32;e",
        "qbfind": "Attrêuva",
        "viewhelppage": "Vizualizza a paggina d'agiutto",
        "categorypage": "Veddi a paggina da categoria",
        "viewtalkpage": "Veddi o ciæto",
-       "otherlanguages": "In âtre lengóe",
+       "otherlanguages": "In âtre lengoe",
        "redirectedfrom": "(Rendirissou da $1)",
        "redirectpagesub": "Paggina de rindirissamento",
        "redirectto": "Rendirissa a:",
        "readonly": "Database bloccòu",
        "enterlockreason": "Scrivi o motivo do blocco, e 'na stimma de quande o saiâ rimosso",
        "readonlytext": "Po-u momento o database o l'è bloccou a-e neuve azonte e modiffiche, foscia pe 'na manutension ordenaia do database, doppo a quæ o saiâ torna accescibile.\n\nL'amministratô ch'o l'ha misso o blocco o l'ha dæto sta spiegassion: $1",
-       "missing-article": "O database o no l'à trovòu o testo di 'na pàgina che ghe saiêiva dovûa êse  co-o nómme de \"$1\" $2.\n\nSpésse vòtte questo o sucede quande a vegne riciamâ, da stöia ò dò-u confronto tra revixioìn, in colegaménto a 'na pàgina scancelâ, a in confronto tra revixioìn che no ghe son ciù ò a in confronto tra revixioìn sénsa ciù a stöia.\n\nSe coscì no fîse l'é probabile che t'aggi scoverto 'n erô into software MediaWiki.\nPe favô ti peu segnalâ quello che l'é sucesso a in [[Special:ListUsers/sysop|aministratô]] dîndo  l'URL in questión.",
+       "missing-article": "O database o no l'à trovòu o testo de 'na pàgina ch'a ghe saiêiva dovûa êse co-o nómme de \"$1\" $2.\n\nSpésse vòtte questo o sucede quande a vegne reciamâ, da-a stöia ò dò-u confronto tra revixioìn, in colegaménto a 'na pàgina scancelâ, a in confronto tra revixioìn che no ghe son ciù ò a in confronto tra revixioìn sénsa ciù a stöia.\n\nSe coscì no fîse l'é probabile che t'aggi scoverto 'n erô into software MediaWiki.\nPe favô ti peu segnalâ quello che l'é sucesso a in [[Special:ListUsers/sysop|aministratô]] dindo  l'URL in questión.",
        "missingarticle-rev": "(nùmero da revixón: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "readonly_lag": "O database o l'è stæto bloccou automaticamente pe consentî a-i server co-i database slave de sincronizzase co-o master",
        "wrongpasswordempty": "No ti g'hæ scrîo nisciûnn-a paròlla d'ordine. Tenta torna.",
        "passwordtooshort": "E password devan aveighe aomanco {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoolong": "A poula segretta a no peu contegnî ciù de {{PLURAL:$1|1 carattere|$1 caratteri}}.",
+       "passwordtoopopular": "No se peu deuviâ de paole segrette troppo ordenaie. Pe piaxei çernitene un-a ciu particolâ.",
        "password-name-match": "A password a dev'ese despægia da-o nomme utente.",
        "password-login-forbidden": "L'utilizzo de sto nomme utente e password o l'è stæto proibio.",
        "mailmypassword": "Reimposta a poula segretta",
        "invalidemailaddress": "L'adresso e-mail indicòu o l'ha un formato non vallido. Inseisci un adresso valido o donque sveua a casella.",
        "cannotchangeemail": "I adressi e-mail no peuan ese modificæ in sce sto wiki.",
        "emaildisabled": "Sto scito o no peu inviâ messaggi de posta eletronnica.",
-       "accountcreated": "Graçie pe esëte registroö!!!",
+       "accountcreated": "Graçie pe êsite registròu!",
        "accountcreatedtext": "L'utensa pe [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|msg]]) a l'é stæta creâ.",
        "createaccount-title": "Creaçion de 'n conto pe {{SITENAME}}",
        "createaccount-text": "Quarcun o l'ha creòu un utensa pe quest'adresso e-mail a {{SITENAME}} ($4) a nomme de $2, co-a poula segretta \"$3\".\nTi doviesci intrâ e cangiâ subbito a to poula segretta.\n\nSe quest'utensa a l'è stæta creâ pe sballio, no stanni a dâ a mente a sto messaggio.",
        "passwordreset-capture-help": "Se ti seleçion-i sta casella, l'e-mail (co-a poula segretta temporannia), o saiâ mostròu a ti, oltre ch'a ese inviòu a l'utente.",
        "passwordreset-email": "Addresso e-mail:",
        "passwordreset-emailtitle": "Dettaggi account sciu {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Quarcun (probabilmente ti, con adresso IP $1) o l'ha domandòu l'invio de 'na neuva poula segretta per l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associòu|I utenti associæ}} a sto addresso e-mail son:\n\n$2\n\n{{PLURAL:$3|Questa poula segretta temporannia a descazziâ|Queste poule segrette temporannie descazzian}} doppo {{PLURAL:$5|un giorno|$5 giorni}}.\nTi doviesci accede e çerne una neuva poula segretta oua. \n\nSe no t'ê stæto t a fâ a domanda, ò se ti t'ê aregordòu a poula segretta originale e no ti veu ciù cangiala, ti peu ignorâ sto messaggio e continuâ a deuviâ a teu vegia poula segretta.",
+       "passwordreset-emailtext-ip": "Quarcun (probabilmente ti, con adresso IP $1) o l'ha domandòu l'invio de 'na neuva poula segretta per l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associòu|I utenti associæ}} a sto addresso e-mail son:\n\n$2\n\n{{PLURAL:$3|Questa poula segretta temporannia a descazziâ|Queste poule segrette temporannie descazzian}} doppo {{PLURAL:$5|un giorno|$5 giorni}}.\nTi doviesci accede e çerne una neuva poula segretta oua. \n\nSe no t'ê stæto ti a fâ a domanda, ò se ti t'hæ aregordòu a poula segretta originale e no ti veu ciù cangiâla, ti peu ignorâ sto messaggio e continuâ a deuviâ a teu vegia poula segretta.",
        "passwordreset-emailelement": "Nomme utente: \n$1\n\nPoula segretta temporannia: \n$2",
-       "passwordreset-emailsent": "Se questo o l'è un addresso de posta elettronnica registròu pe-a teu utensa, alloa saiâ inviâ un'e-mail pe reimpostâ a poula segretta.",
+       "passwordreset-emailsentemail": "Se questo o l'è un addresso de posta elettronnica registròu pe-a teu utensa, alloa saiâ inviâ un'e-mail pe reimpostâ a poula segretta.",
        "passwordreset-emailsent-capture": "L'è stæto inviòu un'e-mail de reimpostaçion da poula segretta, o contegnuo o l'è riportòu chì appreuvo.",
        "passwordreset-emailerror-capture": "L'è stæto generòu un'e-mail de reimpostaçion da poula segretta, riportà chì appreuvo. L'invio {{GENDER:$2|a l'utente}} o no l'è ariêscîo: $1",
        "changeemail": "Cangia o elimmina l'adresso e-mail",
        "anontalkpagetext": "----\n''Sta chì a l'è a paggina de discuscion de un utente anonnimo, ch'o no l'ha ancon creou un'utensa o comunque o no a doeuvia oua. Pe identificâlo l'è quindi necessaio doeuviâ o nummero do so adresso IP. I adresci IP poeuan però ese condivixi da ciù utenti. Se t'ê un utente anonimo e ti ritegni che i commenti inte sta pagina no se riferiscian a ti, [[Special:UserLogin/signup|crea una noeuva utensa]] o donque [[Special:UserLogin|intra con quella che ti g'hæ za]] pe evitâ de chì avanti de ese confuzo con di atri utenti anonnimi .''",
        "noarticletext": "Po-u momento a pagina çercâ a l'è vêua. L'è poscibbile [[Special:Search/{{PAGENAME}}|çercâ 'sto tittolo]] inte âtre pagine do scîto opû [{{fullurl:{{FULLPAGENAME}}|action=edit}} cangiâ a pagina òua].",
        "noarticletext-nopermission": "Òua a pàgina çercâ a l'è vêua. L'è poscìbile [[Special:Search/{{PAGENAME}}|çercâ sto tìtolo]] inte di âtre pàgine do scîto o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} çercâ inti registri corelæ]</span>, ma no ti gh'hæ i outorizzaçioin pe creâ sta paggina.",
+       "missing-revision": "La verscion #$1 da paggina \"{{FULLPAGENAME}}\" a no l'esiste.\n\nQuesto succede solitamente se inta stoia ti sciacchi un vegio ingancio a una paggina scassâ.\n\nI dettaggi peuan ese attrovæ into [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de scançellaçioin].",
+       "userpage-userdoesnotexist": "L'utensa \"$1\" a no corisponde a un utente registròu.\nTi veu davei creâ o modificâ sta paggina?",
        "userpage-userdoesnotexist-view": "L'utensa \"$1\" a no l'è registrâ.",
+       "blocked-notice-logextract": "St'utente o l'è attualmente bloccòu.\nL'urtimo elemento into registro di blocchi o l'è riportòu chì appreuvo pe informassion:",
+       "clearyourcache": "<strong>Notta:</strong> doppo avei sarvou, poriæ ese necessaio nettezâ a cache do proppio navegatô pe vedde i cangiamenti. \n*<strong>Firefox / Safari:</strong> tegnî sciacou o tasto de maiuscole <em>Shift</em> e cliccâ <em>Riecarrega</em>, oppû premme <em>Ctrl-F5</em> ò <em>Ctrl-R</em> (<em>⌘-R</em> insce Mac)\n*<strong>Google Chrome:</strong> premme <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> insce un Mac)\n*<strong>Internet Explorer:</strong> tegnî sciacou o tasto <em>Ctrl</em> e cliccâ <em>Aggiorna</em>, oppû premme <em>Ctrl-F5</em>\n*<strong>Opera:</strong> svuâ completamente a cache da-o menu <em>Strumenti → Preferençe</em>",
+       "usercssyoucanpreview": "'''Suggerimento:''' adeuvia o pomello 'Amia l'anteprimma' per provâ o to neuvo CSS primma de sarvâlo.",
+       "userjsyoucanpreview": "'''Suggerimento:''' adeuvia o pomello 'Amia l'anteprimma' per provâ o to neuvo JavaScript primma de sarvâlo.",
+       "usercsspreview": "'''Questa a l'è solo un'anteprimma do proppio CSS personâ. E modiffiche no son ancon stæte sarvæ!'''",
+       "userjspreview": "'''Questa a l'è solo un'anteprimma do proppio  JavaScript personâ. E modiffiche no son ancon stæte sarvæ!'''",
+       "sitecsspreview": "'''Questa a l'è solo un'anteprimma do CSS. E modiffiche no son ancon stæte sarvæ!'''",
+       "sitejspreview": "'''Questa a l'è solo un'anteprimma pe provâ o JavaScript; e modiffiche no son ancon stæte sarvæ!'''",
+       "userinvalidcssjstitle": "<strong>Attension:</strong> no existe arcun tema con nomme \"$1\". E paggine pe-i .css e .js personalizzæ g'han o tittolo minuscolo, presempio {{ns:user}}:Esempio/vector.css e no {{ns:user}}:Esempio/Vector.css.",
+       "updated": "(Aggiornòu)",
+       "note": "'''Notta:'''",
        "previewnote": "'''Questa chì a l'è solo 'n'anteprimma; i cangiamenti no son ancon stæti sarvæ!'''",
+       "continue-editing": "Vanni a l'area de modiffica",
+       "previewconflict": "L'anteprimma a mostra o scrito presente inta casella de modiffica de d'ato coscì comme o l'apaiâ se ti çerni de sarvalo òua.",
+       "session_fail_preview": "'''N'emmo posciuo elaborâ a modiffica a caosa da pèrdia di dæti relativi a-a sescion.'''\nRitenta.\nSe-o problema o persciste, preuva a [[Special:UserLogout|sciortî]] e a intrâ torna.'''",
+       "edit_form_incomplete": "'''De parte do formulaio de modiffica n'han razonto o server; controlla che e modiffiche seggian intatte e ripreuva.'''",
        "editing": "Modiffica de $1",
        "creating": "T'ê apreuvo a creâ $1",
        "editingsection": "Càngio de $1 (seçión)",
+       "editingcomment": "Càngio de $1 (neuva seçion)",
+       "editconflict": "Conflito d'ediçion: $1",
+       "explainconflict": "Un atro utente o l'ha sarvòu una neuva verscion da paggina de mentre che t'êi apreuvo a cangiâla.\nA casella de modiffica de d'ato a conten o scrito da paggina coscì comm'o l'è òua.\nE teu modiffiche son invece mostræ inta casella de modiffica de sotta.\nTi g'hæ da stramuâ e teu modiffiche inta casella de d'ato.\nSciaccando o pomello '{{int:savearticle}}', o saiâ sarvòu '''solo''' o scrito contegnuo inta casella de d'ato.",
        "yourtext": "O teu testo",
+       "storedversion": "La verscion memorizzâ",
+       "nonunicodebrowser": "'''Attençion: o teu navegatô o no l'è compatibbile co-i caratteri Unicode.''' Pe consentî a modiffica de paggine sença problemi, i caratteri non ASCII saian vixualizzæ inta casella de modiffica sotto forma de codiçi esadeximæ.'''",
+       "editingold": "<strong>Attençion: t'ê apreuvo a modificâ una verscion non aggiornâ da paggina.</strong>\nSarvandola coscì, tutti i cangi fæti doppo sta verscion saian sorvescriti.",
        "yourdiff": "Differense",
        "copyrightwarning": "Nota: Tùtte e contribuçioìn a {{SITENAME}} van conscideræ comme rilasciæ drento a-i termini da licensa d'ûso $2 (veddi $1 pe savéine de ciù).\nSe no ti veu che i testi teu pêuan esse modificæ da quarchedùn sensa limitaçioìn, no mandâli a {{SITENAME}}.<br />\nInviando o testo ti diciâri, sott'a teu responsabilitæ, ch'o l'é stæto scrîto da ti personalmente oppure ch'o l'é stæto piggiòu da 'na fonte de pùbrico domìnio òu anàlogamente lìbea.<br />\n'''NO INVI MATERIÂLE COVERTO DA DRÎTI D'AUTÔ SENSA OUTORIZAÇION!'''",
+       "editpage-cannot-use-custom-model": "O modello do contegnuo de sta paggina o no peu ese modificòu.",
+       "longpageerror": "'''Errô: o scrito inviou o l'è longo {{PLURAL:$1|1|$1}} kilobyte, ciu che-o mascimo consentio de ({{PLURAL:$2|1|$2}} kilobyte).'''\nNo se peu sarvâ.",
+       "protectedpagewarning": "'''Attençion: questa paggina a l'è stæta bloccâ de moddo che solo i utenti co-i privileggi d'amministratô possan modificala.'''\nL'urtimo elemento do registro o l'è riportou chì appreuvo pe referença:",
+       "semiprotectedpagewarning": "'''Notta:''' Questa paggina a l'è stæta bloccä de moddo che solo i utenti registræ possan modificâla.\nL'urtimo elemento do registro o l'è riportou chì appreuvo pe referensa:",
+       "cascadeprotectedwarning": "'''Attençion:''' Questa paggina a l'è stæta bloccâ de moddo che solo i utenti co-i privileggi d'amministratô possan modificala da-o momento ch'a l'é inclusa seleçionando a proteçion \"ricorsciva\" {{PLURAL:$1|inta paggina|inte paggine}}:",
+       "titleprotectedwarning": "'''Attension: Questa paggina a l'è stæta bloccâ de moddo che seggian necessai [[Special:ListGroupRights|di driti speciffichi]] pe creâla.'''\nL'urtimo elemento do registro o l'è riportou chì appreuvo pe referensa:",
        "templatesused": "{{PLURAL:$1|Template dêuviòu|Template dêuviæ}} in sta pàgina:",
-       "templatesusedpreview": "Template dêuviæ inte 'st'anteprimma:",
+       "templatesusedpreview": "{{PLURAL:$1|Template deuviou|Template deuviæ}} in te st'anteprimma:",
+       "templatesusedsection": "{{PLURAL:$1|Template deuviòu|Template deuviæ}} in questa seçion:",
        "template-protected": "(protezûo)",
        "template-semiprotected": "(semiprotezûo)",
        "hiddencategories": "Sta pàgina a fa parte de {{PLURAL:$1|1 categoria ascoza|$1 categorie ascoze}}:",
        "nocreatetext": "A poscibilitæ de creâ nêuve paggine insce {{SITENAME}} a l'è stæta limitâ solo a-i ûtenti registræ.\nSe pêu tornâ inderê e modificâ 'na paggina existente, oppûre [[Special:UserLogin|intrâ ò creâ 'n accesso nêuvo]].",
+       "nocreate-loggedin": "No ti g'hæ i permissi pe creâ de paggine neuve.",
+       "sectioneditnotsupported-title": "Modiffica de seçioin non supportâ",
+       "sectioneditnotsupported-text": "A modiffica de seçioin a no l'è supportâ in questa paggina.",
+       "permissionserrors": "No ti g'hæ o permisso",
+       "permissionserrorstext": "No ti g'hæ i permissi pe fâlo, pe  {{PLURAL:$1|questa raxon|queste raxoin}}:",
        "permissionserrorstext-withaction": "No ti g'hæ i permìssi pe $2 pe {{PLURAL:$1|sta raxon|ste raxoìn}}:",
+       "contentmodelediterror": "No ti peu modificâ sta verscion da-o momento che o so modello de contegnuo o l'è <code>$1</code>, mentre o corrente modello de contegnuo da paggina o l'è <code>$2</code>.",
        "recreate-moveddeleted-warn": "Atençión: ti stæ pe ricreâ 'na pàgina zà scancelâ into passòu.'''\n\nConsciddera se l'è o caxo de continoâ  a cangiâ 'sta pàgina.\nPe comoditæ e cancellaçioìn e i stramui son pubricæ chì sotta:",
        "moveddeleted-notice": "Sta pàgina a l'é stæta scancelâ.\nA lista de scancelaçioìn e di stramui son riportæ chi de sotta pe informaçión.",
+       "moveddeleted-notice-recent": "Spiaxenti, sta paggina a l'è stæta scassâ reçentemente (inte urtime 24 oe).\n\nE açioin de cançellaçion e spostamento pe questa paggina son disponibile chì appreuvo pe referença.",
+       "log-fulllog": "Amîa o log completo",
+       "edit-hook-aborted": "A modifica a l'è stæta annullâ da l'hook.\nO no l'ha dæto arcun-a spiegassion.",
+       "edit-gone-missing": "Imposcibbile aggiornâ a paggina.\nPâ ch'a segge stæta scassâ.",
+       "edit-conflict": "Conflito d'ediçion.",
+       "edit-no-change": "A modiffica a l'è stæta ignorâ za che o scrito o no l'è cangiòu.",
+       "postedit-confirmation-created": "A paggina a l'è stæta creâ.",
+       "postedit-confirmation-restored": "A paggina a l'è stæta ripristinâ.",
+       "postedit-confirmation-saved": "A modiffica a l'è stæta sarvâ.",
+       "edit-already-exists": "Imposcibbile creâ una neyva paggina.\nA l'existe zà.",
+       "defaultmessagetext": "Scrito do messaggio predefinio",
+       "content-failed-to-parse": "Imposcibbile analizzâ $2 pe-o modello $1: $3",
+       "invalid-content-data": "Dæti contegnui non vallidi",
+       "content-not-allowed-here": "Contegnuo in \"$1\" non consentio inta paggina [[$2]]",
+       "editwarning-warning": "Lasciâ sta paggina porriæ caosâ a perdia de tutte e modiffiche fæte.\nSe ti t'hê introu, ti peu disattivâ st'aviso inta seçion \"{{int:prefs-editing}}\" de teu preferençe.",
+       "editpage-notsupportedcontentformat-title": "Formato contegnuo non supportou",
+       "editpage-notsupportedcontentformat-text": "O formato do contegnuo $1 o no l'è supportou da-o modello de contegnuo $2.",
+       "content-model-wikitext": "wikitesto",
+       "content-model-text": "testo normale",
+       "content-model-javascript": "JavaScript",
+       "content-json-empty-object": "Ogetto veuo",
+       "content-json-empty-array": "Array veuo",
+       "duplicate-args-warning": "<strong>Avvertensa:</strong> [[:$1]] o ciamma [[:$2]] con ciù de un valô pe-o parammetro \"$3\".  Solo l'urtimo valô fornio o saiâ deuviou.",
+       "duplicate-args-category": "Paggine che ciamman i template deuviando di parammetri duplicæ",
+       "duplicate-args-category-desc": "A paggina a conten de ciamæ a di template ch'adeuvian di argomenti duplicæ, comme presempio <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ò <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
+       "expensive-parserfunction-warning": "'''Attençion:''' Questa paggina a conten troppe ciamæ a-e fonçioin de parser .\n\nA doviæ aveighene meno de $2, a-o momento ghe n'è $1.",
+       "expensive-parserfunction-category": "Paggine con troppe ciamæ a-e fonçioin de parser .",
        "post-expand-template-inclusion-warning": "'''Atento:''' a dimensción di template che t'æ misso a l'é tròppo grande.\nQuarchedun di teu template o no saiâ incluzo.",
        "post-expand-template-inclusion-category": "Pàgine con di template che gh'àn a dimensción ciù âta do limite mascimo",
        "post-expand-template-argument-warning": "'''Atençión:''' sta pàgina a contegne un ò ciù argomenti di template che son tròppo gràndi pe êse espansi. Sti argomenti no saiàn fæti védde.",
        "post-expand-template-argument-category": "Pàgine con di template che ghe mancàn di argoménti",
+       "parser-template-loop-warning": "Rilevou loop do template: [[$1]]",
+       "parser-template-recursion-depth-warning": "Limmite de ricorscion into template superòu($1)",
+       "language-converter-depth-warning": "Limmite de profonditæ do convertitô de lengoa superòu ($1)",
+       "node-count-exceeded-category": "Paggine dovve l'è superòu o nummero di groppi.",
+       "node-count-exceeded-category-desc": "A paggina suppera o nummero mascimo de groppi.",
+       "node-count-exceeded-warning": "Sta paggina a l'ha superòu o nummero di groppi.",
+       "expansion-depth-exceeded-category": "Paggine inte quæ s'è superòu a profonditæ d'espanscion",
+       "expansion-depth-exceeded-category-desc": "A paggina a suppera a profonditæ mascima d'espanscion.",
+       "expansion-depth-exceeded-warning": "Sta paggine a l'ha superòu a profonditæ d'espanscion",
+       "parser-unstrip-loop-warning": "Rilevou ciclo de Unstrip",
+       "parser-unstrip-recursion-limit": "Superæ i limmiti de ricorscion de Unstrip ($1)",
+       "converter-manual-rule-error": "Rilevou errô inta reggola manoâ de converscion da lengoa",
+       "undo-success": "Questa modiffica a peu ese anullâ.\nControlla e differençe mostræ chì de sotta fra e doe verscioin pe ese seguo che-o contegnuo o corisponde a quante dexidiou, e quindi sarvâ e modiffiche pe completâ a proçedûa d'anullamento.",
+       "undo-failure": "Imposcibbile anullâ a modiffica a caosa de un conflito con de modiffiche intermeddie.",
+       "undo-norev": "A modiffica a no peu ese anullâ perché a no l'existe ò donque a l'è stæta scassâ.",
+       "undo-nochange": "Pâ che-a modiffica a sæ zà stæta anullâ.",
+       "undo-summary": "Annullou a modiffica $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discuscion]])",
+       "undo-summary-username-hidden": "Anullou a modiffica $1 de un utente ascoso",
        "cantcreateaccounttitle": "Non se peu registrâ l'utente",
        "cantcreateaccount-text": "A registrassion da questo addresso IP (<b>$1</b>) a l'è stæta bloccâ da [[User:$3|$3]].\n\nA raxon dæta a l'è ''$2''",
+       "cantcreateaccount-range-text": "A registraçion da di addressi IP inte l'intervallo '''$1''', ch'o  l'includde o teu ('''$4'''), a l'è stæta bloccâ da [[User:$3|$3]].\n\nA raxon dæta da $3 a l'è ''$2''",
        "viewpagelogs": "Veddi i log relativi a 'sta paggina.",
+       "nohistory": "A stoia de verscioin de sta paggina a no gh'è.",
        "currentrev": "Verscion attuâle",
        "currentrev-asof": "Ùrtima revixón do $1",
        "revisionasof": "Verscion do $1",
        "history-show-deleted": "Sôlo scancelæ",
        "histfirst": "primma",
        "histlast": "urtima",
+       "historysize": "({{PLURAL:$1|1 byte|$1 byte}})",
        "historyempty": "(vêua)",
        "history-feed-title": "Stöia de revixioin",
+       "history-feed-description": "Stoia da paggina insce sto scito",
        "history-feed-item-nocomment": "$1 o $2",
+       "history-feed-empty": "A paggina domandâ a no l'existe; porriæ ese stæta scassâ da-o scito o rinominâ. Amîa inta [[Special:Search|paggina de riçerca]] se ghe ne foise de neuve.",
+       "history-edit-tags": "Modiffica i etichette de verscioin seleçionæ",
+       "rev-deleted-comment": "(Ogetto da modiffica rimosso)",
+       "rev-deleted-user": "(nomme utente rimosso)",
+       "rev-deleted-event": "(dettaggi do registro rimossi)",
+       "rev-deleted-user-contribs": "[nomme utente ò addresso IP rimosso - modiffica ascosa da-a stoia]",
+       "rev-deleted-text-permission": "Questa verscion da paggina a l'è stæta '''scassâ'''.\nConsurta o [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} log de cançellaçioin] pe-i dettaggi.",
+       "rev-suppressed-text-permission": "Questa verscion da paggina a l'è stæta '''sopressa'''.\nConsurta a [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} lista de soprescioin] pe-i dettaggi.",
+       "rev-deleted-text-unhide": "Questa verscion da paggina a l'è stæta '''scassâ'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.\nA-i aministratoî l'è ancon consentio de [$1 visualizzâ sta verscion] se necessaio.",
+       "rev-suppressed-text-unhide": "Questa verscion da paggina a l'è stæta '''rimossa'''.\nConsurta a [{{fullurl:{{#Special:Log}}/suppress|page={{PAGENAMEE}}}} lista de rimoçion] pe-i dettaggi.\nA-i aministratoî l'è ancon consentio de [$1 visualizzâ sta verscion] se necessaio.",
+       "rev-deleted-text-view": "Questa verscion da paggina a l'è stæta '''scassâ'''.\nTi ti peu amiala; consurta a [{{fullurl:{{#Special:Log}}/suppress|page={{PAGENAMEE}}}} lista de rimoçion] pe-i dettaggi.",
+       "rev-suppressed-text-view": "Questa verscion da paggina a l'è stæta '''sopressa'''.\nTi ti peu amiâla; consurta a [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} lista de soprescioin] pe-i dettaggi.",
+       "rev-deleted-no-diff": "No ti peu amiâ sto diff percose un-a de verscioin a l'è stæta '''scassâ'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.",
+       "rev-suppressed-no-diff": "No ti peu fâ sto confronto tra verscioin perché un-a a l'è stæta '''scassâ'''.",
+       "rev-deleted-unhide-diff": "Un-a de verscioin de sto confronto a l'è stæta '''scassâ'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.\nTi ti peu ancon [$1 fâ sto confronto] se necessaio.",
        "rev-delundel": "fanni védde/ascondi",
-       "revdelete-radio-set": "Sci",
+       "rev-showdeleted": "mostra",
+       "revisiondelete": "Scassa ò ripristina verscioin",
+       "revdelete-nooldid-title": "Verscion non specificâ",
+       "revdelete-no-file": "O file specificou o no l'existe.",
+       "revdelete-show-file-confirm": "T'ê seguo de voei amiâ a verscion scassâ do file \"<nowiki>$1</nowiki>\" do $2 a $3?",
+       "revdelete-show-file-submit": "Sci",
+       "revdelete-selected-text": "{{PLURAL:$1|Verscion seleçionâ|Verscioin seleçionæ}} de [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|Verscion seleçionata|Verscioin seleçionæ}} do file [[:$2]]:",
+       "logdelete-selected": "{{PLURAL:$1|Evento do registro seleçionou|Eventi do registro seleçionou}}:",
+       "revdelete-legend": "Imposta e limitaçioin de vixibilitæ:",
+       "revdelete-hide-text": "Testo da verscion",
+       "revdelete-hide-image": "Ascondi i contegnui do file",
+       "revdelete-hide-name": "Ascondi obiettivo e parammetri",
+       "revdelete-hide-comment": "Oggetto da modiffica",
+       "revdelete-hide-user": "Nomme ò addresso IP de l'outô",
+       "revdelete-hide-restricted": "Ascondi i dæti a-i amministratoî ascì",
+       "revdelete-radio-same": "(no cangiâ)",
+       "revdelete-radio-set": "Ascoso",
+       "revdelete-radio-unset": "Vixibbile",
+       "revdelete-suppress": "Ascondi i dæti a-i amministratoî ascì",
+       "revdelete-unsuppress": "Elimmina e limitaçioin in scê verscioin ripristinæ",
+       "revdelete-log": "Raxon:",
+       "revdelete-submit": "Applica {{PLURAL:$1|a-a verscion seleçionâ|a-e verscioin seleçionæ}}",
+       "revdelete-success": "'''Vixibilitæ da verscion agiornâ con successo.'''",
+       "revdelete-failure": "'''A vixibilitæ da verscion a no peu ese agiornâ:'''\n$1",
+       "logdelete-success": "'''Registro de vixibilitæ impostou con successo.'''",
+       "logdelete-failure": "No s'è posciuo impostâ o registro de vixibilitæ: $1",
        "revdel-restore": "càngia a vixibilitæ",
+       "pagehist": "Stoia da paggina",
+       "deletedhist": "Stoia scassâ",
+       "revdelete-hide-current": "Imposcibbile asconde l'ogetto con dæta $1 $2 in quanto o l'è a verscion attuale.",
+       "revdelete-show-no-access": "Imposcibbile mostrâ l'ogetto con dæta $1 $2 in quanto o l'è stæto identificou comme \"riservou\" e no se dispon-e do relativo accesso.",
+       "revdelete-modify-no-access": "Imposcibbile modificâ l'ogetto con dæta $1 $2 in quanto o l'è stæto identificou comme \"riservou\" e no se dispon-e do relativo accesso.",
+       "revdelete-modify-missing": "Imposcibbile modificâ l'ogetto con ID $1: into database o no gh'è!",
+       "revdelete-no-change": "'''Attençion:''' l'ogetto con dæta $1 $2 o l'aveiva zà e impostaçioin de vixibilitæ domandæ.",
+       "revdelete-reason-dropdown": "* Raxoin ciù comun-e pe-o scassamento\n** Violaçion do drito d'outô\n** Commenti ò informaçioin personæ inappropiæ\n** Nomme utente inappropiou\n** Informaçion potençialmente diffamatoia",
+       "revdelete-otherreason": "Un atro motivo:",
+       "revdelete-reasonotherlist": "Un'atra raxon",
+       "revdelete-edit-reasonlist": "Modiffica e raxoin do scassamento",
+       "revdelete-offender": "Aotô da verscion:",
+       "suppressionlog": "Registro de sopprescioin",
+       "mergehistory": "Union de stoie da paggina",
+       "mergehistory-box": "Unisci a stoia de doe paggine:",
+       "mergehistory-from": "Paggina d'origgine:",
+       "mergehistory-into": "Paggina de destinaçion:",
+       "mergehistory-list": "Stoia a-a quæ se peu applicâ l'union",
+       "mergehistory-merge": "L'è poscibbile unî e verscioin de [[:$1]] indicæ chì appreuvo a-a stoia de [[:$2]]. Deuvia a colonna co-i pomelli de opçion pe unî tutte e verscioin scin a-a dæta e oa indicæ. \nNotta che deuviando i pomelli de navegaçion, sta colonna a saiâ azerâ.",
+       "mergehistory-go": "Mostra e modiffiche che peuan ese unie",
+       "mergehistory-submit": "Unisci e verscioin",
+       "mergehistory-empty": "Nisciun-a verscion da unî.",
+       "mergehistory-done": "{{PLURAL:$3|Una verscion de $1 a l'è stæta unia|$3 vercsioin de $1 son stæte unie}} a-a stoia de [[:$2]].",
+       "mergehistory-fail": "Imposcibbile unî e stoie. Verificâ a paggina e i parammetri temporali.",
+       "mergehistory-fail-toobig": "Imposcibbile eseguî l'union da stoia essendoghe ciu che o limmite de $1 {{PLURAL:$1|verscion|verscioin}} da mesciâ.",
+       "mergehistory-no-source": "A paggina d'origgine $1 a no l'existe.",
+       "mergehistory-no-destination": "A paggina de destinaçion $1 a no l'existe.",
+       "mergehistory-invalid-source": "A paggina d'origgine a deve aveighe un tittolo vallido.",
+       "mergehistory-invalid-destination": "A paggina de destinaçion a deve aveighe un tittolo vallido.",
+       "mergehistory-autocomment": "Union de [[:$1]] in [[:$2]]",
+       "mergehistory-comment": "Union de [[:$1]] in [[:$2]]: $3",
+       "mergehistory-same-destination": "A paggina d'origgine e quella de destinaçion no peuan ese a mæxima",
+       "mergehistory-reason": "Raxon:",
+       "mergelog": "Unioin",
        "revertmerge": "Anùlla union",
+       "mergelogpagetext": "Chì de sotta 'na lista di urtime unioin de 'na stoia co-in atra",
        "history-title": "Stöia de revixoìn de \"$1\"",
        "difference-title": "$1: differense tra e verscioin",
+       "difference-title-multipage": "$1 e $2: differençe tra-e paggine",
+       "difference-multipage": "(Differençe tra-e paggine)",
        "lineno": "Linia $1:",
        "compareselectedversions": "Confronta e verscioîn selessionæ",
+       "showhideselectedversions": "Mostra/ascondi verscioin seleçionæ",
        "editundo": "Anùlla",
+       "diff-empty": "(Nisciun-a diferença)",
        "diff-multi-sameuser": "({{PLURAL:$1|Una verscion intermedia|$1 De verscioin intermedie}} de 'n mæximo utente {{PLURAL:$1|a no l'è mostrâ|no son mostræ}})",
+       "diff-multi-otherusers": "({{PLURAL:$1|Una verscion intermedia|$1 De verscioin intermedie}} de {{PLURAL:$2|'n atro utente|$2 utenti}} {{PLURAL:$1|a no l'è mostrâ|no son mostræ}})",
+       "diff-multi-manyusers": "({{PLURAL:$1|Una verscion intermedia|$1 verscioin intermedie}} de ciu che $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrâ|mostræ}})",
        "searchresults": "Resultati da reçerca",
        "searchresults-title": "Rezoltati da riçerca de \"$1\"",
+       "titlematches": "Corispondençe into tittolo de paggine",
+       "textmatches": "Corispondençe into scrito de paggine",
+       "notextmatches": "Nisciun-a corispondença into scrito de paggine",
        "prevn": "Precedenti {{PLURAL:$1|$1}}",
        "nextn": "Proscima {{PLURAL:$1|$1}}",
+       "prev-page": "paggina precedente",
+       "next-page": "paggina succesciva",
        "prevn-title": "{{PLURAL:$1|rezoltato precedénte|rezoltati precedénti}}",
        "nextn-title": "Pròscimo $1 {{PLURAL:$1|rezoltato|rezoltati}}",
        "shown-title": "Fanni védde {{PLURAL:$1|in rizoltato|$1 rizoltati}} pe pàgina",
        "search-result-category-size": "{{PLURAL:$1|1 utente|$1 utenti}} ({{PLURAL:$2|1 sottocategoria|$2 sottocategorie}}, {{PLURAL:$3|1 file|$3 file}})",
        "search-redirect": "(redirect $1)",
        "search-section": "(seçión $1)",
+       "search-category": "(categoria $1)",
+       "search-file-match": "(corrispondença into contegnuo do file)",
        "search-suggest": "Fòscia ti voéivi: $1",
+       "search-rewritten": "Mostro i risultæ pe $1. Atrimenti, çerca $2.",
+       "search-interwiki-caption": "Progetti fræ",
+       "search-interwiki-default": "Risultæ da $1:",
+       "search-interwiki-more": "(atro)",
+       "search-relatedarticle": "corelæ",
        "searchrelated": "corelæ",
        "searchall": "tùtti",
+       "showingresults": "Chì appreuvo se mostra a-o mascimo {{PLURAL:$1|'''1''' risultou|'''$1''' risultæ}} a partî da-o nummero '''$2'''.",
+       "showingresultsinrange": "Chì sotta se mostra scin a {{PLURAL:$1|<strong>1</strong> risultou|<strong>$1</strong> risultæ}} da-o <strong>$2</strong> a-o <strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Risultou <strong>$1</strong> de <strong>$3</strong>|Risultæ <strong>$1 - $2</strong> de <strong>$3</strong>}}",
        "search-nonefound": "Mi n'ho atrovòu ninte",
+       "search-nonefound-thiswiki": "Mi n'ho atrovòu ninte",
+       "powersearch-legend": "Riçerca avançâ",
+       "powersearch-ns": "Çerca inti namespace:",
+       "powersearch-togglelabel": "Seleçion-a:",
+       "powersearch-toggleall": "Tutti",
+       "powersearch-togglenone": "Nisciun",
+       "powersearch-remember": "Aregordite a seleçion pe-e proscime riçerche",
+       "search-external": "Riçerca esterna",
+       "searchdisabled": "La riçerca de {{SITENAME}} a no l'è attiva. Into fra tempo ti peu çercâ in sce Google. \nNotta che i seu indexi di contegnui de {{SITENAME}} porrieivan no ese aggiornæ.)",
+       "search-error": "S'è verificou 'n errô durante a riçerca: $1",
        "preferences": "Preferençe",
        "mypreferences": "Preferençe",
+       "prefs-edits": "Modiffiche effettuæ:",
+       "prefsnologintext2": "Pe modificâ e teu preferençe l'è necessaio effettuâ l'intrata.",
+       "prefs-skin": "Pelle",
        "skin-preview": "Anteprimma",
+       "datedefault": "Nisciun-a preferença",
+       "prefs-labs": "Fonçionalitæ sperimentale",
+       "prefs-user-pages": "Paggine utente",
+       "prefs-personal": "Profî utente",
+       "prefs-rc": "Ùrtimi cangiamenti",
+       "prefs-watchlist": "Sotta oservaçion",
+       "prefs-editwatchlist": "Modiffica a lista sotta oservaçion",
+       "prefs-editwatchlist-label": "Modiffica e paggine da teu lista sotta oservaçion:",
+       "prefs-editwatchlist-edit": "Amia e rimeuvi tittoli in sciâ teu lista sotta oservaçion",
+       "prefs-editwatchlist-raw": "Modiffica a lista sotta oservaçion in formato testo",
+       "prefs-editwatchlist-clear": "Scassa a teu lista sotta oservaçion",
+       "prefs-watchlist-days": "Nummero de giorni da fâ vedde inta lista sotta oservaçion",
+       "prefs-watchlist-days-max": "Mascimo $1 {{PLURAL:$1|giorno|giorni}}",
+       "prefs-watchlist-edits": "Nummero de cangi da fâ vedde co-e fonçioin avançæ:",
+       "prefs-watchlist-edits-max": "Nummero mascimo: 1000",
+       "prefs-watchlist-token": "Token lista sotta oservaçion:",
+       "prefs-misc": "Varrie",
+       "prefs-resetpass": "Cangia a pòula segretta",
+       "prefs-changeemail": "Cangia ò rimeuvi l'adresso e-mail",
+       "prefs-setemail": "imposta un adresso email",
+       "prefs-email": "Opçioin email",
+       "prefs-rendering": "Aspetto",
        "saveprefs": "Sarva",
+       "restoreprefs": "Ripristina e impostaçioin predefinie (in tutte e seçioin)",
        "prefs-editing": "Cangia",
+       "rows": "Righe:",
+       "columns": "Colonne:",
        "searchresultshead": "Çerca",
-       "timezonelegend": "Oùa",
+       "stub-threshold": "Limmite pe-i collegamenti a-i sboççi ($1):",
+       "stub-threshold-sample-link": "esempio",
+       "stub-threshold-disabled": "disattivou",
+       "recentchangesdays": "Nummero de giorni da mostrâ inti urtime modiffiche:",
+       "recentchangesdays-max": "Mascimo $1 {{PLURAL:$1|giorno|giorni}}",
+       "recentchangescount": "Nummero de modiffiche da mostrâ pe difetto:",
+       "prefs-help-recentchangescount": "Comprende i urtime modiffiche, paggine de stoie e registri.",
+       "savedprefs": "E teu preferençe son stæte sarvæ.",
+       "savedrights": "I driti utente de {{GENDER:$1|$1}} son stæti sarvæ.",
+       "timezonelegend": "Fuso oraio:",
+       "localtime": "Oa locale:",
+       "timezoneuseserverdefault": "Adeuvia l'oa predefinia do wiki ($1)",
+       "timezoneuseoffset": "Atro (speciffica a differensa)",
+       "servertime": "Oa do server:",
+       "guesstimezone": "Deuvia l'oa do navegatô",
+       "timezoneregion-africa": "Affrica",
+       "timezoneregion-america": "Amerrica",
+       "timezoneregion-antarctica": "Antartide",
+       "timezoneregion-arctic": "Artide",
+       "timezoneregion-asia": "Axia",
+       "timezoneregion-atlantic": "Oçeano Atlantego",
+       "timezoneregion-australia": "Aostrallia",
+       "timezoneregion-europe": "Euiropa",
+       "timezoneregion-indian": "Oçeano Indian",
+       "timezoneregion-pacific": "Oçeano Paxiffego",
        "allowemail": "Permitti a posta elettronega da ätri utenti",
+       "prefs-searchoptions": "Çerca",
+       "prefs-namespaces": "Namespace:",
        "default": "Predefinïo",
        "prefs-files": "File",
+       "prefs-custom-css": "CSS personalizzou",
+       "prefs-custom-js": "JavaScript personalizzou",
+       "prefs-common-css-js": "CSS/JavaScript condiviso pe tutte e pelle:",
+       "prefs-emailconfirm-label": "Conferma de l'e-mail:",
        "youremail": "Indirìsso email:",
-       "username": "Nomme d'utente",
+       "username": "{{GENDER:$1|Nomme utente}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Membro}} {{PLURAL:$1|do gruppo|di gruppi}}:",
+       "prefs-registration": "Dæta de registraçion:",
        "yourrealname": "Nomme vêo:",
        "yourlanguage": "Léngoa:",
-       "yourvariant": "Differensa",
-       "yournick": "Nommeaggio:",
+       "yourvariant": "Variante da lengoa do contegnuo:",
+       "prefs-help-variant": "A variante o grafia co-a quæ ti prefeisci che e paggine do wiki seggian mostræ.",
+       "yournick": "Nomiagio:",
        "badsig": "Errô in ta firma; controlla i comandi HTML.",
-       "badsiglength": "O nommeaggio o l'é tròppo lóngo; o dêve avéi meno de $1 caratteri.",
+       "badsiglength": "A firma scelta a l'è troppo longa.\nA non deve passâ $1 {{PLURAL:$1|carattere|caratteri}}.",
        "email": "Posta elettronega",
        "prefs-help-realname": "* Nomme vëo (opsionâ): se o se scellie de scrivilo, o sajà dêuviòu pe ascrivighe a paternitæ di contegnûi inviæ.",
        "prefs-help-email": "L'email a no l'é obligatöia, ma a te permette de reçéive a paròlla segrétta se ti l'ascòrdi.",
        "prefs-help-email-others": "Ti ti peu scélie ascì de lasciâ che i âtri te contattan via e-mail co-in ingancio da-a to pàgina utente ò de discuscion sénsa rivelâ a to e-mail quande i atri utenti te contattan.",
+       "prefs-help-email-required": "L'addresso email o ghe veu.",
+       "prefs-info": "Informaçioin de base",
+       "prefs-i18n": "Internaçionalizzaçion",
+       "prefs-signature": "Firma",
+       "prefs-dateformat": "Formato da dæta",
+       "prefs-timeoffset": "Oe de differença",
+       "prefs-advancedediting": "Opçioin generæ",
+       "prefs-editor": "Editô",
+       "prefs-preview": "Anteprimma",
+       "prefs-advancedrc": "Opçioin avançæ",
+       "prefs-advancedrendering": "Opçioin avançæ",
+       "prefs-advancedsearchoptions": "Opçioin avançæ",
+       "prefs-advancedwatchlist": "Opçioin avançæ",
+       "prefs-displayrc": "Opçioin de visualizzaçion",
+       "prefs-displaywatchlist": "Opçioin de visualizzaçion",
+       "prefs-tokenwatchlist": "Token",
+       "prefs-diffs": "Differençe",
+       "prefs-help-prefershttps": "Questa preferença a l'aviâ effetto da-o proscimo accesso.",
+       "email-address-validity-valid": "L'addresso e-mail o pâ vallido",
+       "email-address-validity-invalid": "Scrivi un addresso e-mail vallido",
+       "userrights-reason": "Raxon:",
+       "userrights-no-interwiki": "No ti g'hæ i permissi pe modificâ i driti di utenti insce di atre wiki.",
+       "userrights-nodatabase": "O database $1 o no l'esiste ò o no l'è un database locale.",
+       "userrights-nologin": "Pe assegnâ di driti a-i utenti ti g'hæ da [[Special:UserLogin|intrâ]] comme amministratô.",
+       "userrights-notallowed": "No ti g'hæ o permisso de azonze ò rimeuve i driti di utenti.",
+       "userrights-changeable-col": "Gruppi che ti peu modificâ",
+       "userrights-unchangeable-col": "Gruppi che no ti peu modificâ",
+       "userrights-conflict": "Conflito de modiffica di driti utente! Pe piaxei controlla e conferma e teu modiffiche.",
+       "userrights-removed-self": "T'hæ rimosso con successo i teu driti. E quindi, no ti saiæ ciù in grou de accede a questa paggina.",
+       "group": "Gruppo:",
        "group-user": "Ûtenti",
+       "group-autoconfirmed": "Utenti aotoconfermæ",
+       "group-bot": "Bot",
+       "group-sysop": "Amministratoî",
+       "group-bureaucrat": "Buroccrati",
+       "group-suppress": "Soppressoî",
+       "group-all": "(tutti)",
+       "group-user-member": "{{GENDER:$1|utente}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|utente aotoconfermou|utente aotoconfermâ|utente aotoconfermou/â}}",
+       "group-bot-member": "{{GENDER:$1|bot}}",
+       "group-sysop-member": "{{GENDER:$1|amministratô|amministratrixe|amministratô/trixe}}",
+       "group-bureaucrat-member": "{{GENDER:$1|buroccrate}}",
+       "group-suppress-member": "{{GENDER:$1|soppressô|soppressôa}}",
+       "grouppage-user": "{{ns:project}}:Utenti",
+       "grouppage-autoconfirmed": "{{ns:project}}:Utenti autoconfermæ",
+       "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Amministratoî",
+       "grouppage-bureaucrat": "{{ns:project}}:Buroccrati",
+       "grouppage-suppress": "{{ns:project}}:Soppressoî",
        "right-writeapi": "Deuvia l'API in scrittua",
        "newuserlogpage": "Nêuvi utenti",
        "rightslog": "Diritti d'ûtente",
        "action-edit": "càngia sta pàgina",
+       "action-undelete": "Recuppera sta paggina",
+       "action-suppressrevision": "rivedde e ripristinâ e modiffiche ascose",
        "nchanges": "$1 {{PLURAL:$1|modiffica|modiffiche}}",
        "enhancedrc-history": "cronologia",
        "recentchanges": "Ùrtimi cangiamenti",
        "listfiles": "Lista d'archivvi",
        "listfiles_date": "Dæta",
        "file-anchor-link": "file",
-       "filehist": "Stöia de l'archivio",
+       "filehist": "Stöia do file",
        "filehist-help": "Sciacca insce dæta/ôa pe amiâ o file comm'o s'apresentâva into momento indicòu.",
        "filehist-revert": "Ripristina",
        "filehist-current": "Corrente",
        "filehist-dimensions": "Dimenscioin",
        "filehist-filesize": "Dimension de l'archivvio",
        "filehist-comment": "Coménti",
-       "imagelinks": "Ûzo de l'archivio",
+       "imagelinks": "Ûzo do file",
        "linkstoimage": "{{PLURAL:$1|A segoente pàgina a contegne|E segoenti $1 pàgine contegnan}} colegaménti a-o file:",
        "nolinkstoimage": "No gh'è nisciûnn-a pàgina collegâ con 'sto file.",
        "sharedupload": "'St'archivvio o l'è condiviso; sajeiva a dî c'o pêu ese dêuviòu da ciû progetti wiki.",
        "contributions": "Contribuçioin {{GENDER:$1|utente}}",
        "contributions-title": "Contribuçioìn de $1",
        "mycontris": "Contribuçioin",
+       "anoncontribs": "Contribuçioin",
        "contribsub2": "Pe $1 ($2)",
        "uctop": "(ûrtima pe-a paggina)",
        "month": "Partindo da-o meize (e precedénti):",
        "movelogpage": "Lista di stramûi",
        "movereason": "Raxon",
        "revertmove": "Ristorâ",
-       "delete_and_move": "Scassa e mescia",
        "delete_and_move_confirm": "Scì, scassa a pagina",
        "delete_and_move_reason": "Levoö pe fâ röso pe un remescio",
        "export": "Espòrta pàgine",
        "tooltip-compareselectedversions": "Amia e diferense tra e doê verscioìn seleçionæ de sta paggina chì.",
        "tooltip-watch": "Azónzi sta pàgina a-a têu lista d'osservæ speçiâli",
        "tooltip-rollback": "\"Rollback\" annulla e modiffiche a sta pagina de l'urtimo contributô co-in solo clic.",
-       "tooltip-undo": "\"Anùlla\" o permette de anulâ sto cangiaménto e o l'arve o modolo de cangiaménto into modalitæ anteprìmma. Ti peu ascì métte a raxón inte l'ogetto do cangiaménto.",
+       "tooltip-undo": "\"Anùlla\" o permette de anulâ sto cangiaménto e o l'arve o modulo de cangiaménto inta modalitæ anteprìmma. Ti peu ascì métte a raxón inte l'ogetto do cangiaménto.",
        "tooltip-summary": "Scrîvi 'na scintexi",
        "common.css": "/** i stili css scriti chie se applicana tutte e skin */",
        "anonymous": "Utente anonimmo de {{SITENAME}}",
diff --git a/languages/i18n/lki.json b/languages/i18n/lki.json
new file mode 100644 (file)
index 0000000..5d3317d
--- /dev/null
@@ -0,0 +1,3403 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Arash71",
+                       "Hosseinblue",
+                       "Lakzon",
+                       "Mjbmr"
+               ]
+       },
+       "tog-underline": ":خط کیشائن ئۀ ژئر پئؤن",
+       "tog-hideminor": "تغییرات گؤجر ئه رزگ-فئرست تغیرات اخیر ئآشاریا بوو",
+       "tog-hidepatrolled": "دسکاریۀل گه دیار بینۀ ئژ فئرست-رزگ تغییرات اخیر بشارا",
+       "tog-newpageshidepatrolled": "وڵگۀل گه دیار بینۀ ئژ فئرست-رزگ ولگۀل تازۀ بشارا",
+       "tog-hidecategorization": "Hide categorization of pages",
+       "tog-extendwatchlist": " کؤل رزگ-فئرست الؤن(آلشت)کریال-تغیرات نیشان دۀ،نۀ هر تنیا دؤمائنۀل",
+       "tog-usenewrc": "تنیا آڵؤن(آلشتی)کریال تازۀ ؤ لیست پئگیریۀل رزگ بنی-گروه بندی کۀ",
+       "tog-numberheadings": "شؤمارۀ  نئ خودکار سروڵگۀل-عناوین",
+       "tog-showtoolbar": "دیار دائن ابزار دسکاری",
+       "tog-editondblclick": "دسکاری ولگۀل ئۀ دؤ گل کلیک کردن",
+       "tog-editsectiononrightclick": "دسکاری کردن راسال-بخشۀل ئۀ کلیک راست کردن ئۀرؤی سرولگۀل باج کار",
+       "tog-watchcreations": "وڵگۀلئ گه مَسازم ؤ پرؤندۀلئ گه مۀنم اضافۀ که فئرست سئرکردنۀل",
+       "tog-watchdefault": "ولگۀل ؤ پرؤندۀلئ گه دسکاری مۀکم بنه نؤم فئرست سئرکردن",
+       "tog-watchmoves": "ولگۀل ؤ پرؤندۀلئ گه هئزۀ مۀم-جابجا مۀکم بنه نؤم فئرست سئرکردن",
+       "tog-watchdeletion": "ولگۀل ؤ پرؤندۀلئ گه پاکۀ مۀکم بنه نؤم فئرست سئرکردن",
+       "tog-watchrollback": "ولگۀل گه ماره ما-بازگردانی مۀکم بنه نؤم فئرست سئرکردن",
+       "tog-minordefault": "کؤڵ دسکاری بیۀل به عنؤان پئش فرض عڵامت بۀرن",
+       "tog-previewontop": "پیش نمایش وهِ رئ جعبۀ نمایش نیشؤن به",
+       "tog-previewonfirst": "پئش نمایش-ورئ سئرکردن ئۀ اؤڵئن دسکاری نیشؤن به",
+       "tog-enotifwatchlistpages": "ئۀر وڵگۀ یا پرؤندئه ئژ فئرست-رزگ پی‌گیری‌ۀلم دسکاری بی نامه ئۀرا مه کِلّ کۀ",
+       "tog-enotifusertalkpages": "هۀنئگه-وختئ گه ئۀ وڵگۀ گپ کابریم تغییر کریا نامه ئۀرا مه کِل کۀ",
+       "tog-enotifminoredits": "ئۀر تغییرۀل-آڵؤنۀل(آلشتۀل)گؤجۀریجی ئۀر وڵگۀل ؤ پرؤندۀلم کریا نامه ئۀرا مه کِل کۀ",
+       "tog-enotifrevealaddr": "نیشانی ایمیل مه ئۀر ایمیل‌ل حاوواڵ رۀسن نیشؤن دۀ",
+       "tog-shownumberswatching": "گلۀ شؤماری-شؤمار کاربۀل پی‌گیر نیشان دۀ",
+       "tog-oldsig": ":امضائ گه ایسۀ درینئ",
+       "tog-fancysig": "(امضا چؤی ویکی‌متن بوو(بدون پئؤن خودکار نیائن",
+       "tog-uselivepreview": "استفاده از پیش‌نمایش زنده",
+       "tog-forceeditsummary": "هۀنئ گه-وختئ که خؤلاصۀ دسکاریم نَنیؤیسائۀ خۀؤۀ رم کۀ",
+       "tog-watchlisthideown": "دسکاریۀل ووژم ئژ فئرست سئرکردن بشارآ",
+       "tog-watchlisthidebots": "دسکاریۀل ربات ئژ فئرست سئرکردن بشآرا",
+       "tog-watchlisthideminor": "دسکاریۀل گؤجۀر ئژ فئرست سئرکردن بشارآ",
+       "tog-watchlisthideliu": "دسکاری کاربرۀلئ گه هۀتۀنئ نؤم سیستم ئۀ فئرست سئرکردن بشارآ",
+       "tog-watchlistreloadautomatically": "Reload the watchlist automatically whenever a filter is changed (JavaScript required)",
+       "tog-watchlisthideanons": "دةسکاری کاربرةل ناشنا ئة لیست نمائش بشارآ",
+       "tog-watchlisthidepatrolled": "دسکاریۀل گشت خورده-سئرکریا ئژ فئرست سئرکردن بشآرا",
+       "tog-watchlisthidecategorization": "نهفتن رده‌بندی صفحه‌ها",
+       "tog-ccmeonemails": "رؤی نؤیسیائ  ئژ نامۀلئگه کِلۀ مِه هۀم کاربرۀل-بهرۀگرۀل ئۀرا ووژم کِل که",
+       "tog-diffonly": "محتوا وةڵگة، ئة ژئر تفاوت دیار ناوو/نمایش ندهد",
+       "tog-showhiddencats": "دسۀل-رزگۀل آشاریآ نیشؤن دۀ",
+       "tog-norollbackdiff": "دؤما واگردانی تفاوت نیشؤن نه",
+       "tog-useeditwarning": "وخت ئه درچئن  ولگۀ دسکاری ئۀر دسکاریۀل ذخیرل نؤیمئ داشت هؤشدارمۀ بئدۀ",
+       "tog-prefershttps": "همؤیشۀ ئۀرا ئۀ نؤم سیستم هۀتن ئژ اتصالۀل امن بهرۀ بگر-استفادۀ کۀ",
+       "underline-always": "همؤیشۀ",
+       "underline-never": "هؤیچ وخت",
+       "underline-default": "پوسته یا مِه نِی کۀر پیش‌فرض",
+       "editfont-style": ":شئؤۀ قلم جعبهٔ دسکاری",
+       "editfont-default": "پیشفرض مِه نِی کۀر",
+       "editfont-monospace": "قلم ئۀ ۋاصلۀ ثابت",
+       "editfont-sansserif": "قلم بئ گوشۀ",
+       "editfont-serif": "قلم گوشۀ دار",
+       "sunday": "یشۀمۀ",
+       "monday": "دؤشۀمۀ",
+       "tuesday": "سه شۀمۀ",
+       "wednesday": "چووار شۀمۀ",
+       "thursday": "پنج شۀمۀ",
+       "friday": "جؤمۀ",
+       "saturday": "شۀمۀ",
+       "sun": "(هؤۀر(خورشید",
+       "mon": "دؤشۀمۀ",
+       "tue": "سه شۀمۀ",
+       "wed": "چووارشۀمۀ",
+       "thu": "پنج شۀمۀ",
+       "fri": "جؤمۀ",
+       "sat": "شۀمۀ",
+       "january": "نورووژ/دی",
+       "february": "(خاکه لێه(بهمن",
+       "march": "(مانگ ئێد(اسفندگان",
+       "april": "(په نجه(فروردین",
+       "may_long": "(مێرێان(اردیبهشت",
+       "june": "(گاکوور(خرداد",
+       "july": "تیر)ئاگرانی)",
+       "august": "مرداد)مردار)",
+       "september": "(ماڵه ژێر(شهریور",
+       "october": "(ماڵه ژێر دوماێنه(مهر",
+       "november": "آبان)تویل ته کن)",
+       "december": "(مانگه سێه(آذر",
+       "january-gen": "دی)نورووژ)",
+       "february-gen": "(خاکه لێه(بهمن",
+       "march-gen": "(مانگ ئێد(اسفندگان",
+       "april-gen": "(په نجه(فروردین",
+       "may-gen": "(مێرێان(اردیبهشت",
+       "june-gen": "(گاکوور(خرداد",
+       "july-gen": "تیر)ئاگرانی)",
+       "august-gen": "مرداد)مردار یا مرداڵ)",
+       "september-gen": "(ماڵه ژێر(شهریور",
+       "october-gen": "(ماڵه ژێر دوماێنه(مهر",
+       "november-gen": "آبان)تویل ته کن)",
+       "december-gen": "مانگه سێه/آذر",
+       "jan": "دی/نورووژ",
+       "feb": "خاکه لێه/بهمن",
+       "mar": "مانگ ئێد/اسفندگان",
+       "apr": "په نجه/فروردین",
+       "may": "مێرێان/اردیبهشت",
+       "jun": "گاکوور/خرداد",
+       "jul": "تیر/ئاگرانی",
+       "aug": "مرداد/مردار",
+       "sep": "ماڵه ژێر/شهریور",
+       "oct": "ماڵه ژێر دوماێنه/مهر",
+       "nov": "آبان/تویل ته کن",
+       "dec": "مانگه سێه/آذر",
+       "january-date": "$1 ژانویه",
+       "february-date": "$1 فوریه",
+       "march-date": "$1 مارس",
+       "april-date": "$1 آوریل",
+       "may-date": "$1 می",
+       "june-date": "$1 ژوئن",
+       "july-date": "ژولای $1",
+       "august-date": "$1 اگوست",
+       "september-date": "$1 سپتامبر",
+       "october-date": "$1 اکتبر",
+       "november-date": "$1 نوامبر",
+       "december-date": "$1 دسامبر",
+       "pagecategories": "{{PLURAL:$1|رده|ردۀل}}",
+       "category_header": "\"وۀلگۀل  ردهٔ \"$1",
+       "subcategories": "ژیر رده ل",
+       "category-media-header": "\"پۀروۀندۀل ردهٔ \"$1",
+       "category-empty": "<em>این رده در حال حاضر حاوی هیچ صفحه یا پرونده‌ای نیست.</em>",
+       "hidden-categories": "{{PLURAL:$1|رده آشاریا|رده ل آشاریا}}",
+       "hidden-category-category": "رده‌های پنهان",
+       "category-subcat-count": "{{PLURAL:$2|این رده تنها حاوی زیرردهٔ زیر است.|{{PLURAL:$1|این زیررده|این $1 زیررده}} در این رده قرار {{PLURAL:$1|دارد|دارند}}؛ این رده در کل حاوی $2 زیررده است.}}",
+       "category-subcat-count-limited": "ئئ رده/ڕِزگة شامل {{PLURAL:$1|یک|$1}} ژئر رده زیر است.",
+       "category-article-count": "{{PLURAL:$2|این رده فقط دارای صفحهٔ زیر است.|{{PLURAL:$1|این صفحه|این $1 صفحه}} در این رده قرار {{PLURAL:$1|دارد|دارند}}؛ این رده در کل حاوی $2 صفحه است.}}",
+       "category-article-count-limited": "{{PLURAL:$1|صفحهٔ|$1 صفحهٔ}} زیر در ردهٔ فعلی قرار دارند.",
+       "category-file-count": "{{PLURAL:$2|This category contains only the following file.|The following {{PLURAL:$1|file is|$1 files are}} in this category, out of $2 total.}}",
+       "category-file-count-limited": "{{PLURAL:$1|پروندهٔ|$1 پروندهٔ}} زیر در ردهٔ فعلی قرار دارند.",
+       "listingcontinuesabbrev": "(ادامه)",
+       "index-category": "صفحه‌های نمایه‌شده",
+       "noindex-category": "صفحه‌های نمایه‌نشده",
+       "broken-file-category": "صفحه‌های دارای پیوند خراب به پرونده",
+       "about": "دۀربارۀ",
+       "article": "وةڵگة محتوایی",
+       "newwindow": "(واز کردن ئۀر دۀروۀچۀ جدید)",
+       "cancel": "ئآهووسانن/لغو",
+       "moredotdotdot": "...ویشتر/فرةتر",
+       "morenotlisted": "لیست کامل نیۀ",
+       "mypage": "وةڵگة",
+       "mytalk": "قسۀ-گۀپ",
+       "anontalk": "قسۀ-گۀپ",
+       "navigation": "ناوبری",
+       "and": "&#32;و",
+       "qbfind": "پیاکردن-ئادین",
+       "qbbrowse": "مِنِی -گۀشتن",
+       "qbedit": "دسکاری",
+       "qbpageoptions": "ئئ وةڵگة",
+       "qbmyoptions": "وۀلگۀل مِ",
+       "faq": "پرسش‌های متداول",
+       "faqpage": "Project:پرسش‌های متداول",
+       "actions": "کارۀل",
+       "namespaces": "فضای نامۀل",
+       "variants": "قصۀ کِرۀل",
+       "navigation-heading": "منوی ناوبری",
+       "errorpagetitle": "خطا",
+       "returnto": "بازگشت به $1",
+       "tagline": "دۀربارۀ {{SITENAME}}",
+       "help": "یاری کردن",
+       "search": "گئردین/مهِ نی",
+       "searchbutton": "گئردین/مهِ نی",
+       "go": "بِچۆ",
+       "searcharticle": "بِچۆ",
+       "history": "تاریخ وةڵگة",
+       "history_short": "تاریخچه",
+       "updatedmarker": "به‌روزشده از آخرین باری که سرزده‌ام",
+       "printableversion": "نؤسخۀ قاوول چاپ",
+       "permalink": "پیوۀند دائمی",
+       "print": "چاپ",
+       "view": "دیین/سئرکردن",
+       "view-foreign": "مشاهده در $1",
+       "edit": "دةسکاری",
+       "edit-local": "ویرایش توضیحات محلی",
+       "create": "دؤِرس کردن/سازین",
+       "create-local": "افزودن توضیحات محلی",
+       "editthispage": "ئئ وةڵگۀ دةسکاری کةن",
+       "create-this-page": "دؤرِس کردن ئئ وةڵگة",
+       "delete": "حۀذف کردن/پاک کردن",
+       "deletethispage": "حذف این صفحه",
+       "undeletethispage": "بازگردانی ئئ وةڵگة",
+       "undelete_short": "احیای {{PLURAL:$1|یإ دةسکاری|$1 دةسکاری}}",
+       "viewdeleted_short": "نمایش {{PLURAL:$1|یک ویرایش حذف‌شده|$1 ویرایش حذف‌شده}}",
+       "protect": "پروژۀ",
+       "protect_change": "تغییر/آلِشت",
+       "protectthispage": "محافظت إژ ئئ وةڵگة",
+       "unprotect": "تغییر محافظت",
+       "unprotectthispage": "تغییر محافظت ئئ وةڵگة",
+       "newpage": "وةڵگة  تازۀ",
+       "talkpage": "گةپ دةربارة ئئ وةڵگة",
+       "talkpagelinktext": "قسۀ-گۀپ",
+       "specialpage": "وةڵگة/پةرة  ویژة",
+       "personaltools": "ابزارۀل ووژی/شخصی",
+       "articlepage": "نمایش مةقاڵة",
+       "talk": "قسۀل-گۀپۀل",
+       "views": "دیین/سئرکردن",
+       "toolbox": "ابزارۀل",
+       "userpage": "وةڵگة کاربۀر بؤین",
+       "projectpage": "وةڵگة پروژۀ بوین",
+       "imagepage": "وةڵگة پرونده بؤین",
+       "mediawikipage": "نمایش وةڵگة پیغام",
+       "templatepage": "نمایش وةڵگة الگو",
+       "viewhelppage": "نمایش وةڵگة هؤمیاری",
+       "categorypage": "نمایش وةڵگة رده/ڕِزگ",
+       "viewtalkpage": "نمایش وةڵگة  گةپ ؤ گفت",
+       "otherlanguages": "وۀ زوونۀلئ تر",
+       "redirectedfrom": "(تغییرمسیر إژ $1)",
+       "redirectpagesub": "وةڵگة تغییرمسیر",
+       "redirectto": ":تغییر مسیر به",
+       "lastmodifiedat": ".ئئ وۀلگۀآخرین گِل ئۀ $1 سات $2 تۀغیر گِرتیۀسئ",
+       "viewcount": "إژ ئئ وةڵگة  {{PLURAL:$1|یإ گِل|$1$1چةن گِل}} بازدید بیة.",
+       "protectedpage": "وةڵگة محافظت/پڵؤم بیة",
+       "jumpto": ":وازآ کردن/پریدن وۀ",
+       "jumptonavigation": "ناوبری",
+       "jumptosearch": "گئردین/مهِ نی",
+       "view-pool-error": "متأسفانه سرورها در حال حاضر دچار بار اضافی هستند.\nتعداد زیادی از کاربران دارند تلاش می‌کنند که این صفحه را ببینند.\nلطفاً قبل از تلاش دوباره برای دیدن این صفحه مدتی صبر کنید.\n\n$1",
+       "generic-pool-error": "متأسفانه سرورها در حال حاضر دچار بار اضافی هستند.\nتعداد زیادی از کاربران دارند تلاش می‌کنند که این صفحه را ببینند.\nلطفاً قبل از تلاش دوباره برای دیدن این صفحه مدتی صبر کنید.",
+       "pool-timeout": "اتمام مهلت انتظار برای قفل",
+       "pool-queuefull": "صف مخزن پر است",
+       "pool-errorunknown": "خطای نادیاری/ناشنا",
+       "pool-servererror": ".$1 پول سنتر سرویس در دسترس نیست",
+       "poolcounter-usage-error": "خطای استفاده: $1",
+       "aboutsite": "دۀربارۀ {{SITENAME}}",
+       "aboutpage": "Project:درباره",
+       "copyright": " محتوایۀل هانإ ژئرنظر اجازه‌نامهٔ $1 مۀگۀر یۀگإ خلاف یۀ بوشرئ/ذکر بو",
+       "copyrightpage": "{{ns:project}}:حق تکثیر",
+       "currentevents": "رویدادۀل ایسۀ",
+       "currentevents-url": "Project:رویدادةل ایسة",
+       "disclaimers": "دروو نامه -تکذیب نامه",
+       "disclaimerpage": "Project:تکذیب‌نامهٔ عمومی",
+       "edithelp": "راهنمای دۀسکاری کردن",
+       "helppage-top-gethelp": "راهنما",
+       "mainpage": "وةڵگة اصلی/بِنچةک",
+       "mainpage-description": "وةڵگة اصلی/بِنچةک",
+       "policy-url": "Project:سیاستةل",
+       "portal": "دۀروازۀ کاربرۀل",
+       "portal-url": "Project:دۀروازۀ کاربرۀل",
+       "privacy": "أمنیۀت رازداری",
+       "privacypage": "Project:سیاست راز ئاشاردن",
+       "badaccess": "خطای دسترسی",
+       "badaccess-group0": "هؤمة اجازة کارێ گإ گستِتانة نئرینان",
+       "badaccess-groups": "عملی که درخواست کرده‌اید منحصر به کاربران {{PLURAL:$2|این گروه|این گروه‌ها}} است: $1.",
+       "versionrequired": "نسخهٔ $1 از نرم‌افزار مدیاویکی لازم است",
+       "versionrequiredtext": "برای دیدن این صفحه به نسخهٔ $1 از نرم‌افزار مدیاویکی نیاز دارید.\nبه [[Special:Version|این صفحه]] مراجعه کنید.",
+       "ok": "خوو/ باشد",
+       "retrievedfrom": "إژ \"$1\" گیریائۀ",
+       "youhavenewmessages": "{{PLURAL:$3|درین}}$1$2",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|هؤمة}} $1 د {{PLURAL:$3|کاربةرێ تِر|$3 کاربةر}}دِرین($2).",
+       "youhavenewmessagesmanyusers": "شما از تعدادی کاربر $1 دارید ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|پیغام جدید|999=پیامةل تازه}}",
+       "newmessagesdifflinkplural": "{{formatnum:$1}} {{PLURAL:$1|تغییر|999=تغییر}} اخیر",
+       "youhavenewmessagesmulti": ".پیغامةل جدیدی ئة $1 درین",
+       "editsection": "دةسکاری",
+       "editold": "دةسکاری",
+       "viewsourceold": "سئرکردن بِنچۀک/مۀنبۀع",
+       "editlink": "دةسکاری",
+       "viewsourcelink": "سئرکردن بِنچۀک/مۀنبۀع",
+       "editsectionhint": "دۀسکاری بۀخش: $1",
+       "toc": "محتویات",
+       "showtoc": "نیشان دائن",
+       "hidetoc": "ئآشاردن-پنهان کردن",
+       "collapsible-collapse": "آشاردِن",
+       "collapsible-expand": "کلنگاکردن/گسترش",
+       "confirmable-confirm": "{{GENDER:$1|هؤمة}} مطمئن هئینان؟",
+       "confirmable-yes": "أرێ-بةلئ",
+       "confirmable-no": "نة-نةخئر",
+       "thisisdeleted": "نمایش یا احیای $1؟",
+       "viewdeleted": "دیئن$1?",
+       "restorelink": "{{PLURAL:$1|یإ گِل دةسکاری حةذف بیة$1 دةسکاری حةذف بیة}}",
+       "feedlinks": ":حاوواڵ خوةن",
+       "feed-invalid": "نوع خوراک خبرخوان مجاز نیست.",
+       "feed-unavailable": ":حاوواڵ خوةنةل وة دةسترس نیئِن",
+       "site-rss-feed": "خوراک آراس‌اس برای $1",
+       "site-atom-feed": " $1 أرا atom هاوول خوۀن",
+       "page-rss-feed": "خوراک آراس‌اس برای «$1»",
+       "page-atom-feed": " $1 أرا atom هاوول خوۀن",
+       "red-link-title": "$1(ئئ وۀلگۀ نیۀسئ)",
+       "sort-descending": "مرتب‌سازی نزولی",
+       "sort-ascending": "مرتب‌سازی صعودی",
+       "nstab-main": "وةڵگة",
+       "nstab-user": "وۀلگۀ کاربۀر",
+       "nstab-media": "وةڵگة رسانه",
+       "nstab-special": "وۀلگۀ/پۀرۀ ویژۀ",
+       "nstab-project": "وۀلگۀ پروژۀ",
+       "nstab-image": "فایل",
+       "nstab-mediawiki": "پیغام",
+       "nstab-template": "نمونه",
+       "nstab-help": "وۀلگۀل راهنما",
+       "nstab-category": "رِزگ -دۀسۀ",
+       "mainpage-nstab": "وةڵگة اصلی/بِنچةک",
+       "nosuchaction": "چنین عملی وجود نئرێ",
+       "nosuchactiontext": "عمل مشخص‌شده در نشانی اینترنتی نامجاز است.\nممکن است نشانی اینترنتی را اشتباه وارد کرده باشید یا پیوند مشکل‌داری را دنبال کرده باشید.\nهمچنین ممکن است ایرادی در نرم‌افزار استفاده‌شده در {{SITENAME}} وجود داشته باشد.",
+       "nosuchspecialpage": "چنین صفحهٔ ویژه‌ای وجود ندارد",
+       "nospecialpagetext": "<strong>شما یک صفحهٔ ویژهٔ نامجاز را درخواست کرده‌اید.</strong>\n\nفهرستی از صفحه‌های ویژهٔ مجاز در [[Special:SpecialPages|{{int:specialpages}}]] وجود دارد.",
+       "error": "خطا",
+       "databaseerror": "خطای پایگاه داده",
+       "databaseerror-text": "مشکلی در پایگاه‌داده‌ها رخ داده است. \nاین ممکن است نشان‌دهندهٔ ایرادی در نرم‌افزار باشد.",
+       "databaseerror-textcl": "یک خطای پرس‌وجوی پایگاه داده‌های رخ داده است.",
+       "databaseerror-query": "پرس‌ و جو: $1",
+       "databaseerror-function": "تابع: $1",
+       "databaseerror-error": "خطا: $1",
+       "transaction-duration-limit-exceeded": "In order to avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, trying doing multiple smaller operations instead.",
+       "laggedslavemode": "'''هشدار:''' صفحه ممکن است به‌روزرسانی‌های اخیر را شامل نشود.",
+       "readonly": "پایگاه داده قفل بیة",
+       "enterlockreason": "دلیلی برای قفل کردن ذکر کنید، که حاوی تقریبی از زمانی باشد که قفل برداشته خواهد شد",
+       "readonlytext": "پایگاه داده در حال حاضر در برابر تغییرات و ایجاد صفحات قفل شده‌است؛ این وضعیت احتمالاً به خاطر بهینه‌سازی و رسیدگی‌های معمول است که پس از آن وضع به حالت عادی بازخواهد گشت.\n\nمدیری که آن را قفل کرده این توضیح را ارائه کرده‌است: $1",
+       "missing-article": "پایگاه داده متن صفحهٔ با نام «$1» $2 را که باید پیدا می‌کرد نیافت.\n\nاین مشکل معمولاً به علت دنبال‌کردن یک پیوند تفاوت تاریخ‌گذشته یا تاریخچهٔ صفحه‌ای که حذف شده‌است، رخ می‌دهد.\n\nدر غیر این صورت ممکن است اشکالی در نرم‌افزار پیدا کرده باشد.\nلطفاً این مشکل را با ذکر نشانی اینترنتی به یکی از [[Special:ListUsers/sysop|مدیران]] گزارش دهید.",
+       "missingarticle-rev": "(شمارهٔ نسخه: $1)",
+       "missingarticle-diff": "(تفاوت: $1، $2)",
+       "readonly_lag": "پایگاه داده به طور خودکار قفل شده‌است تا نسخه‌های پشتیبان با نسخهٔ اصلی هماهنگ شوند",
+       "nonwrite-api-promise-error": "سرآیند اچ‌تی‌تی‌پی 'Promise-Non-Write-API-Action' ارسال شد ولی درخواست به یک رابط برنامه‌نویسی پودمان نوشتن بود.",
+       "internalerror": "خطای داخلی",
+       "internalerror_info": "خطای داخلی: $1",
+       "internalerror-fatal-exception": "نوع استثنای مخرب \"$1\"",
+       "filecopyerror": "نشد از پروندهٔ «$1» روی «$2» نسخه‌برداری شود.",
+       "filerenameerror": "نشد از پروندهٔ «$1» روی «$2» نسخه‌ برداری شود.",
+       "filedeleteerror": ".نشد پروندهٔ «$1» حذف شود",
+       "directorycreateerror": "نشد مسیر $1 را ایجاد کرد.",
+       "directoryreadonlyerror": "دایرکتوری \"$1\" فقط خواندنی است.",
+       "directorynotreadableerror": "دایرکتوری \"$1\" قابل خواندن نیست.",
+       "filenotfound": "پروندهٔ «$1» یافت نشد.",
+       "unexpected": "مقدار غیرمنتظره: «$1»=«$2».",
+       "formerror": "خطا: نمی‌توان فرم را فرستاد.",
+       "badarticleerror": "نمی‌توان این عمل را بر این صفحه انجام داد.",
+       "cannotdelete": "امکان حذف صفحه یا تصویر «$1» وجود ندارد.\nممکن است قبلاً فرد دیگری آن را حذف کرده باشد.",
+       "cannotdelete-title": "نمی‌توان صفحهٔ «$1» را حذف کرد",
+       "delete-hook-aborted": "حذف توسط قلاب لغو شد.\nتوضیحی در این مورد داده نشد.",
+       "no-null-revision": "امکان ایجاد نسخهٔ پوچ برای صفحهٔ «$1» وجود نداشت",
+       "badtitle": "عنوان گۀن/بد",
+       "badtitletext": "عنوان درخواستی نامعتبر، خالی، یا عنوانی میان‌زبانی یا میان‌ویکی‌ای با پیوند نادرست بود.\nممکن است حاوی یک یا چند نویسه باشد که نمی‌توانند در عنوان‌ها استفاده شوند.",
+       "title-invalid-empty": "عنوان صفحهٔ مورد درخواست خالی است یا فقط عنوان فضای نام ذکر شده‌است.",
+       "title-invalid-utf8": "عنوان صفحهٔ مورد نظر دارای نویسهٔ نادرست یونیکد است.",
+       "title-invalid-interwiki": "صفحهٔ درخواست شده دارای پیوند میان‌ویکی است که نمی‌تواند در عنوان‌ها استفاده شود.",
+       "title-invalid-talk-namespace": "صفحهٔ مورد درخواست به عنوان صفحهٔ بحثی که وجود ندارد، بازگشت می‌کند",
+       "title-invalid-characters": "عنوان صفحهٔ مورد درخواست نویسة نادرست «$1» دارد.",
+       "title-invalid-relative": "عنوان دارای نشانی است. عنوان نشانی‌ها (./, ../) بی‌اعتبار هستند چون معمولاً توسط مرورگر کاربران غیرقابل دسترس هستند.",
+       "title-invalid-magic-tilde": "عنوان صفحهٔ مورد درخواست دارای عبارت جادوئی بی‌اعتبار است (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": " نویسه یونیکد باشد{{PLURAL:$1|byte|bytes}} $1 عنوان صفحهٔ مورد درخواست خیلی طولانی است. نباید از",
+       "title-invalid-leading-colon": ".صفحهٔ درخواستی دارای : بی‌اعتبار در ابتدای عنوانش است",
+       "perfcached": "داده‌های زیر از حافظهٔ نهانی فراخوانی شده‌اند و ممکن است کاملاً به‌روز نباشند. حداکثر {{PLURAL:$1|یک نتیجه| $1 نتیجه}} در حافظهٔ نهانی قابل دسترس است.",
+       "perfcachedts": "داده‌های زیر از حافظهٔ نهانی فراخوانی شده‌اند و آخرین بار در $1 به‌روزرسانی شدند. حداکثر {{PLURAL:$4|یک نتیجه|$4 نتیجه}} در حافظهٔ نهانی قابل دسترس است.",
+       "querypage-no-updates": "امکان به‌روزرسانی این صفحه فعلاً غیرفعال شده‌است.\nاطلاعات این صفحه ممکن است به‌روز نباشد.",
+       "viewsource": "سئرکردن بِنچۀک/مۀنبۀع",
+       "viewsource-title": "نمایش بِنچةک ئةرا $1",
+       "actionthrottled": "جلوی عمل شما گرفته شد",
+       "actionthrottledtext": "به منظور جلوگیری از انتشار خرابکاری، اجازه ندارید که چنین عملی را بیش از چند بار در یک مدت زمان کوتاه انجام بدهید.\nلطفاً پس از چند دقیقه دوباره تلاش کنید.",
+       "protectedpagetext": ".ئئ وةڵگة ئةرا جلوگیری إژ دةسکاری یا فعالیت تر محافظت بیة",
+       "viewsourcetext": ":می‌توانید متن مبدأ این صفحه را مشاهده کنید یا از آن نسخه بردارید",
+       "viewyourtext": "می‌توانید کد مبدأ <strong>ویرایش‌هایتان</strong> در این صفحه را ببینید و کپی کنید.",
+       "protectedinterface": "این صفحه ارائه‌دهندهٔ متنی برای واسط کاربر این نرم‌افزار در این ویکی است و به منظور پیشگیری از خرابکاری محافظت شده‌است.\nبرای افزودن یا تغییر دادن ترجمه برای همهٔ ویکی‌ها، لطفاً از [//translatewiki.net/ translatewiki.net]، پروژهٔ محلی‌سازی مدیاویکی، استفاده کنید.",
+       "editinginterface": "<strong>هشدار:</strong> صفحه‌ای که ویرایش می‌کنید شامل متنی است که در واسط کاربر این نرم‌افزار به کار رفته‌است.\nتغییر این صفحه منجر به تغییر ظاهر واسط کاربر این نرم‌افزار برای دیگر کاربران خواهد شد.",
+       "translateinterface": "برای افزودن یا تغییر دادن ترجمه برای همهٔ ویکی‌ها، لطفاً از [//translatewiki.net/ translatewiki.net]، پروژهٔ محلی‌سازی مدیاویکی، استفاده کنید.",
+       "cascadeprotected": "این صفحه در مقابل ویرایش محافظت شده‌است چون در {{PLURAL:$1|صفحهٔ|صفحه‌های}} محافظت‌شدهٔ زیر که گزینهٔ «آبشاری» در {{PLURAL:$1|آن|آن‌ها}} انتخاب شده قرار گرفته‌است:\n$2",
+       "namespaceprotected": ".هؤمة اجازهٔ دةسکاری وةڵگةل فضای نام '''$1''' نئرین",
+       "customcssprotected": "هؤمة  اجازهٔ دةسکاری این صفحهٔ سی‌اس‌اس را ندارید، زیرا حاوی تنظیم‌های شخصی یک کاربر دیگر است.",
+       "customjsprotected": "شما اجازهٔ ویرایش این صفحهٔ جاوااسکریپت را ندارید، زیرا حاوی تنظیم‌های شخصی یک کاربر دیگر است.",
+       "mycustomcssprotected": "شما دارای مجوز ویرایش این صفحهٔ سی‌اس‌اس نیستید.",
+       "mycustomjsprotected": "شما دارای مجوز ویرایش این صفحهٔ جاوااسکریپت نیستید.",
+       "myprivateinfoprotected": "شما دارای مجوز ویرایش اطلاعات شخصی خود نیستید.",
+       "mypreferencesprotected": "شما دارای مجوز ویرایش تنظیمات خود نیستید.",
+       "ns-specialprotected": ".وةڵگةل ویژه غیر قابل دةسکاریِن",
+       "titleprotected": "این عنوان توسط [[User:$1|$1]] در برابر ایجاد محافظت شده‌است.\nدلیل ارائه‌شده این است: «''$2''».",
+       "filereadonlyerror": "تغییر پرونده «$1» ممکن نیست چون مخزن پرونده «$2» در حالت فقط خواندنی قرار دارد.\n\nمدیری که آن را قفل کرده چنین توضیحی را ذکر کرده:  «$3».",
+       "invalidtitle-knownnamespace": "عنوان نامعتبر با فضای نام «$2» و متن «$3»",
+       "invalidtitle-unknownnamespace": "عنوان نامعتبر با فضای نام ناشناختهٔ شمارهٔ $1 و متن «$2»",
+       "exception-nologin": "وارد سیستم نؤینۀ",
+       "exception-nologin-text": "حواهشا بوونإ سیستم تا دسترسی تان داشتوئإ ئئ وةڵگة",
+       "exception-nologin-text-manual": "لطفاً  $1  تا بتوانید به این صفحه یا عمل دسترسی داشته باشید.",
+       "virus-badscanner": "پیکربندی بد: پویشگر ویروس ناشنا/نادیاری: $1",
+       "virus-scanfailed": "  )$1 پویش ناموفق (کد",
+       "virus-unknownscanner": ":ضدویروس ناشناخته",
+       "logouttext": "'''ایسة دةر چئن هؤمة ثبت بیة.'''\nتوجه داشته باشید که تا حافظهٔ نهان مرورگرتان را پاک نکنید، بعضی از صفحات ممکن است همچنان به گونه‌ای نمایش یابند که انگار وارد شده‌اید.",
+       "welcomeuser": "خؤةش هةتینة/هاتینة $1!",
+       "welcomecreation-msg": "حساوو کاربری هؤمة دؤرس بی.\nفراموش نکنید که [[Special:Preferences|ترجیحات {{SITENAME}}]] خود را تغییر دهید.",
+       "yourname": ":نؤم کاربری",
+       "userlogin-yourname": "نؤم بهرۀگر-کاربر",
+       "userlogin-yourname-ph": "نام کاربۀری تؤن وارد کۀن",
+       "createacct-another-username-ph": "نام کاربۀری تؤن وارد کۀن",
+       "yourpassword": ":رمز عبور",
+       "userlogin-yourpassword": "رۀمز",
+       "userlogin-yourpassword-ph": "یک گذرواژه وارد کنید",
+       "createacct-yourpassword-ph": "یک گذرواژه وارد کنید",
+       "yourpasswordagain": "تکرار گذرواژه:",
+       "createacct-yourpasswordagain": "گذرواژه را دوباره وارد کنید",
+       "createacct-yourpasswordagain-ph": "گذرواژه را وارد کنید برای بار دوم",
+       "remembermypassword": "رمزعبورت وة ئئ رایانة ئةویرت/یادت بو(تابیشترإژ$1{{PLURAL:$1|رووژةل|رووژ}})",
+       "userlogin-remembermypassword": "مإ وارد  بی بیل",
+       "userlogin-signwithsecure": "إژ ورود امن استفاده کةن",
+       "yourdomainname": ":دامنهٔ شما",
+       "password-change-forbidden": ".شما نمی‌توانید گذرواژه‌ها را در این ویکی تغییر دهید",
+       "externaldberror": "خطایی در ارتباط با پایگاه داده رخ داده است یا اینکه شما اجازهٔ به‌روزرسانی حساب خارجی خود را ندارید.",
+       "login": "نؤم هۀتن سیستم",
+       "nav-login-createaccount": " إ نؤم هةتن سیستم/ حساوو کاربةری سازین",
+       "userlogin": " إ نؤم هةتن سیستم/ حساوو کاربةری سازین",
+       "userloginnocreate": "نؤم هۀتن سیستم",
+       "logout": "دةرچئن/خروج",
+       "userlogout": "دةرچئن/خروج",
+       "notloggedin": "وارد سیستم نؤینۀ",
+       "userlogin-noaccount": "حساوو کاربۀری نرین؟",
+       "userlogin-joinproject": "{{SITENAME}}نام نؤیسی کۀن",
+       "nologin": "حساوو کاربۀری نرین؟$1",
+       "nologinlink": "حساووئ أرا ووژتان بِسازِن",
+       "createaccount": "حساووئ أرا ووژتان بِسازِن",
+       "gotaccount": "حساوو کاربۀری دِرین؟$1",
+       "gotaccountlink": "نؤم هۀتن سیستم",
+       "userlogin-resetlink": "جزئیات ورود إ ویرتان/یادتان چئة؟",
+       "userlogin-resetpassword-link": "رۀمزۀتان  ویر/ یاد  چئۀ؟",
+       "userlogin-helplink2": "کمک با ورود",
+       "userlogin-loggedin": "شما در حال حاضر به عنوان {{GENDER:$1|$1}} وارد شده‌اید.\nاز فرم پایین برای ورود به عنوان یک کاربر دیگر استفاده کنید.",
+       "userlogin-createanother": "حساووئ کاربةری تِر بِسازِن",
+       "createacct-emailrequired": "نیشانی ایمیل",
+       "createacct-emailoptional": ")نشانی ایمیل (اختیاری",
+       "createacct-email-ph": "نیشانی ایمیل ووژتان بنؤیسِن",
+       "createacct-another-email-ph": "نیشانی ایمیل ووژتان بنؤیسِن",
+       "createaccountmail": "استفاده از رمز عبور موقت تصادفی و ارسال آن به آدرس ایمیل مشخص شده",
+       "createacct-realname": "*نام راسکانی/واقعی *دل بخواهی",
+       "createaccountreason": ":دةلیل",
+       "createacct-reason": "دةلیل",
+       "createacct-reason-ph": "ئةرا حساووێ  تر مةسازین؟",
+       "createacct-submit": "حساووئ أرا ووژتان بِسازِن",
+       "createacct-another-submit": "حساووئ أرا ووژتان بِسازِن",
+       "createacct-benefit-heading": "{{SITENAME}} is made by people like you.",
+       "createacct-benefit-body1": "{{PLURAL:$1|دۀسکاری|دۀسکاریۀل}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|وۀلگۀ|وۀلگۀل}}",
+       "createacct-benefit-body3": "recent {{PLURAL:$1|contributor|contributors}}",
+       "badretype": "گذرواژةلێ گإ نۆیساتة چؤِی یةک نیِن",
+       "usernameinprogress": ". دِرێ حساوو دؤرسة مةکإ . خواهشا صبر کةن",
+       "userexists": ".نام کاربةری‌ گإ واردت کردئة قبلاً استفاده بیة\n.خواهشا نامێ تر استفادة کةن",
+       "loginerror": "خطای إ نام هةتن سیستم",
+       "createacct-error": "خطای  حساوو کاربةری سازین",
+       "createaccounterror": "نمآوو ئئ حساووة بِسازین: $1",
+       "nocookiesnew": "حساوو کاربةری سازیا، اما هؤمة أ سیستم نهةتینة/نهاتینة.\n{{SITENAME}} برای ورود کاربران به سامانه از کوکی استفاده می‌کند.\nشما کوکی‌ها را از کار انداخته‌اید.\nلطفاً کوکی‌ها را به کار بیندازید، و سپس با نام کاربری و گذرواژهٔ جدیدتان به سامانه وارد شوید.",
+       "nocookieslogin": "{{SITENAME}} برای ورود کاربران به سامانه از کوکی‌ها استفاده می‌کند.\nشما کوکی‌ها را از کار انداخته‌اید.\nلطفاً کوکی‌ها را به کار بیندازید و دوباره امتحان کنید.",
+       "nocookiesfornew": "حساوو کاربةری نةسازریا، زیرا نتوانستیم منبع آن را تأیید کنیم.\nمطمئن شوید که کوکی‌ها فعال هستند، آن‌گاه صفحه را از نو بارگیری کنید و دوباره امتحان کنید.",
+       "noname": ".هؤمة نام کاربةری معتبری دیاری نکردئة",
+       "loginsuccesstitle": "موفق بین چینإ سیستم",
+       "loginsuccess": "هؤمة ایسة هةتیإ نؤم سیستم {{SITENAME}} وۀ نام\"$1\".'",
+       "nosuchuser": "کاربةری وۀ نام «$1» ئة ائرة نیة.\nنام کاربةری وة کةڵنگی و گؤجةری حروف حساسة .\nاملای نام را بررسی کنید، یا [[Special:UserLogin/signup|یک حساب کاربری تازه بسازید]].",
+       "nosuchusershort": "هؤیچ کاربةری وة نام ''$1'' ئة ائرة نیة.\nاملایتان را وارسی کنید.",
+       "nouserspecified": ".باید یإ گِلة  نام کاربةری دیاری کئین",
+       "login-userblocked": ".ئئ کاربةرة بةسیائة. إنؤم هةتِن سیستم مجاز نیة",
+       "wrongpassword": "گذرواژه‌ای که وارد کردید نادرستة.\nخواهشا دووباره تلاش کةن.",
+       "wrongpasswordempty": "گذرواژه‌ای که وارد کرده‌اید، خالی است.\nلطفاً دوباره تلاش کنید.",
+       "passwordtooshort": "گذرواژه باید دست‌کم {{PLURAL:$1|۱ حرف|$1 حرف}} داشته باشد.",
+       "passwordtoolong": "گذرواژه نمی تواند حروفش بیشتر از {{PLURAL:$1|۱ حرف|$1 حرف}}  باشد.",
+       "passwordtoopopular": "Commonly chosen passwords cannot be used. Please choose a more unique password.",
+       "password-name-match": "گذرواژهٔ شما باید با نام کاربری شما تفاوت داشته باشد.",
+       "password-login-forbidden": "استفاده از این نام کاربری و گذرواژه ممنوع است.",
+       "mailmypassword": "دووارة رمز نؤیسائن",
+       "passwordremindertitle": "یادآور گذرواژهٔ {{SITENAME}}",
+       "passwordremindertext": "یک نفر (احتمالاً خود شما، با نشانی آی‌پی $1) گذرواژهٔ جدیدی برای حساب کاربری شما در {{SITENAME}} درخواست کرده‌است ($4). \nیک گذرواژهٔ موقت برای کاربر «$2» ساخته شده و برابر با «$3» قرار داده شده‌است.\nاگر هدفتان همین بوده‌است، اکنون باید وارد سامانه شوید و گذرواژهٔ جدیدی برگزینید.\nگذرواژهٔ موقت شما ظرف {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\n\nاگر کس دیگری این درخواست را کرده‌است یا اینکه شما گذرواژهٔ پیشین خود را به یاد آورده‌اید و دیگر تمایلی به تغییر آن ندارید، می‌توانید این پیغام را نادیده بگیرید و همان گذرواژهٔ پیشین را به کار برید.",
+       "noemail": ".هؤیچ نیشانی ایمیلی ئةرا کاربةر «$1» ثبت نؤیة",
+       "noemailcreate": "شما باید یک آدرس ایمیل درست فراهم کنید",
+       "passwordsent": "گذرواژه‌ای جدید به آدرس ایمیل ثبت شده برای «$1» ارسال شد.\nلطفاً پس از دریافت آن، دوباره به سیستم وارد شوید.",
+       "blocked-mailpassword": "نشانی آی‌پی شما از ویرایش بازداشته شده‌است و از این رو به منظور جلوگیری از سوءاستفاده اجازهٔ بهره‌گیری از قابلیت بازیابی گذرواژه را ندارد.",
+       "eauthentsent": "یک ایمیل تأیید برای آدرس ایمیل به نشانی مورد نظر ارسال شد.\nقبل از اینکه ایمیل دیگری قابل ارسال به این آدرس باشد، باید دستورهایی که در آن ایمیل آمده است را جهت تأیید این مساله که این آدرس متعلق به شماست، اجرا کنید.",
+       "throttled-mailpassword": "یإ گِلة رمز عبور  {{PLURAL:$1| وۀ ساعت |$1 وۀساعتةل}}کِل/ارسال بیة/.\nسی نئهاگئری د أذیأت بییئن، فأقأط یئ گئل رازینە گوڤاردئن د أنجومانامە د نۊ زئنە بییە د هأر {{PLURAL:$1|ساعأت|$1 ساعأتیا}} کئل بییە.",
+       "mailerror": "خطا در ارسال ایمیل: $1",
+       "acct_creation_throttle_hit": "بازدیدکنندگان این ویکی که از نشانی آی‌پی شما استفاده می‌کنند در روز گذشته {{PLURAL:$1|یک حساب کاربری|$1 حساب کاربری}} ساخته‌اند، که بیشترین تعداد مجاز در آن بازهٔ زمانی است.\nبه همین خاطر، بازدیدکنندگانی که از این نشانی آی‌پی استفاده می‌کنند نمی‌توانند در حال حاضر حساب جدیدی بسازند.",
+       "emailauthenticated": "نشانی ایمیل شما در $2 ساعت $3 تأیید شده است.",
+       "emailnotauthenticated": "آدرس ایمیل شما هنوز تأیید نشده است.\nبرای هیچ‌یک از ویژگی‌های زیر، ایمیل ارسال نخواهد شد.",
+       "noemailprefs": "برای راه‌اندازی این قابلیت‌ها یک آدرس ایمیل در ترجیحات خود مشخص کنید.",
+       "emailconfirmlink": "نیشانی ایمیل ووژتان تأئید کةن",
+       "invalidemailaddress": "آدرس ایمیل واردشدهٔ قابل قبول نیست، چرا که دارای ساختار نامعتبری است.\nلطفاً آدرسی با ساختار صحیح وارد کنید و یا بخش مربوط را خالی بگذارید.",
+       "cannotchangeemail": "آدرس‌های ایمیل حساب کاربری در این ویکی قابل تغییر نیست.",
+       "emaildisabled": "این وب سایت قادر به ارسال ایمیل نیست.",
+       "accountcreated": "حساوو کاربةری سازیا",
+       "accountcreatedtext": "حساوو کاربةری ئةرا [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|گةپ]]) ایجاد بیة.",
+       "createaccount-title": "ایجاد حساب کاربری در {{SITENAME}}",
+       "createaccount-text": "یک نفر برای ایمیل شما یک حساب کاربری در {{SITENAME}} با نام «$2» ایجاد کرده‌است ($4)، که گذرواژهٔ آن چنین است: $3\nشما باید به سیستم وارد شوید تا گذرواژهٔ خود را تغییر بدهید.\n\nاگر این حساب اشتباهی ساخته شده است، این پیغام را نادیده بگیرید.",
+       "login-throttled": "شما به تازگی چندین‌بار برای ثبت ورود تلاش کرده‌اید.\nلطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.",
+       "login-abort-generic": "ورود شما ناموفق بود - خاتمهٔ ناگهانی داده شد",
+       "login-migrated-generic": "حساب کاربری شما منتقل شده‌است، و نام کاربری‌تان دیگر در این ویکی وجود ندارد.",
+       "loginlanguagelabel": "$1:زوون",
+       "suspicious-userlogout": "درخواست هؤمة ئةرا  دةرچئن إژ سیستم  رد بیة زیرا به نظر می‌رسد که این  .درخواست توسط یک مرورگر معیوب یا پروکسی میانگیر کل/ارسال بیة",
+       "createacct-another-realname-tip": "نام راسکانی/واقعی دڵ بخواهیة.\nاگر آن را وارد کنید هنگام ارجاع به آثارتان و انتساب آن‌ها به شما از نام واقعی‌تان استفاده خواهد شد.",
+       "pt-login": "نؤم هۀتن.",
+       "pt-login-button": "نؤم هۀتن سیستم",
+       "pt-createaccount": "حساووئ أرا ووژتان بِسازِن",
+       "pt-userlogout": "دةرچئن/خروج",
+       "php-mail-error-unknown": "خطای ناشناخته در تابع  mail()‎ پی‌اچ‌پی",
+       "user-mail-no-addy": "تلاش برای ارسال ایمیل بدون آدرس ایمیل.",
+       "user-mail-no-body": "سعی کردید ایمیلی با محتوای بی‌دلیل کوتاه و یا خالی بفرستید.",
+       "changepassword": "تغییردائن رمز",
+       "resetpass_announce": "شما باید برای پایان ورود به سامانه، گذرواژهٔ جدیدی را تنظیم کنید.",
+       "resetpass_header": "تغییر گذرواژهٔ حساب کاربری",
+       "oldpassword": "گذرواژهٔ پیشین:",
+       "newpassword": "گذرواژهٔ تازه:",
+       "retypenew": "گذرواژهٔ تازه را دوباره وارد کنید",
+       "resetpass_submit": "تنظیم گذرواژه و ورود به سامانه",
+       "changepassword-success": "گذرواژهٔ شما با موفقیت تغییر داده شد!",
+       "changepassword-throttled": "شما به تازگی چندین‌بار برای ثبت ورود تلاش کرده‌اید.\nلطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.",
+       "resetpass_forbidden": "نمی‌توان گذرواژه‌ها را تغییر داد",
+       "resetpass-no-info": "برای دسترسی مستقیم به این صفحه شما باید به سامانه وارد شده باشید.",
+       "resetpass-submit-loggedin": "تغییردائن رمز",
+       "resetpass-submit-cancel": "ئآهووسانن/لغو",
+       "resetpass-wrong-oldpass": "گذرواژهٔ موقت یا اخیر نامعتبر.\nممکن است که شما همینک گذرواژه‌تان را با موفقیت تغییر داده باشید یا درخواست یک گذرواژهٔ موقت تازه کرده باشید.",
+       "resetpass-recycled": "لطفاً رمز عبور خود را به چیز دیگری غیر از رمز عبور فعلی تنظیم کنید.",
+       "resetpass-temp-emailed": "شما با یک کد ایمیل شدهٔ موقت وارد شده‌اید.\nبرای پایان ورود، شما باید رمز عبور جدیدی اینجا وارد کنید:",
+       "resetpass-temp-password": ":رمز عبور موقت",
+       "resetpass-abort-generic": "تغییر گذرواژه به دست یکی از افزونه‌ها لغو شده است.",
+       "resetpass-expired": "رمز عبور شما منقضی شده‌است. لطفاً برای ورود رمز عبور جدیدی را تنظیم کنید.",
+       "resetpass-expired-soft": "رمز عبور شما منقضی شده‌است، و نیاز به تنظیم مجدد دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تنظیم مجدد آن بعدآً، دکمه \"{{int:resetpass-submit-cancel}}\" را کلیک کنید.",
+       "resetpass-validity-soft": "گذرواهٔ شما صحیح نیست: $1\n\nلطفاً یک گذرواژهٔ تازه الآن انتخاب کنید یا بر «{{int:resetpass-submit-cancel}}» کلیک کنید که دوباره آن را بعداً انتخاب کنید.",
+       "passwordreset": "بازنشانی گذرواژه",
+       "passwordreset-text-one": "برای بازنشانی گذرواژه‌تان این فرم را کامل کنید.",
+       "passwordreset-text-many": "{{PLURAL:$1|برای دریافت یک گذرواژهٔ موقت از طریق ایمیل، یکی از خانه‌ها را پر کنید.}}",
+       "passwordreset-disabled": "بازنشانی گذرواژه در این ویکی غیرفعال شده است.",
+       "passwordreset-emaildisabled": "قابلیت‌های ایمیل در این ویکی غیرفعال شده‌اند.",
+       "passwordreset-username": ":نؤم کاربری",
+       "passwordreset-domain": "دامنه:",
+       "passwordreset-capture": "ایمیل نهایی نشان داده شود؟",
+       "passwordreset-capture-help": "اگر این گزینه را علامت بزنید، ایمیل (حاوی گذرواژهٔ موقت) به شما نشان داده خواهد شد و برای کاربر نیز فرستاده خواهد شد.",
+       "passwordreset-email": ":نیشانی ایمیل",
+       "passwordreset-emailtitle": "جزئیات حساب در {{SITENAME}}",
+       "passwordreset-emailtext-ip": "یک نفر (احتمالاً شما، با نشانی آی‌پی $1) درخواست بازنشانی گذرواژه‌تان در {{SITENAME}} ($4) را کرده‌است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این آدرس ایمیل مرتبط هستند:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} پس از {{PLURAL:$5|یک روز|$5 روز}} باطل خواهند شد.\nشما باید هم‌اکنون ثبت ورود کنید و گذرواژه‌ای جدید برگزینید. اگر فکر می‌کنید شخص دیگری این درخواست را داده است یا اگر گذرواژهٔ اصلی‌تان را به یاد آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
+       "passwordreset-emailtext-user": "کاربر $1 از {{SITENAME}} درخواست بازنشانی گذرواژهٔ شما در {{SITENAME}} ($4) را کرده است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این آدرس ایمیل مرتبط است:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} تا {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\nشما باید هم‌اکنون وارد شده و یک گذرواژهٔ جدید برگزینید. اگر شخص دیگری این درخواست را داده است، یا اگر گذرواژهٔ اصلی‌تان را به خاطر آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
+       "passwordreset-emailelement": "نام کاربری: \n$1\n\nگذرواژهٔ موقت: \n$2",
+       "passwordreset-emailsentemail": "اگر ایمیلی را برای حساب کاربریتان مشخص کرده باشید، یک نامهٔ بازنشانی گذرواژه فرستاده شده‌است.",
+       "passwordreset-emailsent-capture": "یک ایمیل بازنشانی که در پایین نمایش داده شده، فرستاده شده است.",
+       "passwordreset-emailerror-capture": "ایمیل بازنشانی، که در زیر نمایش داده شده، ایجاد شد، ولی ارسال آن به {{GENDER:$2|کاربر}} موفقیت‌آمیز نبود: $1",
+       "changeemail": "تغییر یا حذف نشانی ایمیل",
+       "changeemail-header": "برای تغییر ایمیلتان این فرم را کامل کنید. برای حذف ایملیتان کافی است بخش ایمیل را خالی رها کنید و فرم را ارسال کنید.",
+       "changeemail-passwordrequired": "برای تائید این تغییر باید گذرواژه‌تان را وارد کنید.",
+       "changeemail-no-info": ".برای دسترسی مستقیم به این صفحه شما باید به سیستم وارد شده باشید",
+       "changeemail-oldemail": ":نشانی ایمیل ایسة هؤمة",
+       "changeemail-newemail": ":نشانی ایمیل تازة",
+       "changeemail-newemail-help": "برای حذف ایمیل باید این بخش را خالی رها کنید در نتیجه امکان بازگردانی گذرواژه و دریافت ایمیل از ویکی برای شما مقدور نخواهد بود.",
+       "changeemail-none": "(هؤیچ کام)",
+       "changeemail-password": "گذرواژهٔ {{SITENAME}} هؤمة:",
+       "changeemail-submit": "تغییر ایمیل",
+       "changeemail-throttled": "شما به مراتب برای ورود تلاش کرده‌اید.\nلطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.",
+       "changeemail-nochange": "لطفاً رایانامهٔ جدید و متفاوتی وارد کنید.",
+       "resettokens": "بازنشانی شناساننده‌ها",
+       "resettokens-text": "شما می توانید شناساننده‌ها که اجازهٔ دسترسی به برخی داده‌های خصوصی مرتبط با حسابتان را می‌دهد بازنشانی کنید.\nدر صورتی باید این کار را انجام دهید که تصادقاً آن‌ها را با کسی در میان گذاشته‌اید یا به حسابتان نفوذ شده است.",
+       "resettokens-no-tokens": "هیچ شناساننده‌ای برای بازنشانی وجود ندارد.",
+       "resettokens-tokens": "شناساننده‌ها:",
+       "resettokens-token-label": "$1 (مقدار کنونی: $2)",
+       "resettokens-watchlist-token": "شناسانندهٔ خوراک وبِی [[Special:Watchlist|تغییرات صفحه‌هایی که پی‌گیری می‌کنید]] (اتم/آراس‌اس)",
+       "resettokens-done": "بازنشانی شناساننده‌ها.",
+       "resettokens-resetbutton": "بازشناسی شناساننده‌های گزیده‌شده.",
+       "bold_sample": "متن پررنگ",
+       "bold_tip": "متن پررنگ",
+       "italic_sample": "متن کۀچ/هؤۀل",
+       "italic_tip": "متن کۀچ/هؤۀل",
+       "link_sample": "عنوان پیوند",
+       "link_tip": "پیوند درونی",
+       "extlink_sample": "http://www.example.com عنوان پیوند",
+       "extlink_tip": ") را فراموش نکنید http:// پیوند به بیرون (پیشوند",
+       "headline_sample": "متن عنوان",
+       "headline_tip": "عنوان سطح ۲",
+       "nowiki_sample": "متن قالب‌بندی‌نشده اینجا وارد شود",
+       "nowiki_tip": "نادیده‌گرفتن قالب‌بندی ویکی",
+       "image_tip": "تصویر داخل متن",
+       "media_tip": "پیوند پرونده",
+       "sig_tip": "امضای هومۀ و برچسب زۀمان",
+       "hr_tip": " )خط افقی(از آن کم استفاده کنید",
+       "summary": "خلاصه:",
+       "subject": "عنوان:",
+       "minoredit": "یۀ دۀسکاری جزئیکۀ",
+       "watchthis": "پی‌گیری ئئ وۀلگۀ",
+       "savearticle": "ذۀخیرۀ وۀلگۀ",
+       "preview": "پیش‌نمایش",
+       "showpreview": "پیش‌نمایش",
+       "showdiff": "نمایش تغییرةل/پالانةل",
+       "blankarticle": "<strong>هشدار:</strong> شما در حال ایجاد صفحه خالی هستید.\nاگر «{{int:savearticle}}» را دوباره کلیک کنید، صفحه بدون محتوا ایجاد می‌شود.",
+       "anoneditwarning": "<strong>هشدار:</strong> شما وارد نشده‌اید. نشانی آی‌پی شما برای عموم قابل مشاهده خواهد بود اگر هر تغییری ایجاد کنید. اگر <strong>[$1 وارد شوید]</strong> یا <strong>[$2 یک حساب کاربری بسازید]</strong>، ویرایش‌هایتان به نام کاربری‌تان نسبت داده خواهد شد، همراه با مزایای دیگر.",
+       "anonpreviewwarning": "''شما به سامانه وارد نشده‌اید. ذخیره کردن باعث می‌شود که نشانی آی‌پی شما در تاریخچهٔ این صفحه ثبت گردد.''",
+       "missingsummary": "'''یادآوری:''' شما خلاصهٔ ویرایش ننوشته‌اید.\nاگر دوباره دکمهٔ «{{int:savearticle}}» را فشار دهید ویرایش شما بدون آن ذخیره خواهد شد.",
+       "selfredirect": "<strong>هشدار:</strong> شما در حال تغییرمسیر صفحه به خودش هستید.\nامکان دارد هدف اشتباهی را برای تغییرمسیر انتخاب کردید، یا ممکن است صفحهٔ اشتباهی را ویرایش می‌کنید.\n\nاگر بر روی \"{{int:savearticle}}\" دوباره کلیک کنید، تغییرمسیر ساخته خواهد شد.",
+       "missingcommenttext": "لطفاً توضیحی در زیر بیفزایید.",
+       "missingcommentheader": "<strong>یادآوری:</strong> شما موضوع/عنوان این یادداشت را مشخص نکرده‌اید.\nاگر دوباره دکمهٔ «{{int:savearticle}}» را فشار دهید ویرایش شما بدون آن ذخیره خواهد شد.",
+       "summary-preview": "پیش‌نمایش خلاصه:",
+       "subject-preview": ":پیش‌نمایش موضوع",
+       "previewerrortext": "در زمان تلاش برای نمایش دادن تغییرات شما، خطای رخ داد.",
+       "blockedtitle": "کاربر بسته شده‌است",
+       "blockedtext": "<strong>دسترسی حساب کاربری یا نشانی آی‌پی شما بسته شده‌است.</strong>\n\nاین قطع دسترسی توسط $1 انجام شده است.\nدلیل ارائه‌شده چنین است: <em>$2</em>\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
+       "autoblockedtext": "دسترسی نشانی آی‌پی شما قطع شده‌است، زیرا این نشانی آی‌پی توسط کاربر دیگری استفاده شده که دسترسی او توسط $1 قطع شده‌است.\nدلیل ارائه‌شده چنین است:\n\n:''$2''\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه نشانی ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
+       "blockednoreason": "دلیلی مشخص نشده‌است",
+       "whitelistedittext": "برای ویرایش مقاله‌ها باید $1.",
+       "confirmedittext": "شما باید، پیش از ویرایش صفحات، آدرس ایمیل خود را مشخص و تأیید کنید. لطفاً از طریق [[Special:Preferences|ترجیحات کاربر]] این کار را صورت دهید.",
+       "nosuchsectiontitle": "چنین بخشی پیدا نشد",
+       "nosuchsectiontext": "شما تلاش کرده‌اید یک بخش در صفحه را ویرایش کنید که وجود ندارد.\nممکن است در مدتی که شما صفحه را مشاهده می‌کردید این بخش جا به جا یا حذف شده باشد.",
+       "loginreqtitle": "ورود به سامانه لازم است",
+       "loginreqlink": "نؤم هۀتن سیستم",
+       "loginreqpagetext": "برای دیدن صفحه‌های دیگر باید $1.",
+       "accmailtitle": "گذرواژه فرستاده شد.",
+       "accmailtext": "یک گذرواژهٔ تصادفی برای [[User talk:$1|$1]] به $2 فرستاده شد. می‌توان آن را از صفحهٔ ''[[Special:ChangePassword|تغییر گذرواژه]]'' که هنگام ثبت ورود نمایش می‌یابد تغییر داد.",
+       "newarticle": "(تازه)",
+       "newarticletext": "شما پیوندی را دنبال کرده‌اید و به صفحه‌ای رسیده‌اید که هنوز وجود ندارد.\nبرای ایجاد صفحه، در مستطیل زیر شروع به نوشتن کنید (برای اطلاعات بیشتر به [$1 صفحهٔ راهنما] مراجعه کنید).\nاگر به اشتباه اینجا آمده‌اید، دکمهٔ «بازگشت» مرورگرتان را بزنید.",
+       "anontalkpagetext": "----''این صفحهٔ بحث برای کاربر گمنامی است که هنوز حسابی درست نکرده است یا از آن استفاده نمی‌کند.\nبنا بر این برای شناسایی‌اش مجبوریم از نشانی آی‌پی عددی استفاده کنیم.\nچنین نشانی‌های آی‌پی ممکن است توسط چندین کاربر به شکل مشترک استفاده شود.\nاگر شما کاربر گمنامی هستید و تصور می‌کنید اظهار نظرات نامربوط به شما صورت گرفته است، لطفاً برای پیشگیری از اشتباه گرفته شدن با کاربران گمنام دیگر در آینده [[Special:UserLogin/signup|حسابی ایجاد کنید]] یا [[Special:UserLogin|به سامانه وارد شوید]].''",
+       "noarticletext": "این صفحه هم‌اکنون دارای هیچ متنی نیست.\nشما می‌توانید در صفحه‌های دیگر [[Special:Search/{{PAGENAME}}|عنوان این صفحه را جستجو کنید]]،\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} سیاهه‌های مرتبط را جستجو کنید]،\nیا [{{fullurl:{{FULLPAGENAME}}|action=edit}} این صفحه را ویرایش کنید]</span>.",
+       "noarticletext-nopermission": "\nThere is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages, or <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>, but you do not have permission to create this page.",
+       "missing-revision": "ویرایش #$1 از صفحهٔ «{{FULLPAGENAME}}» موجود نیست.\n\nمعمولاً در اثر پیوند به تاریخچهٔ به‌روز نشدهٔ صفحهٔ حذف شده است.\nمی‌توانید جزئیات بیشتر را در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] بیابید.",
+       "userpage-userdoesnotexist": "حساب کاربر «<nowiki>$1</nowiki>» ثبت نشده‌است.\nلطفاً مطمئن شوید که می‌خواهید این صفحه را ایجاد یا ویرایش کنید.",
+       "userpage-userdoesnotexist-view": "حساب کاربری «$1» ثبت نشده‌است.",
+       "blocked-notice-logextract": "دسترسی این کاربر در حال حاضر بسته است.\nآخرین مورد سیاهه قطع دسترسی در زیر آمده‌است:",
+       "clearyourcache": "<strong>نکته:</strong> پس از ذخیره‌کردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.\n*<strong>فایرفاکس / سافاری:</strong> کلید <em>Shift</em> را نگه دارید و روی دکمهٔ <em>Reload</em> کلیک کنید، یا کلید‌های <em>Ctrl-F5</em> یا <em>Ctrl-R</em> را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های <em>⌘-R</em>)\n*<strong>گوگل کروم:</strong> کلیدهای <em>Ctrl+Shift+R</em> را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های <em>⌘-Shift-R</em>)\n*<strong>اینترنت اکسپلورر:</strong> کلید <em>Ctrl</em> را نگه‌دارید و روی دکمهٔ <em>Refresh</em> کلیک کنید، یا کلید‌های <em>Ctrl-F5</em> را با هم فشار دهید\n*<strong>اپرا:</strong> حافظهٔ نهانی مرورگر را از طریق منوی <em>Tools &rarr; Preferences</em> پاک کنید",
+       "usercssyoucanpreview": "'''نکته:''' پیش از ذخیره‌کردن پرونده سی‌اس‌اس خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
+       "userjsyoucanpreview": "'''نکته:''' پیش از ذخیره‌کردن پروندهٔ جاوااسکریپت خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
+       "usercsspreview": "'''فراموش مکنید که شما فقط دارید پیش‌نمایش سی‌اس‌اس کاربری‌تان را می‌بینید.'''\n'''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
+       "userjspreview": "'''به یاد داشته باشید که شما فقط دارید جاوااسکریپت کاربری‌تان را امتحان می‌کنید/پیش‌نمایش آن را می‌بینید.'''\n'''این جاوااسکریپت هنوز ذخیره نشده‌است!'''",
+       "sitecsspreview": "'''به یاد داشته باشید که شما فقط دارید پیش‌نمایش این سی‌اس‌اس را می‌بینید.'''\n'''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
+       "sitejspreview": "'''فراموش مکنید که شما فقط دارید پیش‌نمایش سی‌اس‌اس کاربری‌تان را می‌بینید.'''\n'''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
+       "userinvalidcssjstitle": "'''هشدار:''' پوسته‌ای به نام «$1» وجود ندارد.\nبه یاد داشته باشید که صفحه‌های شخصی ‎.css و ‎.js باید عنوانی با حروف کوچک داشته باشند؛ نمونه: {{ns:user}}:فو/vector.css در مقابل {{ns:user}}:فو/Vector.css.",
+       "updated": "(تازة سازی بیة)",
+       "note": "'''نکته:'''",
+       "previewnote": "'''به یاد داشته باشید که این فقط پیش‌نمایش است.'''\nتغییرات شما هنوز ذخیره نشده‌است!",
+       "continue-editing": "بچۆإ بةخش دةکاری",
+       "previewconflict": "این پیش‌نمایش منعکس‌کنندهٔ متن ناحیهٔ ویرایش متن بالایی است، به شکلی که اگر متن را ذخیره کنید نمایش خواهد یافت.",
+       "session_fail_preview": "'''شرمنده! به علت از دست رفتن اطلاعات نشست کاربری نمی‌توانیم ویرایش شما را پردازش کنیم.'''\nلطفاً دوباره سعی کنید.\nاگر دوباره به همین پیام برخوردید از سامانه [[Special:UserLogout|خارج شوید]] و دوباره وارد شوید.",
+       "session_fail_preview_html": "'''متأسفانه امکان ثبت ویرایش شما به خاطر از دست رفتن اطلاعات نشست کاربری وجود ندارد.'''\n\n''با توجه به این که در {{SITENAME}} امکان درج اچ‌تی‌ام‌ال خام فعال است، پیش‌نمایش صفحه پنهان شده تا امکان حملات مبتنی بر جاوااسکریپت وجود نداشته باشد.''\n\n'''اگر مطمئن هستید که این پیش‌نمایش یک ویرایش مجاز است، آن را تکرار کنید.'''\nاگر تکرار پیش‌نمایش نتیجه نداد، از سامانه [[Special:UserLogout|خارج شوید]] و دوباره وارد شوید.",
+       "token_suffix_mismatch": "'''ویرایش شما ذخیره نشد، زیرا مرورگر شما نویسه‌های نقطه‌گذاری را در کد امنیتی ویرایش از هم پاشیده‌است.'''\nویرایش شما مردود شد تا از خراب شدن متن صفحه جلوگیری شود.\nگاهی این اشکال زمانی پیش می‌آید که شما از یک پروکسی تحت وب استفاده کنید.",
+       "edit_form_incomplete": "'''بعضی قسمت‌های فرم ویرایش به سرور نرسیدند؛ اطمینان حاصل کنید که ویرایش‌های شما کامل است و دوباره تلاش کنید.'''",
+       "editing": "درئ $1 دۀسکاریۀ مۀکإ",
+       "creating": "ساخت $1",
+       "editingsection": ")در حال ویرایش $1 (بخش",
+       "editingcomment": "در حال ویرایش $1 (بخش تازه)",
+       "editconflict": "تعارض ویرایشی: $1",
+       "explainconflict": "از وقتی ویرایش این صفحه را آغاز کرده‌اید شخص دیگری آن را تغییر داده است.\nناحیهٔ متنی بالایی شامل متن صفحه به شکل کنونی آن است.\nتغییرات شما در ناحیهٔ متنی پایینی نشان داده شده‌است.\nشما باید تغییراتتان را با متن کنونی ترکیب کنید.\nبا فشردن دکمهٔ «{{int:savearticle}}» <strong>فقط</strong> متن ناحیهٔ متنی بالایی ذخیره خواهد شد.",
+       "yourtext": "متن شما",
+       "storedversion": "نسخهٔ ذخیره شده",
+       "nonunicodebrowser": "'''هشدار: مرورگر شما با استانداردهای یونیکد سازگار نیست.'''\nراه حلی به کار گرفته شده تا شما بتوانید صفحات را با امنیت ویرایش کنید: کاراکترهای غیر ASCII به صورت کدهایی در مبنای شانزده به شما نشان داده می‌شوند.",
+       "editingold": "'''هشدار: شما در حال ویرایش نسخه‌ای قدیمی از این صفحه هستید.'''\nاگر ذخیره‌اش کنید، هر تغییری که پس از این نسخه انجام شده‌است از بین خواهد رفت.",
+       "yourdiff": "تفاوت‌ها",
+       "copyrightwarning": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} منتشرشده تحت $2 در نظر گرفته‌می‌شوند (برای جزئیات بیش‌تر $1 را ببینید).\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش و توزیع شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید (برای جزئیات بیش‌تر $1 را ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
+       "copyrightwarning2": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} ممکن است توسط دیگر مشارکت‌کنندگان تغییر یابند، ویرایش یا حذف شوند.\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید ($1 را برای جزئیات بیشتر ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
+       "editpage-cannot-use-custom-model": "مدل محتوای این صفحه نمی‌تواند عوض شود.",
+       "longpageerror": "'''خطا: متنی که ارسال کرده‌اید {{PULAR:$1|یک کیلوبایت|$1 کیلوبایت}} طول دارد. این مقدار از مقدار بیشینهٔ {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} بیشتر است.'''\nنمی‌توان آن را ذخیره کرد.",
+       "readonlywarning": "'''هشدار: پایگاه داده برای نگهداری قفل شده‌است، به همین علت هم‌اکنون نمی‌توانید ویرایش‌هایتان را ذخیره کنید.'''\nاگر می‌خواهید متن را در یک پروندهٔ متنی کپی کنید و برای آینده ذخیره‌اش کنید.\n\nمدیری که آن را قفل کرده این توضیح را ارائه کرده‌است: $1",
+       "protectedpagewarning": "'''هشدار: این صفحه قفل شده‌است تا فقط کاربران با دسترسی مدیریت بتوانند ویرایشش کنند.'''\nآخرین موارد سیاهه در زیر آمده‌است:",
+       "semiprotectedpagewarning": "'''توجه:''' این صفحه قفل شده‌است تا تنها کاربران ثبت‌نام‌کرده قادر به ویرایش آن باشند.\nآخرین موارد سیاهه در زیر آمده‌است:",
+       "cascadeprotectedwarning": "<strong>هشدار:</strong> این صفحه به علت قرارگرفتن در {{PLURAL:$1|صفحهٔ|صفحه‌های}} آبشاری-محافظت‌شدهٔ زیر قفل شده‌است تا فقط مدیران بتوانند ویرایشش کنند.",
+       "titleprotectedwarning": "'''هشدار: این صفحه به شکلی قفل شده‌است که برای ایجاد آن [[Special:ListGroupRights|اختیارات خاصی]] لازم است.'''\nآخرین موارد سیاهه در زیر آمده است:",
+       "templatesused": "{{PLURAL:$1|Template|Templates}} used on this page:",
+       "templatesusedpreview": "{{PLURAL:$1|الگوی|الگوهای}} استفاده شده در این پیش‌نمایش:",
+       "templatesusedsection": "{{PLURAL:$1|الگوی|الگوهای}} استفاده شده در این بخش:",
+       "template-protected": "(حفاظت‌ بی)",
+       "template-semiprotected": "(نیمه‌حفاظت‌شده)",
+       "hiddencategories": "This page is a member of {{PLURAL:$1|1 hidden category|$1 hidden categories}}:",
+       "nocreatetext": "{{SITENAME}} قابلیت ایجاد صفحه‌های تازه را محدود کرده‌است.\nمی‌توانید بازگردید و صفحه‌ای موجود را ویرایش کنید یا اینکه  [[Special:UserLogin|به سامانه وارد شوید یا حساب کاربری ایجاد کنید]].",
+       "nocreate-loggedin": "شما اجازهٔ ایجاد صفحه‌های تازه را ندارید.",
+       "sectioneditnotsupported-title": "ویرایش بخش‌ها پشتیبانی نمی‌شود",
+       "sectioneditnotsupported-text": "این صفحه از ویرایش بخش‌ها پشتیبانی نمی‌کند.",
+       "permissionserrors": "خطای سطح دسترسی",
+       "permissionserrorstext": "شما اجازهٔ انجام این کار را به این {{PLURAL:$1|دلیل|دلایل}} ندارید:",
+       "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:",
+       "contentmodelediterror": "امکان ویرایش این نسخه برای شما نیست چون نوع محتوای آن <code>$1</code> است و نوع محتوای کنونی صفحه <code>$2</code> است.",
+       "recreate-moveddeleted-warn": "<strong>هشدار: شما در حال ایجاد صفحه‌ای هستید که قبلاً حذف شده‌است.</strong>\n\nدر نظر داشته باشید که آیا ادامهٔ ویرایش این صفحه کار درستی‌است یا نه.\nسیاههٔ حذف و انتقال این صفحه در زیر نشان داده شده‌است:",
+       "moveddeleted-notice": "This page has been deleted.\nThe deletion and move log for the page are provided below for reference.",
+       "moveddeleted-notice-recent": "متاسفانه صفحه قبلا حذف شده‌است (در ۲۴ ساعت اخیر) \nدلیل حذف و سیاههٔ انتقال در پائین موجود است.",
+       "log-fulllog": "مشاهدهٔ سیاههٔ کامل",
+       "edit-hook-aborted": "ویرایش توسط قلاب لغو شد.\nتوضیحی در این مورد داده نشد.",
+       "edit-gone-missing": "امکان به‌روز کردن صفحه وجود ندارد.\nبه نظرمی‌رسد که صفحه حذف شده باشد.",
+       "edit-conflict": "تعارض ویرایشی.",
+       "edit-no-change": "ویرایش شما نادیده گرفته شد، زیرا تغییری در متن داده نشده بود.",
+       "postedit-confirmation-created": "وةڵگة دؤرس بیة",
+       "postedit-confirmation-restored": "صفحه بازیابی شده است.",
+       "postedit-confirmation-saved": "ویرایش شما ذخیره شد.",
+       "edit-already-exists": "امکان ساختن صفحهٔ تازه وجود ندارد.\nاین صفحه از قبل وجود داشته‌است.",
+       "defaultmessagetext": "متن پیش‌فرض پیغام",
+       "content-failed-to-parse": "عدم موفقیت در تجزیه محتوای $2 برای مدل $1: $3",
+       "invalid-content-data": "داده محتوای نامعتبر",
+       "content-not-allowed-here": "محتوای «$1» در صفحهٔ [[$2]] مجاز نیست",
+       "editwarning-warning": "خروج از این برگه ممکن است باعث شود که شما هر شانسی که به وجود آورده‌اید را از دست بدهید.\nاگر شما وارد سامانه شده‌اید، می‌توانید این هشدار را در بخش «{{int:prefs-editing}}» ترجیحاتتان غیرفعال کنید.",
+       "editpage-notsupportedcontentformat-title": "فرمت محتوا پشتیبانی نشده",
+       "editpage-notsupportedcontentformat-text": "فرمت محتوای $1 توسط مدل محتوای $2 پشتیبانی نشده‌است.",
+       "content-model-wikitext": "ویکی‌متن",
+       "content-model-text": "متنی ساده",
+       "content-model-javascript": "جاوااسکریپت",
+       "content-json-empty-object": "ابجکت خالی",
+       "content-json-empty-array": "آرایهٔ خالی",
+       "duplicate-args-warning": "<strong>هشدار:</strong> [[:$1]] [[:$2]] را با بیش از یک مقدار برای پارامتر «$3» صدا می‌زند. فقط آخرین مقدار داده شده استفاده خواهد شد.",
+       "duplicate-args-category": "صفحه‌های دارای آرگومان تکراری در فراخوانی الگو",
+       "duplicate-args-category-desc": "صفحاتی که دارای آرگومان تکراری هستند مانند، <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> یا <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
+       "expensive-parserfunction-warning": ".هشدار:''' این صفحه حاوی تعدادی زیادی فراخوانی دستورهای تجزیه‌گر است'''\n\nتعداد آن‌ها باید کمتر از $2 {{PLURAL:$2|،فراخوانی|فراخوانی}} باشد. \nواینک  ،{{PLURAL:$1|فراخوانی|فراخوانی$1}} است",
+       "expensive-parserfunction-category": "صفحه‌هایی که حاوی تعداد زیادی فراخوانی سنگین دستورهای تجزیه‌گر هستند",
+       "post-expand-template-inclusion-warning": "هشدار: الگو بیش از اندازه بزرگ است.\nبرخی الگوها ممکن است شامل نشوند.",
+       "post-expand-template-inclusion-category": "صفحه‌هایی که تعداد الگوهای به‌کاررفته در آن‌ها بیش از اندازه است",
+       "post-expand-template-argument-warning": "'''هشدار:''' این صفحه شامل دست کم یک پارامتر الگو است که بیش از اندازه بزرگ است.\nاین پارامترها نادیده گرفته شدند.",
+       "post-expand-template-argument-category": "صفحه‌های حاوی الگوهایی با پارامترهای نادیده‌گرفته‌شده",
+       "parser-template-loop-warning": "حلقه در الگو پیدا شد: [[$1]]",
+       "parser-template-recursion-depth-warning": "محدودیت عمق بازگشت الگو رد شد ($1)",
+       "language-converter-depth-warning": "محدودیت عمق مبدل زبانی رد شد ($1)",
+       "node-count-exceeded-category": "صفحه‌هایی که از حداکثر تعداد گره تجاوز کرده‌اند",
+       "node-count-exceeded-category-desc": "این صفحه از تعداد حداکثر اشکال فراتر رفته است.",
+       "node-count-exceeded-warning": "صفحه از حداکثر تعداد گره فراتر رفته‌است",
+       "expansion-depth-exceeded-category": "صفحه‌هایی که از حداکثر عمق بسط دادن تجاوز کرده‌اند",
+       "expansion-depth-exceeded-category-desc": "رده برای صفحاتی که در آنها از عمق گسترش فراتر رفته است.",
+       "expansion-depth-exceeded-warning": "صفحه حداکثر عمق بسط دادن تجاوز کرد",
+       "parser-unstrip-loop-warning": "حلقه در دستور unstrip پیدا شد",
+       "parser-unstrip-recursion-limit": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
+       "converter-manual-rule-error": "خطا در قوانین مبدل دستی زبان",
+       "undo-success": "این ویرایش را می‌توان خنثی کرد.\nلطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که می‌خواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثی‌سازی ویرایش را به پایان ببرید.",
+       "undo-failure": "به علت تعارض با ویرایش‌های میانی، این ویرایش را نمی‌توان خنثی کرد.",
+       "undo-norev": "این ویرایش را نمی‌توان خنثی کرد چون وجود ندارد یا حذف شده‌است.",
+       "undo-nochange": "به نظر می‌رسد ویرایش از پیش واگردانی شده است.",
+       "undo-summary": "خنثی‌سازی ویرایش $1 توسط [[Special:Contributions/$2|$2]] ([[User talk:$2|بحث]])",
+       "undo-summary-username-hidden": "خنثی‌سازی نسخهٔ $1 به دست یک کاربر پنهان‌شده",
+       "cantcreateaccounttitle": "نمی‌توان حساب باز کرد",
+       "cantcreateaccount-text": "امكان ساختن حساب کاربری از این این نشانی آی‌پی ('''$1''') توسط [[User:$3|$3]] سلب شده است.\n\nدلیل ارائه شده توسط $3 چنین است: $2",
+       "cantcreateaccount-range-text": "ایجاد حساب از آدرس آی‌پی در مجموعه‌ی '''$1'''، که شامل آدرس آی‌پی شما ('''$4''') است، توسط [[User:$3|$3]] متوقف شده‌است.\nدلیل ارائه شده توسط $3، $2 است.",
+       "viewpagelogs": "نمایش سیاهه‌های این صفحه",
+       "nohistory": "این صفحه تاریخچهٔ ویرایش ندارد.",
+       "currentrev": "نسخهٔ فعلی",
+       "currentrev-asof": "نسخهٔ کنونی تا $1",
+       "revisionasof": "نؤسخهٔ $1",
+       "revision-info": "Revision as of $1 by {{GENDER:$6|$2}}$7",
+       "previousrevision": "← ورژن کؤئنۀ/قۀدیمی",
+       "nextrevision": "نسخهٔ جدیدتر ←",
+       "currentrevisionlink": "نمایش نسخهٔ فعلی",
+       "cur": "فعلی",
+       "next": "بچؤ نووا/بعدی",
+       "last": "قبلی/دؤمائن",
+       "page_first": "إژ أؤةل",
+       "page_last": "دؤمائن/آخرین",
+       "histlegend": "انتخاب تفاوت: دکمه‌های گرد کنار ویرایش‌هایی که می‌خواهید با هم مقایسه کنید را علامت بزنید و دکمهٔ Enter را بزنید یا دکمهٔ پایین را فشار دهید.<br />\nاختصارات: '''({{int:cur}})''' = تفاوت با نسخهٔ فعلی، '''({{int:last}})''' = تفاوت با نسخهٔ قبلی، '''({{int:minoreditletter}})''' = ویرایش جزئی.",
+       "history-fieldset-title": "مرور تاریخچه",
+       "history-show-deleted": "فقط حذف‌شده",
+       "histfirst": "قدیمی ترین/کۆنەترین",
+       "histlast": "تازه ترین",
+       "historysize": "({{PLURAL:$1|۱ بایت|$1 بایت}})",
+       "historyempty": "(پةتی/حالی)",
+       "history-feed-title": "تاریخچهٔ ویرایش‌ها",
+       "history-feed-description": "تاریخچهٔ ویرایش‌های این صفحه در ویکی",
+       "history-feed-item-nocomment": "$1 در $2",
+       "history-feed-empty": "صفحهٔ درخواست شده وجود ندارد.\nممکن است که از ویکی حذف یا اینکه نامش تغییر داده شده باشد.\nصفحات تازه را برای موارد مرتبط در این ویکی [[Special:Search|جستجو کنید]].",
+       "history-edit-tags": "ویرایش برچسب نسخه‌های انتخاب شده",
+       "rev-deleted-comment": "(خلاصه ویرایش حذف شد)",
+       "rev-deleted-user": "(نام کاربری حذف شد)",
+       "rev-deleted-event": "(جزئیات سیاهه پاک شده)",
+       "rev-deleted-user-contribs": "[نام کاربری یا نشانی آی‌پی حذف شده - ویرایش مخفی شده در مشارکت‌ها]",
+       "rev-deleted-text-permission": "این ویرایش از این صفحه '''حذف شده‌است'''.\nممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
+       "rev-suppressed-text-permission": "این ویرایش از این صفحه '''حذف شده‌است'''.\nشما می‌توانید آن را ببینید؛ ممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
+       "rev-deleted-text-unhide": "این ویرایش از این صفحه '''حذف شده‌است'''.\nممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.\nشما کماکان می‌توانید در صورت تمایل [$1 این نسخه را ببینید].",
+       "rev-suppressed-text-unhide": "این ویرایش از این صفحه '''فرونشانده شده‌است'''.\nممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ فرونشانی] موجود باشد.\nشما کماکان می‌توانید در صورت تمایل [$1 این نسخه را ببینید].",
+       "rev-deleted-text-view": "این دةسکاری از این صفحه '''حذف شده‌است'''.\nشما می‌توانید آن را ببینید؛ ممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
+       "rev-suppressed-text-view": "این دةسکاری از این صفحه '''فرونشانی شده‌است'''.\nشما می‌توانید آن را ببینید؛ ممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ فرونشانی] موجود باشد.",
+       "rev-deleted-no-diff": "شما نمی‌توانید این تفاوت را مشاهده کنید زیرا یکی از دو نسخه '''پاک شده‌است'''.\nممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
+       "rev-suppressed-no-diff": "شما نمی‌توانید این تفاوت را مشاهده کنید زیرا یکی از نسخه‌ها '''پاک شده‌است'''.",
+       "rev-deleted-unhide-diff": "یکی از دو نسخهٔ این تفاوت '''پاک شده‌است'''.\nممکن است اطلاعات مرتبط با آن در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.\nشما کماکان می‌توانید در صورت تمایل [$1 این تفاوت را ببینید].",
+       "rev-suppressed-unhide-diff": "یکی از ورژن های این تفاوت '''فرونشانی شده‌است'''.\nممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page=سیاههٔ فرونشانی{{FULLPAGENAMEE}}}}] موجود باشد.\nشما کماکان می‌توانید در صورت تمایل [$1 این تفاوت را ببینید].",
+       "rev-deleted-diff-view": "یکی از نسخه‌های این تفاوت '''پاک شده‌است'''.\nشما می‌توانید این تفاوت را ببینید؛ ممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] موجود باشد.",
+       "rev-suppressed-diff-view": "یکی از نسخه‌های این تفاوت '''فرونشانی شده‌است'''.\nشما می‌توانید این تفاوت را ببینید؛ ممکن است جزئیاتی در [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} سیاههٔ فرونشانی] موجود باشد.",
+       "rev-delundel": "نمایش/ئاشاردن",
+       "rev-showdeleted": "نیشان دائن",
+       "revisiondelete": "حذف/احیای نسخه‌ها",
+       "revdelete-nooldid-title": "نسخهٔ هدف مجاز نیست",
+       "revdelete-nooldid-text": "شما نسخه‌های هدف را برای انجام این عمل مشخص نکرده‌اید یا این نسخه‌ها وجود ندارند، یا این که شما می‌خواهید آخرین ورژن را پنهان کنید.",
+       "revdelete-no-file": "فایل مشخص شده وجود ندارد.",
+       "revdelete-show-file-confirm": "آیا مطمئن هستید که می‌خواهید یک نسخهٔ پاک شده از پروندهٔ «<nowiki>$1</nowiki>» مورخ $2 ساعت $3 را ببینید؟",
+       "revdelete-show-file-submit": "أرێ-بةلئ",
+       "revdelete-selected-text": "{{PLURAL:$1|نسخهٔ انتخاب‌شده|نسخه‌های انتخابی}} [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|نسخهٔ انتخاب‌شدهٔ|نسخه‌های انتخابی}} [[:$2]]:",
+       "logdelete-selected": "{{PLURAL:$1|مورد|موارد}} انتخاب شده از سیاهه:",
+       "revdelete-text-text": "مشخصات ورژن های حذف شده همچنان در تاریخچه صفحه نمایان خواهد بود ولی دسترسی به قسمت‌هایی از محتویات این نسخه‌ها برای عموم ممکن نخواهد بود.",
+       "revdelete-text-file": "نسخه‌های پاک شده همچنان در تاریخچهٔ پرونده نمایان خواهد بود ولی قسمت‌هایی از محتویات آن‌ها برای عموم غیرقابل دسترس خواهد بود.",
+       "logdelete-text": "ورژن های حذف‌شده همچنان در سیاهه‌های نمایان خواهد بود ولی قسمت‌هایی از محتویات آن‌ها غیرقابل دسترس برای عموم خواهد بود.",
+       "revdelete-text-others": "سایر مدیران هنوز می‌توانند این محتوای پنهان را ببینند و از همین راه موارد حذف شده را احیا کنند، مگر آن که محدودیت‌های دیگری اعمال گردد.",
+       "revdelete-confirm": "خواهشا تأیید کنید که می‌خواهید این کار را انجام دهید، عواقب آن را درک می‌کنید و این کار را طبق [[{{MediaWiki:Policy-url}}|سیاست‌ها]] انجام می‌دهید.",
+       "revdelete-suppress-text": "فرونشانی باید '''تنها''' برای موارد زیر استفاده شود:\n* اطلاعات به طور بالقوه افتراآمیز\n* اطلاعات نامناسب شخصی\n*: ''نشانی منزل، شماره تلفن، کد ملی و غیره.''",
+       "revdelete-legend": "تنظیم محدودیت‌های پیدایی",
+       "revdelete-hide-text": "متن نسخه",
+       "revdelete-hide-image": "نهفتن محتویات فایل",
+       "revdelete-hide-name": "نهفتن متغییرها و هدف",
+       "revdelete-hide-comment": "خلاصة دةسکاری",
+       "revdelete-hide-user": "نام کاربری/نشانی آی‌پی",
+       "revdelete-hide-restricted": "فرونشانی اطلاعات برای مدیران به همراه دیگران",
+       "revdelete-radio-same": "(بدون تغییر)",
+       "revdelete-radio-set": "آشاریا/پنهان",
+       "revdelete-radio-unset": "دیارۀ-نمایان",
+       "revdelete-suppress": "از دسترسی مدیران به داده نیز مانند سایر کاربران جلوگیری به عمل آید.",
+       "revdelete-unsuppress": "حذف محدودیت‌ها در بازبینی‌های ترمیم‌شده",
+       "revdelete-log": ":دةلیل",
+       "revdelete-submit": "اعمال بر {{PLURAL:$1|نسخهٔ|نسخه‌های}} انتخاب شده",
+       "revdelete-success": "'''پیدایی ورژن با موفقیت به روز شد.'''",
+       "revdelete-failure": "'''پیدایی ورژن ها قابل به روز کردن نیست:'''\n$1",
+       "logdelete-success": "تغییر پیدایی مورد با موفقیت انجام شد.",
+       "logdelete-failure": "'''پیدایی سیاهه‌ها قابل تنظیم نیست:'''\n$1",
+       "revdel-restore": "تغییر پیدایی",
+       "pagehist": "تاریخ وةڵگة",
+       "deletedhist": "تاریخچهٔ پاک شده",
+       "revdelete-hide-current": "خطا در پنهان کردن مورد مورخ $2 ساعت $1: این نسخه، ورژن اخیر است و قابل پنهان کردن نیست.",
+       "revdelete-show-no-access": "خطا در پنهان کردن مورد مورخ $2 ساعت $1: این نسخه علامت «محدودیت» دارد و شما به آن دسترسی ندارید.",
+       "revdelete-modify-no-access": "خطا در پنهان کردن مورد مورخ $2 ساعت $1: این نسخه علامت «محدودیت» دارد و شما به آن دسترسی ندارید.",
+       "revdelete-modify-missing": "خطا در پنهان کردن مورد شمارهٔ $1: این نسخه در پایگاه داده وجود ندارد!",
+       "revdelete-no-change": "'''هشدار:''' مورد مورخ $2 ساعت $1 از پیش تنظیمات پیدایی درخواست شده را دارا بود.",
+       "revdelete-concurrent-change": "خطا در پنهان کردن مورد مورخ $2 ساعت $1: به نظر می‌رسد که در مدتی که شما برای تغییر وضعیت آن تلاش می‌کردید وضعیت آن توسط فرد دیگری تغییر یافته است.\nخواهشا سیاهه‌ها را بررسی کنید.",
+       "revdelete-only-restricted": "خطا در پنهان کردن مورد مورخ $2 ساعت $1: شما نمی‌توانید موارد را از دید مدیران پنهان کنید مگر آن که یکی دیگر از گزینه‌های پنهان‌سازی را نیز انتخاب کنید.",
+       "revdelete-reason-dropdown": "*دلایل متداول حذف\n** نقض حق تکثیر\n** اظهار نظر یا اطلاعات فردی نامناسب\n** نام کاربری نامناسب\n** اطلاعات به طور بالقوه افتراآمیز",
+       "revdelete-otherreason": ":دلیل دیگر/اضافی",
+       "revdelete-reasonotherlist": "دلیل دیگر",
+       "revdelete-edit-reasonlist": "دةسکاری دلایل حذف",
+       "revdelete-offender": "نویسنده ورژن:",
+       "suppressionlog": "سیاههٔ فرونشانی",
+       "suppressionlogtext": "در زیر فهرستی از آخرین حذف‌ها و قطع دسترسی‌هایی که حاوی محتوایی هستند که از مدیران پنهان شده‌اند را می‌بینید.\nبرای مشاهدهٔ فهرستی از قطع دسترسی‌های فعال [[Special:BlockList|فهرست بسته‌شده‌ها]] را ببینید.",
+       "mergehistory": "یکی کردن تاریخچه صفحات",
+       "mergehistory-header": "این صفحه به شما این امکان را می‌دهد که نسخه‌های تاریخچهٔ یک مقاله را با یک مقاله دیگر ادغام کنید.\nاطمینان حاصل کنید که این تغییر به توالی زمانی ویرایش‌ها لطمه نخواهد زد.",
+       "mergehistory-box": "ادغام ورژنهای دو صفحه:",
+       "mergehistory-from": "صفحهٔ مبدأ:",
+       "mergehistory-into": "صفحهٔ مقصد:",
+       "mergehistory-list": "تاریخچهٔ قابل ادغام",
+       "mergehistory-merge": "ورژن های زیر از [[:$1]] قابل ادغام با [[:$2]] هستند.\nاز ستون دکمه‌های رادیویی استفاده کنید تا نسخه‌هایی را که تا قبل از زمانی مشخص ایجاد شده‌اند انتخاب کنید.\nتوجه کنید که کلیک روی پیوندها سبب بازگشت ستون به حالت اولیه می‌شود.",
+       "mergehistory-go": "نمایش تاریخچه قابل ادغام",
+       "mergehistory-submit": "ادغام ورژن ها",
+       "mergehistory-empty": "هیچ‌یک از ورژن ها قابل ادغام نیستند.",
+       "mergehistory-done": "$3 نسخه از $1 در {{PLURAL:$3|ادغام شد}}به [[:$2]].",
+       "mergehistory-fail": "ادغام تاریخچه ممکن نیست، لطفاً گزینه‌های صفحه و زمان را بازبینی کنید.",
+       "mergehistory-fail-toobig": "نمی‌توان ادغام تاریخچه را انجام داد که بیشتر از محدودیت $1 {{PLURAL:$1|نسخه}} انتقال داده خواهد شد.",
+       "mergehistory-no-source": "صفحهٔ مبدأ $1 وجود ندارد.",
+       "mergehistory-no-destination": "صفحهٔ مقصد $1 وجود ندارد.",
+       "mergehistory-invalid-source": "صفحهٔ مبدأ باید عنوانی معتبر داشته باشد.",
+       "mergehistory-invalid-destination": "صفحهٔ مقصد باید عنوانی معتبر داشته باشد.",
+       "mergehistory-autocomment": "[[:$1]] را در [[:$2]] ادغام کرد",
+       "mergehistory-comment": "[[:$1]] را در [[:$2]] ادغام کرد: $3",
+       "mergehistory-same-destination": "صفحهٔ مبدأ و مقصد نمی‌تواند یکی باشد",
+       "mergehistory-reason": ":دةلیل",
+       "mergelog": "سیاههٔ ادغام",
+       "revertmerge": "واگردانی ادغام",
+       "mergelogpagetext": "در زیر سیاههٔ آخرین موارد ادغام تاریخچهٔ یک صفحه در صفحه‌ای دیگر را می‌بینید.",
+       "history-title": "Revision history of \"$1\"",
+       "difference-title": "\"$1\" تفاوت بین نسخه‌ها",
+       "difference-title-multipage": "$1 و $2: تفاوت بین صفحات",
+       "difference-multipage": "(تفاوت بین صفحات)",
+       "lineno": ": خط $1",
+       "compareselectedversions": "مقایسهٔ ورژن های انتخاب‌شده",
+       "showhideselectedversions": "تغییر پدیداری ورژن های انتخاب‌شده",
+       "editundo": "خنثی کردن",
+       "diff-empty": "(بدون تفاوت)",
+       "diff-multi-sameuser": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} by the same user not shown)",
+       "diff-multi-otherusers": "({{PLURAL:$1|۱ نسخهٔ میانی|$1 نسخه‌ٔ میانی}} ویرایش شده توسط {{PLURAL:$2|۱ کاربر|$2 کاربر}} نشان داده نشده)",
+       "diff-multi-manyusers": "({{PLURAL:$1|یک|$1}} ورژن میانی ویرایش شده توسط بیش از {{PLURAL:$2|یک|$2}} کاربر نشان داده نشده است)",
+       "difference-missing-revision": "{{PLURAL:$2|یإ گِلة دةسکاری|$2 دةسکاری}} إژ تفاوت ($1) {{PLURAL:$2|پیدا نؤیة |پیدا نؤیة}}.\n\nمعمولا در اثر پیوند به تاریخچه به روز نشده صفحه حذف شده است .\nمیتوانید جزئیات بیشتر را از    [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]  پیدا کنید.",
+       "searchresults": "نتایج مِنِی کردن",
+       "searchresults-title": "\"نتایج جستجو برای \"$1",
+       "titlematches": "تطبیق عنوان مقاله",
+       "textmatches": "تطبیق متن مقاله",
+       "notextmatches": "متن هیچ مقاله‌ای مطابقت ندارد",
+       "prevn": "تای قبلی{{PLURAL:$1|$1}}",
+       "nextn": "تای بعدی{{PLURAL:$1|$1}}",
+       "prev-page": "صفحهٔ قبلی",
+       "next-page": "وةڵگة تِر/بعدی",
+       "prevn-title": "پيشتر $1 {{PLURAL:$1|نتيجه|نتيجةل}}",
+       "nextn-title": "Next $1 {{PLURAL:$1|result|results}}",
+       "shown-title": "نمایش$1 {{PLURAL:$1|نتیجه|نتایج}} وۀ هۀر وۀلگۀ",
+       "viewprevnext": "($3)($2 {{int:pipe-separator}} $1)نمایش",
+       "searchmenu-exists": " {{PLURAL:$2|0=|همچنین نتایج جستجوی دیگری را ببینید.}} '''صفحه‌ای با عنوان  \"[[:$1]]\" در این ویکی وجود دارد.'''",
+       "searchmenu-new": "<strong>Create the page \"[[:$1]]\" on this wiki!</strong> {{PLURAL:$2|0=|See also the page found with your search.|See also the search results found.}}",
+       "searchprofile-articles": "وۀلگۀ محتوایی",
+       "searchprofile-images": "چندرسانه‌ای",
+       "searchprofile-everything": "کؤل چئ",
+       "searchprofile-advanced": "پیشرفتۀ",
+       "searchprofile-articles-tooltip": "جستجو در $1",
+       "searchprofile-images-tooltip": "مِنِی کردن پۀروۀندۀل",
+       "searchprofile-everything-tooltip": "مِنِی کردن کؤل محتوا) (شاملا وۀلگۀل گۀپ و قسۀ",
+       "searchprofile-advanced-tooltip": "جستجو در فضاهای نام دلخواه",
+       "search-result-size": "$1 ({{PLURAL:$2|1 واژۀ|$2 واژۀل}})",
+       "search-result-category-size": "{{PLURAL:$1|یک عضو|$1 عضو}} ({{PLURAL:$2|یک زیررده|$2 زیررده}}، {{PLURAL:$3|یک پرونده|$3 پرونده}})",
+       "search-redirect": "(تغییرمسیر $1)",
+       "search-section": "(بۀخش $1)",
+       "search-category": "(رده  $1)",
+       "search-file-match": "(تشابه محتوی پرونده)",
+       "search-suggest": "نۀظۀرتان یۀ بیۀ: $1",
+       "search-rewritten": "نمایش نتایج $1. جستجوی به جای $2.",
+       "search-interwiki-caption": "پروژةل خۆئة",
+       "search-interwiki-default": "نتایج از $1 :",
+       "search-interwiki-more": "(فرةتر)",
+       "search-relatedarticle": "مرتبط",
+       "searchrelated": "مرتبط",
+       "searchall": "کؤل",
+       "showingresults": "نمایش حداکثر {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} در پایین، آغاز از شماره '''$2'''.",
+       "showingresultsinrange": "نمایش در پائین تا {{PLURAL:$1|<strong>1</strong> نتیجه|<strong>$1</strong> نتیجه}} در محدودهٔ #<strong>$2</strong> تا #<strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|نتایج <strong>$1</strong> از <strong>$3</strong>|نتایج <strong>$1 - $2</strong> از <strong>$3</strong>}}",
+       "search-nonefound": ".نتیجه گإ هؤمۀ إگرۀکتانۀ  پئانؤی",
+       "search-nonefound-thiswiki": "نتیجه‌ای منطبق با این درخواست در این وب‌گاه موجود نبود.",
+       "powersearch-legend": "مِنِی کردن پیشرفته",
+       "powersearch-ns": "جستجو در فضاهای نام:",
+       "powersearch-togglelabel": "بررسی:",
+       "powersearch-toggleall": "کۆل",
+       "powersearch-togglenone": "هؤیچ کام",
+       "powersearch-remember": "انتخاب را برای جستجوهای بعدی به خاطر داشته‌باش",
+       "search-external": "جستجوی خارجی",
+       "searchdisabled": "جستجو در {{SITENAME}} فعال نیست.\nموقتاً می‌توانید از جستجوی Google استفاده کنید.\nتوجه کنید که نتایج حاصل از جستجو با آن روش ممکن است به‌روز نباشند.",
+       "search-error": "خطایی هنگام جست‌وجو رخ داده است: $1",
+       "preferences": "تمارزوةل/ترجیحات",
+       "mypreferences": "تمارزوةل/ترجیحات",
+       "prefs-edits": "تعداد دةسکاریةل:",
+       "prefsnologintext2": "خواهشمند است برای تغییر تنظیمات‌تان وارد شوید.",
+       "prefs-skin": "پوسته",
+       "skin-preview": "پیش‌نمایش",
+       "datedefault": "بدون ترجیح",
+       "prefs-labs": "گزینه‌های آزمایشی",
+       "prefs-user-pages": "وةڵگةل کاربۀری",
+       "prefs-personal": "داده‌های کاربر",
+       "prefs-rc": "تۀغیرۀل/ئالشتیۀل ایسۀ",
+       "prefs-watchlist": "لیست پی‌گیریۀل",
+       "prefs-editwatchlist": "ویرایش فهرست پی‌گیری‌ها",
+       "prefs-editwatchlist-label": "ویرایش همه فهرست پیگیری‌هایتان:",
+       "prefs-editwatchlist-edit": "دیدن و حذف عنوان‌ها از فهرست پیگیری‌هایتان",
+       "prefs-editwatchlist-raw": "ویرایش فهرست خام پیگیری‌ها",
+       "prefs-editwatchlist-clear": "پاک کردن فهرست پیگیری‌هایتان",
+       "prefs-watchlist-days": "تعداد روزهایی که باید در فهرست پی‌گیری‌ها نمایش داده شود:",
+       "prefs-watchlist-days-max": "حداکثر $1 {{PLURAL:$1|روز}}",
+       "prefs-watchlist-edits": "تعداد ویرایش‌های نشان‌داده‌شده در فهرست پی‌گیری‌های گسترش‌یافته:",
+       "prefs-watchlist-edits-max": "حداکثر تعداد: ۱۰۰۰",
+       "prefs-watchlist-token": "رمز فهرست پی‌گیری:",
+       "prefs-misc": "متفرقه",
+       "prefs-resetpass": "تغییردائن رمز",
+       "prefs-changeemail": "تغییر یا حذف نشانی ایمیل",
+       "prefs-setemail": "تنظیم آدرس ایمیل",
+       "prefs-email": "گزینه‌های ایمیل",
+       "prefs-rendering": "نمایش صفحه",
+       "saveprefs": "ذخیرۀ",
+       "restoreprefs": "برگرداندن تمام تنظیمات پیش‌فرض (در تمامی قسمت‌ها)",
+       "prefs-editing": "دةسکاری کردن",
+       "rows": "تعداد سطرها:",
+       "columns": "تعداد ستون‌ها:",
+       "searchresultshead": "گئردین/مهِ نی",
+       "stub-threshold": "آستانهٔ ویرایش پیوندهای ناقص ($1):",
+       "stub-threshold-sample-link": "نمونه",
+       "stub-threshold-disabled": "غیرفعال‌سازی/إ کار کةتن",
+       "recentchangesdays": "تعداد روزهای نمایش داده‌شده در تغییرات اخیر:",
+       "recentchangesdays-max": "حداکثر $1 {{PLURAL:$1|روز}}",
+       "recentchangescount": ":تعداد پیش‌فرض ویرایش‌های نمایش یافته",
+       "prefs-help-recentchangescount": "این گزینه شامل تغییرات اخیر، تاریخچهٔ صفحه‌ها و سیاهه‌ها می‌شود.",
+       "prefs-help-watchlist-token2": "این کلید رمز خوراک وب فهرست پی‌گیری‌های شماست.\nهرکس آن را بداند می‌تواند فهرست پی‌گیری‌هایتان را بخواند، بنابراین آن را به اشتراک نگذارید. [[Special:ResetTokens|اگر لازم است آن را تغییر دهید اینجا را کلیک کنید]].",
+       "savedprefs": "ترجیحات شما ذخیره شد.",
+       "savedrights": "دسترسی کاربری {{GENDER:$1|$1}} ذخیره شده‌است.",
+       "timezonelegend": "منطقه زمانی:",
+       "localtime": "زمان محلی:",
+       "timezoneuseserverdefault": "استفاده از پیش‌فرض ویکی ($1)",
+       "timezoneuseoffset": "دیگر (اختلاف را مشخص کنید)",
+       "servertime": "زمان سرور:",
+       "guesstimezone": "از مرورگر گرفته شود",
+       "timezoneregion-africa": "ئافریقا",
+       "timezoneregion-america": "ئامریکا",
+       "timezoneregion-antarctica": "قطب جنوبی",
+       "timezoneregion-arctic": "قطب شمالی",
+       "timezoneregion-asia": "ئاسیا",
+       "timezoneregion-atlantic": "اقیانوس اطلس",
+       "timezoneregion-australia": "ئۆسترالیا",
+       "timezoneregion-europe": "اؤرووپا",
+       "timezoneregion-indian": "اؤقیانووس هند",
+       "timezoneregion-pacific": "اؤقیانوس آرام",
+       "allowemail": "امکان دریافت ایمیل از دیگر کاربران",
+       "prefs-searchoptions": "گئردین/مهِ نی",
+       "prefs-namespaces": "فضای نامۀل",
+       "default": "پیش‌فرض",
+       "prefs-files": "فایل",
+       "prefs-custom-css": "سی‌اس‌اس شخصی",
+       "prefs-custom-js": "جاوااسکریپت شخصی",
+       "prefs-common-css-js": "سی‌اس‌اس/جاوااسکریپت مشترک برای تمام پوسته‌ها:",
+       "prefs-reset-intro": "شما می‌توانید از این صفحه برای بازگرداندن تنظیمات خود به پیش‌فرض تارنما استفاده کنید.\nاین کار بازگشت‌ناپذیر است.",
+       "prefs-emailconfirm-label": "تأیید ایمیل:",
+       "youremail": "ایمیل:",
+       "username": "{{GENDER:$1|نام کاربری}}:",
+       "prefs-memberingroups": "{{GENDER:$2|أندوم}}  {{PLURAL:$1|دةسة|دةسةل}}:",
+       "prefs-registration": "زمان ثبت‌نام:",
+       "yourrealname": ":نام ڕاسکانی",
+       "yourlanguage": ":زوون",
+       "yourvariant": "گویش زبان محتوا:",
+       "prefs-help-variant": "گویش انتخابی شما برای نمایش محتوای صفحه‌ها در این ویکی",
+       "yournick": "امضای تازه:",
+       "prefs-help-signature": "نظرهای نوشته‌شده در صفحهٔ بحث باید با «<nowiki>~~~~</nowiki>» امضا شوند؛ این علامت به‌صورت خودکار به امضای شما و مهر تاریخ تبدیل خواهد شد.",
+       "badsig": "امضای خام نامجاز.\nلطفاً برچسب‌های اچ‌تی‌ام‌ال را بررسی کنید.",
+       "badsiglength": "امضای شما بیش از اندازه طولانی است.\nامضا باید کمتر از $1 {{PLURAL:$1|نویسه}} طول داشته باشد.",
+       "yourgender": "ترجیح می‌دهید چگونه توصیف شوید؟",
+       "gender-unknown": "هنگام ذکر شما، نرم‌افزار تا جای ممکن از کلمات خنثی از نظر جنسیت استفاده خواهد",
+       "gender-male": "پیا",
+       "gender-female": "ژن",
+       "prefs-help-gender": "انجام این تنظیم اختیاری است.\nنرم‌افزار از این مقدار برای اشارهٔ صحیح به جنسیت و ذکر شما برای دیگران با استفاده از دستور زبان درست استفاده می‌کند.\nاین اطلاعات عمومی خواهند بود.",
+       "email": "ایمیل",
+       "prefs-help-realname": "نام واقعی اختیاری است.\nاگر وارد شده است هنگام ارجاع به آثارتان و انتساب آن‌ها به شما ممکن است از نام واقعی‌تان استفاده شود.",
+       "prefs-help-email": "آدرس ایمیل اختیاری است، اما فرستادن گذرواژه‌ای جدید را اگر گذرواژهٔ خود را فراموش کنید ممکن می‌کند.",
+       "prefs-help-email-others": "شما همچنین می‌توانید انتخاب کنید که کاربران بتوانند از طریق پیوندی در صفحهٔ کاربری یا صفحهٔ بحث کاربری‌تان به شما ایمیل ارسال کنند.\nآدرس ایمیل شما زمانی که دیگران با شما تماس بگیرند فاش نمی‌شود.",
+       "prefs-help-email-required": "آدرس ایمیل اجباری است.",
+       "prefs-info": "اطلاعات اولیه",
+       "prefs-i18n": "بین‌المللی‌سازی",
+       "prefs-signature": "امضا",
+       "prefs-dateformat": "آرایش تاریخ",
+       "prefs-timeoffset": "فاصلهٔ زمانی",
+       "prefs-advancedediting": "تنظیمات عمومی",
+       "prefs-editor": "دةسکاری کةر",
+       "prefs-preview": "پیش‌نمایش",
+       "prefs-advancedrc": "گزینه‌های پیشرفته",
+       "prefs-advancedrendering": "گزینه‌های پیشرفته",
+       "prefs-advancedsearchoptions": "گزینه‌های پیشرفته",
+       "prefs-advancedwatchlist": "گزینه‌های پیشرفته",
+       "prefs-displayrc": "گزینه‌های نمایش",
+       "prefs-displaywatchlist": "گزینه‌های نمایش",
+       "prefs-tokenwatchlist": "نیشانة",
+       "prefs-diffs": "تفاوت‌ها",
+       "prefs-help-prefershttps": "تأثیر این ترجیح بعد از ورود بعدی شما اعمال خواهد شد.",
+       "prefswarning-warning": "تغییراتتان به ترجیحات هنوز ذحیره نشده است.\nاگر این صفحه بدون کلیک بر «$1» ترک کنید ترجیحاتتان ذخیره نخواهد شد.",
+       "prefs-tabs-navigation-hint": "نکته: شما می توانید از کلیدهای جهت‌نمای چپ و راست برای حرکت بین زبانه‌ها در فهرست زبانه‌ها استفاده کنید.",
+       "email-address-validity-valid": "آدرس ایمیل معتبر به نظر می‌رسد",
+       "email-address-validity-invalid": "آدرس ایمیل معتبر وارد کنید",
+       "userrights": "مدیریت اختیارات کاربر",
+       "userrights-lookup-user": "مدیریت گروه‌های کاربری",
+       "userrights-user-editname": "یک نام کاربری وارد کنید:",
+       "editusergroup": "ویرایش گروه‌های کاربری",
+       "editinguser": "تغییر اختیارات کاربری کاربر {{GENDER:$1|کاربر}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "ویرایش گروه‌های کاربری",
+       "saveusergroups": "ثبت گروه‌های کاربری",
+       "userrights-groupsmember": "عضو:",
+       "userrights-groupsmember-auto": "عضو ضمنی:",
+       "userrights-groups-help": "شما می‌توانید گروه‌هایی را که کاربر در آن قرار دارد تغییر دهید:\n* جعبهٔ علامت‌خورده نشانهٔ بودن کاربر در آن گروه است.\n* جعبهٔ خالی نشانهٔ نبودن کاربر در آن گروه است.\n* علامت * به این معنی‌است که اگر آن گروه را بیفزایید نمی‌توانید بعداً برش دارید، و برعکس.",
+       "userrights-reason": ":دةلیل",
+       "userrights-no-interwiki": "شما اجازهٔ تغییر اختیارات کاربران دیگر ویکی‌ها را ندارید.",
+       "userrights-nodatabase": "پایگاه دادهٔ $1 وجود ندارد یا محلی نیست.",
+       "userrights-nologin": "شما باید با یک حساب کاربری مدیر [[Special:UserLogin|به سامانه وارد شوید]] تا بتوانید اختیارات کاربران را تعیین کنید.",
+       "userrights-notallowed": "شما مجوز برای افزودن یا حذف حقوق کاربر را ندارید.",
+       "userrights-changeable-col": "گروه‌هایی که می‌توانید تغییر دهید",
+       "userrights-unchangeable-col": "گروه‌هایی که نمی‌توانید تغییر دهید",
+       "userrights-conflict": "تعارض دسترسی‌های کاربری! لطفاً بررسی کنید و تغییرات را تأیید کنید.",
+       "userrights-removed-self": "شما با موفقیت دسترسی‌های خود را واستاندید. به این ترتیب شما دیگر به این صفحه دسترسی ندارید.",
+       "group": "گروه:",
+       "group-user": "کاربۀر",
+       "group-autoconfirmed": "کاربران تأییدشدهٔ خودکار",
+       "group-bot": "ربات‌ها",
+       "group-sysop": "مدیران",
+       "group-bureaucrat": "دیوان‌سالاران",
+       "group-suppress": "فرونشانندگان",
+       "group-all": "(کۆل)",
+       "group-user-member": "{{GENDER:$1|کاربةر}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|کاربةر تأیید بی}}",
+       "group-bot-member": "ربات",
+       "group-sysop-member": "{{GENDER:$1|مدیر}}",
+       "group-bureaucrat-member": "{{GENDER:$1|دیوان‌سالار}}",
+       "group-suppress-member": "{{GENDER:$1|فرونشاننده}}",
+       "grouppage-user": "{{ns:project}}:کاربرةل",
+       "grouppage-autoconfirmed": "{{ns:project}}:کاربرةل تأییدشده",
+       "grouppage-bot": "{{ns:project}}:رباتةل",
+       "grouppage-sysop": "{{ns:project}}:مدیرةل",
+       "grouppage-bureaucrat": "{{ns:project}}:دیوان‌سالاران",
+       "grouppage-suppress": "{{ns:project}}:فرونشانی",
+       "right-read": "خؤةنِن وةڵگةل",
+       "right-edit": ".دةسکاری وةڵگةل",
+       "right-createpage": "ایجاد صفحه (در مورد صفحه‌های غیر بحث)",
+       "right-createtalk": "یجاد صفحه‌های بحث",
+       "right-createaccount": "ایجاد حساووةل کاربةری",
+       "right-minoredit": "علامت زدن ویرایش‌ها به عنوان جزئی",
+       "right-move": "جاوواز کردن وةڵگة",
+       "right-move-subpages": "انتقال صفحات به همراه زیر‌صفحات‌شان",
+       "right-move-rootuserpages": "انتقال صفحه‌های کاربری سرشاخه",
+       "right-move-categorypages": "انتقال صفحهٔ رده",
+       "right-movefile": "انتقال پرونده‌ها",
+       "right-suppressredirect": "انتقال صفحه بدون ایجاد تغییرمسیر از نام قبلی",
+       "right-upload": "بارنیائن فایلۀل",
+       "right-reupload": "بارگذاری دوبارهٔ پرونده‌ای که از قبل وجود دارد",
+       "right-reupload-own": "بارگذاری دوبارهٔ پرونده‌ای که پیش از این توسط همان کاربر بارگذاری شده‌است",
+       "right-reupload-shared": "باطل‌کردن محلی پرونده‌های مشترک",
+       "right-upload_by_url": "ارگذاری پرونده از یک نشانی اینترنتی",
+       "right-purge": "پاک‌کردن میانگیر صفحه بدون مشاهدهٔ صفحهٔ تأیید",
+       "right-autoconfirmed": "از محدودیت‌های سرعت آی‌پی‌-محور تاثیر نمی‌گیرد",
+       "right-bot": "تلقی‌شده به عنوان یک فرآیند خودکار",
+       "right-nominornewtalk": "ویرایش جزئی صفحه‌های بحث به شکلی که باعث اعلان پیغام تازه نشود",
+       "right-apihighlimits": "سقف بالاتر استفاده از API",
+       "right-writeapi": " نؤیسائنAPIاستفادۀ إژ",
+       "right-delete": "حۀذف وةڵگةل",
+       "right-bigdelete": "حذف صفحه‌های دارای تاریخچهٔ بزرگ",
+       "right-deletelogentry": "حذف و احیای مدخل‌های خاصی از سیاهه",
+       "right-deleterevision": "حذف و احیای نسخه‌های خاصی از صفحه",
+       "right-deletedhistory": "مشاهدهٔ موارد حذف‌شده از تاریخچه، بدون دیدن متن آن‌ها",
+       "right-deletedtext": "مشاهدهٔ متن حذف‌شده و تغییرات بین نسخه‌های حذف‌شده",
+       "right-browsearchive": "جستجوی صفحه‌های حذف‌شده",
+       "right-undelete": "بازگردانی ئئ وةڵگة",
+       "right-suppressrevision": "مشاهده  و احیای ویرایش‌هایی که از کاربران پنهان شده‌اند",
+       "right-viewsuppressed": "مشاهده نسخه‌هایی که از کاربران مخفی شده‌اند",
+       "right-suppressionlog": "مشاهدهٔ سیاهه‌های خصوصی",
+       "right-block": "قطع دسترسی ویرایشی دیگر کاربران",
+       "right-blockemail": "قطع دسترسی دیگر کاربران برای ارسال ایمیل",
+       "right-hideuser": "قطع دسترسی کاربر و پنهان کردن آن از دید عموم",
+       "right-ipblock-exempt": "تاثیر نپذیرفتن از قطع دسترسی‌های آی‌پی، خودکار یا فاصله‌ای",
+       "right-proxyunbannable": "تاثیر نپذیرفتن از قطع دسترسی خودکار پروکسی‌ها",
+       "right-unblockself": "بازکردن دسترسی خود",
+       "right-protect": "تغییر میزان محافظت صفحات و ویرایش صفحات محافظت‌شده آبشاری",
+       "right-editprotected": "ویرایش صفحه‌های محافظت‌شده به عنوان «{{int:protect-level-sysop}}»",
+       "right-editsemiprotected": "ویرایش صفحه حفاظت‌شده به عنوان \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "ویرایش مدل محتوای یک صفحه",
+       "right-editinterface": "ویرایش واسط کاربری",
+       "right-editusercssjs": "ویرایش صفحه‌های CSS و JS دیگر کاربرها",
+       "right-editusercss": "ویرایش صفحه‌های CSS دیگر کاربرها",
+       "right-edituserjs": "ویرایش صفحه‌های JS دیگر کاربرها",
+       "right-editmyusercss": "پرونده‌های سی‌اس‌اس کاربری خود را ویرایش کنید",
+       "right-editmyuserjs": "پرونده‌های جاوااسکریپت کاربری خود را ویرایش کنید",
+       "right-viewmywatchlist": "فهرست پیگیری‌های خود را ببینید",
+       "right-editmywatchlist": "فهرست پیگیری‌های خود را ویرایش کنید. توجه داشته باشید برخی از اقدامات حتی بدون این دسترسی هم صفحات را اضافه می‌کنند.",
+       "right-viewmyprivateinfo": "داده‌های خصوصی خود را ببینید (مانند آدرس ایمیل و نام واقعی)",
+       "right-editmyprivateinfo": "داده‌های خصوصی خود را ویرایش کنید (مانند آدرس ایمیل و نام واقعی)",
+       "right-editmyoptions": "ویرایش ترجیحات خود",
+       "right-rollback": "واگردانی سریع ویرایش‌های آخرین کاربری که یک صفحه را ویرایش کرده‌است",
+       "right-markbotedits": "علامت زدن ویرایش‌های واگردانی‌شده به عنوان ویرایش ربات",
+       "right-noratelimit": "تاثیر نپذیرفتن از محدودیت سرعت",
+       "right-import": "واردکردن صفحه از ویکی‌های دیگر",
+       "right-importupload": "واردکردن صفحه از طریق بارگذاری پرونده",
+       "right-patrol": "گشت زدن به ویرایش‌های دیگران",
+       "right-autopatrol": "گشت زدن خودکار ویرایش‌های خودش",
+       "right-patrolmarks": "مشاهدهٔ برچسب گشت تغییرات اخیر",
+       "right-unwatchedpages": "مشاهدهٔ فهرست صفحه‌هایی که پی‌گیری نمی‌شوند",
+       "right-mergehistory": "ادغام تاریخچهٔ صفحات",
+       "right-userrights": "ویرایش تمام اختیارات کاربرها",
+       "right-userrights-interwiki": "ویرایش اختیارات کاربرهای ویکی‌های دیگر",
+       "right-siteadmin": "قفل‌کردن و بازکردن پایگاه داده‌ها",
+       "right-override-export-depth": "برون‌بری صفحه‌ها شامل صفحه‌های پیوند شده تا عمق ۵",
+       "right-sendemail": "ارسال ایمیل به دیگر کاربران",
+       "right-passwordreset": "مشاهدهٔ نامه‌های تنظیم مجدد گذرواژه",
+       "right-managechangetags": "ایجاد و حذف [[Special:Tags|برچسب‌ها]] از پایگاه داده",
+       "right-applychangetags": "تائید [[Special:Tags|برچسب]] بر روی تغییرات یک نفر",
+       "right-changetags": "افزودن یا حذف [[Special:Tags|برچسب]] قراردادی بر روی نسخه یا سیاهه ورودی‌ها",
+       "newuserlogpage": "سیاههٔ ایجاد کاربر",
+       "newuserlogpagetext": "این سیاهه‌ای از نام‌های کاربری تازه‌ساخته‌شده است.",
+       "rightslog": "سیاههٔ اختیارات کاربر",
+       "rightslogtext": "این سیاههٔ تغییرات اختیارات کاربر است.",
+       "action-read": "خؤةنِن ئئ وةڵگة",
+       "action-edit": "ئئ وةڵگۀ دةسکاری کةن",
+       "action-createpage": "دورس کردن وةڵگة",
+       "action-createtalk": "ایجاد صفحه‌های بحث",
+       "action-createaccount": "ایجاد این حساب کاربری",
+       "action-history": "مشاهده تاریخچه این صفحه",
+       "action-minoredit": "علامت زدن این ویرایش به عنوان جزئی",
+       "action-move": "جاوواز کردن ئئ وۀلگۀ",
+       "action-move-subpages": "انتقال این صفحه و زیرصفحه‌های آن",
+       "action-move-rootuserpages": "انتقال صفحه‌های کاربری سرشاخه",
+       "action-move-categorypages": "انتقال صفحهٔ رده",
+       "action-movefile": "جاوواز کردن ئئ وۀلگۀ",
+       "action-upload": "بارگذاری این پرونده",
+       "action-reupload": "نوشتن روی این پرونده موجود",
+       "action-reupload-shared": "باطل کردن این پرونده روی یک مخزن مشترک",
+       "action-upload_by_url": "بارگذاری این پرونده از یک نشانی اینترنتی",
+       "action-writeapi": "استفاده از API نوشتن",
+       "action-delete": "حةذف ئئ وةڵگة",
+       "action-deleterevision": "حذف این نسخه",
+       "action-deletedhistory": "مشاهدهٔ تاریخچهٔ حذف شدهٔ این صفحه",
+       "action-browsearchive": "جستجوی صفحه‌های حذف‌شده",
+       "action-undelete": "بازگردانی ئئ وةڵگة",
+       "action-suppressrevision": "مشاهده و احیای ویرایش‌های حذف شده",
+       "action-suppressionlog": "مشاهدهٔ این سیاههٔ خصوصی",
+       "action-block": "قطع دسترسی این کاربر از ویرایش‌کردن",
+       "action-protect": "تغییر سطح محافظت این صفحه",
+       "action-rollback": "واگردانی سریع ویرایش‌های آخرین کاربری که یک صفحه را ویرایش کرده‌است",
+       "action-import": "واردکردن صفحه از ویکی‌های دیگر",
+       "action-importupload": "واردکردن صفحه از طریق بارگذاری پرونده",
+       "action-patrol": "گشت زدن ویرایش دیگران",
+       "action-autopatrol": "گشت زدن ویرایش خودتان",
+       "action-unwatchedpages": "مشاهدهٔ صفحه‌های پی‌گیری نشده",
+       "action-mergehistory": "ادغام تاریخچهٔ این صفحه",
+       "action-userrights": "ادغام تاریخچهٔ این صفحه",
+       "action-userrights-interwiki": "ویرایش اختیارات کاربری کاربران یک ویکی دیگر",
+       "action-siteadmin": "قفل‌کردن و بازکردن پایگاه داده‌ها",
+       "action-sendemail": "ایمیل کِل کۀ",
+       "action-editmywatchlist": "فهرست پیگیری‌های خود را ویرایش کنید",
+       "action-viewmywatchlist": "فهرست پیگیری‌های خود را ببینید",
+       "action-viewmyprivateinfo": "اطلاعات خصوصی خود را ببینید",
+       "action-editmyprivateinfo": "اطلاعات خصوصی خود را ویرایش کنید",
+       "action-editcontentmodel": "ویرایش مدل محتوای یک صفحه",
+       "action-managechangetags": "ایجاد و حذف تگ‌ها از پایگاه داده",
+       "action-applychangetags": "اعمال برچسب بر روی تغییرات شما",
+       "action-changetags": "افزودن یا حذف برچسب قراردادی بر روی نسخه یا سیاهه ورودی‌ها",
+       "nchanges": "$1 {{PLURAL:$1|تغییرةل|تغییر}}",
+       "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|از آخرین بازدید}}",
+       "enhancedrc-history": "تاریخچه",
+       "recentchanges": "تۀغیرۀل/ئالشتیۀل ایسۀ",
+       "recentchanges-legend": "گزینه‌های تغییرات اخیر",
+       "recentchanges-summary": ".آخرین تغییرۀل ویکی ئۀ ئئ وۀلگۀ پی‌گیری کۀن",
+       "recentchanges-noresult": "هیچ تغییری در طول دورهٔ تعیین‌شده با این معیارها هم‌خوانی نداشت.",
+       "recentchanges-feed-description": "آخرین تغییرات ویکی را در این خوراک پی‌گیری کنید.",
+       "recentchanges-label-newpage": "ئئ دۀسکاریۀ وۀلگۀ تازه ساختئ",
+       "recentchanges-label-minor": "یة دةسکاری جزئیکة",
+       "recentchanges-label-bot": "ئئ دۀسکاری یۀ رباتئ انجؤم دائه",
+       "recentchanges-label-unpatrolled": "این ویرایش هنوز گشت‌زنی نشده است",
+       "recentchanges-label-plusminus": "حجم وۀلگۀ به اندازه این مقدار بایت تغییر یافته است",
+       "recentchanges-legend-heading": "'''اختصارۀل:'''",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنین به [[Special:NewPages|فهرست صفحات تازه]] نگاه کنید)",
+       "recentchanges-submit": "نیشان دائن",
+       "rcnotefrom": "در زیر تغییرات از <strong>$3, $4</strong> (تا <strong>$1</strong> {{PLURAL:$5|نشان داده شده‌است|نشان داده شده‌اند}}).",
+       "rclistfrom": "نمایش تغییرات تازه با شروع از $3 $2",
+       "rcshowhideminor": "$1 دۀسکاریۀل جزئی",
+       "rcshowhideminor-show": "نیشان دائن",
+       "rcshowhideminor-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhidebots": "$1 ربات‌ها",
+       "rcshowhidebots-show": "نیشان دائن",
+       "rcshowhidebots-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhideliu": "$1 کاربرۀل نام نؤیسی کِریا",
+       "rcshowhideliu-show": "نیشان دائن",
+       "rcshowhideliu-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhideanons": "$1 کاربرۀل ناشنا",
+       "rcshowhideanons-show": "نیشان دائن",
+       "rcshowhideanons-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhidepatr": "$1 ویرایش‌های گشت‌خورده",
+       "rcshowhidepatr-show": "نیشان دائن",
+       "rcshowhidepatr-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhidemine": "$1 ویرایش‌ۀل ووژِم",
+       "rcshowhidemine-show": "نیشان دائن",
+       "rcshowhidemine-hide": "ئآشاردن-پنهان کردن",
+       "rcshowhidecategorization": "$1 رده‌بندی صفحه‌ها",
+       "rcshowhidecategorization-show": "نیشان دائن",
+       "rcshowhidecategorization-hide": "ئآشاردن-پنهان کردن",
+       "rclinks": "نمایش آخرین $1 تغییر در $2 روز اخیر<br />$3",
+       "diff": "تفاوت",
+       "hist": "تاریخچۀ",
+       "hide": "ئآشاردن-پنهان کردن",
+       "show": "نیشان دائن",
+       "minoreditletter": "جز",
+       "newpageletter": "نو",
+       "boteditletter": "ر",
+       "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کاربر}} پی‌گیرنده]",
+       "rc_categories": "محدود به این رده‌ها (رده‌ها را با «|» جدا کنید):",
+       "rc_categories_any": "هر کدام از منتخب‌ها",
+       "rc-change-size-new": " $1دؤما تۀقیر دائن{{PLURAL:$1|بایت|بایتل}}",
+       "newsectionsummary": "/* $1 */ بةخش جدید",
+       "rc-enhanced-expand": "نمایش جزئیات",
+       "rc-enhanced-hide": "نهفتن جزئیات",
+       "rc-old-title": "ایجادشده با عنوان اصلی «$1»",
+       "recentchangeslinked": "تغییرۀل مرتبط",
+       "recentchangeslinked-feed": "تغییرات مرتبط",
+       "recentchangeslinked-toolbox": "تغییرۀ مرتبط",
+       "recentchangeslinked-title": "تغییرات مرتبط با $1",
+       "recentchangeslinked-summary": "در زیر فهرستی از تغییرات اخیر صفحه‌های پیوند داده شده از این صفحه (یا اعضای رده مورد نظر) را می‌بینید.\nصفحه‌هایی که در [[Special:Watchlist|فهرست پی‌گیری‌هایتان]] باشند به صورت '''پررنگ''' نشان داده می‌شوند.",
+       "recentchangeslinked-page": ":نام وةڵگة",
+       "recentchangeslinked-to": "نمایش تغییرات صفحه‌هایی که به صفحهٔ داده‌شده پیوند دارند",
+       "recentchanges-page-added-to-category": "[[:$1]] اضافة بیة رده/ڕِزگ",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] و {{PLURAL:$2|یک صفحه|$2 صفحه}}ٔ دیگر به رده اضافه شدند",
+       "recentchanges-page-removed-from-category": "[[:$1]] إژ رده/ڕِزگ حةذف بی",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] و {{PLURAL:$2|یک صفحه|$2 صفحه}}ٔ دیگر از رده حذف شدند",
+       "autochange-username": "تغییرات خودکار مدیاویکی",
+       "upload": "بارنیائن فایل",
+       "uploadbtn": "بارنیائن فایل",
+       "reuploaddesc": "بازگشت به فرم بارگذاری",
+       "upload-tryagain": "ارسال توضیحات تغییر یافته پرونده",
+       "uploadnologin": "إ سیستم نِهةتئة/نِهاتئة",
+       "uploadnologintext": "برای بارگذاری پرونده باید $1.",
+       "upload_directory_missing": "شاخهٔ بارگذاری ($1) وجود ندارد و قابل ایجاد نیست.",
+       "upload_directory_read_only": "شاخهٔ بارگذاری ($1) از طرف سرور وب قابل نوشتن نیست.",
+       "uploaderror": "خطای بارگذاری",
+       "upload-recreate-warning": "'''هشدار: پرونده‌ای با این نام حذف یا منتقل شده است.'''\n\nبرای راحتی، سیاههٔ حذف و انتقال برای این صفحه در زیر آمده است:",
+       "uploadtext": "از فرم زیر برای بارگذاری کردن پرونده‌های جدید استفاده کنید.\nبرای دیدن پرونده‌هایی که قبلاً بارگذاری شده‌اند به [[Special:FileList|فهرست پرونده‌ها]] بروید. بارگذاری نیز مجدد در [[Special:Log/upload|سیاههٔ بارگذاری‌ها]] و حذف پرونده‌ها در [[Special:Log/delete|deletion log]] ثبت می‌شود.\n\nبعد از این که پرونده‌ای را بارگذاری کردید، به این سه شکل می‌توانید آن را در صفحات استفاده کنید:\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' برای استفاده از نسخه کامل پرونده\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code>''' برای استفاده از یک نسخه ۲۰۰ پیکسلی از پرونده درون یک جعبه در سمت چپ متن که عبارت alt text در آن به عنوان توضیح استفاده شده\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' برای ایجاد یک پیونده مستقیم به پرونده بدون نمایش پرونده",
+       "upload-permitted": "{{PLURAL:$2|نوع|انواع}} پرونده مجاز: $1.",
+       "upload-preferred": "{{PLURAL:$2|نوع|انواع}} پرونده ترجیح‌داده شده: $1.",
+       "upload-prohibited": "{{PLURAL:$2|نوع|انواع}} پرونده نامجاز: $1.",
+       "uploadlogpage": "سیاههٔ بارگذاری‌ها",
+       "uploadlogpagetext": "فهرست زیر فهرستی از آخرین بارگذاری پرونده‌ها است.\nبرای مرور دیداری [[Special:NewFiles|نگارخانهٔ پرونده‌های جدید]] را ببینید.",
+       "filename": "نام پرونده",
+       "filedesc": ":خلاصه",
+       "fileuploadsummary": "خلاصه:",
+       "filereuploadsummary": "تغییرات پرونده:",
+       "filestatus": "وضعیت حق تکثیر:",
+       "filesource": ":بِنچۀک/مۀنبۀع",
+       "ignorewarning": "چشم‌پوشی از هشدار و ذخیرهٔ پرونده.",
+       "ignorewarnings": "چشم‌پوشی از همهٔ هشدارها",
+       "minlength1": "نام پرونده دست کم باید یک حرف باشد.",
+       "illegalfilename": "نام پرونده «$1» نویسه‌هایی را شامل می‌شود که در نام صفحات مجاز نیستند.\nلطفاً نام پرونده را تغییر دهید و آن را دوباره بارگذاری کنید.",
+       "filename-toolong": "نام پرونده نباید از ۲۴۰ بایت طولانی‌تر باشد.",
+       "badfilename": "نام پرونده به «$1» تغییر کرد.",
+       "filetype-mime-mismatch": "پسوند پرونده «$1.‎» با نوع MIME آن ($2) مطابقت ندارد.",
+       "filetype-badmime": "پرونده‌هایی که نوع MIME آن‌ها $1 باشد برای بارگذاری مجاز نیستند.",
+       "filetype-bad-ie-mime": "این پرونده را نمی‌توانید بارگذاری کنید زیرا اینترنت اکسپلورر آن را به عنوان «$1» تشخیص می‌دهد، که یک نوع پروندهٔ نامجاز و احتمالاً خطرناک است.",
+       "filetype-unwanted-type": "'''«‎.‎$1»''' یک نوع پرونده ناخواسته است.\n{{PLURAL:$3|نوع پرونده ترجیح داده شده|انواع پرونده ترجیح داده شده}} از این قرار است: $2 .",
+       "filetype-banned-type": "&lrm;'''\".$1\"''' {{PLURAL:$4|یک نوع پروندهٔ نامجاز است|انواعی پروندهٔ نامجاز هستند}}.\n{{PLURAL:$3|نوع پروندهٔ مجاز|انواع پروندهٔ مجاز}} از این قرار است: $2.",
+       "filetype-missing": "این پرونده پسوند (مثلاً «‎.jpg») ندارد.",
+       "empty-file": "پرونده‌ای که ارسال کردید خالی بود.",
+       "file-too-large": "پرونده‌ای که ارسال کردید بیش از اندازه بزرگ بود.",
+       "filename-tooshort": "نام پرونده بیش از اندازه کوتاه است.",
+       "filetype-banned": "این نوع پرونده ممنوع است.",
+       "verification-error": "پرونده از آزمون تأیید پرونده گذر نکرد.",
+       "hookaborted": "تغییری که می‌خواستید ایجاد کنید توسط یک قلاب افزونه خاتمه ناگهانی داده شد.",
+       "illegal-filename": "نام پرونده مجاز نیست.",
+       "overwrite": "نوشتن روی یک پرونده موجود مجاز نیست.",
+       "unknown-error": "خطای ناشناخته‌ای رخ داد.",
+       "tmp-create-error": "امکان ساخت پرونده موقت وجود نداشت.",
+       "tmp-write-error": "خطا در نوشتن پرونده موقت.",
+       "large-file": "توصیه می‌شود که پرونده‌ها بزرگتر از $1 نباشند؛\nاندازهٔ این پرونده $2 است.",
+       "largefileserver": "این پرونده از اندازه‌ای که سرور پیکربندی شده تا بپذیرد بزرگتر است.",
+       "emptyfile": "پروندهٔ بارگذاری‌شده خالی به نظر می‌رسد.\nاین مشکل ممکن است به علت خطای تایپی در نام پرونده باشد.\nلطفاً تأیید کنید که می‌خواهید این پرونده را با همین شرایط بارگذاری کنید.",
+       "windows-nonascii-filename": "این ویکی از نام پرونده با نویسه‌های خاص پشتیبانی نمی‌کند.",
+       "fileexists": "پرونده‌ای با همین نام از قبل موجود است، اگر مطمئن {{GENDER:|نیستید}} که می‌خواهید آن پرونده را تغییر دهید، لطفاً <strong>[[:$1]]</strong> را بررسی کنید.\n[[$1|thumb]]",
+       "filepageexists": "صفحهٔ توضیح برای این پرونده از قبل در <strong>[[:$1]]</strong> ایجاد شده‌است، اما پرونده‌ای با این نام وجود ندارد.\nخلاصه‌ای که وارد می‌کنید در صفحهٔ توضیح نمایش نخواهد یافت.\nبرای آن که خلاصه شما نمایش یابد، باید آن را به صورت دستی ویرایش کنید.\n[[$1|thumb]]",
+       "fileexists-extension": "پرونده‌ای با نام مشابه وجود دارد: [[$2|thumb]]\n* نام پرونده‌ای که بارگذاری می‌کردید: <strong>[[:$1]]</strong>\n* نام پرونده‌ای که از قبل موجود بود: <strong>[[:$2]]</strong>\nمی‌خواهید بیش از یک نام متمایز استفاده کنید؟",
+       "fileexists-thumbnail-yes": "به نظر می‌رسد که این پرونده، یک تصویر کوچک شده (''بندانگشتی'' یا ''thumbnail'') باشد.\n[[$1|thumb]]\nلطفاً پروندهٔ <strong>[[:$1]]</strong> را بررسی کنید.\nاگر پرونده‌ای که بررسی کردید، همین تصویر در اندازهٔ اصلی‌اش است، نیازی به بارگذاری یک نسخهٔ بندانگشتی اضافه نیست.",
+       "file-thumbnail-no": "نام پرونده با <strong>$1</strong> آغاز می‌شود.\nبه نظر می‌رسد که این پرونده، یک تصویر ''بندانگشتی'' ''(thumbnail)'' از تصویر بزرگتر اصلی باشد.\nاگر تصویر با اندازهٔ اصلی را دارید، آن را بارگذاری کنید؛ در غیر این صورت، نام پرونده را تغییر دهید.",
+       "fileexists-forbidden": "در حال حاضر، پرونده‌ای به همین نام وجود دارد، و قابل رونویسی نیست.\nاگر هم‌چنان می‌خواهید که پروندهٔ خود را بارگذاری کنید، لطفاً برگردید و نام دیگری استفاده کنید.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "در حال حاضر، پرونده‌ای با همین نام در انبارهٔ مشترک پرونده‌ها وجود دارد.\nاگر هنوز می‌خواهید پرونده خود را بار کنید، لطفاً برگردید و پروندهٔ موردنظر خود را با نام دیگری بار کنید.\n[[File:$1|thumb|center|$1]]",
+       "file-exists-duplicate": "به نظر می‌رسد این پرونده نسخه‌ای تکراری از {{PLURAL:$1|پروندهٔ|پرونده‌های}} زیر باشد:",
+       "file-deleted-duplicate": "یک پرونده نظیر این پرونده ([[:$1]]) قبلاً حذف شده‌است.\nشما باید تاریخچهٔ حذف آن پرونده را قبل از بارگذاری مجدد آن ببینید.",
+       "file-deleted-duplicate-notitle": "یک پرونده یکسان بااین پرونده قبلاً حذف شده است و عنوان متوقف شده‌است.\nشما باید از کسی که دسترسی مشاهدهٔ پرونده متوقف شده را دارد، درخواست کنید تا شرایط را قبل از بارگذاری مجدد بررسی کند.",
+       "uploadwarning": "هشدار بارگذاری",
+       "uploadwarning-text": "لطفاً توضیحات پرونده را در زیر تغییر دهید و دوباره تلاش کنید.",
+       "savefile": "ذخیرهٔ پرونده",
+       "uploaddisabled": "بارگذاری غیرفعال است.",
+       "copyuploaddisabled": "بارگذاری از طریق نشانی اینترنتی غیرفعال است.",
+       "uploaddisabledtext": "امکان بارگذاری پرونده غیرفعال است.",
+       "php-uploaddisabledtext": "بارگذاری پرونده‌های پی‌اچ‌پی غیرفعال است.\nلطفاً تنظیمات file_uploads را بررسی کنید.",
+       "uploadscripted": "این صفحه حاوی کد اچ‌تی‌ام‌ال یا اسکریپتی است که ممکن است به‌نادرست توسط مرورگر وب تفسیر شود.",
+       "upload-scripted-pi-callback": "نمی‌توان یک پرونده شامل دستورالعمل پردازش استایل‌شیت اکس‌ام‌ال بارگذاری کرد.",
+       "uploaded-script-svg": "عنصر قابل برنامه‌ریزی «$1» در پرونده بارگذاری اس‌وی‌جی یافت شد.",
+       "uploaded-hostile-svg": "سی‌اس‌اس نا امن در عنصر سبک پروندهٔ بارگذاری شدهٔ اس‌وی‌جی یافت شد.",
+       "uploaded-event-handler-on-svg": "قرار دادن ویژگی‌های مدیریت رویداد <code>$1=\"$2\"</code> در پرونده‌های اس‌وی‌جی مجاز نیست.",
+       "uploaded-href-attribute-svg": "ویژگی‌های href <code>&lt;$1 $2=\"$3\"&gt;</code> با هدف غیر محلی (برای نمونه، http://, javascript:, etc) در پرونده‌های اس‌وی‌جی مجاز نیست.",
+       "uploaded-href-unsafe-target-svg": "در پرونده SVG بارگذاری‌شده برای هدف نادرست <code>&lt;$1 $2=\"$3\"&gt;</code> برچسب href یافت شد.",
+       "uploaded-animate-svg": "برچسب  \"animate\" یافت شده ممکن است herf را تغییر دهد. از مشخصه \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> در پرونده SVG بارگذاری‌شده استفاده کنید.",
+       "uploaded-setting-event-handler-svg": "تنظیمات مشخصه گرداننده رویداد بسته شده‌است. کد <code>&lt;$1 $2=\"$3\"&gt;</code>  در پرونده بارگذاری‌شده یافت شد.",
+       "uploaded-setting-href-svg": "استفاده از برچسب \"set\" برای افزودن مشخصهٔ \"href\" به عنصر والد بسته شده",
+       "uploaded-wrong-setting-svg": "استفاده از برچسب \"set\" برای افزودن remote/data/script هدف برای هر مشخصهٔ بسته شده در پرونده SVG بارگذاری شده <code>&lt;set to=\"$1\"&gt;</code> یافت شد.",
+       "uploaded-setting-handler-svg": "پرونده SVG تنظیم شده با مشخصهٔ \"handler\"  با remote/data/script بسته شده‌است. در پروندهٔ بارگذاری‌شده <code>$1=\"$2\"</code> یافت شد.",
+       "uploaded-remote-url-svg": "پرونده SVG تنظیم شده با remote URL بسته شده‌است. در پروندهٔ بارگذاری‌شده <code>$1=\"$2\"</code> یافت شد.",
+       "uploaded-image-filter-svg": "پالایه پرونده در نشانی:<code>&lt;$1 $2=\"$3\"&gt;</code>  در پرونده SVG بارگذاری‌شده یافت شد.",
+       "uploadscriptednamespace": "این پوشه اس‌وی‌جی شامل فضای نام غیرقانونی '$1' است",
+       "uploadinvalidxml": "XML در پروندهٔ بارگذاری‌شده نمی‌تواند تجزیه شود.",
+       "uploadvirus": "این پرونده ویروس دارد!\nجزئیات : $1",
+       "uploadjava": "این پرونده یک پرونده زیپ است که حاوی پرونده‌ای از نوع ‎‎.class جاوا است.\nبارگذاری پرونده‌های جاوا مجاز نیست، چرا که ممکن است اجازه دور زدن محدودیت‌های امنیتی را بدهند.",
+       "upload-source": "پرونده منبع",
+       "sourcefilename": ":نام اصلی وةڵگة",
+       "sourceurl": " : url بن چۀک",
+       "destfilename": "نام پروندهٔ مقصد:",
+       "upload-maxfilesize": "حداکثر اندازهٔ پرونده: $1",
+       "upload-description": "توضیحات پرونده",
+       "upload-options": "گزینه‌های بارگذاری",
+       "watchthisupload": "پی‌گیری این پرونده",
+       "filewasdeleted": "پرونده‌ای با همین نام پیشتر بارگذاری و پس از آن پاک شده‌است.\nشما باید $1 را قبل از بارگذاری مجدد آن ببینید.",
+       "filename-thumb-name": "به نظر می رسد که عنوان thumbnail است. لطفاً تصویر thumbnail  از دیگر ویکی‌ها را بارگذاری نکنید. عنوان پرونده را اصلاح کنید به صورتی که پیشوند thumbnail نداشته باشد.",
+       "filename-bad-prefix": "نام پرونده‌ای که بارگذاری می‌کنید با '''$1''' آغاز می‌شود که یک پیشوند مخصوص تصاویر ثبت شده توسط دوربین‌های دیجیتال است.\nلطفاً نامی بهتر برای پرونده برگزینید.",
+       "upload-success-subj": "بارگذاری با موفقیت انجام شد",
+       "upload-success-msg": "بارگذاری شما از [$2] موفق بود. این پرونده در اینجا قابل دسترسی است: [[:{{ns:file}}:$1]]",
+       "upload-failure-subj": "مشکل در بارگذاری",
+       "upload-failure-msg": "مشکلی در بارگذاری شما از [$2] وجود داشت:\n\n$1",
+       "upload-warning-subj": "هشدار بارگذاری",
+       "upload-warning-msg": "فرم بارگذاری مشکلی داشت [$2]. شما می‌توانید به [[Special:Upload/stash/$1|فرم بارگذاری]] بازگردید تا این اشکال را رفع کنید.",
+       "upload-proto-error": "پروتکل نادرست",
+       "upload-proto-error-text": "بارگذاری از دوردست به نشانی‌هایی که با <code dir=ltr>http://</code> یا <code dir=ltr>ftp://</code> آغاز شوند نیاز دارد.",
+       "upload-file-error": "خطای داخلی",
+       "upload-file-error-text": "هنگام تلاش برای ایجاد یک پروندهٔ  موقت در سرور یک خطای داخلی رخ داد.\nلطفاً با یک [[Special:ListUsers/sysop|مدیر]] تماس بگیرید.",
+       "upload-misc-error": "خطای نامعلوم در بارگذاری",
+       "upload-misc-error-text": "هنگام بارگذاری، خطایی نامعلوم رخ داد.\nلطفاً اطمینان حاصل کنید که نشانی اینترنتی معتبر و قابل دسترسی است و بعد دوباره تلاش کنید.\nاگر مشکل همچنان برقرار بود با یکی از [[Special:ListUsers/sysop|مدیران]] تماس بگیرید.",
+       "upload-too-many-redirects": "نشانی اینترتی حاوی تعداد بیش از اندازه‌ای تغییرمسیر است",
+       "upload-http-error": "یک خطای اچ‌تی‌تی‌پی رخ داد: $1",
+       "upload-copy-upload-invalid-domain": "بارگذاری کپی پرونده‌ها از این دامنه امکان‌پذیر نیست.",
+       "upload-dialog-title": "بارنیائن فایل",
+       "upload-dialog-button-cancel": "ئآهووسانن/لغو",
+       "upload-dialog-button-done": "انجؤم بی",
+       "upload-dialog-button-save": "ذخیرۀ",
+       "upload-dialog-button-upload": "بارگذاری بی",
+       "upload-form-label-select-file": "فایلئ انتخاب کۀ",
+       "upload-form-label-infoform-title": "جزئیات",
+       "upload-form-label-infoform-name": "نؤم",
+       "upload-form-label-infoform-description": "توضیحةل",
+       "upload-form-label-usage-title": "کاربرد",
+       "upload-form-label-usage-filename": "نؤم فایل",
+       "foreign-structured-upload-form-label-own-work": "یة کار ووژمة",
+       "foreign-structured-upload-form-label-infoform-categories": "رده ها/ڕِزگةل",
+       "foreign-structured-upload-form-label-infoform-date": "تاریخ",
+       "foreign-structured-upload-form-label-own-work-message-local": "تائید می کنم که این پرونده را تحت مجوزها و سیاست‌های {{SITENAME}} بارگذاری می‌کنم.",
+       "foreign-structured-upload-form-label-not-own-work-message-local": "اگر امکان بارگذاری پرونده تحت سیاست‌های {{SITENAME}} را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "foreign-structured-upload-form-label-not-own-work-local-local": "ممکن بخواهید از [[Special:Upload|پنجرهٔ بارگذاری پیش‌فرض]] استفاده کنید.",
+       "foreign-structured-upload-form-label-own-work-message-default": "متوجهم که این پرونده را بر روی مخزن مشترک بارگذاری می‌کنم و تائید می‌کنم که تحت سیاست‌ها و مجوزهای آنجا عمل می‌کنم.",
+       "foreign-structured-upload-form-label-not-own-work-message-default": "اگر امکان بارگذاری پرونده تحت سیاست‌ها و مجوزهای مخزن اشتراک‌گذاری را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "foreign-structured-upload-form-label-not-own-work-local-default": "در صورتی که نمی‌شود پرونده را تحت سیاست‌ها بارگذاری کنید ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
+       "foreign-structured-upload-form-label-own-work-message-shared": "تصدیق می‌کنم که مالک حق تکثیر این پرونده هستم و موافق اشتراک‌گذاری آن تحت مجوز [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] هستم و موافق [https://wikimediafoundation.org/wiki/Terms_of_Use سیاست نحوهٔ استفاده] هستم.",
+       "foreign-structured-upload-form-label-not-own-work-message-shared": "اگر مالک حق تکثیر این پرونده نیستید یا قصد بارگذاری تحت مجوز دیگری دارید، از [https://commons.wikimedia.org/wiki/Special:UploadWizard جادوگر بارگذاری ویکی‌انبار] استفاده کنید.",
+       "foreign-structured-upload-form-label-not-own-work-local-shared": "در صورتی که سایت امکان بارگذاری پرونده را تحت سیاست‌ها بارگذاری می‌دهد ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
+       "backend-fail-stream": "نمی‌توان پروندهٔ $1 را ارسال کرد.",
+       "backend-fail-backup": "نمی‌توان نسخهٔ پشتیبان برای پروندهٔ $1 ایجاد کرد",
+       "backend-fail-notexists": "پروندهٔ $1 وجود ندارد.",
+       "backend-fail-hashes": "دریافت هش‌های پرونده برای مقایسه ناموفق بود.",
+       "backend-fail-notsame": "پروندهٔ غیریکسانی در $1 وجود دارد.",
+       "backend-fail-invalidpath": "$1 مسیر ذخیره‌سازی معتبری نیست.",
+       "backend-fail-delete": "نمی‌توان پروندهٔ $1 را حذف کرد.",
+       "backend-fail-describe": "نمی‌توان فرادادهٔ پروندهٔ «$1» را تغییر داد.",
+       "backend-fail-alreadyexists": "پروندهٔ $1 از قبل وجود داشت.",
+       "backend-fail-store": "نمی‌توان پروندهٔ $1 را در $2 ذخیره کرد.",
+       "backend-fail-copy": "نشد از پروندهٔ «$1» روی «$2» نسخه‌برداری شود.",
+       "backend-fail-move": "نمی‌توان پروندهٔ $1 را به $2 منتقل کرد.",
+       "backend-fail-opentemp": "نمی‌توان پروندهٔ موقتی را باز کرد.",
+       "backend-fail-writetemp": "امکان نوشتن بر روی پروندهٔ موقتی وجود ندارد.",
+       "backend-fail-closetemp": "نمی‌توان پروندهٔ موقتی را بست.",
+       "backend-fail-read": "نمی‌توان پروندهٔ $1 را خواند.",
+       "backend-fail-create": "نمی‌توان بر روی پروندهٔ $1 اطلاعات نوشت.",
+       "backend-fail-maxsize": "نمی‌توان بر روی پروندهٔ $1 اطلاعات نوشت چون بزرگتر از {{PLURAL:$2|یک بایت|$2 بایت}} است.",
+       "backend-fail-readonly": "پشتیبان «$1» درحال حاضر در وضیت فقط خواندنی است. دلیل ارائه شده چنین است: «$2»",
+       "backend-fail-synced": "پرونده «$1» در پشتیبان‌های ذخیره داخلی در وضعیتی ناپایدار قرار دارد",
+       "backend-fail-connect": "ارتباط با پشیبان ذخیره «$1» برقرار نشد.",
+       "backend-fail-internal": "خطایی نامعلوم در پشتیبان ذخیره «$1» رخ داد.",
+       "backend-fail-contenttype": "تعیین نوع محتوای پرونده برای ذخیره در «$1» ناموفق بود.",
+       "backend-fail-batchsize": "دسته‌ای مشتمل بر $1 {{PLURAL:$1|عملکرد|عملکردها}} پرونده به پشتیبان ذخیره داده شد؛ حداکثر مجاز $2 {{PLURAL:$2|عملکرد|عملکردها}} است.",
+       "backend-fail-usable": "امکان خواندن یا نوشتن پروندهٔ $1 وجود نداشت چرا که سطح دسترسی کافی نیست یا شاخه/محفظهٔ مورد نظر وجود ندارد.",
+       "filejournal-fail-dbconnect": "امکان وصل شدن به پایگاه داده دفترخانه برای پشتیبان ذخیره‌سازی «$1» وجود نداشت.",
+       "filejournal-fail-dbquery": "امکان به روز کردن پایگاه داده دفترخانه برای پشتیبان ذخیره‌سازی «$1» وجود نداشت.",
+       "lockmanager-notlocked": "نمی‌توان قفل «$1» را گشود؛ چون قفل نشده‌است.",
+       "lockmanager-fail-closelock": "امکان بستن پرونده قفل شده \"$1\" وجود ندارد.",
+       "lockmanager-fail-deletelock": "امکان حذف پرونده قفل شده \"$1\" وجود ندارد.",
+       "lockmanager-fail-acquirelock": "نمی‌توان قفل «$1» را کسب کرد.",
+       "lockmanager-fail-openlock": "امکان باز کردن پرونده قفل شده \"$1\" وجود ندارد.",
+       "lockmanager-fail-releaselock": "نمی‌توان قفل «$1» را گشود.",
+       "lockmanager-fail-db-bucket": "امکان ارتباط با تعداد کافی پایگاه داده قفل‌ها در محفظه $1 وجود نداشت.",
+       "lockmanager-fail-db-release": "بازکردن قفل‌های پایگاه دادهٔ $1 ممکن نیست.",
+       "lockmanager-fail-svr-acquire": "امکان گرفتن قفل‌های سرور $1 وجود ندارد.",
+       "lockmanager-fail-svr-release": "امکان باز کردن قفل‌های سرور $1 وجود ندارد.",
+       "zip-file-open-error": "در هنگام باز کردن پرونده زیپ برای بررسی محتوای آن خطایی رخ داد.",
+       "zip-wrong-format": "پرونده مشخص شده یک پرونده زیپ نیست.",
+       "zip-bad": "پرونده زیپ خراب یا غیر قابل خواندن است.\nنمی‌توان محتوای آن را از نظر امنیت به درستی بررسی کرد.",
+       "zip-unsupported": "پرونده زیپ از ویژگی‌هایی استفاده می‌کند که توسط مدیاویکی پشتیبانی نمی‌شوند.\nنمی‌توان محتوای آن را از نظر امنیت به درستی بررسی کرد.",
+       "uploadstash": "انبار بارگذاری",
+       "uploadstash-summary": "این صفحه دسترسی به پرونده‌هایی که بارگذاری شده‌اند (یا در حال بارگذاری هستند) اما هنوز در ویکی منتشر نشده‌اند را فراهم می‌کند. این پرونده‌ها توسط هیچ کاربری به جز کسی که آن‌ها را بارگذاری کرده قابل دیدن نیستند.",
+       "uploadstash-clear": "پاک‌کردن پرونده‌های انبارشده",
+       "uploadstash-nofiles": "شما هیچ پروندهٔ انبارشده‌ای ندارید.",
+       "uploadstash-badtoken": "انجام این اقدام ناموفق بود، احتمالاً به این دلیل که اعتبار ویرایش شما به اتمام رسیده است. دوباره امتحان کنید.",
+       "uploadstash-errclear": "پاک‌کردن پرونده‌ها ناموفق بود.",
+       "uploadstash-refresh": "تازه کردن فهرست پرونده‌ها",
+       "invalid-chunk-offset": "جابجایی نامعتبر قطعه",
+       "img-auth-accessdenied": "منع دسترسی",
+       "img-auth-nopathinfo": "PATH_INFO موجود نیست.\nسرور شما برای ردکردن این مقدار تنظیم نشده‌است.\nممکن است مبتنی بر سی‌جی‌آی باشد و از img_auth پشتیبانی نکند.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization را ببینید.",
+       "img-auth-notindir": "مسیر درخواست شده در شاخهٔ بارگذاری تنظیم‌شده قرار ندارد.",
+       "img-auth-badtitle": "امکان ایجاد یک عنوان مجاز از «$1» وجود ندارد.",
+       "img-auth-nologinnWL": "شما به سامانه وارد نشده‌اید و «$1» در فهرست سفید قرار ندارد.",
+       "img-auth-nofile": "پرونده «$1» وجود ندارد.",
+       "img-auth-isdir": "شما تلاش کرده‌اید به شاخهٔ «$1» دسترسی پیدا کنید.\nتنها دسترسی به پرونده مجاز است.",
+       "img-auth-streaming": "در حال جاری ساختن «$1».",
+       "img-auth-public": "عملکرد img_auth.php برونداد پرونده‌ها از یک ویکی خصوصی است.\nاین ویکی به عنوان یک ویکی عمومی تنظیم شده‌است.\nبرای امنیت بهینه، img_auth.php غیرفعال است.",
+       "img-auth-noread": "کاربر دسترسی خواندن «$1» را ندارد.",
+       "http-invalid-url": "نشانی نامعتبر: $1",
+       "http-invalid-scheme": "نشانی‌های اینترنتی با طرح «$1» پشتیبانی نمی‌شوند.",
+       "http-request-error": "درخواست اچ‌تی‌تی‌پی به علت خطایی ناشناخته، ناموفق بود.",
+       "http-read-error": "خطای خواندن اچ‌تی‌تی‌پی.",
+       "http-timed-out": "مهلت درخواست اچ‌تی‌تی‌پی به سر رسید.",
+       "http-curl-error": "خطا در آوردن نشانی اینترنتی: $1",
+       "http-bad-status": "در حین درخواست اچ‌تی‌تی‌پی خطایی رخ داد: $1 $2",
+       "upload-curl-error6": "دسترسی به نشانی اینترنتی ممکن نشد",
+       "upload-curl-error6-text": "نشانی اینترنتی داده شده قابل دسترسی نیست.\nلطفاً درستی آن و اینکه تارنما برقرار است را بررسی کنید.",
+       "upload-curl-error28": "مهلت بارگذاری به سر رسید",
+       "upload-curl-error28-text": "این تارنما بیش از اندازه در پاسخ تعلل کرد.\nلطفاً بررسی کنید که آیا تارنما فعال و برخط است یا نه، سپس لختی درنگ کنید و دوباره تلاش نمایید.\nشاید بد نباشد که در زمان خلوت‌تری دوباره تلاش کنید.",
+       "license": "اجازه‌نامه:",
+       "license-header": "اجازه‌نامه",
+       "nolicense": "هیچ کدام انتخاب نشده‌است",
+       "licenses-edit": "گزینه‌های مجوز ویرایش",
+       "license-nopreview": "(پیش‌نمایش وجود ندارد)",
+       "upload_source_url": "(شما یک پرونده انتخاب از یک URL معتبر و دسترس عموم انتخاب کردید)",
+       "upload_source_file": "(پرونده‌ای از رایانهٔ شما انتخاب شده‌است)",
+       "listfiles-delete": "حۀذف کردن/پاک کردن",
+       "listfiles-summary": "این صفحهٔ ویژه تمام پرونده‌های بارگذاری‌شده را نمایش می‌دهد.",
+       "listfiles_search_for": "جستجو به دنبال نام پرونده چندرسانه‌ای:",
+       "listfiles-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
+       "imgfile": "فایل",
+       "listfiles": "فهرست پرونده‌ها",
+       "listfiles_thumb": "چنه کلئکی/گؤجۀر بی",
+       "listfiles_date": "تاریخ",
+       "listfiles_name": "نؤم",
+       "listfiles_user": "کاربۀر",
+       "listfiles_size": "اندازۀ",
+       "listfiles_description": "توضیحةل",
+       "listfiles_count": "نسخه‌ها",
+       "listfiles-show-all": "شامل نسخه‌های قدیمی عکس‌ها",
+       "listfiles-latestversion": "نسخهٔ فعلی",
+       "listfiles-latestversion-yes": "أرێ-بةلئ",
+       "listfiles-latestversion-no": "نة-نةخئر",
+       "file-anchor-link": "فایل",
+       "filehist": "تاریخ پۀروۀندۀ",
+       "filehist-help": ".روی تاریخ/زمان‌ها کلیک کنید تا نسخهٔ مربوط به آن هنگام را ببینید",
+       "filehist-deleteall": "حذف کۆل",
+       "filehist-deleteone": "حۀذف کردن/پاک کردن",
+       "filehist-revert": "واگردانی/گِلآ دائن",
+       "filehist-current": "نؤسخهٔ ایسه",
+       "filehist-datetime": "تاریخ/وۀخت",
+       "filehist-thumb": "چنه کلئکی/گؤجۀر بی",
+       "filehist-thumbtext": "عۀسگ بندانگشتی/چنۀ کلک إژ نؤسخهٔ مورخ $1",
+       "filehist-nothumb": "فاقد بندانگشتی",
+       "filehist-user": "کاربۀر",
+       "filehist-dimensions": "ابعاد",
+       "filehist-filesize": "قاووارۀ-اندازۀ پرؤندۀ",
+       "filehist-comment": "توضیح",
+       "imagelinks": "استفادۀ إژ پۀروۀنده",
+       "linkstoimage": "ژئر پیوندۀ دِرِنإ ئئ عۀسگۀ{{PLURAL:$1|وۀلگۀل$1|وۀلگۀ}}",
+       "linkstoimage-more": "بیش از $1 صفحه به این پرونده پیوند {{PLURAL:$1|دارد|دارند}}.\nفهرست زیر تنها {{PLURAL:$1|اولین پیوند|اولین $1 پیوند}} به این صفحه را نشان می‌دهد.\n[[Special:WhatLinksHere/$2|فهرست کامل]] نیز موجود است.",
+       "nolinkstoimage": ".این پرونده در هیچ صفحه‌ای به کار نرفته‌است",
+       "morelinkstoimage": "[[Special:WhatLinksHere/$1|پیوندهای دیگر]] به این پرونده را ببینید.",
+       "linkstoimage-redirect": "$1 (تغییرمسیر پرونده) $2",
+       "duplicatesoffile": "{{PLURAL:$1|پروندهٔ|پرونده‌های}} زیر نسخهٔ تکراری این پرونده {{PLURAL:$1|است|هستند}} ([[Special:FileDuplicateSearch/$2|اطلاعات بیشتر]]):",
+       "sharedupload": "این پرونده در $1 قرار دارد و ممکن است در دیگر پروژه‌ها هم استفاده شود.",
+       "sharedupload-desc-there": "این پرونده در $1 قرار دارد و ممکن است در دیگر پروژه‌ها هم استفاده شود.\nبرای اطلاعات بیشتر لطفاً [$2 صفحهٔ توضیحات پرونده] را ببینید.",
+       "sharedupload-desc-here": "این پرونده در $1 قرار دارد و ممکن است در پروژه‌های دیگر هم استفاده شود.\nتوضیحات موجود در [$2 صفحهٔ توضیحات پرونده در آنجا]، در زیر نشان داده شده‌است.",
+       "sharedupload-desc-edit": "این پرونده از $1 است و می‌تواند توسط پروژه‌های دیگر هم استفاده شود.\nاگر خواستید می‌توانید توضیحات پرونده را از [$2 صفحهٔ توضیحاتش] در آنجا ویرایش کنید.",
+       "sharedupload-desc-create": "این پرونده از $1 است و می‌تواند توسط پروژه‌های دیگر هم استفاده شود.\nاگر خواستید می‌توانید توضیحات پرونده را از [$2 صفحهٔ توضیحاتش] در آنجا ویرایش کنید.",
+       "filepage-nofile": "پرونده‌ای با این نام وجود ندارد.",
+       "filepage-nofile-link": "پرونده‌ای با این نام وجود ندارد، اما شما می‌توانید آن را [$1 بارگذاری کنید].",
+       "uploadnewversion-linktext": "بارگذاری نسخهٔ جدیدی از پرونده",
+       "shared-repo-from": "إژ $1",
+       "shared-repo": "یک مخزن مشترک",
+       "shared-repo-name-wikimediacommons": "ویکی‌انبار",
+       "upload-disallowed-here": "متأسفانه شما نمی‌توانید این پرونده را بازنویس کنید.",
+       "filerevert": "واگردانی $1",
+       "filerevert-legend": "واگردانی پرونده",
+       "filerevert-intro": "شما در حال واگردانی '''[[Media:$1|$1]]''' به [$4 نسخهٔ مورخ $2 ساعت $3] هستید.",
+       "filerevert-comment": ":دةلیل",
+       "filerevert-defaultcomment": "واگردانی به نسخهٔ $1 ساعت $2 ($3)",
+       "filerevert-submit": "بچۆ",
+       "filerevert-success": "<strong>[[Media:$1|$1]]</strong> به [$4 نسخهٔ مورخ $2 ساعت $3] واگردانده شد.",
+       "filerevert-badversion": "نسخهٔ قدیمی‌تری از این پرونده وجود نداشت.",
+       "filedelete": "حذف $1",
+       "filedelete-legend": "حذف پرونده",
+       "filedelete-intro": "شما در حال حذف کردن پروندهٔ '''[[Media:$1|$1]]''' به همراه تمام تاریخچه‌اش هستید.",
+       "filedelete-intro-old": "شما در حال حذف نسخه '''[[Media:$1|$1]]''' مورخ [$4 $2 ساعت $3] هستید.",
+       "filedelete-comment": ":دةلیل",
+       "filedelete-submit": "حۀذف کردن/پاک کردن",
+       "filedelete-success": "'''$1''' حذف بی.",
+       "filedelete-success-old": "نسخهٔ '''[[Media:$1|$1]]''' مورخ $2 ساعت $3 حذف شد.",
+       "filedelete-nofile": "'''$1''' وجود ندارد.",
+       "filedelete-nofile-old": "نسخهٔ بایگانی‌شده‌ای از '''$1''' با مشخصات داده شده، وجود ندارد.",
+       "filedelete-otherreason": "دلیل دیگر/اضافی:",
+       "filedelete-reason-otherlist": "دلیل دیگر",
+       "filedelete-reason-dropdown": "*دلایل متداول حذف\n** نقض حق تکثیر\n** پروندهٔ تکراری",
+       "filedelete-edit-reasonlist": "ویرایش دلایل حذف",
+       "filedelete-maintenance": "حذف و احیای پرونده‌ها در مدت نگهداری به طور موقت غیرفعال است.",
+       "filedelete-maintenance-title": "نمی‌تواند پرونده را حذف کند",
+       "mimesearch": "جستجوی بر اساس MIME",
+       "mimesearch-summary": "با کمک این صفحه شما می‌توانید پرونده‌هایی که یک نوع MIME به خصوص دارند را پیدا کنید.\nورودی: به صورت contenttype/subtype یا contenttype/*&lrm;، نظیر <code>image/jpeg</code>.",
+       "mimetype": "نوع MIME:",
+       "download": "گرتن-دانڵوود",
+       "unwatchedpages": "صفحه‌های پی‌گیری‌نشده",
+       "listredirects": "فهرست صفحه‌های تغییرمسیر",
+       "listduplicatedfiles": "فهرست همهٔ پرونده‌ها به‌همراه تکراری‌ها",
+       "listduplicatedfiles-summary": "این فهرست پرونده‌هایی با نسخه‌های اخیر این پرونده تکراری است که نسخه‌های اخبر سایر پرونده‌ها است. فقط پرونده‌های محلی در نظر گرفته شده‌اند.",
+       "listduplicatedfiles-entry": "[[:File:$1|$1]][[$3|{{PLURAL:$2|یک تکرار|$2 تکرار}}]] دارد.",
+       "unusedtemplates": "الگوهای استفاده‌نشده",
+       "unusedtemplatestext": "این صفحه همهٔ صفحاتی در فضای نام {{ns:template}} را که در هیچ صفحه‌ای به کار نرفته‌اند، فهرست می‌کند.\nبه یاد داشته باشید که پیش از پاک‌کردن این صفحات پیوندهای دیگر به آنها را هم وارسی کنید.",
+       "unusedtemplateswlh": "پیوندهای دیگر",
+       "randompage": "وةڵگة بةختةکی",
+       "randompage-nopages": "هیچ صفحه‌ای در این {{PLURAL:$2|فضای نام|فضاهای نام}} موجود نیست: $1.",
+       "randomincategory": "وةڵگة بةختةکی در رده/ڕِزگ",
+       "randomincategory-invalidcategory": "«$1» نامی معتبر برای یک ردهٔ نیست.",
+       "randomincategory-nopages": "  .وجود نئرێ[[:Category:$1|$1]]هؤیج وةڵگة وة رده/ڕِزگ",
+       "randomincategory-category": "رده/ڕِزگ:",
+       "randomincategory-legend": "وةڵگة بةختةکی در رده/ڕِزگ",
+       "randomincategory-submit": "بِچۆ",
+       "randomredirect": "تغییرمسیر تصادفی",
+       "randomredirect-nopages": "هیج صفحهٔ تغییرمسیری در فضای نام «$1» موجود نیست.",
+       "statistics": "آمارۀل",
+       "statistics-header-pages": "آمارۀل وۀلگه",
+       "statistics-header-edits": "آمار ویرایش‌ها",
+       "statistics-header-users": "آمار کاربةرةل",
+       "statistics-header-hooks": "آمارۀل بقیة",
+       "statistics-articles": "وۀلگۀ محتوایی",
+       "statistics-pages": "وةڵگةل",
+       "statistics-pages-desc": "تمام صفحه‌های این ویکی، از جمله صفحه‌های بحث، تغییرمسیر و غیره",
+       "statistics-files": "پرونده‌های بارگذاری‌شده",
+       "statistics-edits": "ویرایش صفحه‌ها از هنگامی که {{SITENAME}} راه‌اندازی شده",
+       "statistics-edits-average": "متوسط ویرایش‌ها به ازای هر صفحه",
+       "statistics-users": "[[Special:ListUsers|کاربةرةل]] نان نؤیسی کردئإ",
+       "statistics-users-active": "کاربران فعال",
+       "statistics-users-active-desc": "کاربرانی که در {{PLURAL:$1|روز|$1 روز}} قبل فعالیتی انجام داده‌اند",
+       "pageswithprop": "صفحه‌های دارای خاصیت صفحه",
+       "pageswithprop-legend": "صفحه‌های دارای خاصیت صفحه",
+       "pageswithprop-text": "این صفحه فهرستی است از صفحه‌هایی که از یک خاصیت صفحهٔ خاص استفاده می‌کنند.",
+       "pageswithprop-prop": "نام خاصیت:",
+       "pageswithprop-submit": "بِچۆ",
+       "pageswithprop-prophidden-long": "جزییات مخفی متن طولانی ($1)",
+       "pageswithprop-prophidden-binary": "جزییات مقدار مخفی باینری ($1)",
+       "doubleredirects": "تغییرمسیرهای دوتایی",
+       "doubleredirectstext": "این صفحه فهرستی از صفحه‌های تغییرمسیری را ارائه می‌کند که به صفحهٔ تغییرمسیر دیگری اشاره می‌کنند.\nهر سطر دربردارندهٔ پیوندهایی به تغییرمسیر اول و دوم و همچنین مقصد تغییرمسیر دوم است، که معمولاً صفحهٔ مقصد واقعی است و نخستین تغییرمسیر باید به آن اشاره کند.\nموارد <del>خط خورده</del> درست شده‌اند.",
+       "double-redirect-fixed-move": "[[$1]] انتقال داده شده‌است.\n\nبه صورت خودکار به‌روز شده‌است و  تغییرمسیری به [[$2]] داده شد.",
+       "double-redirect-fixed-maintenance": "رفع خودکار تغییرمسیر دوتایی از [[$1]] به [[$2]] در روند نگهداری.",
+       "double-redirect-fixer": "تعمیرکار تغییرمسیرها",
+       "brokenredirects": "تغییرمسیرهای خراب",
+       "brokenredirectstext": "تغییرمسیرهای زیر به یک صفحهٔ ناموجود پیوند دارند:",
+       "brokenredirects-edit": "دةسکاری",
+       "brokenredirects-delete": "حۀذف کردن/پاک کردن",
+       "withoutinterwiki": "صفحه‌های بدون پیوند میان‌ویکی",
+       "withoutinterwiki-summary": "این صفحات پیوندی به صفحه‌ای به زبان دیگر نمی‌دارند:",
+       "withoutinterwiki-legend": "پیشوند",
+       "withoutinterwiki-submit": "نیشان دائن",
+       "fewestrevisions": "مقاله‌های دارای کمترین شمار ویرایش",
+       "nbytes": "$1 {{PLURAL:$1|بایت|بایتۀل}}",
+       "ncategories": "$1{{PLURAL:$1|رده|رده ها}}",
+       "ninterwikis": "$1 {{PLURAL:$1|میان‌ویکیةل|میان‌ویکی}}",
+       "nlinks": "$1 {{PLURAL:$1|پیوندةل|پیوند}}",
+       "nmembers": "$1 {{PLURAL:$1|member|members}}",
+       "nmemberschanged": "$1 → $2   {{PLURAL:$2| عضو|عضو}}",
+       "nrevisions": "$1 {{PLURAL:$1| نسخه ها|نسخه}}",
+       "nimagelinks": "{{PLURAL:$1|مورد استفاده در $1 {{PLURAL:$1|صفحه ها|صفحه}}}}",
+       "ntransclusions": "در $1 {{PLURAL:$1|صفحه|صفحه ها}} استفاده بیة",
+       "specialpage-empty": "نتیجه‌ای برای این گزارش وجود ندارد.",
+       "lonelypages": "وةڵگةل یتیم",
+       "lonelypagestext": "به صفحه‌های زیر از هیچ صفحهٔ دیگری در {{SITENAME}} پیوند داده نشده‌است و در هیچ صفحهٔ دیگری گنجانده نشده‌اند.",
+       "uncategorizedpages": "صفحه‌های رده‌بندی‌نشده",
+       "uncategorizedcategories": "رده‌های رده‌بندی‌نشده",
+       "uncategorizedimages": "پرونده‌های رده‌بندی‌نشده",
+       "uncategorizedtemplates": "الگوهای رده‌بندی‌نشده",
+       "unusedcategories": "رده‌های استفاده‌نشده",
+       "unusedimages": "پرونده‌های استفاده‌نشده",
+       "wantedcategories": "رده‌های مورد نیاز",
+       "wantedpages": "وةڵگةل مورد نیاز",
+       "wantedpages-summary": "فهرست صفحه‌های ناموجود با بیشترین پیوند به آنها، به استثنای صفحه‌هایی که فقط تغییرمسیر به آنها دارند. برای یک فهرست از صفحه‌های ناموجود که تغییرمسیر به آنها دارند، [[{{#special:BrokenRedirects}}|فهرست تغییرمسیرهای شکسته]] را ببینید.",
+       "wantedpages-badtitle": "عنوان نامجاز در مجموعهٔ نتایج: $1",
+       "wantedfiles": "وةڵگةل مورد نیاز",
+       "wantedfiletext-cat": "پرونده‌های زیر استفاده می‌شوند اما موجود نیستند. همچنین ممکن است پرونده‌های مخازن خارجی با وجود موجود بودن در اینجا فهرست شوند. هرگونه رتبه مثبت کاذب <del>خط خواهد خورد.</del> علاوه بر این، صفحاتی که پرونده‌هایی ناموجود را در خود جای داده‌اند در [[:$1]] فهرست شده‌اند.",
+       "wantedfiletext-cat-noforeign": "پرونده‌های زیر استفاده می‌شود اما وجود ندارد. علاوه بر این، صفحاتی که پرونده‌ها در آنها وجود دارند فهرست شده‌اند در [[:$1]].",
+       "wantedfiletext-nocat": "پرونده‌های زیر استفاده می‌شوند اما موجود نیستند. همچنین ممکن است پرونده‌های مخازن خارجی با وجود موجود بودن در اینجا فهرست شوند. هرگونه رتبهٔ مثبت کاذب <del>خط خواهد خورد.</del>",
+       "wantedfiletext-nocat-noforeign": "پرونده‌های زیر استفاده می‌شوند اما وجود ندارد.",
+       "wantedtemplates": "الگوهای مورد نیاز",
+       "mostlinked": "صفحه‌هایی که بیشتر از همه به آن‌ها پیوند داده شده‌است",
+       "mostlinkedcategories": "رده‌هایی که بیشتر از همه به آن‌ها پیوند داده شده‌است",
+       "mostlinkedtemplates": "بیشترین صفحات تراگنجانده‌شده",
+       "mostcategories": "صفحه‌های دارای بیشترین رده",
+       "mostimages": "پرونده‌هایی که بیشتر از همه به آن‌ها پیوند داده شده‌است",
+       "mostinterwikis": "صفحه‌های دارای بیشترین میان‌ویکی",
+       "mostrevisions": "صفحه‌های دارای بیشترین نسخه",
+       "prefixindex": "کۆل وةڵگةل با پیشوند",
+       "prefixindex-namespace": "کۆل وةڵگةل دارای پیشوند (فضای‌نام $1)",
+       "prefixindex-submit": "نیشان دائن",
+       "prefixindex-strip": "حذف پیشوند در فهرست",
+       "shortpages": "وةڵگةل کؤِڵ/کوتاه",
+       "longpages": "وةڵگةل دؤِڕ/دراز",
+       "deadendpages": "وةڵگةل بن بست",
+       "deadendpagestext": "صفحه‌های زیر به هیچ صفحهٔ دیگری در {{SITENAME}} پیوند ندارند.",
+       "protectedpages": "وةڵگة محافظت/پڵؤم بیة",
+       "protectedpages-indef": "فقط محافظت‌های بی‌پایان",
+       "protectedpages-summary": "در این صفحه فهرست صفحات موجود است که در حال حاضر محافظت شده اند. برای فهرست عنوان‌هایی که از ایجاد محافظت شده‌اند، به [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] مراجعه کنید.",
+       "protectedpages-cascade": "فقط محافظت‌های آبشاری",
+       "protectedpages-noredirect": "پنهان کردن تغییر مسیرها",
+       "protectedpagesempty": "در حال حاضر هیچ‌صفحه‌ای محافظت نشده‌است.",
+       "protectedpages-timestamp": "برچسب زمان",
+       "protectedpages-page": "وةڵگة",
+       "protectedpages-expiry": "انقضا",
+       "protectedpages-performer": "کاربر حفاظت‌کننده",
+       "protectedpages-params": "پارامترهای حفاظت",
+       "protectedpages-reason": "دةلیل",
+       "protectedpages-submit": "نمایش وةڵگةل",
+       "protectedpages-unknown-timestamp": "ناشنا/نادیار",
+       "protectedpages-unknown-performer": "کاربر ناشناس",
+       "protectedtitles": "عنوانةل محافظت/پڵؤم بیة",
+       "protectedtitles-summary": "این صفحه فهرست صفحات موجود است که در حال حاضر محافظت از ساخت شده‌اند. برای فهرست عنوان‌هایی که محافظت از ویرایش شده‌اند، به [[{{#special:ProtectedPages}}|{{int:protectedpages}}]] مراجعه کنید.",
+       "protectedtitlesempty": "در حال حاضر هیچ عنوانی با این پارامترها محافظت نشده‌است.",
+       "protectedtitles-submit": "نمایش عناوین",
+       "listusers": "لیست کاربةرةل",
+       "listusers-editsonly": "فقط کاربرانی که ویرایش دارند را نشان بده",
+       "listusers-creationsort": "مرتب کردن بر اساس تاریخ ایجاد",
+       "listusers-desc": "ترتیب نزولی",
+       "usereditcount": "$1 {{PLURAL:$1|ویرایش ها|ویرایش}}",
+       "usercreated": "{{GENDER:$3|ایجادشده}} در تاریخ $1 در ساعت $2",
+       "newpages": "وۀلگۀ تازۀ",
+       "newpages-username": ":نؤم کاربری",
+       "ancientpages": " کۆنةترین/قدیمی ترین وةڵگةل",
+       "move": "جاوواز کرِدِن",
+       "movethispage": "جاوواز کردن ئئ وۀلگۀ",
+       "unusedimagestext": "پرونده‌های زیر موجودند اما در هیچ صفحه‌ای به کار نرفته‌اند.\nلطفاً توجه داشته باشید که دیگر وبگاه‌ها ممکن است با یک نشانی اینترنتی مستقیم به یک پرونده پیوند دهند، و با وجود این که در استفادهٔ فعال هستند در این جا فهرست شوند.",
+       "unusedcategoriestext": "این رده‌ها وجود دارند ولی هیچ مقاله یا ردهٔ دیگری از آنها استفاده نمی‌کند.",
+       "notargettitle": "مقصدی نیست",
+       "notargettext": "شما صفحهٔ یا کاربر مقصدی برای انجام این عمل روی آن مشخص نکرده‌اید.",
+       "nopagetitle": "هانة وةڵگة وجود نِئرێ",
+       "nopagetext": "صفحهٔ هدفی که شما مشخص کردید وجود ندارد.",
+       "pager-newer-n": "{{PLURAL:$1|یک مورد جدیدتر|$1 مورد جدیدتر}}",
+       "pager-older-n": "{{PLURAL:$1|پوشۀ1|پوشۀ$1}}",
+       "suppress": "سرکوب",
+       "querypage-disabled": "این صفحه ویژه به دلایل عملکردی غیرفعال شده‌است.",
+       "apihelp": "راهنمای API",
+       "apihelp-no-such-module": "پودمان \" $1 \" یافت نشد.",
+       "booksources": "منابع کتاب",
+       "booksources-search-legend": "جستجوی منابع کتاب",
+       "booksources-search": "گئردین/مهِ نی",
+       "booksources-text": "در زیر فهرستی از پیوندها به وبگاه‌های دیگر آمده‌است که کتاب‌های نو و دست دوم می‌فروشند، و همچنین ممکن است اطلاعات بیشتری راجع به کتاب مورد نظر شما داشته باشند:",
+       "booksources-invalid-isbn": "شابک داده شده مجاز به نظر نمی‌رسد؛ از جهت اشکالات هنگام کپی کردن از منبع اصلی بررسی کنید.",
+       "specialloguserlabel": "مجری:",
+       "speciallogtitlelabel": "هدف (عنوان یا {{ns:user}}:نام کاربر برای کاربر):",
+       "log": "سیاهه‌ها",
+       "all-logs-page": "تمام سیاهه‌های عمومی",
+       "alllogstext": "نمایش یک‌جای تمام سیاهه‌های موجود در {{SITENAME}}.\nمی‌توانید با انتخاب نوع سیاهه، نام کاربری (حساس به کوچکی و بزرگی حروف) و صفحه‌های تغییریافته (حساس به بزرگی و کوچکی حروف)، نمایش را محدودتر سازید.",
+       "logempty": "مورد منطبق با منظور شما در سیاهه یافت نشد.",
+       "log-title-wildcard": "صفحه‌هایی را جستجو کن که عنوانشان با این عبارت آغاز می‌شود",
+       "showhideselectedlogentries": "تغییر پدیداری موارد انتخاب‌شده سیاهه",
+       "log-edit-tags": "ویرایش برچسب سیاههٔ انتخاب شده",
+       "allpages": "کۆل وةڵگةل",
+       "nextpage": "وةڵگةبعد ($1)",
+       "prevpage": "وةڵگة قبلی ($1)",
+       "allpagesfrom": "نمایش وةڵگةل با شروع إژ:",
+       "allpagesto": "نمایش صفحات با پایان در:",
+       "allarticles": "کول وۀلگۀل",
+       "allinnamespace": "همهٔ صفحات (فضای نام $1)",
+       "allpagessubmit": "بِچۆ",
+       "allpagesprefix": "نمایش صفحه‌های دارای پیشوند:",
+       "allpagesbadtitle": "عنوان صفحهٔ داده‌شده نامعتبر است یا اینکه دارای پیشوندی بین‌زبانی یا بین‌ویکی‌ای است. ممکن است نویسه‌هایی بدارد که نمی‌توان از آنها در عنوان صفحات استفاده کرد.",
+       "allpages-bad-ns": "{{SITENAME}} دارای فضای نام «$1» نیست.",
+       "allpages-hide-redirects": "پنهان کردن تغییر مسیرها",
+       "cachedspecial-viewing-cached-ttl": "شما در حال مشاهدهٔ نسخه‌ای از این صفحه که در میانگیر قرار دارد هستید که ممکن است برای $1 قبل باشد.",
+       "cachedspecial-viewing-cached-ts": "شما در حال مشاهدهٔ نسخه‌ای از این صفحه که در میانگیر قرار دارد هستید، و این نسخه ممکن است کاملاً واقعی نباشد.",
+       "cachedspecial-refresh-now": "مشاهده آخرین.",
+       "categories": "رده‌ ل",
+       "categoriespagetext": "{{PLURAL:$1|ردهٔ|رده‌های}} زیر دارای صفحات یا پرونده‌هایی {{PLURAL:$1|است|هستند}}.\n[[Special:UnusedCategories|رده‌های استفاده‌نشده]] در اینجا نمایش داده نشده‌اند.\nهمچنین [[Special:WantedCategories|رده‌های مورد نیاز]] را ببینید.",
+       "categoriesfrom": "نمایش رده‌ها با شروع از:",
+       "special-categories-sort-count": "مرتب کردن بر اساس تعداد",
+       "special-categories-sort-abc": "مرتب کردن الفبایی",
+       "deletedcontributions": "مشارکت‌های حذف‌شده",
+       "deletedcontributions-title": "مشارکت‌های حذف‌شده",
+       "sp-deletedcontributions-contribs": "مشارکت‌ها",
+       "linksearch": "جستجوی پیوندهای بیرونی",
+       "linksearch-pat": "الگوی جستجو:",
+       "linksearch-ns": "فضای نام:",
+       "linksearch-ok": "گئردین/مهِ نی",
+       "linksearch-text": "نشانه‌هایی مانند «‎*.wikipedia.org» را می‌توان استفاده کرد.\nحداقل یک دامنه سطح بالا ، به عنوان مثال \"*.org\" نیاز دارد.<br />\n{{PLURAL:$2|پروتکل|پروتکل‌های}} پشتیبانی‌شده: $1 (پیش‌فرض برای http:// در صورت مشخص نشدن پروتکل تنظیم شده‌است).",
+       "linksearch-line": "$1 از $2 پیوند دارد",
+       "linksearch-error": "نشانه‌ها فقط در ابتدای نام میزبان اینترنتی می‌توانند استفاده شوند.",
+       "listusersfrom": "نمایش کاربران با شروع از:",
+       "listusers-submit": "نیشان دائن",
+       "listusers-noresult": "هیچ کاربری یافت نشد.",
+       "listusers-blocked": "(بسته شده)",
+       "activeusers": "فهرست کاربران فعال",
+       "activeusers-intro": "در زیر فهرستی از کاربرانی را می‌بینید که در $1 {{PLURAL:$1|روز|روزها}} گذشته فعالیتی داشته‌اند.",
+       "activeusers-count": "$1 {{PLURAL:$1|فعالیت|فعالیت ها}} در {{PLURAL:$3|روز|$3 روز}} اخیر",
+       "activeusers-from": "نمایش کاربران با آغاز از:",
+       "activeusers-hidebots": "نهفتن ربات‌ها",
+       "activeusers-hidesysops": "نهفتن مدیران",
+       "activeusers-noresult": "کاربری پیدا نشد.",
+       "activeusers-submit": "نمایش کاربةرةل فعال/کارکةر",
+       "listgrouprights": "اختیارات گروه‌های کاربری",
+       "listgrouprights-summary": "فهرست زیر شامل گروه‌های کاربری تعریف شده در این ویکی و اختیارات داده شده به آن‌ها است.\nاطلاعات بیشتر در مورد هر یک از اختیارات را در [[{{MediaWiki:Listgrouprights-helppage}}]] بیابید.",
+       "listgrouprights-key": "* <span class=\"listgrouprights-granted\">اختیارات داده‌شده</span>\n* <span class=\"listgrouprights-revoked\">اختیارات گرفته‌شده</span>",
+       "listgrouprights-group": "گروه",
+       "listgrouprights-rights": "دسترسی‌ها",
+       "listgrouprights-helppage": "Help:دسترسی‌های گروهی",
+       "listgrouprights-members": "(فهرست اعضا)",
+       "listgrouprights-addgroup": "می‌تواند این {{PLURAL:$2|گروه|گروه‌ها}} را اضافه کند: $1",
+       "listgrouprights-removegroup": "می‌تواند این {{PLURAL:$2|گروه|گروه‌ها}} را حذف کند: $1",
+       "listgrouprights-addgroup-all": "می‌تواند تمام گروه‌ها را اضافه کند",
+       "listgrouprights-removegroup-all": "می‌تواند تمام گروه‌ها را حذف کند",
+       "listgrouprights-addgroup-self": "می‌تواند حساب خود را به این {{PLURAL:$2|گروه|گروه‌ها}} اضافه کند: $1",
+       "listgrouprights-removegroup-self": "می‌تواند حساب خود را از این {{PLURAL:$2|گروه|گروه‌ها}} حذف کند: $1",
+       "listgrouprights-addgroup-self-all": "می‌تواند حساب خود را به تمام گروه‌ها اضافه کند",
+       "listgrouprights-removegroup-self-all": "می‌تواند حساب خود را از تمام گروه‌ها حذف کند",
+       "listgrouprights-namespaceprotection-header": "محدودیت فضای نام",
+       "listgrouprights-namespaceprotection-namespace": "فضای نام",
+       "listgrouprights-namespaceprotection-restrictedto": "دسترسی(های) مجاز کاربر برای ویرایش",
+       "trackingcategories": "تؤرگِرتنردیابی رده/ڕِزگ\n)رده/ڕِزگ تؤرگِرتن(ردیابی",
+       "trackingcategories-summary": "این صفحه فهرست رده‌هایی ردیابی است که به‌صورت خودکار توسط مدیاویکی پر می‌شوند است. نام‌هایشان می‌تواند پس از تغییر پیام‌های سامانه‌ای مرتبط در فضای نام {{ns:8}} تغییر یابد.",
+       "trackingcategories-msg": "تؤرگِرتن(ردیابی) رده/ڕِزگ",
+       "trackingcategories-name": "نام پیغام",
+       "trackingcategories-desc": "معیارهای گنجایش رده",
+       "noindex-category-desc": "این صفحه توسط ربات‌ها فهرست‌نشده‌است به این دلیل که واژه جادویی <code><nowiki>__NOINDEX__</nowiki></code> در آن یا در فضای که پرچم مجاز است دارد.",
+       "index-category-desc": "این صفحه <code><nowiki>__INDEX__</nowiki></code> درونش دارد (و در فضای نامی است که پرچم مجاز است)، و به این دلیل توسط ربات مجاز است که به‌صورت عادی نباید می‌شد.",
+       "post-expand-template-inclusion-category-desc": "پس از گسترش همهٔ الگوها، حجم صفحه بزرگتر از <code>$wgMaxArticleSize</code> است بنابراین بعضی از الگو گسترش نیافته‌اند.",
+       "post-expand-template-argument-category-desc": "پس از گسترش یک آرگومان الگو (چیزی بین آکولادهای سه‌تایی، مانند <code>{{{Foo}}}</code>) صفحه بزرگ‌تر از <code>$wgMaxArticleSize</code> می‌شود.",
+       "expensive-parserfunction-category-desc": "توابع هزینه‌بر گران (مانند <code>#ifexist</code>) زیادی در صفجه استفاده شده‌ است. [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit] را ببینید.",
+       "broken-file-category-desc": "صفحه شامل یک پیوند پرونده خراب است (پیوندی برای جاسازی‌کردن یک پرونده هنگامی که آن پرونده وجود ندارد).",
+       "hidden-category-category-desc": "رده در محتوای صفحه‌اش شامل <code><nowiki>__HIDDENCAT__</nowiki></code> است، که از به طور پیش‌فرض نشان‌دادن جعبه پیوندهای رده در صفحات جلوگیری می‌کند.",
+       "trackingcategories-nodesc": "هیچ شرحی وة دةسرةس نیة.",
+       "trackingcategories-disabled": "رده غیرفعال‌شده است",
+       "mailnologin": "نشانی‌ای از فرستنده موجود نیست",
+       "mailnologintext": "برای ارسال ایمیل به کاربران دیگر باید [[Special:UserLogin|به سیستم وارد شوید]] و آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات]] خود داشته باشید.",
+       "emailuser": "ایمیل به این کاربر",
+       "emailuser-title-target": "ارسال ایمیل به این {{GENDER:$1|کاربر}}",
+       "emailuser-title-notarget": "ارسال ایمیل به کاربر",
+       "emailpagetext": "شما می‌توانید از فرم زیر برای ارسال ایمیلی به این {{GENDER:$1|کاربر}} استفاده کنید.\nنشانی ایمیلی که در [[Special:Preferences|ترجیحات کاربریتان]] وارد کرده‌اید در نشانی فرستندهٔ ایمیل خواهد آمد، تا گیرنده بتواند پاسخ دهد.",
+       "defemailsubject": "ایمیل {{SITENAME}} از طرف کاربر «$1»",
+       "usermaildisabled": "ایمیل کاربر غیر قعال است",
+       "usermaildisabledtext": "شما در این ویکی نمی‌توانید به دیگر کاربران ایمیل ارسال کنید",
+       "noemailtitle": "آدرس ایمیل موجود نیست",
+       "noemailtext": "این کاربر آدرس ایمیل معتبری مشخص نکرده است.",
+       "nowikiemailtext": "این کاربر انتخاب کرده که از دیگر کاربران ایمیل دریافت نکند.",
+       "emailnotarget": "نام کاربری ناموجود یا نامعتبر برای گیرنده.",
+       "emailtarget": "نام کاربری دریافت‌کننده را وارد کنید",
+       "emailusername": ":نؤم کاربری",
+       "emailusernamesubmit": "ارسال/کِل کردن",
+       "email-legend": "ارسال ایمیل به کاربر دیگر {{SITENAME}}",
+       "emailfrom": ":إژ",
+       "emailto": "به:",
+       "emailsubject": "عنوان:",
+       "emailmessage": ":پیغام",
+       "emailsend": "كِل كردن/ارسال",
+       "emailccme": "رونوشت پیغام را برایم بفرست.",
+       "emailccsubject": "رونوشت پیغام شما به $1: $2",
+       "emailsent": "ایمیل کِل بی",
+       "emailsenttext": "پیام ایمیل شما فرستاده شد.",
+       "emailuserfooter": "این ایمیل با استفاده از ویژگی «{{int:emailuser}}» {{SITENAME}} توسط $1 به {{GENDER:$2|$2}} {{GENDER:$1|ارسال شد}}.",
+       "usermessage-summary": "گذاشتن پیغام سامانه.",
+       "usermessage-editor": "پیغام رسان سامانه",
+       "watchlist": "لیست پی‌گیریۀل",
+       "mywatchlist": "لیست پی‌گیریۀل",
+       "watchlistfor2": "برای $1 $2",
+       "nowatchlist": "در فهرست پی‌گیری‌های شما هیچ موردی نیست.",
+       "watchlistanontext": "برای مشاهده و ویرایش فهرست پی‌گیری‌های خود از  استفاده کنید.",
+       "watchnologin": "إ سیستم نِهةتئة/نِهاتئة",
+       "addwatch": "افزودن به فهرست پی‌گیری",
+       "addedwatchtext": "«[[:$1]]» و صفحهٔ بحث آن به [[Special:Watchlist|فهرست پی‌گیری‌های]] شما اضافه شد.",
+       "addedwatchtext-short": "صفحه \" $1 \" به فهرست پیگیریهای خود اضافه شده است.",
+       "removewatch": "حذف از فهرست پی‌گیری",
+       "removedwatchtext": "صفحهٔ «[[:$1]]» و صفحهٔ بحث آن از [[Special:Watchlist|فهرست پی‌گیری‌های شما]] برداشته شد.",
+       "removedwatchtext-short": "صفحهٔ \"$1\" از فهرست پیگیری‌های شما حذف شده‌است.",
+       "watch": "پی‌گیری",
+       "watchthispage": "پی‌گیری ئئ وۀلگۀ",
+       "unwatch": "توقف پی‌گیری",
+       "unwatchthispage": "توقف پی‌گیری",
+       "notanarticle": "صفحه محتوایی نیست",
+       "notvisiblerev": "آخرین نسخه توسط کاربری دیگر حذف شده‌است",
+       "watchlist-details": "بدون احتساب صفحه‌های جداگانهٔ بحث، {{PLURAL:$1|$1 صفحه|$1 صفحه ها}} در فهرست پی‌گیری‌های شما قرار {{PLURAL:$1|دارد|دارند}}.",
+       "wlheader-enotif": "ایمیل‌های اعلان فعال است.",
+       "wlheader-showupdated": "صفحه‌هایی که پس از آخرین بازدید شما تغییر کرده‌اند '''پررنگ''' نمایش داده شده‌اند.",
+       "wlnote": "در زیر {{PLURAL:$1|تغییری|<strong>$1</strong> تغییری}} که در {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} گذشته انجام شده موجود است، تاریخ آخرین بازیابی: $3، $4",
+       "wlshowlast": "نمایش آخرین $1 ساعت $2 روز",
+       "watchlistall2": "کؤل",
+       "watchlist-hide": "ئآشاردن-پنهان کردن",
+       "watchlist-submit": "نیشان دائن",
+       "wlshowtime": "دوره زمانی نمایش:",
+       "wlshowhideminor": "دۀسکاریۀل جزئی",
+       "wlshowhidebots": "ربات‌ها",
+       "wlshowhideliu": " کاربرۀل نام نؤیسی کِریا",
+       "wlshowhideanons": " کاربرۀل ناشنا/نادیاری",
+       "wlshowhidepatr": "ویرایش‌های گشت‌خورده",
+       "wlshowhidemine": "دةسکاریةل مإ",
+       "watchlist-options": "گزینه‌های پی‌گیری",
+       "watching": "...پی‌گیری",
+       "unwatching": "توقف پی‌گیری...",
+       "watcherrortext": "ایرادی در هنگام عوض کردن تنظیمات فهرست پیگیرتان برای «$1» رخ داد.",
+       "enotif_reset": "نشان‌گذاری همهٔ صفحات به عنوان بازدیدشده",
+       "enotif_impersonal_salutation": "کاربر {{SITENAME}}",
+       "enotif_subject_deleted": "{{SITENAME}} وةڵگة $1 توسط {{gender:$2|$2}} حذف بی.",
+       "enotif_subject_created": "{{SITENAME}} وةڵگة $1 توسط {{gender:$2|$2}} سازیا.",
+       "enotif_subject_moved": "{{SITENAME}} وةڵگة $1 توسط {{gender:$2|$2}} جاوواز بی.",
+       "enotif_subject_restored": "{{SITENAME}} وةڵگة $1 توسط {{gender:$2|$2}} احیا شد.",
+       "enotif_subject_changed": "{{SITENAME}} وةڵگة $1 توسط {{gender:$2|$2}} تغییر کرد.",
+       "enotif_body_intro_deleted": "صفحهٔ $1 {{SITENAME}} در تاریخ $PAGEEDITDATE توسط {{gender:$2|$2}} حذف شد، $3 را ببینید.",
+       "enotif_body_intro_created": "{{SITENAME}} صفحهٔ $1 در تاریخ $PAGEEDITDATE توسط {{gender:$2|$2}} ایجاد شد. $3 را برای نسخهٔ کنونی شاهده کنید.",
+       "enotif_body_intro_moved": "{{SITENAME}} صفحهٔ $1 در تاریخ $PAGEEDITDATE توسط {{gender:$2|$2}} انتقال یافت، $3 را برای نسخهٔ کنونی شاهده کنید.",
+       "enotif_body_intro_restored": "{{SITENAME}} صفحهٔ $1 در تاریخ $PAGEEDITDATE توسط {{gender:$2|$2}} احیا شد، $3 را برای نسخهٔ کنونی شاهده کنید.",
+       "enotif_body_intro_changed": "{{SITENAME}} صفحهٔ $1 در تاریخ $PAGEEDITDATE توسط {{gender:$2|$2}} تغییر کرد، $3 را برای نسخهٔ کنونی شاهده کنید.",
+       "enotif_lastvisited": "برای دیدن همهٔ تغییرات از آخرین باری که سر زده‌اید $1 را ببینید.",
+       "enotif_lastdiff": "برای نمایش این تغییر $1 را ببینید.",
+       "enotif_anon_editor": " کاربرۀل ناشنا/نادیاری$1",
+       "enotif_body": "$WATCHINGUSERNAME گرامی،\n\n$PAGEINTRO $NEWPAGE\n\n\nتوضیح ویراستار: $PAGESUMMARY $PAGEMINOREDIT\n\nتماس با ویراستار:\nنامه: $PAGEEDITOR_EMAIL\nویکی: $PAGEEDITOR_WIKI\n\nتا هنگامی که به صفحه سر نزده‌اید، در صورت رخ‌دادنِ احتمالیِ فعالیت بیشتر، تا زمانی که در با کاربریتان در سامانه هستید، اعلانیه‌ای برای شما فرستاده نخواهد شد.\nشما همچنین می‌توانید در صفحهٔ پی‌گیری‌های خود پرچم‌های مربوط به آگاهی‌رسانی را صفر کنید همچنین می‌توانید پرچم‌های آگاهی‌سازی را بازنشانی کنید.\n\nدوستدار شما، سامانهٔ آگاهی‌رسانی {{SITENAME}}\n\n--\nبرای تغییر تنظیمات فهرست ایمیل‌های اعلان به {{canonicalurl:{{#special:EditWatchlist}}}} بروید.\n\nبرای تغییر تنظیمات فهرست پی‌گیری‌هایتان به {{canonicalurl:{{#special:EditWatchlist}}}} بروید.\n\nبرای حذف صفحه از فهرست پی‌گیری‌هایتان به $UNWATCHURL بروید.\n\nبازخورد و کمک بیشتر:\n$HELPPAGE",
+       "deletepage": "حۀذف وةڵگة",
+       "confirm": "تأیید",
+       "excontent": "محتوای وةڵگة این بود: «$1»",
+       "excontentauthor": "محتوای صفحه این بود: «$1» و تنها مشارکت‌کننده «[[Special:Contributions/$2|$2]] ([[User talk:$2|بحث]])» بود",
+       "exbeforeblank": "محتوای صفحه قبل از خالی‌کردن این بود: «$1»",
+       "delete-confirm": "حذف «$1»",
+       "delete-legend": "حۀذف کردن/پاک کردن",
+       "historywarning": "<strong>هشدار:</strong> صفحه‌ای که در حال پاک‌کردن آن هستید دارای یک تاریخچه همراه $1 {{PLURAL:$1|بازبینی|بازبینی‌ها}} است:",
+       "confirmdeletetext": "شما در حال حذف کردن یک صفحه یا تصویر از پایگاه داده‌ها همراه با تمام تاریخچهٔ آن هستید.\nلطفاً این عمل را تأیید کنید و اطمینان حاصل کنید که عواقب این کار را می‌دانید و این عمل را مطابق با [[{{MediaWiki:Policy-url}}|سیاست‌ها]] انجام می‌دهید.",
+       "actioncomplete": "عملكرد كامل بيه",
+       "actionfailed": "عمل ناموفق بود",
+       "deletedtext": "«$1» حذف شد.\nبرای سابقهٔ حذف‌های اخیر به $2 مراجعه کنید.",
+       "dellogpage": "سیاههٔ حذف",
+       "dellogpagetext": "فهرست زیر فهرستی از آخرین حذف‌هاست.\nهمهٔ زمان‌های نشان‌داده‌شده زمان خادم (وقت گرینویچ) است.",
+       "deletionlog": "سیاههٔ حذف",
+       "reverted": "به نسخهٔ قدیمی‌تر واگردانده شد",
+       "deletecomment": ":دةلیل",
+       "deleteotherreason": "دلیل دیگر/اضافی:",
+       "deletereasonotherlist": "دلیل دیگر",
+       "deletereason-dropdown": "*دلایل متداول حذف\n** هرزنگار\n** خرابکاری\n** نقض حق تکثیر\n** درخواست کاربر\n** تغییرمسیر شکسته",
+       "delete-edit-reasonlist": "ویرایش دلایل حذف",
+       "delete-toobig": "این صفحه تاریخچهٔ ویرایشی بزرگی دارد، که شامل بیش از $1 {{PLURAL:$1|نسخه|نسخه ها}} است.\nبه منظور جلوگیری از اختلال ناخواسته در {{SITENAME}} حذف این گونه صفحات محدود شده‌است.",
+       "delete-warning-toobig": "ین صفحه تاریخچهٔ ویرایشی بزرگی دارد، که شامل بیش از $1 {{PLURAL:$1|نسخه|نسخه ها}} است.\nحذف آن ممکن است که عملکرد پایگاه دادهٔ {{SITENAME}} را مختل کند;\nبا احتیاط ادامه دهید.",
+       "deleteprotected": "شما نمی‌توانید این صفحه را پاک کنید چون که از آن محافظت شده‌است.",
+       "deleting-backlinks-warning": "''' هشدار:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|صفحه‌های دیگری]] هستند که به صفحه‌ای که شما در حال حذف آن هستید پیوند دارند یا آن را تراگنجانیده‌اند.",
+       "rollback": "واگردانی ویرایش‌ها",
+       "rollbacklink": "واگردانی/گِلآ دائن",
+       "rollbacklinkcount": "rollback $1 {{PLURAL:$1|edit|edits}}",
+       "rollbacklinkcount-morethan": "واگردانی بیش از {{PLURAL:$1|ویرایش|ویرایش ها}}$1",
+       "rollbackfailed": "واگردانی نشد",
+       "cantrollback": "نمی‌توان ویرایش را واگرداند؛\nآخرین مشارکت‌کننده تنها مؤلف این مقاله است.",
+       "alreadyrolled": "واگردانی آخرین ویرایش [[:$1]] توسط [[User:$2|$2]] ([[User talk:$2|بحث]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ممکن نیست؛\nپیش از این شخص دیگری مقاله را ویرایش یا واگردانی کرده‌است.\n\nآخرین ویرایش توسط [[User:$3|$3]] ([[User talk:$3|بحث]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) انجام شده‌است.",
+       "editcomment": "خلاصهٔ ویرایش این بود: «''$1''».",
+       "revertpage": "ویرایش [[Special:Contributions/$2|$2]] ([[User talk:$2|بحث]]) به آخرین تغییری که [[User:$1|$1]] انجام داده بود واگردانده شد",
+       "revertpage-nouser": "ویرایش‌های انجام‌شده توسط (نام کاربری حذف شده) به آخرین ویرایش [[User:$1|$1]] واگردانی شد.",
+       "rollback-success": "ویرایش‌های $1 واگردانی شد؛\nصفحه به آخرین ویرایش $2 برگردانده شد.",
+       "sessionfailure-title": "خطای نشست کاربری",
+       "sessionfailure": "به نظر می‌رسد مشکلی در مورد نشست کاربری شما وجود دارد؛\nعمل درخواست شده در اقدامی پیشگیرانه در برابر ربوده‌شدن اطلاعات نشست کاربری، لغو شد.\nلطفاً دکمهٔ «بازگشت» را در مرورگر خود بفشارید و صفحه‌ای که از آن به اینجا رسیده‌اید را دوباره فراخوانی کنید، سپس مجدداً سعی کنید.",
+       "changecontentmodel": "ویرایش نمونه محتوای یک صفحه",
+       "changecontentmodel-legend": "تغییر نوع محتوی",
+       "changecontentmodel-title-label": "عنوان وةڵگة",
+       "changecontentmodel-model-label": "نمونه محتوای جدید",
+       "changecontentmodel-reason-label": ":دةلیل",
+       "changecontentmodel-success-title": "نمونه محتوی تغییر یافت",
+       "changecontentmodel-success-text": "نوع محتوی [[:$1]]  تغییر یافت",
+       "changecontentmodel-cannot-convert": "محتوی در [[:$1]] نمی‌تواند به گونه‌ای از $2 تبدیل شود.",
+       "changecontentmodel-nodirectediting": "نمونه محتوی $1 امکان ویرایش مستقیم را پشتیبانی نمی‌کند",
+       "log-name-contentmodel": "سیاهه تغییر نمونه محتوی",
+       "log-description-contentmodel": "رویدادهای مرتبط با نمونه محتوی‌های یک صفحه",
+       "logentry-contentmodel-change": "نمونه محتوای صفحهٔ $3 از \"$4\" به \"$5\" توسط $1 {{GENDER:$2|تغییر داده شد}}",
+       "logentry-contentmodel-change-revertlink": "واگردانی/گِلآ دائن",
+       "logentry-contentmodel-change-revert": "واگردانی/گِلآ دائن",
+       "protectlogpage": "سیاههٔ محافظت",
+       "protectlogtext": "در زیر فهرستی از تغییرات سطح محافظت صفحه‌ها آمده‌است.\n[[Special:ProtectedPages|فهرست صفحه‌های محافظت‌شده]] را برای دیدن فهرست محافظت‌های مؤثر صفحه‌ها ببینید.",
+       "protectedarticle": "«[[$1]]» را محافظت کرد",
+       "modifiedarticleprotection": "وضعیت محافظت «[[$1]]» را تغییر داد",
+       "unprotectedarticle": "صفحهٔ «[[$1]]» را از محافظت بیرون آورد",
+       "movedarticleprotection": "تنظیمات محافظت را از «[[$2]]» به «[[$1]]» منتقل کرد",
+       "protect-title": "تغییر وضعیت محافظت «$1»",
+       "protect-title-notallowed": "مشاهده سطح حفاظت  \" $1 \"",
+       "prot_1movedto2": "[[$1]] به [[$2]] منتقل بی",
+       "protect-badnamespace-title": "فضای نام بدون محافظت",
+       "protect-badnamespace-text": "صفحه‌های موجود در این فضای نام، نمی‌توانند محافظت شوند.",
+       "protect-norestrictiontypes-text": "امکان محافظت این صفحه به علت نبودن نوع محدودیت، مقدور نیست.",
+       "protect-norestrictiontypes-title": "صفحهٔ غیرقابل محافظت",
+       "protect-legend": "تأیید محافظت",
+       "protectcomment": ":دةلیل",
+       "protectexpiry": "زمان سرآمدن:",
+       "protect_expiry_invalid": "زمان سرآمدن نامعتبر است.",
+       "protect_expiry_old": "زمان سرآمدن در گذشته‌است.",
+       "protect-unchain-permissions": "باز کردن سایر گزینه‌های محافظت",
+       "protect-text": "شما می‌توانید سطح محافظت صفحهٔ '''$1''' را ببینید و از اینجا آن را تغییر دهید.",
+       "protect-locked-blocked": "شما در مدتی که دسترسی‌تان قطع است نمی‌توانید سطح محافظت صفحات را تغییر دهید.\nتنظیمات فعلی صفحهٔ '''$1''' از این قرار است:",
+       "protect-locked-dblock": "به دلیل قفل شدن پایگاه داده، امکان تغییر سطح محافظت صفحه وجود ندارد.\nتنظیمات فعلی صفحهٔ '''$1''' به این قرار است:",
+       "protect-locked-access": "حساب کاربری شما اجازهٔ تغییر سطح محافظت صفحه را ندارد.\nتنظیمات فعلی صفحهٔ '''$1''' به این قرار است:",
+       "protect-cascadeon": "این صفحه در حال حاضر محافظت شده‌است زیرا در {{PLURAL:$1|صفحهٔ|صفحه‌های}} زیر که گزینهٔ محافظت آبشاری {{PLURAL:$1|آن|آن‌ها}} فعال است، گنجانده شده است.\nتغییراتی به سطح محافظت این صفحه به محافظت ابشاری تأثیر نخواهد گذاشت.",
+       "protect-default": "همهٔ کاربرها",
+       "protect-fallback": "فقط به کاربرهایی که دسترسی «$1» دارند، اجازه داده می‌شود",
+       "protect-level-autoconfirmed": "تنها کاربران تأییدشده",
+       "protect-level-sysop": "فقط مدیران",
+       "protect-summary-cascade": "آبشاری",
+       "protect-expiring": "زمان سرآمدن $1 (UTC)",
+       "protect-expiring-local": "منقضی $1",
+       "protect-expiry-indefinite": "بی‌پایان",
+       "protect-cascade": "محافظت آبشاری - از همهٔ صفحه‌هایی که در این صفحه آمده‌اند نیز محافظت می‌شود.",
+       "protect-cantedit": "شما نمی‌تواند وضعیت محافظت این صفحه را تغییر دهید، چون اجازه ویرایش آن را ندارید.",
+       "protect-othertime": "زمانی دیگر:",
+       "protect-othertime-op": "زمانی دیگر",
+       "protect-existing-expiry": "زمان انقضای موجود: $2، $3",
+       "protect-existing-expiry-infinity": "زمان انقضای موجود: بی‌نهایت",
+       "protect-otherreason": "دلیل دیگر/اضافی:",
+       "protect-otherreason-op": "دلیل دیگر",
+       "protect-dropdown": "*دلایل متداول محافظت\n** خرابکاری گسترده\n** هرزنگاری گسترده\n** جنگ ویرایشی غیر سازنده\n** صفحهٔ پر بازدید",
+       "protect-edit-reasonlist": "ویرایش دلایل محافظت",
+       "protect-expiry-options": "۱ ساعت:1 hour,۱ روز:1 day,۱ هفته:1 week,۲ هفته:2 weeks,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year,بی‌پایان:infinite",
+       "restriction-type": "دسترسی:",
+       "restriction-level": "سطح محدودیت:",
+       "minimum-size": "حداقل اندازه",
+       "maximum-size": "حداکثر اندازه:",
+       "pagesize": "(بایت)",
+       "restriction-edit": "دةسکاری",
+       "restriction-move": "جاوواز کرِدِن",
+       "restriction-create": "دؤِرس کردن/سازین",
+       "restriction-upload": "بارگذاری",
+       "restriction-level-sysop": "کاملاً محافظت‌شده",
+       "restriction-level-autoconfirmed": "نیمه‌حفاظت‌شده",
+       "restriction-level-all": "هر سطحی",
+       "undelete": "احیای صفحهٔ حذف‌شده",
+       "undeletepage": "نمایش و احیای صفحه‌های حذف‌شده",
+       "undeletepagetitle": "'''آن چه در ادامه می‌آید شامل نسخه‌های حذف شدهٔ [[:$1|$1]] است'''.",
+       "viewdeletedpage": "نمایش صفحه‌های حذف‌شده",
+       "undeletepagetext": "{{PLURAL:$1|صفحهٔ زیر حدف شده|صفحه‌های زیر حذف شده‌اند}} ولی هنوز در بایگانی {{PLURAL:$1|هست|هستند}} و {{PLURAL:$1|می‌تواند احیا شود|می‌توانند احیا شوند}}.\nاین بایگانی ممکن است هر چند وقت تمیز شود.",
+       "undelete-fieldset-title": "احیای نسخه‌ها",
+       "undeleteextrahelp": "برای احیای تمام تاریخچهٔ صفحه، همهٔ جعبه‌ها را خالی رها کرده و دکمهٔ '''''{{int:undeletebtn}}''''' را کلیک کنید.\nبرای انجام احیای انتخابی، جعبه‌های متناظر با نسخه‌های مورد نظر برای احیا را علامت زده و دکمهٔ '''''{{int:undeletebtn}}''''' را کلیک کنید.",
+       "undeleterevisions": "$1 نسخه حذف {{PLURAL:$1|شده‌است|شده‌اند}}",
+       "undeletehistory": "اگر این صفحه را احیا کنید، همهٔ نسخه‌های آن در تاریخچه احیا خواهند شد.\nاگر صفحهٔ جدیدی با نام یکسان از زمان حذف ایجاد شده باشد، نسخه‌های احیاشده در تاریخچهٔ قبلی خواهند آمد.",
+       "undeleterevdel": "احیای صفحه‌های در حالتی که باعث حذف شدن بخشی از آخرین نسخهٔ صفحه یا پرونده بشود مقدور نیست.\nدر این حالت شما باید جدیدترین نسخهٔ حذف شده را نیز احیا کنید.",
+       "undeletehistorynoadmin": "این مقاله حذف شده‌است.\nدلیل حذف این مقاله به همراه مشخصات کاربرانی که قبل از حذف این صفحه را ویرایش کرده‌اند، در خلاصهٔ زیر آمده‌است.\nمتن واقعی این ویرایش‌های حذف شده فقط در دسترس مدیران است.",
+       "undelete-revision": "نسخهٔ حذف شدهٔ $1 (به تاریخ $4 ساعت $5) توسط $3:",
+       "undeleterevision-missing": "نسخه نامعتبر یا مفقود است.\nممکن است پیوندتان نادرست باشد یا اینکه نسخه از بایگانی حذف یا بازیابی شده باشد .",
+       "undelete-nodiff": "نسخهٔ قدیمی‌تری یافت نشد.",
+       "undeletebtn": "احیا",
+       "undeletelink": "نمایش/احیا",
+       "undeleteviewlink": "دیین/سئرکردن",
+       "undeleteinvert": "انتخاب بپلئ/برعۀسگ بؤ",
+       "undeletecomment": ":دةلیل",
+       "undeletedrevisions": "$1 نسخه احیا {{PLURAL:$1|شد}}",
+       "undeletedrevisions-files": "$1 نسخه و $2 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
+       "undeletedfiles": "$1 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
+       "cannotundelete": "احیا ناموفق بود:\n$1",
+       "undeletedpage": "'''$1 احیا شد'''\n\nبرای دیدن سیاههٔ حذف‌ها و احیاهای اخیر به  [[Special:Log/delete|سیاههٔ حذف]] رجوع کنید.",
+       "undelete-header": "برای دیدن صفحه‌های حذف‌شدهٔ اخیر [[Special:Log/delete|سیاههٔ حذف]] را ببینید.",
+       "undelete-search-title": "جستجوی صفحه‌های حذف‌شده",
+       "undelete-search-box": "جستجوی صفحه‌های حذف‌شده",
+       "undelete-search-prefix": "نمایش صفحات با شروع از:",
+       "undelete-search-submit": "گئردین/مهِ نی",
+       "undelete-no-results": "هیچ صفحهٔ منطبقی در بایگانی حذف‌شده‌ها یافت نشد.",
+       "undelete-filename-mismatch": "امکان احیای نسخهٔ $1 وجود ندارد: نام پرونده مطابقت نمی‌کند.",
+       "undelete-bad-store-key": "امکان احیای نسخهٔ $1 وجود ندارد: پرونده قبل از حذف از دست رفته بود.",
+       "undelete-cleanup-error": "خطا در حذف تاریخچهٔ استفاده نشدهٔ «$1».",
+       "undelete-missing-filearchive": "امکان احیای تاریخچهٔ شمارهٔ $1 وجود ندارد زیرا اطلاعات در پایگاه داده وجود ندارد.\nممکن است پیشتر احیا شده باشد.",
+       "undelete-error": "خطا صفحه غیرقابل حذف",
+       "undelete-error-short": "خطا در احیای پرونده: $1",
+       "undelete-error-long": "در زمان احیای پرونده خطا رخ داد:\n\n$1",
+       "undelete-show-file-confirm": "آیا مطمئن هستید که می‌خواهید یک نسخهٔ حذف شده از پرونده \"<nowiki>$1</nowiki>\" مورخ $2 ساعت $3 را ببینید؟",
+       "undelete-show-file-submit": "أرێ-بةلئ",
+       "namespace": "فضای نامۀل",
+       "invert": "انتخاب بپلئ/برعۀسگ بؤ",
+       "tooltip-invert": "این جعبه را علامت بزنید تا تغییرات صفحه‌های داخل فضای نام انتخاب شده (و دیگر فضاهای نام علامت زده شده) پنهان شوند",
+       "tooltip-whatlinkshere-invert": "این جعبه را برای پنهان کردن پیوند صفحاتی که فضای نامشان انتخاب شده‌است، انتخاب کنید.",
+       "namespace_association": "فضای نام مرتبط",
+       "tooltip-namespace_association": "این جعبه را علامت بزنید تا فضای نام بحث یا موضوع مرتبط با فضای نام انتخاب شده هم شامل شود",
+       "blanknamespace": "(اصلی)",
+       "contributions": "هؤمکاریۀل{{GENDER:$1|کاربۀر}}",
+       "contributions-title": "مشارکت‌های کاربری $1",
+       "mycontris": "هؤمکاری کِرۀل",
+       "anoncontribs": "هؤمکاری کِرۀل",
+       "contribsub2": "برای {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
+       "nocontribs": "هیچ تغییری با این مشخصات یافت نشد.",
+       "uctop": "(نؤسخهٔ ایسه)",
+       "month": ":)در این سال (و پیش از آن",
+       "year": ":)در این سال (و پیش از آن",
+       "sp-contributions-newbies": "فقط مشارکت‌های تازه‌کاران نمایش داده شود",
+       "sp-contributions-newbies-sub": "برای تازه‌کاران",
+       "sp-contributions-newbies-title": "مشارکت‌های کاربری برای حساب‌های تازه‌کار",
+       "sp-contributions-blocklog": "سیاههٔ بسته‌شدن‌ها",
+       "sp-contributions-suppresslog": "کمک‌های کاربر متوقف شده",
+       "sp-contributions-deleted": "مشارکت‌های حذف‌شدهٔ کاربر",
+       "sp-contributions-uploads": "بارگذاری‌ها",
+       "sp-contributions-logs": "سیاهه‌ها",
+       "sp-contributions-talk": "قسۀ-گۀپ",
+       "sp-contributions-userrights": "مدیریت اختیارات کاربر",
+       "sp-contributions-blocked-notice": "این کاربر در حال حاضر بسته شده‌است.\nآخرین سیاههٔ بسته شدن در زیر آمده‌است:",
+       "sp-contributions-blocked-notice-anon": "این نشانی آی‌پی در حال حاضر بسته است.\nآخرین سیاههٔ بسته شدن در زیر آمده‌است:",
+       "sp-contributions-search": "جستجوی مشارکت‌ها",
+       "sp-contributions-username": "نشانی آی‌پی یا نام کاربری:",
+       "sp-contributions-toponly": "فقط ویرایش‌هایی که آخرین نسخه‌اند نمایش داده شود",
+       "sp-contributions-newonly": "فقط نمایش ویرایش‌هایی که ایجاد صفحه هستند",
+       "sp-contributions-submit": "گئردین/مهِ نی",
+       "whatlinkshere": "پیوندۀل وۀ ئئ وةڵگة",
+       "whatlinkshere-title": "وۀلگۀلئ گإ  وۀ «$1» پیوۀند دِرِن",
+       "whatlinkshere-page": ":وةڵگة",
+       "linkshere": "The following pages link to <strong>[[:$1]]</strong>:",
+       "nolinkshere": "هیچ صفحه‌ای به '''[[:$1]]''' پیوند ندارد.",
+       "nolinkshere-ns": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''[[:$1]]''' پیوند ندارد.",
+       "isredirect": "صفحهٔ تغییرمسیر",
+       "istemplate": " تراگنجانش‌ها",
+       "isimage": "پیوند پرونده",
+       "whatlinkshere-prev": "{{PLURAL:$1|previous|previous $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|next|next $1}}",
+       "whatlinkshere-links": "← پیوند",
+       "whatlinkshere-hideredirs": "$1 تغییرمسیر",
+       "whatlinkshere-hidetrans": "$1 تراگنجانش‌ها",
+       "whatlinkshere-hidelinks": "$1 پیوند",
+       "whatlinkshere-hideimages": "$1 پیوندهای پرونده",
+       "whatlinkshere-filters": "پالانۀل/فیلترۀل",
+       "whatlinkshere-submit": "بِچۆ",
+       "autoblockid": "شناسه قطع دسترسی خودکار #$1",
+       "block": "بستن کاربر.",
+       "unblock": "بازکردن کاربر",
+       "blockip": "بستن {{GENDER:$1|کاربر}}",
+       "blockip-legend": "بستن کاربر",
+       "blockiptext": "از فرم زیر برای بستن دسترسی ویرایش یک نشانی آی‌پی یا نام کاربری مشخص استفاده کنید.\nاین کار فقط فقط باید برای جلوگیری از خرابکاری و بر اساس [[{{MediaWiki:Policy-url}}|سیاست قطع دسترسی]] انجام شود.\nدلیل مشخص این کار را در زیر ذکر کنید (مثلاً با ذکر صفحه‌های به‌خصوصی که مورد خرابکاری واقع شده‌اند).",
+       "ipaddressorusername": "نشانی آی‌پی یا نام کاربری:",
+       "ipbexpiry": "زمان سرآمدن:",
+       "ipbreason": ":دةلیل",
+       "ipbreason-dropdown": "*دلایل متداول قطع دسترسی\n**واردکردن اطلاعات نادرست\n**پاک‌کردن اطلاعات مفید از صفحات\n**هرزنگاری از طریق درج مکرر پیوند به وب‌گاه‌ها\n**درج چرندیات یا نوشته‌های بی‌معنا در صفحات\n**تهدید یا ارعاب دیگر کاربران\n**سوء استفاده از چند حساب کاربری\n**نام کاربری نامناسب",
+       "ipb-hardblock": "جلوگیری از ویرایش کردن کاربران ثبت نام کرده از طریق این نشانی آی‌پی",
+       "ipbcreateaccount": "جلوگیری از ایجاد حساب",
+       "ipbemailban": "جلوگیری از ارسال ایمیل",
+       "ipbenableautoblock": "بستن  خودکار آخرین نشانی آی‌پی استفاده شده توسط کاربر و نشانی‌های دیگری که از آن‌ها برای ویرایش تلاش می‌کند",
+       "ipbsubmit": "این کاربر بسته شود",
+       "ipbother": "زمانی دیگر",
+       "ipboptions": "۲ ساعت:2 hours,۱ روز:1 day,۳ روز:3 days,۱ هفته:1 week,۲ هفته:2 weeks,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year,بی‌پایان:infinite",
+       "ipbhidename": "نهفتن نام کاربری از ویرایش‌ها و فهرست‌ها",
+       "ipbwatchuser": "پی‌گیری صفحهٔ کاربری و بحث این کاربر",
+       "ipb-disableusertalk": "جلوگیری از ویرایشی صفحهً بحث توسط خود کاربر در زمانی که بسته است",
+       "ipb-change-block": "بستن دوبارهٔ کاربر با این تنظیم‌ها",
+       "ipb-confirm": "تأیید بستن",
+       "badipaddress": "نشانی آی‌پی نامجاز",
+       "blockipsuccesssub": "بستن با موفقیت انجام شد",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] بسته شد.<br />\nبرای بررسی بسته‌شده‌ها [[Special:BlockList|فهرست بسته‌شده‌ها]] را ببینید.",
+       "ipb-blockingself": "شما در حال بستن خودتان هستید!  آیا مطمئن هستید که می‌خواهید چنین کاری انجام دهید؟",
+       "ipb-confirmhideuser": "شما در حال بستن یک کاربر هستید که «پنهان‌سازی کاربر» برایش فعال شد‌ه‌است. این کار نام کاربر را از همهٔ فهرست‌ها و سیاهه‌ها مخفی می‌کند. آیا مطمئن هستید که می‌خواهید آن را انجام دهید؟",
+       "ipb-confirmaction": "اگر واقعاً مطمئنید که می‌خواهید آن را انجام دهید، لطفاً زمینهٔ \"{{int:ipb-confirm}}\" را در زیر بررسی کنید.",
+       "ipb-edit-dropdown": "ویرایش دلایل قطع‌دسترسی",
+       "ipb-unblock-addr": "باز کردن $1",
+       "ipb-unblock": "باز کردن نام کاربری یا نشانی آی‌پی",
+       "ipb-blocklist": "دیدن قطع دسترسی‌های موجود",
+       "ipb-blocklist-contribs": "مشارکت‌های $1",
+       "unblockip": "بازکردن کاربر",
+       "unblockiptext": "برای بازگرداندن دسترسی نوشتن به یک نشانی آی‌پی یا نام کاربری بسته‌شده از فرم زیر استفاده کنید.",
+       "ipusubmit": "باز کردن دسترسی",
+       "unblocked": "دسترسی [[User:$1|$1]] دوباره برقرار شد",
+       "unblocked-range": "$1 باز شد",
+       "unblocked-id": "قطع دسترسی شماره $1 خاتمه یافت",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] رفع قطع دسترسی شد.",
+       "blocklist": "کاربران بسته‌شده",
+       "ipblocklist": "کاربران بسته‌شده",
+       "ipblocklist-legend": "جستجوی کاربر بسته شده",
+       "blocklist-userblocks": "پنهان کردن بسته‌شدن‌های حساب",
+       "blocklist-tempblocks": "پنهان کردن بستن‌های موقت",
+       "blocklist-addressblocks": "پنهان کردن تک آی‌پی‌های بسته شده",
+       "blocklist-rangeblocks": "پنهان کردنی قطع دسترسی بازه‌ها",
+       "blocklist-timestamp": "برچسب زمان",
+       "blocklist-target": "هةدةف",
+       "blocklist-expiry": "زمان سرآمدن",
+       "blocklist-by": "مدیر قطع دسترسی کننده",
+       "blocklist-params": "پارامترهای بستن",
+       "blocklist-reason": "دةلیل",
+       "ipblocklist-submit": "گئردین/مهِ نی",
+       "ipblocklist-localblock": "قطع دسترسی محلی",
+       "ipblocklist-otherblocks": "سایر {{PLURAL:$1|بستن‌ها|بستن‌}}",
+       "infiniteblock": "بی‌پایان",
+       "expiringblock": "در $1 ساعت $2 به پایان می‌رسد",
+       "anononlyblock": "فقط کاربران گمنام",
+       "noautoblockblock": "بستن خودکار غیرفعال است",
+       "createaccountblock": "امکان ساخت حساب گرفته‌شده",
+       "emailblock": "ایمیل بسته‌شده",
+       "blocklist-nousertalk": "نمی‌تواند صفحهٔ بحث خود را ویرایش کند",
+       "ipblocklist-empty": "فهرست بسته‌شدن‌ها خالی‌است.",
+       "ipblocklist-no-results": "دسترسی حساب کاربری یا نشانی آی‌پی مورد نظر قطع نیست.",
+       "blocklink": "بۀستن",
+       "unblocklink": "باز شود",
+       "change-blocklink": "تغییر قطع دسترسی",
+       "contribslink": "هؤمکاریۀل",
+       "emaillink": "ایمیل کِل کۀ",
+       "autoblocker": "به طور خودکار بسته شد چون آی‌پی شما به تازگی توسط کاربر «[[User:$1|$1]]» استفاده شده‌است.\nدلیل قطع دسترسی $1 چنین است \"$2\"",
+       "blocklogpage": "سیاههٔ بسته‌شدن‌ها",
+       "blocklog-showlog": "دسترسی این کاربر در گذشته بسته شده‌است.\nسیاههٔ قطع دسترسی در زیر نمایش یافته است:",
+       "blocklog-showsuppresslog": "دسترسی این کاربر قبلاً بسته شده و این کاربر پنهان شده‌است.\nسیاههٔ قطع دسترسی در زیر نمایش یافته است:",
+       "blocklogentry": "«[[$1]]» را تا $2 بست $3",
+       "reblock-logentry": "تنظیمات قطع دسترسی [[$1]] را تغییر داد به پایان قطع دسترسی در $2 $3",
+       "blocklogtext": "این سیاهه‌ای از بستن و باز کردن کاربرها است.\nنشانی‌های آی‌پی که به طور خودکار بسته شده‌اند فهرست نشده‌اند.\nبرای فهرست محرومیت‌ها و بسته‌شدن‌های حال حاضر به [[Special:BlockList|فهرست بسته‌شده‌ها]] مراجعه کنید.",
+       "unblocklogentry": "$1 را باز کرد",
+       "block-log-flags-anononly": "فقط کاربران گمنام",
+       "block-log-flags-nocreate": "قابلیت ایجاد حساب غیرفعال شد",
+       "block-log-flags-noautoblock": "قطع دسترسی خودکار غیرفعال شد",
+       "block-log-flags-noemail": "ایمیل بسته‌شد",
+       "block-log-flags-nousertalk": "صفحهٔ بحث خود را نمی‌تواند ویرایش کند",
+       "block-log-flags-angry-autoblock": "قطع دسترسی خودکار پیشرفته فعال شد",
+       "block-log-flags-hiddenname": "نام کاربری پنهان",
+       "range_block_disabled": "بستن یک بازه توسط مدیران غیر فعال است.",
+       "ipb_expiry_invalid": "زمان سرآمدن نامعتبر.",
+       "ipb_expiry_temp": "قطع دسترسی کاربرهای پهنان باید همیشگی باشد.",
+       "ipb_hide_invalid": "قادر به سرکوب این حساب نیست; این بیشتر از {{PLURAL:$1|یک ویرایش|$1 ویرایش‌ها}} دارد.",
+       "ipb_already_blocked": "«$1» همین الان هم بسته‌است",
+       "ipb-needreblock": "دسترسی $1 از قبل بسته است. آیا می‌خواهید تنظیمات آن را تغییر دهید؟",
+       "ipb-otherblocks-header": "سایر {{PLURAL:$1|قطع دسترسی‌ها|قطع دسترسی‌}}",
+       "unblock-hideuser": "‫به این خاطر که حساب کاربری این کاربر مخفی شده‌است شما نمی‌توانید آن را باز کنید.‬",
+       "ipb_cant_unblock": "خطا: شناسه بسته‌شدن $1 یافت نشد. ممکن است پیشتر باز شده باشد.",
+       "ipb_blocked_as_range": "خطا: نشانی آی‌پی $1 به شکل مستقیم بسته نشده‌است و نمی‌تواند باز شود.\nاین نشانی به همراه بازه $2 بسته شده که قابل باز شدن است.",
+       "ip_range_invalid": "بازهٔ آی‌پی نامعتبر.",
+       "ip_range_toolarge": "قطع دسترسی بازه‌های بزرگتر از /$1 مجاز نیست.",
+       "proxyblocker": "مسدود کننده پروکسی",
+       "proxyblockreason": "نشانی آی‌پی شما بسته شده است چون متعلق به یک پروکسی باز است.\nلطفاً با ارائه دهندهً خدمات اینترنت خود یا پشتیبانی فنی تماس بگیرید و آنها را از این مشکل امنیتی جدی آگاه کنید.",
+       "sorbsreason": "نشانی آی‌پی شما توسط DNSBL مورد استفاده {{SITENAME}} به عنوان یک پروکسی باز گزارش شده است.",
+       "sorbs_create_account_reason": "نشانی آی‌پی شما توسط DNSBL مورد استفاده {{SITENAME}} به عنوان یک پروکسی باز گزارش شده‌است.\nشما اجازهٔ ساختن حساب کاربری ندارید.",
+       "xffblockreason": "نشانی آی‌پی در X-Forwarded-For header موجود است و پروکسی شما یا سروری که از آن استفاده می‌کنید بسته‌شده‌است. دلیل بسته‌شدن: $1",
+       "cant-see-hidden-user": "کاربری که می‌خواهید ببندید قبلاً بسته شده و پنهان گردیده است. چون شما دسترسی پنهان کردن کاربران را ندارید، نمی‌توانید قطع دسترسی کاربر را ببینید یا ویرایش کنید.",
+       "ipbblocked": "شما نمی‌توانید دسترسی دیگر کاربران را ببندید یا باز کنید زیرا دسترسی خودتان بسته است.",
+       "ipbnounblockself": "شما مجاز به باز کردن دسترسی خود نیستید.",
+       "lockdb": "قفل کردن پایگاه داده",
+       "unlockdb": "از قفل در آوردن پایگاه داده",
+       "lockdbtext": "قفل کردن پایگاه داده امکان ویرایش صفحات، تغییر تنظیمات، ویرایش پی‌گیری‌ها، و سایر تغییراتی را که نیازمند تغییری در پایگاه داده است، از همهٔ کاربران سلب می‌کند.\nلطفاً تأیید کنید که همین کار را می‌خواهید انجام دهید، و در اولین فرصت پایگاه داده را از حالت قفل شده خارج خواهید کرد.",
+       "unlockdbtext": "از قفل در آوردن پایگاه داده به تمامی کاربران اجازه می‌دهد که توانایی ویرایش صفحات، تغییر تنظیمات، تغییر پی‌گیری‌ها و هر تغییر دیگری که نیازمند تغییر در پایگاه داده باشد را دوباره به دست بیاورند.\nلطفاً تأیید کنید که همین کار را می‌خواهید انجام دهید.",
+       "lockconfirm": "بله، من جداً می‌خواهم پایگاه داده را قفل کنم.",
+       "unlockconfirm": "بله، من جداً می‌خواهم پایگاه داده را از قفل در آورم.",
+       "lockbtn": "قفل کردن پایگاه داده",
+       "unlockbtn": "از قفل درآوردن پایگاه داده",
+       "locknoconfirm": "شما در جعبهٔ تأیید تیک نزدید",
+       "lockdbsuccesssub": "قفل کردن پایگاه داده با موفقیت انجام شد",
+       "unlockdbsuccesssub": "قفل پایگاه داده برداشته شد",
+       "lockdbsuccesstext": "پایگاه داده قفل شد.\n<br />فراموش نکنید [[Special:UnlockDB|remove the lock]] که پس از اتمام نگهداری قفل را بردارید.",
+       "unlockdbsuccesstext": "پایگاه داده از قفل در آمد.",
+       "lockfilenotwritable": "قفل پایگاه داده نوشتنی نیست. برای این که بتوانید پایگاه داده را قفل یا باز کنید، باید این پرونده نوشتنی باشد.",
+       "databasenotlocked": "پایگاه داده قفل نیست.",
+       "lockedbyandtime": "(به وسیلهٔ $1 در $2 ساعت $3)",
+       "move-page": "انتقال $1",
+       "move-page-legend": "جاوواز کردن وةڵگة",
+       "movepagetext": "با استفاده از فرم زیر نام صفحه تغییر خواهد کرد، و تمام تاریخچه‌اش به نام جدید منتقل خواهد شد.\nعنوان قدیمی تبدیل به یک صفحهٔ تغییرمسیر به عنوان جدید خواهد شد.\nشما می‌توانید تغییرمسیرهایی که به عنوان اصلی اشاره دارند را به صورت خودکار به‌روزرسانی کنید.\nپیوندهای که به عنوان صفحهٔ قدیمی وجود دارند، تغییر نخواهند کرد؛ حتماً تغییرمسیرهای [[Special:DoubleRedirects|دوتایی]] یا [[Special:BrokenRedirects|خراب]] را بررسی کنید.\n'''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.\n\nتوجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،\nمگر این آخرین ویرایش تغییرمسیر باشد و در  تاریخچهٔ ویرایشی نداشته باشد.\nاین یعنی اگر اشتباه کردید می‌توانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمی‌توانید روی صفحات موجود بنویسید.\n\n'''هشدار!'''\nانتقال صفحات به نام جدید ممکن است تغییر اساسی و غیرمنتظره‌ای برای صفحات محبوب باشد؛\nلطفاً مطمئن شوید که قبل از انتقال دادن صفحه، عواقب این کار را درک می‌کنید.",
+       "movepagetext-noredirectfixer": "استفاده از فرم زیر سبب تغییر نام یک صفحه و انتقال تمام تاریخچهٔ آن به نام جدید می‌شود.\nعنوان پیشین تغییرمسیری به عنوان جدید خواهد شد.\nبه خاطر داشته باشید که [[Special:DoubleRedirects|تغییرمسیرهای دوتایی]] یا [[Special:BrokenRedirects|تغییرمسیرهای خراب]] را بررسی کنید.\nشما مسئولید که مطمئن شوید پس از انتقال، پیوندها به عنوان پیشین به جایی منتهی می‌شوند که باید.\n\nتوجه کنید که اگر صفحه‌ای تحت عنوان جدید از قبل موجود باشد، انتقال انجام '''نخواهد شد'''، مگر اینکه صفحه خالی و یا تغییرمسیر باشد و تاریخچهٔ ویرایشی دیگری نداشته باشد.\nاین یعنی اگر صفحه را به نامی اشتباه منتقل کردید می‌توانید این تغییر را واگردانی کنید، اما نمی‌توانید یک صفحه را به صفحه‌ای که از قبل موجود است انتقال دهید.\n\n'''هشدار!'''\nانتقال صفحه‌های پربیننده ممکن است عملی غیرمنتظره باشد؛\nلطفاً پیش از انتقال مطمئن شوید از نتیجهٔ کار آگاهید.",
+       "movepagetalktext": "اگر این گزینه را انتخاب کنید، صفحهٔ بحث مرتبط به صورت خودکار انتقال داده می‌شود به عنوان جدید و در صورت عدم انتخاب گزینه، صفحهٔ بحث جدید یک صفحهٔ خالی خواهد بود و در این حالت، باید صفحه را بطور دستی انتقال داده و یا محتویات دو صفحه را با ویرایش ادغام کنید.",
+       "moveuserpage-warning": "'''هشدار:''' شما در حال انتقال دادن یک صفحهٔ کاربر هستید. توجه داشته باشید که تنها صفحه منتقل می‌شود و نام کاربر تغییر '''نمی‌یابد'''.",
+       "movecategorypage-warning": "<strong>هشدار:</strong> شما در حال انتقال صفحه رده هستید. لطفاً توجه داشته باشید که فقط صفحه منتقل خواهد شد و  صفحات در رده قدیمی می‌مانند و به رده جدید <em>نمی‌روند</em>.",
+       "movenologintext": "برای انتقال صفحات باید کاربر ثبت‌شده بوده و [[Special:UserLogin|به سامانه وارد شوید]].",
+       "movenotallowed": "شما اجازهٔ انتقال دادن صفحات را ندارید.",
+       "movenotallowedfile": "شما اجازهٔ انتقال پرونده‌ها را ندارید.",
+       "cant-move-user-page": "شما اجازه ندارید صفحه‌های کاربری سرشاخه را انتقال دهید.",
+       "cant-move-to-user-page": "شما اجازه ندارید که یک صفحه را به یک صفحهٔ کاربر انتقال دهید (به استثنای زیر صفحه‌های کاربری).",
+       "cant-move-category-page": "شما اجازهٔ انتقال دادن صفحهٔ رده‌ها را ندارید.",
+       "cant-move-to-category-page": "شما مجوز برای انتقال صفحه به صفحه رده ندارید.",
+       "newtitle": "عنوان تازه:",
+       "move-watch": "پی‌گیری صفحه‌های مبدأ و مقصد",
+       "movepagebtn": "جاوواز کردن وةڵگة",
+       "pagemovedsub": "انتقال با موفقیت انجام شد",
+       "movepage-moved": "'''«$1» به «$2» منتقل شد'''",
+       "movepage-moved-redirect": "یک تغییرمسیر ایجاد شد.",
+       "movepage-moved-noredirect": "از ایجاد تغییرمسیر ممانعت شد.",
+       "articleexists": "صفحه‌ای با این نام از قبل وجود دارد، یا نامی که انتخاب کرده‌اید معتبر نیست.\nلطفاً نام دیگری انتخاب کنید.",
+       "cantmove-titleprotected": "شما نمی‌توانید صفحه را به این نشانی انتقال دهید، چرا که عنوان جدید در برابر ایجاد محافظت شده‌است",
+       "movetalk": "صفحهٔ بحث هم منتقل شود",
+       "move-subpages": "انتقال زیرصفحه‌ها (تا $1 صفحه)",
+       "move-talk-subpages": "انتقال زیرصفحه‌های صفحهٔ بحث (تا $1 صفحه)",
+       "movepage-page-exists": "صفحهٔ $1 از قبل وجود دارد و نمی‌تواند به طور خودکار جایگزین شود.",
+       "movepage-page-moved": "صفحهٔ $1 به $2 انتقال یافت.",
+       "movepage-page-unmoved": "صفحهٔ $1 را نمی‌توان به $2 انتقال داد.",
+       "movepage-max-pages": "حداکثر تعداد صفحه‌های ممکن ($1 {{PLURAL:$1|صفحه|صفحه ها}}) که می‌توان انتقال داد منتقل شدند و صفحه‌های دیگر را نمی‌توان به طور خودکار منتقل کرد.",
+       "movelogpage": "سیاههٔ انتقال",
+       "movelogpagetext": "در زیر فهرستی از انتقال صفحات آمده‌است.",
+       "movesubpage": "{{PLURAL:$1|زیرصفحه|زیرصفحه‌ها}}",
+       "movesubpagetext": "این صفحه $1 زیرصفحه دارد که در زیر نمایش {{PLURAL:$1|یافته‌است|یافته‌اند}}.",
+       "movenosubpage": "این صفحه هیچ زیرصفحه‌ای ندارد.",
+       "movereason": ":دةلیل",
+       "revertmove": "واگردانی/گِلآ دائن",
+       "delete_and_move_text": "== نیاز به حذف ==\n\nمقالهٔ مقصد «[[:$1]]» وجود دارد. آیا می‌خواهید آن را حذف کنید تا انتقال ممکن شود؟",
+       "delete_and_move_confirm": "بله، صفحه حذف شود",
+       "delete_and_move_reason": "حذف برای ممکن‌شدن انتقال  «[[$1]]»",
+       "selfmove": "عنوان‌های صفحهٔ مبدأ و مقصد یکی است؛\nانتقال صفحه به خودش ممکن نیست.",
+       "immobile-source-namespace": "امکان انتقال صفحه‌ها در فضای نام «$1» وجود ندارد",
+       "immobile-target-namespace": "امکان انتقال صفحه‌ها به فضای نام «$1» وجود ندارد",
+       "immobile-target-namespace-iw": "پیوند میان‌ویکی هدفی مجاز برای انتقال صفحه نیست.",
+       "immobile-source-page": "این صفحه قابل انتقال نیست.",
+       "immobile-target-page": "امکان انتقال به این عنوان مقصد وجود ندارد.",
+       "bad-target-model": "مقصد مورد نظر از مدل محتوایی متفاوتی استفاده می‌کند. تبدیل $1 به $2 ممکن نیست.",
+       "imagenocrossnamespace": "امکان انتقال تصویر به فضای نام غیر پرونده وجود ندارد",
+       "nonfile-cannot-move-to-file": "امکان انتقال محتوای غیر پرونده به فضای نام پرونده وجود ندارد",
+       "imagetypemismatch": "پسوند پرونده تازه با نوع آن سازگار نیست",
+       "imageinvalidfilename": "نام پروندهٔ هدف نامجاز است",
+       "fix-double-redirects": "به روز کردن تمامی تغییرمسیرهایی که به مقالهٔ اصلی اشاره می‌کنند",
+       "move-leave-redirect": "بر جا گذاشتن یک تغییرمسیر",
+       "protectedpagemovewarning": "'''هشدار:''' این صفحه قفل شده‌است به طوری که تنها کاربران با دسترسی مدیریت می‌توانند آن را انتقال دهند.\nآخرین موارد سیاهه در زیر آمده است:",
+       "semiprotectedpagemovewarning": "'''تذکر:''' این صفحه قفل شده‌است به طوری که تنها کاربران ثبت نام کرده می‌توانند آن را انتقال دهند.\nآخرین موارد سیاهه در زیر آمده است:",
+       "move-over-sharedrepo": "== پرونده موجود است ==\n[[:$1]] در یک مخزن مشترک وجود دارد. انتقال یک پرونده به این نام باعث باطل شدن پرونده مشترک خواهد شد.",
+       "file-exists-sharedrepo": "نام پرونده انتخاب شده از قبل در یک مخزن مشترک استفاده شده‌است.\nلطفاً یک نام دیگر برگزینید.",
+       "export": "برون‌بری صفحات",
+       "exporttext": "شما می‌توانید متن و تاریخچهٔ ویرایش یک صفحهٔ مشخص یا مجموعه‌ای از صفحات را به شکل پوشیده در اکس‌ام‌ال برون‌بری کنید.\nاین اطلاعات را می‌توان در ویکی دیگری که نرم‌افزار «مدیاویکی» را اجرا می‌کند از طریق [[Special:Import|صفحهٔ درون‌ریزی]] وارد کرد.\n\nبرای برون‌بری صفحات، عنوان آن‌ها را در جعبهٔ زیر وارد کنید (در هر سطر فقط یک عنوان) و مشخص کنید که آیا نسخهٔ اخیر صفحه را به همراه نسخه‌های قدیمی‌تر و تاریخچهٔ صفحه می‌خواهید، یا تنها نسخهٔ اخیر صفحه و اطلاعات آخرین ویرایش را می‌خواهید.\n\nدر حالت دوم، شما می‌توانید از یک پیوند استفاده کنید، مثلاً [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] برای صفحهٔ «[[{{MediaWiki:Mainpage}}]]».",
+       "exportall": "برون‌بری همهٔ صفحات",
+       "exportcuronly": "فقط نسخهٔ فعلی شامل شود، نه کل تاریخچه",
+       "exportnohistory": "----\n'''توجه:''' امکان برون‌بری تاریخچهٔ کامل صفحات از طریق این صفحه به دلایل اجرایی از کار انداخته شده‌است.",
+       "exportlistauthors": "شامل فهرست کامل مشارکت‌کنندگان هر صفحه",
+       "export-submit": "در بِردن",
+       "export-addcattext": ":افزودن وةڵگةل إژ رده/ڕِزگ",
+       "export-addcat": "افزودن",
+       "export-addnstext": "افزودن صفحات از فضای نام:",
+       "export-addns": "افزودن",
+       "export-download": "ذخیره به صورت پرونده",
+       "export-templates": "شامل شدن الگوها",
+       "export-pagelinks": "شامل شدن صفحه‌های پیوند شده تا این عمق:",
+       "allmessages": "پیغام‌های سامانه",
+       "allmessagesname": "نؤم",
+       "allmessagesdefault": "متن پیش‌فرض پیغام",
+       "allmessagescurrent": "متن کنونی پیغام",
+       "allmessagestext": "این فهرستی از پیغام‌های سامانه‌ای موجود در فضای نام مدیاویکی است.\nچنانچه مایل به مشارکت در محلی‌سازی مدیاویکی هستید لطفاً [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation محلی‌سازی مدیاویکی] و [//translatewiki.net translatewiki.net] را ببینید.",
+       "allmessagesnotsupportedDB": "این صفحه نمی‌تواند استفاده شود به این دلیل که <bdi>'''$wgUseDatabaseMessages'''</bdi> غیرفعال شده‌است.",
+       "allmessages-filter-legend": "پالانۀل/فیلترۀل",
+       "allmessages-filter": "پالودن بر اساس وضعیت شخصی‌سازی:",
+       "allmessages-filter-unmodified": "تغییر نیافته",
+       "allmessages-filter-all": "کۆل",
+       "allmessages-filter-modified": "تغییر یافته",
+       "allmessages-prefix": "پالودن بر اساس پسوند:",
+       "allmessages-language": ":زوون",
+       "allmessages-filter-submit": "بِچۆ",
+       "allmessages-filter-translate": "چاوواشۀگر زوون",
+       "thumbnail-more": "کۀلنگ کِردن",
+       "filemissing": "پرونده وجود ندارد",
+       "thumbnail_error": "خطا در ایجاد بندانگشتی: $1",
+       "thumbnail_error_remote": "پیام خطای  $1 :\n$2",
+       "djvu_page_error": "صفحهٔ DjVu خارج از حدود مجاز",
+       "djvu_no_xml": "امکان پیدا کردن پروندهٔ XML برای استفادهٔ DjVu وجود نداشت.",
+       "thumbnail-temp-create": "نمی‌توان پروندهٔ بندانگشتی موقت را ساخت",
+       "thumbnail-dest-create": "نمی‌توان تصویر بندانگشتی را در مقصد ذخیره کرد",
+       "thumbnail_invalid_params": "پارامترهای نامجاز در تصویر بندانگشتی (thumbnail)",
+       "thumbnail_toobigimagearea": "پرونده‌ای با اندازهٔ بیشتر از $1",
+       "thumbnail_dest_directory": "اشکال در ایجاد پوشهٔ مقصد",
+       "thumbnail_image-type": "تصویر از نوع پشتیبانی نشده",
+       "thumbnail_gd-library": "تنظیمات ناقص کتابخانهٔ GD: عملکرد $1 وجود ندارد",
+       "thumbnail_image-missing": "پرونده به نظر گم شده‌است: $1",
+       "thumbnail_image-failure-limit": "تلاش‌های ناموفق اخیر بسیاری ($1 یا بیشتر) برای ارائهٔ این تصویر کوچک وجود داشته‌ است. لطفأ بعداً دوباره تلاش کنید.",
+       "import": "واردکردن وةڵگةل",
+       "importinterwiki": "درون‌ریزی از یک ویکی دیگر",
+       "import-interwiki-text": "یک ویکی و یک نام صفحه را انتخاب کنید تا اطلاعات از آن درون‌ریزی شود.\nتاریخ نسخه‌ها و نام ویرایش‌کنندگان ثابت خواهد ماند.\nاطلاعات مربوط به درون‌ریزی صفحات از ویکی دیگر در [[Special:Log/import|سیاههٔ درون‌ریزی‌ها]] درج خواهد شد.",
+       "import-interwiki-sourcewiki": "ویکی منبع:",
+       "import-interwiki-sourcepage": "صفحهٔ مبدأ:",
+       "import-interwiki-history": "تمام نسخه‌های تاریخچهٔ این صفحه انتقال داده شود",
+       "import-interwiki-templates": "تمام الگوها را شامل شود",
+       "import-interwiki-submit": "درون‌ریزی شود",
+       "import-mapping-default": "درون‌ریزی برای موقعیت‌های پیش‌فرض",
+       "import-mapping-namespace": "درون‌ریزی برای یک فضای نام:",
+       "import-mapping-subpage": "درون‌ریزی به عنوان زیرصفحهٔ صفحهٔ:",
+       "import-upload-filename": "نام پرونده:",
+       "import-comment": ":گةپةل/قِسةل",
+       "importtext": "لطفاً پرونده را از ویکی منبع با کمک [[Special:Export|ابزار برون‌بری]] دریافت کنید.\nسپس آن را روی دستگاه‌تان ذخیره کنید و اینجا بارگذاری نمایید.",
+       "importstart": "در حال درون‌ریزی صفحات...",
+       "import-revision-count": "$1 {{PLURAL:$1|  ویرایش ها|ویرایش}}",
+       "importnopages": "صفحه‌ای برای درون‌ریزی نیست.",
+       "imported-log-entries": "$1 {{PLURAL:$1|مورد سیاهه|مورد سیاهه ها}} درون ریزی شد.",
+       "importfailed": "درون‌ریزی صفحات شکست خورد: <nowiki>$1</nowiki>",
+       "importunknownsource": "نوع مأخذ درون‌ریزی معلوم نیست",
+       "importcantopen": "پروندهٔ درون‌ریزی صفحات باز نشد",
+       "importbadinterwiki": "پیوند میان‌ویکی نادرست",
+       "importsuccess": "درون‌ریزی با موفقیت انجام شد!",
+       "importnosources": "هیچ منبعی برای درون‌ریزی اطلاعات از ویکی‌های دیگر تعریف نشده‌است.",
+       "importnofile": "هیچ پرونده‌ای برای درون‌ریزی بارگذاری نشده‌است.",
+       "importuploaderrorsize": "در بارگذاری پروندهٔ درون‌ریزی، اشکال رخ داد.\nاندازهٔ پرونده بیشتر از حداکثر اندازهٔ مجاز است.",
+       "importuploaderrorpartial": "در بارگذاری پروندهٔ درون‌ریزی، اشکال رخ داد. پرونده به طور ناقص بارگذاری شده‌است.",
+       "importuploaderrortemp": "در بارگذاری پروندهٔ درون‌ریزی، اشکال رخ داد.\nپوشهٔ موقت پیدا نشد.",
+       "import-parse-failure": "خطا در تجزیهٔ اکس‌ام‌ال بارگذاری‌شده",
+       "import-noarticle": "صفحه‌ای برای بارگذاری وجود ندارد!",
+       "import-nonewrevisions": "نسخه‌ای درون‌ریزی نشد (همه یا در حال حاضر وجود دارند، یا به دلیل خطا‌ها نادیده گرفته شده‌اند).",
+       "xml-error-string": "$1 در سطر $2، ستون $3 (بایت $4): $5",
+       "import-upload": "بارگذاری داده اکس‌ام‌ال",
+       "import-token-mismatch": "از دست رفتن اطلاعات نشست کاربری. لطفاً دوباره امتحان کنید.",
+       "import-invalid-interwiki": "از ویکی مشخص شده نمی‌توان درون‌ریزی انجام داد.",
+       "import-error-edit": "صفحهٔ «$1» وارد نشد، چون شما مجاز به ویرایش آن نیستید.",
+       "import-error-create": "صفحهٔ «$1» وارد نشد، چون شما مجاز به ایجاد آن نیستید.",
+       "import-error-interwiki": "صفحه «$1» وارد نشد. چون نام آن برای پیوند خارجی (interwiki) رزرو شده‌است.",
+       "import-error-special": "صفحهٔ «$1» درون‌ریزی نشد، چرا که متعلق به فضای نام نامجاز است.",
+       "import-error-invalid": "صفحه \"$1\" به دلیل نامعتبر بودن نامش که ممکن بود در ویکی نامعتبر باشد، وارد نشد.",
+       "import-error-unserialize": "امکان خارج کردن نسخهٔ $2 از صفحهٔ «$1» از حالت سریال‌شده وجود نداشت. گزارش شد که نسخه از مدل محتوای $3 استفاده می‌کند که به صورت $4 سریال شده‌است.",
+       "import-error-bad-location": "بازبینی $2 با استفاده از مدل محتوای $3 نمی‌تواند در \"$1\" در این ویکی ذخیره شده باشد، از آنجایی که مدل در آن صفحه پشتیبانی نشده‌است.",
+       "import-options-wrong": "{{PLURAL:$2|جزئیات|جزئیات ها}} اشتباه: <nowiki>$1</nowiki>",
+       "import-rootpage-invalid": "با توجه به ریشه صفحه عنوان نامعتبر است.",
+       "import-rootpage-nosubpage": "فضای نام  \"$1\" صفحهٔ مبنا اجازهٔ زیرصفحه نمی‌دهد.",
+       "importlogpage": "سیاههٔ درون‌ریزی‌ها",
+       "importlogpagetext": "درون‌ریزی صفحات به همراه تاریخچهٔ ویرایش آن‌ها از ویکی‌های دیگر.",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|نسخه|نسخه ها}} واردشده",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|نسخه|نسخه ها}} واردشده از $2",
+       "javascripttest": "آزمایش جاوا اسکریپت",
+       "javascripttest-pagetext-noframework": "این صفحه برای اجرای آزمایش‌های جاوا اسکریپت کنار گذاشته شده‌است.",
+       "javascripttest-pagetext-unknownframework": "چارچوب آزمایشی ناشناخته «$1».",
+       "javascripttest-pagetext-unknownaction": "تابع ناشناختهٔ \"$1\".",
+       "javascripttest-pagetext-frameworks": "لطفاً یکی از چارچوب‌های آزمایش زیر را انتخاب کنید: $1",
+       "javascripttest-pagetext-skins": "پوسته‌ای را برای اجرای آزمایش‌ها انتخاب کنید:",
+       "javascripttest-qunit-intro": "[$1 مستندات آزمایش] را در mediawiki.org ببینید.",
+       "tooltip-pt-userpage": "وةڵگة کاربۀری هؤمۀ",
+       "tooltip-pt-anonuserpage": "صفحهٔ کاربری نشانی آی‌پی‌ای که با آن ویرایش می‌کنید",
+       "tooltip-pt-mytalk": "وۀلگۀ گۀپ هؤمۀ",
+       "tooltip-pt-anontalk": "بحث پیرامون ویرایش‌های این نشانی آی‌پی",
+       "tooltip-pt-preferences": "ترجیحات ووِژم",
+       "tooltip-pt-watchlist": "فهرست صفحه‌هایی که شما تغییرات آن‌ها را پی‌گیری می‌کنید",
+       "tooltip-pt-mycontris": "فهرست مشارکت‌های شما",
+       "tooltip-pt-anoncontribs": "لیست دةسکاریةل دؤرس بی/سازریا إژ ئئ آدرس ای پی",
+       "tooltip-pt-login": "توصیه مۀکیم بونإ نام سامانه ، هۀرچۀند اجباری نیۀ",
+       "tooltip-pt-logout": "دةرچئن/خروج",
+       "tooltip-pt-createaccount": "مکئس تانۀ مۀکیم حساووئ بسازن و بونإ سامانۀ؛ هرچۀند حساوو کاربری سازین دل .بخوایۀ",
+       "tooltip-ca-talk": "گۀپ/قسۀ دۀربارۀ بنچۀک/محتوا وۀلگۀ",
+       "tooltip-ca-edit": "ئئ وۀلگۀ دۀسکاری کۀن",
+       "tooltip-ca-addsection": "بۀخش تازه بسازِن",
+       "tooltip-ca-viewsource": ".ئئ وۀلگۀ محافظۀت بیۀ\nمۀتؤنین  متن مبدأ/بنچۀک بؤینین",
+       "tooltip-ca-history": "ورژن دؤمائن/پئش ئئ وۀلگۀ",
+       "tooltip-ca-protect": "محافظت إژ ئئ وةڵگة",
+       "tooltip-ca-unprotect": "تغییر محافظت ئئ وةڵگة",
+       "tooltip-ca-delete": "حةذف ئئ وةڵگة",
+       "tooltip-ca-undelete": "بازگرداندن نسخه‌های صفحهٔ حذف‌شده",
+       "tooltip-ca-move": "جاوواز کردن ئئ وۀلگۀ",
+       "tooltip-ca-watch": "اضافۀ کردن ئئ وۀلگۀ وۀ لیست پیگیریۀل تان",
+       "tooltip-ca-unwatch": "حذف کردن ئئ وۀلگۀ وۀ لیست پیگیریۀل تان",
+       "tooltip-search": " {{SITENAME}}مِنِی کرد أ نوم",
+       "tooltip-search-go": "بچؤ وۀلگۀ گإ نام راسکانی/دقیق هۀسئ",
+       "tooltip-search-fulltext": "مِنِی کردن وۀلگۀل/پۀرۀل ئۀرا ئئ مۀتنۀ",
+       "tooltip-p-logo": "وۀلگۀ اصلی بوینن",
+       "tooltip-n-mainpage": "وۀلگۀ اصلی بوینن",
+       "tooltip-n-mainpage-description": "وۀلگۀ اصلی بوینن",
+       "tooltip-n-portal": "دۀربارۀ پروژه،أؤۀگإ مۀتؤینین انجؤم دین و چۀ وۀ کؤ بکینۀ دی/پئا کین",
+       "tooltip-n-currentevents": "پئا کردن اطلاعات پس‌زمینه دۀربارۀ رویدادۀلایسۀ",
+       "tooltip-n-recentchanges": "لیستی إژ تۀغیرۀل ایسۀ إ ویکی",
+       "tooltip-n-randompage": " وۀلگۀ بۀختۀکی  ئآوردِن",
+       "tooltip-n-help": "جای أرا پئاکردن/أدی کردن",
+       "tooltip-t-whatlinkshere": "لیست کؤل وۀلگۀل ویکی گإ پیوۀند درن ائرۀ",
+       "tooltip-t-recentchangeslinked": "تغییرۀل ایسۀ وۀلگۀلئ گإ ئئ وۀلگۀ  پیوند درئۀ  اؤِنۀ",
+       "tooltip-feed-rss": "خبرنامه آراس‌اس برای این صفحه",
+       "tooltip-feed-atom": "حاووال اتم أرا ئئ وۀلگۀ",
+       "tooltip-t-contributions": "لیست هؤمکاریۀل ئئ کاربرۀ",
+       "tooltip-t-emailuser": "ارسال ایمیل به این کاربر",
+       "tooltip-t-info": "اطلاعات بیشتر دربارهٔ این صفحه",
+       "tooltip-t-upload": "بارنیائن فایلۀل",
+       "tooltip-t-specialpages": "لیست کؤل وۀلگۀل ویژۀ",
+       "tooltip-t-print": "نوسخهٔ قاوول چاپ ئئ وۀلگۀ",
+       "tooltip-t-permalink": "پیوند پایدار وۀ ئئ نؤسخه إژ وۀلگۀ",
+       "tooltip-ca-nstab-main": "وۀلگۀ محتویات بوینن",
+       "tooltip-ca-nstab-user": "وةڵگة  کاربۀر بؤین",
+       "tooltip-ca-nstab-media": "دیدن صفحهٔ مدیا",
+       "tooltip-ca-nstab-special": "ائ وۀلگۀ ویژئۀ وۀ قاوول دۀسکاری نیۀ",
+       "tooltip-ca-nstab-project": "وۀلگۀ پروژۀ بوینن",
+       "tooltip-ca-nstab-image": "وةڵگة پۀروۀندۀ بؤین",
+       "tooltip-ca-nstab-mediawiki": "نمایش پیغام سامانه",
+       "tooltip-ca-nstab-template": "نمایش الگو",
+       "tooltip-ca-nstab-help": "نمایش وةڵگة هؤمیاری",
+       "tooltip-ca-nstab-category": "دیین/سئرکردن وۀلگۀ رده",
+       "tooltip-minoredit": "این ویرایش را ویرایش جزئی نشانه‌گذاری کن",
+       "tooltip-save": "تغییرات خود را ذخیره کنید",
+       "tooltip-preview": "پیش‌نمایش تغییرات شما، لطفاً قبل از ذخیره‌کردن صفحه از این کلید استفاده     \nکنید",
+       "tooltip-diff": ".نمایش تغییراتی که شما در متن داده‌اید",
+       "tooltip-compareselectedversions": "دیدن تفاوت‌های دو نسخهٔ انتخاب‌شده از این صفحه",
+       "tooltip-watch": "این صفحه را به فهرست پی‌گیری‌هایتان بیفزایید.",
+       "tooltip-watchlistedit-normal-submit": "حذف عنوان‌ها",
+       "tooltip-watchlistedit-raw-submit": "بروزرسانی پی‌گیری‌ها",
+       "tooltip-recreate": "ایجاد دوبارهٔ صفحه صرف نظر از حذف شدن قبلی آن",
+       "tooltip-upload": "شروع بارگذاری",
+       "tooltip-rollback": "«واگردانی» ویرایش(های) آخرین ویرایش‌کنندهٔ این صفحه را با یک کلیک بازمی‌گرداند.",
+       "tooltip-undo": "«خنثی‌سازی» این ویرایش را خنثی می‌کند و جعبهٔ ویرایش را در حالت پیش‌نمایش باز می‌کند تا افزودن دلیل در خلاصهٔ ویرایش ممکن شود.",
+       "tooltip-preferences-save": "ذخیره کردن ترجیحات",
+       "tooltip-summary": "خلاصه‌ای وارد کنید",
+       "anonymous": "{{PLURAL:$1|کاربر|کاربران}} گمنام {{SITENAME}}",
+       "siteuser": "$1، کاربر {{SITENAME}}",
+       "anonuser": "$1 کاربر ناشناس {{SITENAME}}",
+       "lastmodifiedatby": "این صفحه آخرین بار در $2، $1 به دست $3 تغییر یافته‌است.",
+       "othercontribs": "بر اساس اثری از $1",
+       "others": "دیگران",
+       "siteusers": "$1، {{PLURAL:$2|کاربر|کاربران}} {{SITENAME}}",
+       "anonusers": "$1 {{PLURAL:$2|کاربر|کاربران}} ناشناس {{SITENAME}}",
+       "creditspage": "اعتبارات این صفحه",
+       "nocredits": "اطلاعات سازندگان این صفحه موجود نیست.",
+       "spamprotectiontitle": "پالایهٔ هرزنگاری‌ها",
+       "spamprotectiontext": "از ذخیره کردن صفحه توسط پالایهٔ هرزنگاری‌ها جلوگیری شد.\nمعمولاً این اتفاق زمانی می‌افتد که متن تازه صفحه، حاوی پیوندی به یک نشانی وب باشد که در فهرست سیاه قرار دارد.",
+       "spamprotectionmatch": "متن زیر چیزی‌است که پالایهٔ هرزه‌نگاری ما را به کارانداخت: $1",
+       "spambot_username": "هرزه‌تمیزکارِ مدیاویکی",
+       "spam_reverting": "واگردانی به آخرین نسخه‌ای که پیوندی به $1 ندارد.",
+       "spam_blanking": "تمام نسخه‌ها حاوی پیوند به $1 بود، در حال خالی کردن",
+       "spam_deleting": "تمام نسخه‌ها حاوی پیوند به $1 بود، در حال حذف",
+       "simpleantispam-label": ".بررسی ضدهرزنگاری\n<strong>نکنید</strong>!این قسمت را پر",
+       "pageinfo-title": "اطلاعات در مورد «$1»",
+       "pageinfo-not-current": "متأسفانه تهیه اطلاعات ویرایش‌های قدیمی غیرممکن است.",
+       "pageinfo-header-basic": "اطلاعات اولیه",
+       "pageinfo-header-edits": "ویرایش تاریخچه",
+       "pageinfo-header-restrictions": "حفاظت از صفحه",
+       "pageinfo-header-properties": "ويژگی‌های صفحه",
+       "pageinfo-display-title": "نمایش عنوان",
+       "pageinfo-default-sort": "کلید مرتب‌سازی پیش‌فرض",
+       "pageinfo-length": "حجم صفحه  (بایت)",
+       "pageinfo-article-id": "شناسهٔ صفحه",
+       "pageinfo-language": "زبان محتوای صفحه",
+       "pageinfo-content-model": "ساختار محتوای صفحه",
+       "pageinfo-robot-policy": "‌فهرست‌کردن توسط ربات‌ها",
+       "pageinfo-robot-index": "مجاز",
+       "pageinfo-robot-noindex": "بی صلا",
+       "pageinfo-watchers": "شمار پی‌گیری‌کنندگان صفحه",
+       "pageinfo-visiting-watchers": "تعداد پیگیری‌کنندگان صفحه که تغییرات اخیر را بازبینی کرده‌اند",
+       "pageinfo-few-watchers": "کمتر از  $1 {{PLURAL:$1| پی‌گیرها|پی‌گیر}}",
+       "pageinfo-few-visiting-watchers": "امکان دارد یا ندارد که کاربری ویرایش‌های اخیر را بازبینی کرده باشد",
+       "pageinfo-redirects-name": "تعداد تغییرمسیرها به این صفحه",
+       "pageinfo-subpages-name": "زیرصفحه‌های این صفحه",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|تغییرمسیر|تغییرمسیرها}}; $3 {{PLURAL:$3|غیرتغییرمسیر|غیرتغییرمسیر ها}})",
+       "pageinfo-firstuser": "به‌وجود آورندهٔ صفحه",
+       "pageinfo-firsttime": "زمان ایجاد صفحه",
+       "pageinfo-lastuser": "آخرین دةسکاری کةر",
+       "pageinfo-lasttime": "تاریخ آخرین ویرایش",
+       "pageinfo-edits": "شمار کلی ویرایش‌ها",
+       "pageinfo-authors": "تعداد کلی نویسندگان یکتا",
+       "pageinfo-recent-edits": "شماره ویرایش‌های اخیر (در $1 گذشته)",
+       "pageinfo-recent-authors": "تعداد نویسندگان یکتای اخیر",
+       "pageinfo-magic-words": "{{PLURAL:$1|حرف|حروف}} جادویی ($1)",
+       "pageinfo-hidden-categories": "{{PLURAL:$1| ردهٔ|ردهٔ}} پنهان ( $1 )",
+       "pageinfo-templates": "{{PLURAL:$1|الگو|الگوها}} استفاده‌شده ($1)",
+       "pageinfo-transclusions": "{{PLURAL:$1|صفحهٔ|صفحه‌های}} تراگنجانش‌شده در ($1)",
+       "pageinfo-toolboxlink": "اطلاعات وۀلگۀ/پۀرۀ",
+       "pageinfo-redirectsto": "تغییرمسیر به",
+       "pageinfo-redirectsto-info": "زانستةنیةل",
+       "pageinfo-contentpage": "شمرده شده به عنوان صفحهٔ محتوایی",
+       "pageinfo-contentpage-yes": "أرێ-بةلئ",
+       "pageinfo-protect-cascading": "محافظت آبشاری از اینجا",
+       "pageinfo-protect-cascading-yes": "أرێ-بةلئ",
+       "pageinfo-protect-cascading-from": "محافظت آبشاری از",
+       "pageinfo-category-info": "اطلاعات رده",
+       "pageinfo-category-total": "تعداد کلی اعضاء",
+       "pageinfo-category-pages": "تعداد وۀلگۀل",
+       "pageinfo-category-subcats": "تعداد زیررده‌ها",
+       "pageinfo-category-files": "تعداد پرونده‌ها",
+       "markaspatrolleddiff": "برچسب گشت بزن",
+       "markaspatrolledtext": "به این صفحه برچسب گشت بزن",
+       "markedaspatrolled": "برچسب گشت زده شد",
+       "markedaspatrolledtext": "به نسخهٔ انتخاب شده از [[:$1]] برچسب گشت زده شد.",
+       "rcpatroldisabled": "گشت‌زنی تغییرات اخیر غیرفعال است",
+       "rcpatroldisabledtext": "امکان گشت‌زنی تغییرات اخیر در حال حاضر غیرفعال است.",
+       "markedaspatrollederror": "برچسب گشت زده نشد",
+       "markedaspatrollederrortext": "باید یک نسخه را مشخص کنید تا برچسب گشت بخورد.",
+       "markedaspatrollederror-noautopatrol": "شما نمی‌توانید به تغییرات انجام شده توسط خودتان برچسب گشت بزنید.",
+       "markedaspatrollednotify": "این تغییر روی $1 برچسب گشت خورد.",
+       "markedaspatrollederrornotify": "زدن برچسب گشت، ناموفق بود.",
+       "patrol-log-page": "سیاههٔ گشت",
+       "patrol-log-header": "این سیاهه‌ای از ویرایش‌های گشت‌خورده است.",
+       "log-show-hide-patrol": "$1 سیاههٔ گشت‌زنی",
+       "log-show-hide-tag": "$1 سیاهه برچسب",
+       "deletedrevision": "$1 نسخهٔ حذف شدهٔ قدیمی",
+       "filedeleteerror-short": "خطا در حذف پرونده: $1",
+       "filedeleteerror-long": "در زمان حذف پرونده خطا رخ داد:\n\n$1",
+       "filedelete-missing": "پروندهٔ $1 قابل حذف نیست چون پرونده‌ای به این نام وجود ندارد.",
+       "filedelete-old-unregistered": "نسخهٔ پروندهٔ $1 در پایگاه داده وجود ندارد.",
+       "filedelete-current-unregistered": "پرونده‌ای با نام $1 در پایگاه داده موجود نیست.",
+       "filedelete-archive-read-only": "امکان نوشتن در پوشهٔ تاریخچهٔ $1 وجود ندارد.",
+       "previousdiff": "→ تفاوت قدیمی‌تر",
+       "nextdiff": "تفاوت جدیدتر ←",
+       "mediawarning": "'''هشدار''': این پرونده ممکن است حاوی کدهای مخرب باشد.\nبا اجرای آن رایانهٔ شما ممکن است آسیب ببیند.",
+       "imagemaxsize": "محدودیت ابعاد تصویر:<br />''(برای صفحه‌های توصیف پرونده)''",
+       "thumbsize": "اندازهٔ بنداگشتی:",
+       "widthheightpage": "$1×$2، $3 {{PLURAL:$3|صفحه ها|صفحه}}",
+       "file-info": "اندازهٔ پرونده: $1، نوع  MIME $2",
+       "file-info-size": "$1×$2نوع،$3أندازۀ پرونده،پیکسلMIME:$4",
+       "file-info-size-pages": "$1 × $2 pixels, اندازه پرونده: $3, MIME type: $4, $5 {{PLURAL:$5|وةڵگة| وةڵگة }}",
+       "file-nohires": "تفکیک‌پذیری بالاتری در دسترس نیست.",
+       "svg-long-desc": "SVG file, nominally $1 × $2 pixels, file size: $3",
+       "svg-long-desc-animated": "پروندهٔ اس‌وی‌جی متحرک، با ابعاد <span dir=\"ltr\">$1 × $2</span> پیکسل، اندازهٔ پرونده: $3",
+       "svg-long-error": "پرونده SVG نامجاز: $1",
+       "show-big-image": "پۀروۀندۀ اصلی",
+       "show-big-image-preview": ". اندازهٔ این پیش‌نمایش: $1",
+       "show-big-image-preview-differ": "حجم پیش‌نمایش $3 این $2 file:$1",
+       "show-big-image-other": " . $1:تر/دیگر{{PLURAL:$2|کیفیت|کیفیتۀل}}",
+       "show-big-image-size": "$1 × $2 پیکسلۀل",
+       "file-info-gif-looped": "چرخش‌دار",
+       "file-info-gif-frames": "$1 {{PLURAL:$1|قاب ها|قاب}}",
+       "file-info-png-looped": "چرخش‌دار",
+       "file-info-png-repeat": "{{PLURAL:$1|$1 {{PLURAL:$1|بارها|بار}} پخش شد}}",
+       "file-info-png-frames": "$1 {{PLURAL:$1|قاب ها|قاب}}",
+       "file-no-thumb-animation": "'''توجه: به علت مسائل فنی پیش‌نمایش پرونده به صورت متحرک نمایش داده نمی‌شود.'''",
+       "file-no-thumb-animation-gif": "'''توجه:به علت مسائل فنی پیش‌نمایش پرونده‌های GIF مانند این پرونده، به صورت متحرک نمایش داده نمی‌شود.'''",
+       "newimages": "نگارخانهٔ پرونده‌های جدید",
+       "imagelisttext": "در زیر فهرست $1 {{PLURAL:$1|تصویر|تصاویر}} که $2 مرتب شده است آمده است.",
+       "newimages-summary": "این صفحهٔ ویژه آخرین پرونده‌های بارگذاری شده را نمایش می‌دهد",
+       "newimages-legend": "پالانۀل/فیلترۀل",
+       "newimages-label": "نام پرونده (یا قسمتی از آن):",
+       "newimages-showbots": "نمایش بارگذاری‌ها توسط ربات‌ها",
+       "noimages": "چیزی برای دیدن نیست.",
+       "ilsubmit": "گئردین/مهِ نی",
+       "bydate": "از روی تاریخ",
+       "sp-newimages-showfrom": "نشان‌دادن تصویرهای جدید از $2، $1 به بعد",
+       "seconds": "{{PLURAL:$1|$1 ثانیه ها|$1 ثانیه یا}}",
+       "minutes": "{{PLURAL:$1|دقیقه ها|دقیقه}}",
+       "hours": "{{PLURAL:$1|ساعت ها|ساعت}}",
+       "days": "{{PLURAL:$1|روزها|روز}}",
+       "weeks": "{{PLURAL:$1|$1 هفته ها|$1 هفته}}",
+       "months": "{{PLURAL:$1|$1 ماه|}}",
+       "years": "{{PLURAL:$1|$1 سال|}}",
+       "ago": "$1 دؤماتر",
+       "just-now": "فقط ایسه",
+       "hours-ago": "$1 {{PLURAL:$1|ساعت |ساعتةلئ}} دماتر",
+       "minutes-ago": "$1 {{PLURAL:$1|دیقه|دیقةلئ}} دماتر",
+       "seconds-ago": "$1 {{PLURAL:$1|ثانیه|ثانیه ها}} قبل",
+       "monday-at": "دوشنبهٔ $1",
+       "tuesday-at": "سه‌شنبهٔ $1",
+       "wednesday-at": "چهارشنبهٔ $1",
+       "thursday-at": "پنج‌شنبهٔ $1",
+       "friday-at": "جمعهٔ $1",
+       "saturday-at": "شنبهٔ $1",
+       "sunday-at": "یک‌شنبهٔ $1",
+       "yesterday-at": "دیروز در $1",
+       "bad_image_list": "اطلاعات را باید اینگونه وارد کنید:\n\nفقط موارد درون فهرست (سطرهایی که با * شروع می‌شوند) در نظر گرفته می‌شوند.\nنخستین پیوند هر سطر باید پیوندی به یک پروندهٔ معیوب باشد.\nپیوندهایی بعدی در همان سطر استثنا در نظر گرفته می‌شوند.",
+       "metadata": "فراداده",
+       "metadata-help": "این پرونده حاوی اطلاعات اضافه‌ای‌است که احتمالاً دوربین دیجیتال یا پویشگری که در ایجاد یا دیجیتالی‌کردن آن به کار رفته آن را افزوده‌است. اگر پرونده از وضعیت ابتدایی‌اش تغییر داده شده باشد آنگاه ممکن است شرح و تفصیلات موجود اطلاعات تصویر را تماماً بازتاب ندهد.",
+       "metadata-expand": "نمایش جزئیات تفصیلی",
+       "metadata-collapse": "نهفتن جزئیات تفصیلی",
+       "metadata-fields": "فرادادهٔ تصویر نشان داده شده در این پیغام وقتی جدول فراداده‌های تصویر جمع شده باشد هم نمایش داده می‌شود. بقیهٔ موارد تنها زمانی نشان داده می‌شوند که جدول یاد شده باز شود.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-imagewidth": "پهنا",
+       "exif-imagelength": "بةرزی/ارتفاع",
+       "exif-bitspersample": "نقطه در هر جزء",
+       "exif-compression": "شِمای فشرده‌سازی",
+       "exif-photometricinterpretation": "ترکیب نقاط",
+       "exif-orientation": "جهت",
+       "exif-samplesperpixel": "تعداد اجزا",
+       "exif-planarconfiguration": "آرایش داده‌ها",
+       "exif-ycbcrsubsampling": "نسبت زیرنمونهٔ Y به C",
+       "exif-ycbcrpositioning": "موقعیت Y و C",
+       "exif-xresolution": "تفکیک‌پذیری افقی",
+       "exif-yresolution": "تفکیک‌پذیری عمودی",
+       "exif-stripoffsets": "جایگاه داده‌های تصویر",
+       "exif-rowsperstrip": "تعداد ردیف‌ها در هر نوار",
+       "exif-stripbytecounts": "بایت در هر نوار فشرده",
+       "exif-jpeginterchangeformat": "جابه‌جایی نسبت به JPEG SOI",
+       "exif-jpeginterchangeformatlength": "بایت دادهٔ JPEG",
+       "exif-whitepoint": "رنگینگی نقطهٔ سفید",
+       "exif-primarychromaticities": "رنگ‌پذیری اولویت‌ها",
+       "exif-ycbcrcoefficients": "ضرایب ماتریس تبدیل فضای رنگی",
+       "exif-referenceblackwhite": "جفت مقادیر مرجع سیاه و سفید",
+       "exif-datetime": "تاریخ و زمان تغییر پرونده",
+       "exif-imagedescription": "عنوان تصویر",
+       "exif-make": "شرکت سازندهٔ دوربین",
+       "exif-model": "مدل دوربین",
+       "exif-software": "نرم‌افزار استفاده‌شده",
+       "exif-artist": "تصویربردار/هنرمند",
+       "exif-copyright": "دارندهٔ حق تکثیر",
+       "exif-exifversion": "نسخهٔ exif",
+       "exif-flashpixversion": "نسخهٔ پشتیبانی‌شدهٔ Flashpix",
+       "exif-colorspace": "فضای رۀنگی",
+       "exif-componentsconfiguration": "معنی هر یک از مؤلفه‌ها",
+       "exif-compressedbitsperpixel": "حالت فشرده‌سازی تصویر",
+       "exif-pixelydimension": "پهنای تصویر",
+       "exif-pixelxdimension": "بلندی تصویر",
+       "exif-usercomment": "توضیحات کاربر",
+       "exif-relatedsoundfile": "پروندهٔ صوتی مربوط",
+       "exif-datetimeoriginal": "تاریخ و زمان تولید داده‌ها",
+       "exif-datetimedigitized": "تاریخ و زمان دیجیتالی‌شدن",
+       "exif-subsectime": "کسر ثانیهٔ تاریخ و زمان",
+       "exif-subsectimeoriginal": "کسر ثانیهٔ زمان اصلی",
+       "exif-subsectimedigitized": "کسر ثانیهٔ زمان دیجیتال",
+       "exif-exposuretime": "زمان نوردهی",
+       "exif-exposuretime-format": "$1 ثانیه ($2)",
+       "exif-fnumber": "ضریب اف",
+       "exif-exposureprogram": "برنامهٔ نوردهی",
+       "exif-spectralsensitivity": "حساسیت طیفی",
+       "exif-isospeedratings": "درجه‌بندی سرعت ایزو",
+       "exif-shutterspeedvalue": "سرعت آپکس شاتر",
+       "exif-aperturevalue": "انازه اپکس دیافراگم",
+       "exif-brightnessvalue": "روشنایی آپکس",
+       "exif-exposurebiasvalue": "خطای نوردهی",
+       "exif-maxaperturevalue": "حداکثر گشادگی زمین",
+       "exif-subjectdistance": "فاصلهٔ سوژه",
+       "exif-meteringmode": "حالت سنجش نور",
+       "exif-lightsource": "منبع نور",
+       "exif-flash": "فلاش",
+       "exif-focallength": "فاصلهٔ کانونی عدسی",
+       "exif-subjectarea": "مساحت جسم",
+       "exif-flashenergy": "قدرت فلاش",
+       "exif-focalplanexresolution": "تفکیک‌پذیری X صفحهٔ کانونی",
+       "exif-focalplaneyresolution": "تفکیک‌پذیری Y صفحهٔ کانونی",
+       "exif-focalplaneresolutionunit": "واحد تفکیک‌پذیری صفحهٔ کانونی",
+       "exif-subjectlocation": "جاگه موضوع",
+       "exif-exposureindex": "شاخص نوردهی",
+       "exif-sensingmethod": "روش حسگری",
+       "exif-filesource": "منبع پرونده",
+       "exif-scenetype": "نوع صحنه",
+       "exif-customrendered": "ظهور عکس سفارشی",
+       "exif-exposuremode": "حالت نوردهی",
+       "exif-whitebalance": "تعادل رنگ سفید (white balance)",
+       "exif-digitalzoomratio": "نسبت زوم دیجیتال",
+       "exif-focallengthin35mmfilm": "فاصلهٔ کانونی برای فیلم ۳۵ میلی‌متری",
+       "exif-scenecapturetype": "نوع ضبط صحنه",
+       "exif-gaincontrol": "تنظیم صحنه",
+       "exif-contrast": "کنتراست",
+       "exif-saturation": "غلظت رنگ",
+       "exif-sharpness": "وضوح",
+       "exif-devicesettingdescription": "شرح تنظیمةل دستگاه",
+       "exif-subjectdistancerange": "محدودهٔ فاصلهٔ سوژه",
+       "exif-imageuniqueid": "شناسهٔ یکتای تصویر",
+       "exif-gpsversionid": "نسخهٔ برچسب جی‌پی‌اس",
+       "exif-gpslatituderef": "عرض جغرافیایی شمالی یا جنوبی",
+       "exif-gpslatitude": "عرض جغرافیایی",
+       "exif-gpslongituderef": "طول جغرافیایی شرقی یا غربی",
+       "exif-gpslongitude": "طول جغرافیایی",
+       "exif-gpsaltituderef": "نقطهٔ مرجع ارتفاع",
+       "exif-gpsaltitude": "ارتفاع",
+       "exif-gpstimestamp": "زمان جی‌پی‌اس (ساعت اتمی)",
+       "exif-gpssatellites": "ماهواره‌های استفاده‌شده برای اندازه‌گیری",
+       "exif-gpsstatus": "وضعیت گیرنده",
+       "exif-gpsmeasuremode": "حالت اندازه‌گیری",
+       "exif-gpsdop": "دقت اندازه‌گیری",
+       "exif-gpsspeedref": "یکای سرعت",
+       "exif-gpsspeed": "سرعت گیرندهٔ جی‌پی‌اس",
+       "exif-gpstrackref": "مرجع برای جهت حرکت",
+       "exif-gpstrack": "جهت حرکت",
+       "exif-gpsimgdirectionref": "مرجع برای جهت تصویر",
+       "exif-gpsimgdirection": "جهت تصویر",
+       "exif-gpsmapdatum": "اطلاعات نقشه‌برداری ژئودزیک",
+       "exif-gpsdestlatituderef": "مرجع برای عرض جغرافیایی مقصد",
+       "exif-gpsdestlatitude": "عرض جغرافیایی مقصد",
+       "exif-gpsdestlongituderef": "مرجع برای عرض جغرافیایی مقصد",
+       "exif-gpsdestlongitude": "عرض جغرافیایی مقصد",
+       "exif-gpsdestbearingref": "مرجع برای جهت مقصد",
+       "exif-gpsdestbearing": "جهت مقصد",
+       "exif-gpsdestdistanceref": "مرجع برای فاصله تا مقصد",
+       "exif-gpsdestdistance": "فاصله تا مقصد",
+       "exif-gpsprocessingmethod": "نام روش پردازش GPS",
+       "exif-gpsareainformation": "نام ناحیهٔ جی‌پی‌اس",
+       "exif-gpsdatestamp": "تاریخ جی‌پی‌اس",
+       "exif-gpsdifferential": "تصحیح جزئی جی‌پی‌اس",
+       "exif-jpegfilecomment": "توضیحات پرونده JPEG",
+       "exif-keywords": "واژه‌های کلیدی",
+       "exif-worldregioncreated": "منطقه‌ای از جهان که تصویر در آن گرفته شده",
+       "exif-countrycreated": "کشوری که تصویر در آن گرفته شده",
+       "exif-countrycodecreated": "کد کشوری که تصویر در آن گرفته شده",
+       "exif-provinceorstatecreated": "استان یا ایالتی که تصویر در آن گرفته شده",
+       "exif-citycreated": "شهری که تصویر در آن گرفته شده",
+       "exif-sublocationcreated": "بخشی از شهر که تصویر در آن گرفته شده",
+       "exif-worldregiondest": "منقطه جهان نمایش داده شده",
+       "exif-countrydest": "کشور نمایش داده شده",
+       "exif-countrycodedest": "کد کشور نمایش داده شده",
+       "exif-provinceorstatedest": "استان یا ایالت نمایش داده شده",
+       "exif-citydest": "شهر نمایش داده شده",
+       "exif-sublocationdest": "بخش شهر نمایش داده شده",
+       "exif-objectname": "عنوان کوتاه",
+       "exif-specialinstructions": "دستورالعمل‌های ویژه",
+       "exif-headline": "سةر وةڵگة",
+       "exif-credit": "صاحب امتیاز/ارائه کننده",
+       "exif-source": "بِنچۀک/مۀنبۀع",
+       "exif-editstatus": "وضعیت تحریریه تصویر",
+       "exif-urgency": "فوریت/هڵةپڵة",
+       "exif-fixtureidentifier": "نام ستون نشریه",
+       "exif-locationdest": "محل به تصویر کشیده شده",
+       "exif-locationdestcode": "کد محل به تصویر کشیده شده",
+       "exif-objectcycle": "زمان روز که این رسانه برای آن در نظر گرفته شده",
+       "exif-contact": "زانستن دربارۀ تماس",
+       "exif-writer": "نویسنده",
+       "exif-languagecode": "زوون",
+       "exif-iimversion": "نسخه IIM",
+       "exif-iimcategory": "رده/ڕِزگ",
+       "exif-iimsupplementalcategory": "رده‌های تکمیلی",
+       "exif-datetimeexpires": "استفاده تا تاریخ",
+       "exif-datetimereleased": "منتشر شده در",
+       "exif-originaltransmissionref": "کد محل انتقال اصلی",
+       "exif-identifier": "شناسه/دیارکةر",
+       "exif-lens": "لنز مورد استفاده",
+       "exif-serialnumber": "شماره سریال دوربین",
+       "exif-cameraownername": "صاحب دوربین",
+       "exif-label": "برچسب",
+       "exif-datetimemetadata": "تاریخ آخرین تغییر فراداده",
+       "exif-nickname": "نام غیررسمی تصویر",
+       "exif-rating": "امتیاز (از 5)",
+       "exif-rightscertificate": "گواهینامه مدیریت حقوق",
+       "exif-copyrighted": "وضعیت حق تکثیر",
+       "exif-copyrightowner": "دارندهٔ حق تکثیر",
+       "exif-usageterms": "شرایط استفاده",
+       "exif-webstatement": "نسخه برخط اعلامیه حق تکثیر",
+       "exif-originaldocumentid": "شناسهٔ یکتای سند اصلی",
+       "exif-licenseurl": "نشانی اینترنتی برای مجوز حق تکثیر",
+       "exif-morepermissionsurl": "اطلاعات مجوزهای جایگزین",
+       "exif-attributionurl": "در زمان استفاده مجدد، لطفاً پیوند دهید به",
+       "exif-preferredattributionname": "در زمان استفاده مجدد، لطفاً اعتبار دهید به",
+       "exif-pngfilecomment": "توضیحات پرونده PNG",
+       "exif-disclaimer": "تکذیب‌نامه/درۆنامة",
+       "exif-contentwarning": "هشدار محتوا",
+       "exif-giffilecomment": "توضیحات پرونده GIF",
+       "exif-intellectualgenre": "نوع مورد",
+       "exif-subjectnewscode": "کد موضوع",
+       "exif-scenecode": "IPTC کد صحنه",
+       "exif-event": "رویداد به تصویر کشیده شده",
+       "exif-organisationinimage": "سازمان به تصویر کشیده شده",
+       "exif-personinimage": "فرد به تصویر کشیده شده",
+       "exif-originalimageheight": "بلندی تصویر قبل از برش دادن",
+       "exif-originalimagewidth": "پهنای تصویر قبل از برش دادن",
+       "exif-compression-1": "غیرفشرده",
+       "exif-compression-2": "رمزگذاری سی‌سی‌آی‌تی‌تی گروه ۳ یک بعدی به روش هافمن تغییریافته روی طول",
+       "exif-compression-3": "رمزگذاری نمابر سی‌سی‌آی‌تی‌تی گروه ۳",
+       "exif-compression-4": "رمزگذاری نمابر سی‌سی‌آی‌تی‌تی گروه ۴",
+       "exif-copyrighted-true": "دارای حق تکثیر",
+       "exif-copyrighted-false": "وضعیت حق‌تکثیر تعیین نشده است",
+       "exif-unknowndate": "تاریخ نامعلوم/نادیار",
+       "exif-orientation-1": "عادی",
+       "exif-orientation-2": "افقی/لاووةلا پشت و رو بیة",
+       "exif-orientation-3": "۱۸۰ درجه چرخیده",
+       "exif-orientation-4": "عمودی پشت و روشده",
+       "exif-orientation-5": "۹۰° پادساعتگرد چرخیده و عمودی پشت و رو شده",
+       "exif-orientation-6": "۹۰° پادساعتگرد چرخیده",
+       "exif-orientation-7": "۹۰° ساعتگرد چرخیده و عمودی پشت و رو شده",
+       "exif-orientation-8": "۹۰° ساعتگرد چرخیده",
+       "exif-planarconfiguration-1": "قالب بزرگ/قؤین",
+       "exif-planarconfiguration-2": "قالب دووجهی",
+       "exif-colorspace-65535": "تنظیم‌نؤیة",
+       "exif-componentsconfiguration-0": "وجود ندارد",
+       "exif-exposureprogram-0": "تعریف‌نشده",
+       "exif-exposureprogram-1": "دةسی-رئ نیشاندر",
+       "exif-exposureprogram-2": "برنامهٔ عادی",
+       "exif-exposureprogram-3": "اولویت دیافراگم",
+       "exif-exposureprogram-4": "اولویت شاتر",
+       "exif-exposureprogram-5": "برنامه خلاق (با گرایش به سمت عمق میدان)",
+       "exif-exposureprogram-6": "برنامه پرجنبش (با گرایش به سمت سرعت بیشتر شاتر)",
+       "exif-exposureprogram-7": "حالت پرتره (برای عکس‌های نزدیک که پس‌زمینه خارج از فاصلهٔ کانونی است)",
+       "exif-exposureprogram-8": "حالت منظره (برای عکس‌های منظره که تمرکز روی پس‌زمینه است)",
+       "exif-subjectdistance-value": "$1 متر",
+       "exif-meteringmode-0": "ناشنا/نادیار",
+       "exif-meteringmode-1": "میانگین",
+       "exif-meteringmode-2": "میانگین با مرکز سنگین",
+       "exif-meteringmode-3": "تک‌نقطه‌ای",
+       "exif-meteringmode-4": "چندنقطه‌ای",
+       "exif-meteringmode-5": "طرح‌دار",
+       "exif-meteringmode-6": "جزئی",
+       "exif-meteringmode-255": "بۀقیۀ",
+       "exif-lightsource-0": "ناشنا/نادیار",
+       "exif-lightsource-1": "رووشتای رووژ",
+       "exif-lightsource-2": "فلورسانت",
+       "exif-lightsource-3": "تنگستن (نور بدون گرما)",
+       "exif-lightsource-4": "فلاش",
+       "exif-lightsource-9": "هوای خوب",
+       "exif-lightsource-10": "آسمان ابری",
+       "exif-lightsource-11": "سایه",
+       "exif-lightsource-12": "مهتابی در روز (D 5700 – 7100K)",
+       "exif-lightsource-13": "مهتابی سفید در روز (N 4600 – 5400K)",
+       "exif-lightsource-14": "مهتابی سفید خنک (W 3900 – 4500K)",
+       "exif-lightsource-15": "مهتابی سفید (WW 3200 – 3700K)",
+       "exif-lightsource-17": "نور استاندارد A",
+       "exif-lightsource-18": "نور استاندارد B",
+       "exif-lightsource-19": "نور استاندارد C",
+       "exif-lightsource-24": "لامپ تنگستن کارخانه ISO",
+       "exif-lightsource-255": "سایر منبةل/بِنچةکةل",
+       "exif-flash-fired-0": "فلاش زده نشد",
+       "exif-flash-fired-1": "با زدن فلاش",
+       "exif-flash-return-0": "فاقد عملکرد کشف نور انعکاسی",
+       "exif-flash-return-2": "نور انعکاسی کشف نشد",
+       "exif-flash-return-3": "نور انعکاسی کشف شد",
+       "exif-flash-mode-1": "فلاش زدن اجباری",
+       "exif-flash-mode-2": "جلوگیری اجباری از فلاش زدن",
+       "exif-flash-mode-3": "حالت خودکار",
+       "exif-flash-function-1": "فاقد عملکرد فلاش",
+       "exif-flash-redeye-1": "حالت اصلاح سرخی چشم‌ها",
+       "exif-focalplaneresolutionunit-2": "اینچ",
+       "exif-sensingmethod-1": "تعریف‌نشده/نادیاری",
+       "exif-sensingmethod-2": "حسگر ناحیهٔ رنگی یک تراشه‌ای",
+       "exif-sensingmethod-3": "حسگر ناحیهٔ رنگی دو تراشه‌ای",
+       "exif-sensingmethod-4": "حسگر ناحیهٔ رنگی سه تراشه‌ای",
+       "exif-sensingmethod-5": "حسگر ناحیه‌ای ترتیبی رنگ‌ها",
+       "exif-sensingmethod-7": "حسگر سه‌خطی",
+       "exif-sensingmethod-8": "حسگر خطی ترتیبی رنگ‌ها",
+       "exif-filesource-3": "دوربین عکاسی دیجیتال",
+       "exif-scenetype-1": "تصویر مستقیماً عکاسی شده",
+       "exif-customrendered-0": "ظهور عادی",
+       "exif-customrendered-1": "ظهور سفارشی",
+       "exif-exposuremode-0": "نوردهی خودکار",
+       "exif-exposuremode-1": "نوردهی دستی",
+       "exif-exposuremode-2": "قاب‌بندی خودکار (Auto bracket)",
+       "exif-whitebalance-0": "تنظیم خودکار تعادل رنگ سفید (white balance)",
+       "exif-whitebalance-1": "تنظیم دستی تعادل رنگ سفید (white balance)",
+       "exif-scenecapturetype-0": "استاندارد",
+       "exif-scenecapturetype-1": "چشم‌انداز",
+       "exif-scenecapturetype-2": "پرتره",
+       "exif-scenecapturetype-3": "شبانه",
+       "exif-gaincontrol-0": "هؤیچ کام",
+       "exif-gaincontrol-1": "افزایش حداقل دریافتی",
+       "exif-gaincontrol-2": "افزایش حداکثر دریافتی",
+       "exif-gaincontrol-3": "کاهش حداقل دریافتی",
+       "exif-gaincontrol-4": "کاهش حداکثر دریافتی",
+       "exif-contrast-0": "عادی",
+       "exif-contrast-1": "نرم",
+       "exif-contrast-2": "زبر",
+       "exif-saturation-0": "عادی",
+       "exif-saturation-1": "رنگ‌های رقیق شده",
+       "exif-saturation-2": "رنگ‌های تغلیظ شده",
+       "exif-sharpness-0": "عادی",
+       "exif-sharpness-1": "نرم",
+       "exif-sharpness-2": "زبر",
+       "exif-subjectdistancerange-0": "ناشنا/نادیار",
+       "exif-subjectdistancerange-1": "کةڵِنگ",
+       "exif-subjectdistancerange-2": "نمای نزدیک",
+       "exif-subjectdistancerange-3": "نمای دور",
+       "exif-gpslatitude-n": "عرض جغرافیایی شمالی",
+       "exif-gpslatitude-s": "عرض جغرافیایی جنوبی",
+       "exif-gpslongitude-e": "طول جغرافیایی شرقی",
+       "exif-gpslongitude-w": "طول جغرافیایی غربی",
+       "exif-gpsaltitude-above-sealevel": "$1 {{PLURAL:$1|متر|مترها}} بالاتر از سطح دریا",
+       "exif-gpsaltitude-below-sealevel": "$1 {{PLURAL:$1|متر|مترها}} پایین‌تر از سطح دریا",
+       "exif-gpsstatus-a": "در حال اندازه‌گیری",
+       "exif-gpsstatus-v": "مقایسه‌پذیری اندازه‌گیری",
+       "exif-gpsmeasuremode-2": "اندازه‌گیری دوبعدی",
+       "exif-gpsmeasuremode-3": "اندازه‌گیری سه‌بعدی",
+       "exif-gpsspeed-k": "کیلومتر بر ساعت",
+       "exif-gpsspeed-m": "مایل بر ساعت",
+       "exif-gpsspeed-n": "گره",
+       "exif-gpsdestdistance-k": "کیلومتر",
+       "exif-gpsdestdistance-m": "مایل",
+       "exif-gpsdestdistance-n": "مایل دریایی",
+       "exif-gpsdop-excellent": "عالی ($1)",
+       "exif-gpsdop-good": "خوب ($1)",
+       "exif-gpsdop-moderate": "متوسط ($1)",
+       "exif-gpsdop-fair": "نه چندان خوب ($1)",
+       "exif-gpsdop-poor": "ضعیف ($1)",
+       "exif-objectcycle-a": "تةنیا شؤةکی/شؤصو",
+       "exif-objectcycle-p": "تةنیا ایووارة/عصر",
+       "exif-objectcycle-b": "شؤةکی و ایووارة",
+       "exif-gpsdirection-t": "جهت درست",
+       "exif-gpsdirection-m": "جهت مغناطیسی",
+       "exif-ycbcrpositioning-1": "وسط‌چین‌شده",
+       "exif-ycbcrpositioning-2": "اشتراکی/هام بةشی",
+       "exif-dc-contributor": "هؤمکاری کِرۀل",
+       "exif-dc-coverage": "محدوده مکانی و یا زمانی رسانه",
+       "exif-dc-date": "تاریخ(ها)",
+       "exif-dc-publisher": "بۀشا کۀر-ناشر",
+       "exif-dc-relation": "رسانه‌های مرتبط",
+       "exif-dc-rights": "حقوق",
+       "exif-dc-source": "رسانه منبع/بِنچةک",
+       "exif-dc-type": "نوع رسانه",
+       "exif-rating-rejected": "رد شده",
+       "exif-isospeedratings-overflow": "کةڵنگ تر إژ ۶۵۵۳۵",
+       "exif-iimcategory-ace": "*هؤنةر، فةرهنگ و خاپوورة*سرگرمی",
+       "exif-iimcategory-clj": "جنایت و قانون",
+       "exif-iimcategory-dis": "بلایا و حوادث",
+       "exif-iimcategory-fin": "بازةرگانی و تجارت",
+       "exif-iimcategory-edu": "آموزش",
+       "exif-iimcategory-evn": "زِنی جاگة/محیط زیست",
+       "exif-iimcategory-hth": "رامی/آزائی/ساق/سلامت",
+       "exif-iimcategory-hum": "تمارزو*خؤزگاڵ* آئم/علاقه بشر",
+       "exif-iimcategory-lab": "کار",
+       "exif-iimcategory-lif": "*روش ژیائن و وةختةل آسائش*فراغت",
+       "exif-iimcategory-pol": "سیاسةتةل",
+       "exif-iimcategory-rel": "مذهب و اعتقاد",
+       "exif-iimcategory-sci": "علم و فناوری",
+       "exif-iimcategory-soi": "مسائل اجتماعی",
+       "exif-iimcategory-spo": "وةرزش",
+       "exif-iimcategory-war": "جنگ ، درگیری و ناآرامی",
+       "exif-iimcategory-wea": "آوو و هآووا",
+       "exif-urgency-normal": "عادی ($1)",
+       "exif-urgency-low": "کم ($1)",
+       "exif-urgency-high": "فِرة/زیاد ($1)",
+       "exif-urgency-other": "اولویت تعریف شده توسط کاربر ($1)",
+       "namespacesall": "کؤل",
+       "monthsall": "کؤل",
+       "confirmemail": "نیشانی ایمیل ووژتان تأئید کةن",
+       "confirmemail_noemail": "شما در صفحهٔ [[Special:Preferences|ترجیحات کاربری]] خود آدرس ایمیل معتبری وارد نکرده‌اید.",
+       "confirmemail_text": "این ویکی، شما را ملزم به تأیید آدرس ایمیل خود، پیش از استفاده از خدمات ایمیل در اینجا می‌کند. دکمهٔ زیرین را فعال کنید تا ایمیلی تأییدی به آدرس ایمیل شما فرستاده شود. این ایمیل دربردارندهٔ پیوندی خواهد بود که حاوی یک کد است. پیوند را در مرورگر خود بار کنید کنید تا آدرس ایمیل شما تأیید شود.",
+       "confirmemail_pending": "یک کد تأییدی پیشتر برای شما به صورت ایمیل فرستاده شده است. اگر همین اواخر حساب خود را باز کرده‌اید شاید بد نباشد که پیش از درخواست یک کد جدید چند دقیقه درنگ کنید تا شاید ایمیل قبلی برسد.",
+       "confirmemail_send": "پُست‌کردن یک کد تأیید",
+       "confirmemail_sent": "یک نامهٔ تأییدی فرستاده شد.",
+       "confirmemail_oncreate": "یک کد تأییدی به آدرس ایمیل شما فرستاده شد.\nبرای واردشدن به سامانه نیازی به این کد نیست، ولی برای راه‌اندازی امکانات وابسته به ایمیل در این ویکی به آن نیاز خواهید داشت.",
+       "confirmemail_sendfailed": "ارسال ایمیل تأییدی ممکن نشد.\nنشانی ایمیل را از نظر وجود نویسه‌های نامعتبر بررسی کنید.\n\nپاسخ سیستم ارسال ایمیل: $1",
+       "confirmemail_invalid": "کد تأیید نامعتبر است. ممکن است که منقضی شده باشد.",
+       "confirmemail_needlogin": "لطفاً برای تأیید آدرس ایمیلتان $1.",
+       "confirmemail_success": "آدرس ایمیل شما تأیید شده‌است.\n\nاکنون می‌توانید [[Special:UserLogin|به سیستم وارد شوید]] و از ویکی لذت ببرید.",
+       "confirmemail_loggedin": "نشانی ایمیل شما تأیید شد.",
+       "confirmemail_subject": "تأیید نشانی ایمیل {{SITENAME}}",
+       "confirmemail_body": "یک نفر، احتمالاً خود شما، از نشانی آی‌پی $1 حساب کاربری‌ای با نام «$2» و این آدرس ایمیل در {{SITENAME}} ایجاد کرده است.\n\nبرای تأیید این که این حساب واقعاً متعلق به شماست و نیز برای فعال سازی قابلیت ایمیل {{SITENAME}} پیوند زیر را در مرورگر اینترنت خود باز کنید:\n\n$3\n\nاگر شما این حساب کاربری را ثبت *نکرده‌اید*، لطفاً پیوند زیر را\nباز کنید تا تأیید آدرس ایمیل لغو شود:\n\n$5\n\nاین کدِ تأیید در تاریخ $4 منقضی خواهد شد.",
+       "confirmemail_body_changed": "یک نفر، احتمالاً خود شما، از نشانی آی‌پی $1 آدرس ایمیل حساب «$2» در {{SITENAME}} را تغییر داده است.\n\nبرای تأیید این که این حساب واقعاً به شما تعلق دارد و فعال کردن دوبارهٔ قابلیت ایمیل در {{SITENAME}}، پیوند زیر را در مرورگرتان باز کنید:\n\n$3\n\nاگر این حساب متعلق به شما نیست، پیوند زیر را باز کنید تا تغییر آدرس ایمیل لغو شود:\n\n$5\n\nاین تأییدیه در $4 منقضی می‌گردد.",
+       "confirmemail_body_set": "یک نفر، احتمالاً خود شما، از نشانی آی‌پی $1,\nآدرس ایمیل حساب «$2» در {{SITENAME}} را به این آدرس تغییر داده است.\n\nبرای تأیید این که این حساب واقعاً به شما تعلق دارد و فعال کردن دوبارهٔ قابلیت ایمیل در {{SITENAME}}، پیوند زیر را در مرورگرتان باز کنید:\n\n$3\n\nاگر این حساب متعلق به شما نیست، پیوند زیر را باز تا تغییر آدرس ایمیل، لغو شود:\n\n$5\n\nاین تأییدیه در $4 منقضی می‌گردد.",
+       "confirmemail_invalidated": "تأیید نشانی ایمیل لغو شد",
+       "invalidateemail": "لغو تأیید نشانی ایمیل",
+       "scarytranscludedisabled": "[تراگنجانش بین‌ویکیانه فعال نیست]",
+       "scarytranscludefailed": "[فراخوانی الگو برای $1 میسر نشد]",
+       "scarytranscludefailed-httpstatus": "[فراخوانی الگو برای $1 میسر نشد: خطای اچ‌تی‌تی‌پی $2]",
+       "scarytranscludetoolong": "[نشانی اینترنتی مورد نظر (URL) بیش از اندازه بلند بود]",
+       "deletedwhileediting": "'''هشدار''': این صفحه پس از اینکه شما آغاز به ویرایش آن کرده‌اید، حذف شده است!",
+       "confirmrecreate": "کاربر [[User:$1|$1]] ([[User talk:$1|بحث]]) این مقاله را پس از اینکه شما آغاز به ویرایش آن نموده‌اید به دلیل زیر حذف کرده است :\n: ''$2''\nلطفاً تأیید کنید که مجدداً می‌خواهید این مقاله را بسازید.",
+       "confirmrecreate-noreason": "کاربر [[User:$1|$1]] ([[User talk:$1|بحث]]) این صفحه را پس از شروع ویرایش‌تان پاک کرده‌است.  لطفاً تأیید کنید که شما واقعاً می‌خواهید آن را دوباره ایجاد کنید.",
+       "recreate": "دووارة دوِرس کردن",
+       "confirm_purge_button": "خوو/ باشد",
+       "confirm-purge-top": "پاک‌کردن نسخهٔ حافظهٔ نهانی (Cache) این صفحه را تأیید می‌کنید؟",
+       "confirm-purge-bottom": "خالی کردن میانگیر یک صفحه باعث می‌شود که آخرین نسخهٔ آن نمایش یابد.",
+       "confirm-watch-button": "خوو/ باشد",
+       "confirm-watch-top": "اضافۀ کردن ئئ وۀلگۀ وۀ لیست پیگیریۀل تان",
+       "confirm-unwatch-button": "خوو/ باشد",
+       "confirm-unwatch-top": " ئئ وۀلگۀ وۀ لیست پیگیریۀل تان حذف بو؟",
+       "semicolon-separator": "؛&#32;",
+       "quotation-marks": "«$1»",
+       "imgmultipageprev": "←وةڵگة پئش",
+       "imgmultipagenext": "وةڵگة تِر/بعدی→",
+       "imgmultigo": "بِچۆ!",
+       "imgmultigoto": "بچۆ وةڵگة $1",
+       "img-lang-default": "(زوون پئش فرض)",
+       "img-lang-info": "ارائه این تصویر در  $1 .  $2",
+       "img-lang-go": "بِچۆ",
+       "ascending_abbrev": "ورِ بِڵِنگی/صعودی",
+       "descending_abbrev": "ورِ هووار/نزولی",
+       "table_pager_next": "وةڵگة بعدی",
+       "table_pager_prev": "وةڵگة  پئش",
+       "table_pager_first": "وةڵگة أؤةڵئن",
+       "table_pager_last": "وةڵگة دؤمائن/آخر",
+       "table_pager_limit": "نمایش $1 مورد در هر وةڵگة",
+       "table_pager_limit_label": "تعداد موارد در هر وةڵگة :",
+       "table_pager_limit_submit": "بِچۆ",
+       "table_pager_empty": "بدون نتیجه",
+       "autosumm-blank": "وةڵگة را خالی کرد",
+       "autosumm-replace": "جایگزینی وةڵگة با '$1'",
+       "autoredircomment": "تغییرمسیر به [[$1]]",
+       "autosumm-new": "وةڵگة تازه حاوی «$1» ایجاد کرد",
+       "autosumm-newblank": "ایجاد وةڵگة خالی",
+       "lag-warn-normal": "ممکن است تغییرات تازه‌تر از $1 {{PLURAL:$1|ثانیه|ثانیه ها}} در این فهرست نشان داده نشوند.",
+       "lag-warn-high": "ممکن است، به خاطر پس‌افتادگی زیاد سرور پایگاه داده، تغییرات تازه‌تر از $1 {{PLURAL:$1|ثانیه|ثانیه ها}} در این فهرست نشان داده نشده باشند.",
+       "watchlistedit-normal-title": "دةسکاری لیست پی‌گیریةل",
+       "watchlistedit-normal-legend": "حذف عنوان‌ها از فهرست پی‌گیری‌ها",
+       "watchlistedit-normal-explain": "عنوان‌های موجود در فهرست پی‌گیری شما در زیر نشان داده شده‌اند.\nبرای حذف هر عنوان جعبهٔ کنار آن را علامت بزنید و دکمهٔ «{{int:Watchlistedit-normal-submit}}» را بفشارید.\nشما همچنین می‌توانید [[Special:EditWatchlist/raw|فهرست خام را ویرایش کنید]].",
+       "watchlistedit-normal-submit": "حذف عنوان‌ها",
+       "watchlistedit-normal-done": "$1 عنوان از فهرست پی‌گیری‌های شما حذف {{PLURAL:$1|شد|شدند}}:",
+       "watchlistedit-raw-title": "ویرایش فهرست خام پی‌گیری‌ها",
+       "watchlistedit-raw-legend": "ویرایش فهرست خام پی‌گیری‌ها",
+       "watchlistedit-raw-explain": "عنوان‌های موجود در فهرست پی‌گیری‌های شما در زیر نشان داده شده‌اند، و شما می‌توانید مواردی را حذف یا اضافه کنید؛ هر مورد در یک سطر جداگانه باید قرار بگیرد.\nدر پایان، دکمهٔ «{{int:Watchlistedit-raw-submit}}» را بفشارید.\nتوجه کنید که شما می‌توانید از [[Special:EditWatchlist|ویرایشگر استاندارد فهرست پی‌گیری‌ها]] هم استفاده کنید.",
+       "watchlistedit-raw-titles": "عنوانةل:",
+       "watchlistedit-raw-submit": "به‌روزرسانی پی‌گیری‌ها",
+       "watchlistedit-raw-done": "فهرست پی‌گیری‌های شما به روز شد.",
+       "watchlistedit-raw-added": "$1 عنوان به فهرست پی‌گیری‌ها اضافه {{PLURAL:$1|شد|شدند}}:",
+       "watchlistedit-raw-removed": "$1 عنوان حذف {{PLURAL:$1|شد|شدند}}:",
+       "watchlistedit-clear-title": "لیست پیگیری پاک بیة",
+       "watchlistedit-clear-legend": "پاکسازی فهرست پیگیری",
+       "watchlistedit-clear-explain": "همه عناوین از فهرست پیگیریهای شما حذف خواهد شد",
+       "watchlistedit-clear-titles": "عنوانةل:",
+       "watchlistedit-clear-submit": "پاک کردن فهرست پیگیریها (این دائم است!)",
+       "watchlistedit-clear-done": "فهرست پیگیریهای شما پاک شد.",
+       "watchlistedit-clear-removed": "$1 عنوان حذف {{PLURAL:$1|شد|شدند}}:",
+       "watchlistedit-too-many": "تعداد زیادی صفحه برای نمایش در اینجا وجود دارد.",
+       "watchlisttools-clear": "پاکسازی فهرست پیگیری",
+       "watchlisttools-view": "لیست پیگیریةل",
+       "watchlisttools-edit": "مشاهده و ویرایش فهرست پی‌گیری‌ها",
+       "watchlisttools-raw": "ویرایش فهرست خام پی‌گیری‌ها",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|گۀپ]])",
+       "duplicate-defaultsort": "هشدار: ترتیب پیش‌فرض «$2» ترتیب پیش‌فرض قبلی «$1» را باطل می‌کند.",
+       "duplicate-displaytitle": "<strong>هشدار:</strong> نمایش عنوان \" $2 \"باعث ابطال پیش نمایش عنوان\" $1 \" می‌شود.",
+       "invalid-indicator-name": "<strong>خطا:</strong>ویژگی های شاخص‌های وضعیت صفحهٔ <code>name</code> نباید خالی باشند.",
+       "version": "نسخه",
+       "version-extensions": "افزونه‌های نصب‌شده",
+       "version-skins": "پوسته‌های نصب شده",
+       "version-specialpages": "وةڵگة/پةرة  ویژة",
+       "version-parserhooks": "قلاب‌های تجزیه‌گر",
+       "version-variables": "متغیرها",
+       "version-antispam": "جلوگیری از هرزنامه",
+       "version-other": "بۀقیۀ",
+       "version-mediahandlers": "به‌دست‌گیرنده‌های رسانه‌ها",
+       "version-hooks": "قلاب‌ها",
+       "version-parser-extensiontags": "برچسب‌های افزونه تجزیه‌گر",
+       "version-parser-function-hooks": "قلاب‌های عملگر تجزیه‌گر",
+       "version-hook-name": "نام قلاب",
+       "version-hook-subscribedby": "وارد شده توسط",
+       "version-no-ext-name": "[بی نام]",
+       "version-license": "اجازه‌نامهٔ مدیاویکی",
+       "version-ext-license": "مجوزها",
+       "version-ext-colheader-name": "گستره‌ها",
+       "version-skin-colheader-name": "پوسته",
+       "version-ext-colheader-version": "نسخه",
+       "version-ext-colheader-license": "مجوز",
+       "version-ext-colheader-description": "توصیفات",
+       "version-ext-colheader-credits": "نویسندگان",
+       "version-license-title": "مجوز برای $1",
+       "version-license-not-found": "هیچ جزئیاتی از اطلاعات مجوز برای این گستره پیدا نشد.",
+       "version-credits-title": "اعتبارها برای $1",
+       "version-credits-not-found": "هیچ جزئیاتی از اطلاعات اعتبارها برای این گستره پیدا نشد.",
+       "version-poweredby-credits": "این ویکی توسط '''[https://www.mediawiki.org/ مدیاویکی]''' پشتیبانی می‌شود، کلیهٔ حقوق محفوظ است © 2001-$1 $2.",
+       "version-poweredby-others": "دیگران",
+       "version-poweredby-translators": "زوون چاوواشةکرةلtranslatewiki.net",
+       "version-credits-summary": "افراد زیر را به خاطر ویرایش‌هایش در [[Special:Version|مدیاویکی]] معرفی می‌نمائیم.",
+       "version-license-info": "مدیاویکی یک نرم‌افزار آزاد است. می‌توانید آن را با شرایط نگارش ۲، یا (با نظر خودتان) هر نگارش جدیدتری از پروانه جامع همگانی گنو که توسط بنیاد نرم‌افزار آزاد منتشر شده‌است، بازنشر کنید.\n\nمدیاویکی با این امید که مفید واقع شود منتشر شده‌است، ولی هیچ‌گونه ضمانتی، حتا ضمانت ضمنی تجاری یا مناسب بودن برای یک مصرف خاص را ارائه نمی‌کند. برای اطلاعات بیش‌تر، پروانه جامع همگانی گنو را مشاهده کنید.\n\nشما باید [{{SERVER}}{{SCRIPTPATH}}/COPYING یک نسخه از پروانه جامع همگانی گنو] را به همراه این برنامه دریافت کرده باشید. در غیر این صورت با Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA یا آن را [//www.gnu.org/licenses/old-licenses/gpl-2.0.html مکاتبه کرده یا آن را به صورت برخط بخوانید].",
+       "version-software": "نسخهٔ نصب‌شده",
+       "version-software-product": "محصول",
+       "version-software-version": "نسخه",
+       "version-entrypoints": "نشانی اینترنتی محل ورود",
+       "version-entrypoints-header-entrypoint": "نقطه ورود",
+       "version-entrypoints-header-url": "نشانی اینترنتی",
+       "version-libraries": "کتابخانهٔ نصب شده",
+       "version-libraries-library": "کتاووخانة",
+       "version-libraries-version": "نسخه",
+       "version-libraries-license": "اجازه‌نامه",
+       "version-libraries-description": "توضیحةل",
+       "version-libraries-authors": "نویسندگان",
+       "redirect": "تغییرمسیر توسط پرونده، کاربر، صفحه یا شناسهٔ نسخه",
+       "redirect-legend": "تغییرمسیر به یک پرونده یا صفحه",
+       "redirect-summary": "این صفحهٔ ویژه به پرونده (نام پرونده داده‌شده)، صفحه (شماره شناسهٔ صفحه یا شماره نسخهٔ داده‌شده) یا صفحهٔ کاربری (شناسهٔ عددی کاربری داده‌شده) تغییرمسیر می‌یابد. طرز استفاده: [[{{#Special:Redirect}}/file/Example.jpg]]، \n[[{{#Special:Redirect}}/page/64308]]، [[{{#Special:Redirect}}/revision/328429]] یا [[{{#Special:Redirect}}/user/101]].",
+       "redirect-submit": "بِچۆ",
+       "redirect-lookup": "مِنِی کردن/گئردین:",
+       "redirect-value": "ارزش:",
+       "redirect-user": "شناسهٔ کاربر",
+       "redirect-page": "شناسهٔ وةڵگة",
+       "redirect-revision": "نسخهٔ وةڵگة",
+       "redirect-file": "نام پرونده",
+       "redirect-not-exists": "مقدار پیدا نشد",
+       "fileduplicatesearch": "جستجو برای پرونده‌های تکراری",
+       "fileduplicatesearch-summary": "جستجو برای پرونده‌های تکراری بر اساس مقدار درهم‌شدهٔ آن‌ها صورت می‌گیرد.",
+       "fileduplicatesearch-legend": "جستجوی موارد تکراری",
+       "fileduplicatesearch-filename": "نام پرونده:",
+       "fileduplicatesearch-submit": "گئردین/مهِ نی",
+       "fileduplicatesearch-info": "<span dir=\"ltr\">$1 × $2</span> پیکسل<br />اندازهٔ پرونده: $3<br />نوع MIME: $4",
+       "fileduplicatesearch-result-1": "پروندهٔ «$1» مورد تکراری ندارد.",
+       "fileduplicatesearch-result-n": "پروندهٔ «$1» دارای {{PLURAL:$2|یک مورد تکراری|$2 مورد تکراری}} است.",
+       "fileduplicatesearch-noresults": "پرونده‌ای با نام «$1» أ دی نؤی /پئا نؤی.",
+       "specialpages": "وۀلگۀل/پۀرۀل ویژۀ",
+       "specialpages-note-top": "شرح علائم",
+       "specialpages-note": "* صفحه‌های ویژهٔ عادی.\n* <span class=\"mw-specialpagerestricted\">صفحه‌های ویژهٔ محدودشده.</span>",
+       "specialpages-group-maintenance": "گزارش‌های نگهداری",
+       "specialpages-group-other": "سایر وةڵگةل ویژه",
+       "specialpages-group-login": " إ نؤم هةتن سیستم/ حساوو کاربةری سازین",
+       "specialpages-group-changes": "تغییرات اخیر و سیاهه‌ها",
+       "specialpages-group-media": "گزارش بارگذاری رسانه‌ها",
+       "specialpages-group-users": "کاربرها و دسترسی‌ها",
+       "specialpages-group-highuse": "وةڵگةل پربازدید",
+       "specialpages-group-pages": "لیست وةڵگةل",
+       "specialpages-group-pagetools": "ابزارةل وةڵگة",
+       "specialpages-group-wiki": "داده و ابزارها",
+       "specialpages-group-redirects": "وةڵگةل ویژهٔ تغییرمسیر دهنده",
+       "specialpages-group-spam": "ابزارهای هرزنگاری",
+       "specialpages-group-developer": "ابزارهای توسعه‌دهندگان",
+       "blankpage": "وةڵگة خالی",
+       "intentionallyblankpage": "این وةڵگة به طور عمدی خالی گذاشته شده است.",
+       "external_image_whitelist": " #این سطر را همان‌گونه که هست رها کنید<pre>\n#عبارت‌های باقاعده (regex) را در زیر قرار دهید (فقط بخشی که بین // قرار می‌گیرد)\n#آن‌ها با نشانی اینترنتی تصاویر خارجی پیوند داده شده تطبیق داده می‌شوند\n#مواردی که مطابق باشند به صورت تصویر نمایش می‌یابند، و در غیر این صورت تنها یک پیوند به تصویر نمایش می‌یابد\n#سطرهایی که با # آغاز شوند به عنوان توضیحات در نظر گرفته می‌شوند\n#این سطرها به کوچکی و بزرگی حروف حساس هستند\n\n#عبارت‌های باقاعده (regex)  را زیر این سطر قرار دهید. این سطر را همان‌گونه که هست رها کنید</pre>",
+       "tags": "برچسب‌های تغییر مجاز",
+       "tag-filter": ":فیلتر کۀ[[Special:Tags|برچسب‌ۀل]]",
+       "tag-filter-submit": "پالانۀل/فیلترۀل",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|بۀرچۀسب|بۀرچۀسبۀل}}]]:$2)",
+       "tags-title": "برچسب‌ها",
+       "tags-intro": "این وةڵگة فهرستی‌است از برچسب‌هایی که نرم‌افزار با آن‌ها ویرایش‌ها را علامت‌گذری می‌کند، به همراه معانی آن‌ها.",
+       "tags-tag": "نام برچسب",
+       "tags-display-header": "نمایش در فهرست‌های تغییرات",
+       "tags-description-header": "توضیح کامل معنی",
+       "tags-source-header": "بِنچۀک/مۀنبۀع",
+       "tags-active-header": "فعال(کارکةر)؟",
+       "tags-hitcount-header": "تغییرهای برچسب‌دار",
+       "tags-actions-header": "کارۀل",
+       "tags-active-yes": "أرێ-بةلئ",
+       "tags-active-no": "نة-نةخئر",
+       "tags-source-extension": "تعریف‌شده بر پایه افزونه",
+       "tags-source-manual": "اعمال شده به صورت دستی توسط ربات‌ها یا کاربرها",
+       "tags-source-none": "دیگر استفاده نمی‌شود",
+       "tags-edit": "دةسکاری",
+       "tags-delete": "حۀذف کردن/پاک کردن",
+       "tags-activate": "فعال کردن",
+       "tags-deactivate": "غیرفعال کردن/إکار کةتن",
+       "tags-hitcount": "$1 {{PLURAL:$1|تغییرها|تغییر}}",
+       "tags-manage-no-permission": "شما اجازه مدیریت تغییر تگ‌ها را ندارید.",
+       "tags-create-heading": "ایجاد یک برچسب جدید",
+       "tags-create-explanation": "به طور پیش‌فرض، تگ‌های تازه ایجاد شده برای استفاده کاربران و ربات‌ها در دسترس قرار می‌گیرند.",
+       "tags-create-tag-name": "نام برچسب:",
+       "tags-create-reason": ":دةلیل",
+       "tags-create-submit": "دؤِرس کردن/سازین",
+       "tags-create-no-name": "نام تگ باید دیار بو.",
+       "tags-create-invalid-chars": "نام تگ‌ها نباید حاوی کاما (<code>,</code>) یا خط مورب (<code>/</code>) باشد.",
+       "tags-create-invalid-title-chars": "نام تگ‌ها نباید شامل حروفی شود که نمی‌توان از آن‌ها در عنوان صفحات استفاده کرد.",
+       "tags-create-already-exists": "تگ \"$1\" ایسة وجود دِرێ.",
+       "tags-create-warnings-above": "در هنگام ایجاد تگ \"$1\" با {{PLURAL:$2|هشدار|هشدارهای}} زیر پیش آمد:",
+       "tags-create-warnings-below": "آیا مایل به ادامه ایجاد تگ هستید؟",
+       "tags-delete-title": "حذف برچسب",
+       "tags-delete-explanation-initial": "شما در حال حذف تگ «$1» از پایگاه داده هستید.",
+       "tags-delete-explanation-in-use": "این از {{PLURAL:$2|$2 ویرایش یا ورودی سیاهه|همهٔ $2 ویرایش و/یا ورودی سیاهه}} حذف خواهد شد با وجودی که الان تائید شده‌است.",
+       "tags-delete-explanation-warning": "این عمل <strong>غیر قابل بازگشت</strong> است، حتی توسط مدیران پایگاه داده. مطمئن باشید که این همان تگی است که می‌خواهید آن‌را حذف کنید.",
+       "tags-delete-explanation-active": "<strong>برچسب \"$1\" هنوز فعال است و در آینده اعمال خواهد شد.</strong> برای جلوگیری از این اتفاق، به قسمت(‌هایی) که برچسب فعال شده رفته و از آنجا غیرفعالش کنید.",
+       "tags-delete-reason": ":دةلیل",
+       "tags-delete-submit": "این تگ را به‌صورت غیرقابل بازگشت حذف کن",
+       "tags-delete-not-allowed": "برچسب‌هایی که در یک افزونه تعریف می‌شوند قابل حذف نیستند، مگر اینکه آن افزونه در این مورد خاص این قابلیت را بدهد.",
+       "tags-delete-not-found": "تگ «$1» وجود نئرێ.",
+       "tags-delete-too-many-uses": "برچسب \"$1\" در بیش از $2 {{PLURAL:$2|نسخه|نسخه ها}} اعمال شده است و نمی‌توان آن را حذف نمود",
+       "tags-delete-warnings-after-delete": "برچسب \"$1\" با موفقیت حذف شد، اما با {{PLURAL:$2|خطای|خطاهای}} زیر همراه بود:",
+       "tags-activate-title": "فعال‌سازی برچسب",
+       "tags-activate-question": "شما در حال فعال‌سازی تگ «$1» هستید.",
+       "tags-activate-reason": ":دةلیل",
+       "tags-activate-not-allowed": "فعال‌سازی تگ «$1» ممکن نیست.",
+       "tags-activate-not-found": "تگ «$1» وجود نئرێ.",
+       "tags-activate-submit": "فعال کردن",
+       "tags-deactivate-title": "فعال‌سازی برچسب",
+       "tags-deactivate-question": "شما در حال غیرفعال‌سازی تگ «$1» هستید.",
+       "tags-deactivate-reason": ":دةلیل",
+       "tags-deactivate-not-allowed": "غیرفعال‌سازی تگ «$1» ممکن نیست.",
+       "tags-deactivate-submit": "غیرفعال کردن/إکار کةتن",
+       "tags-apply-no-permission": "دسترسی برای تغییر برچسب تغییراتتان را ندارید.",
+       "tags-apply-not-allowed-one": "اجازهٔ تائید برچسب «$1» به صورت دستی وجود ندارد.",
+       "tags-apply-not-allowed-multi": "اجازهٔ تائید {{PLURAL:$2|برچسب|برچسب ها}} به صورت دستی وجود ندارد:$1",
+       "tags-update-no-permission": "شما اجازهٔ افزودن یا حذف برچسب از خود نسخه یا سیاهه را ندارید.",
+       "tags-update-add-not-allowed-one": "اجازهٔ افزودن برچسب «$1» به صورت دستی وجود ندارد.",
+       "tags-update-add-not-allowed-multi": "اجازهٔ افزودن {{PLURAL:$2|برچسب|برچسب ها}} به صورت دستی وجود ندارد:$1",
+       "tags-update-remove-not-allowed-one": "اجازهٔ حذف برچسب «$1» به صورت دستی وجود ندارد.",
+       "tags-update-remove-not-allowed-multi": "اجازهٔ حذف {{PLURAL:$2|برچسب|برچسب ها}} به صورت دستی وجود ندارد:$1$1",
+       "tags-edit-title": "ویرایش برچسب‌ها",
+       "tags-edit-manage-link": "مدیریت برچسب‌ها",
+       "tags-edit-revision-selected": "{{PLURAL:$1|نسخهٔ انتخاب شده|نسخهٔ انتخاب شده ها}} [[:$2]]:",
+       "tags-edit-logentry-selected": "{{PLURAL:$1|سیاههٔ انتخاب شده ها|سیاههٔ انتخاب شده}}:",
+       "tags-edit-revision-legend": "افزودن یا حذف برچسب از {{PLURAL:$1|این نسخه|همهٔ $1 نسخه‌ها}}",
+       "tags-edit-logentry-legend": "افزودن یا حذف برچسب از {{PLURAL:$1|این سیاهه|همهٔ $1 سیاهه‌ها}}",
+       "tags-edit-existing-tags": "برچسب‌های موجود:",
+       "tags-edit-existing-tags-none": "\"هؤیچ کام\"",
+       "tags-edit-new-tags": "برچسب جدید:",
+       "tags-edit-add": "افزودن این برچسب‌ها:",
+       "tags-edit-remove": "حذف این برچسب‌ها:",
+       "tags-edit-remove-all-tags": "(حذف همهٔ برچسب‌ها)",
+       "tags-edit-chosen-placeholder": "انتخاب تعدادی برچسب",
+       "tags-edit-chosen-no-results": "برچسبی برای انتخاب یافت نشد",
+       "tags-edit-reason": ":دةلیل",
+       "tags-edit-revision-submit": "اعمال تغییرات بر روی {{PLURAL:$1|این نسخه|$1 نسخه}}",
+       "tags-edit-logentry-submit": "اعمال تغییرات بر روی {{PLURAL:$1|این سیاهه|$1 سیاهه}}",
+       "tags-edit-success": "تغییرات با موفقیت اعمال شدند.",
+       "tags-edit-failure": "امکان اعمال تغییرات وجود ندارد: $1",
+       "tags-edit-nooldid-title": "نسخهٔ مقصد نادرست",
+       "tags-edit-nooldid-text": "نسخهٔ مقصد برای اعمال تابع مورد نظر را مشخص نکرده‌اید، یا نسخهٔ مورد نظر وجود ندارد.",
+       "tags-edit-none-selected": "لطفاً حداقل یک برچسب برای افزودن یا حذف انتخاب کنید.",
+       "comparepages": "مقایسة وةڵگةل",
+       "compare-page1": "وةڵگةل ۱",
+       "compare-page2": "وةڵگةل ۲",
+       "compare-rev1": "نسخهٔ ۱",
+       "compare-rev2": "نسخهٔ ۲",
+       "compare-submit": "مقایسه",
+       "compare-invalid-title": "عنوان تعیین‌شده نامعتبر است.",
+       "compare-title-not-exists": "عنوان مشخص شده وجود ندارد.",
+       "compare-revision-not-exists": "پالایهٔ مشخص شده وجود ندارد.",
+       "dberr-problems": "پوزش! این تارنما از مشکلات فنی رنج می‌برد.",
+       "dberr-again": "چند دقیقه صبر کنید و دوباره وةڵگة را بارگیری کنید.",
+       "dberr-info": "(امکان برقراری ارتباط با پایگاه داده وجود ندارد: $1)",
+       "dberr-info-hidden": "(امکان تماس با پایگاه‌داده نیست)",
+       "dberr-usegoogle": "شما در این مدت می‌توانید با استفاده از گوگل جستجو کنید.",
+       "dberr-outofdate": "توجه کنید که نمایه‌های آن‌ها از محتوای ما ممکن است به روز نباشد.",
+       "dberr-cachederror": "آن‌چه در ادامه می‌آید یک کپی از صفحهٔ درخواست شده است که در کاشه قرار دارد، و ممکن است به روز نباشد.",
+       "htmlform-invalid-input": "بخشی از ورودی شما مشکل دارد",
+       "htmlform-select-badoption": "مقدار وارد شده یک گزینهٔ قابل قبول نیست.",
+       "htmlform-int-invalid": "مقداری که وارد کردید یک عدد صحیح نیست.",
+       "htmlform-float-invalid": "مقداری که وارد کردید یک عدد نیست.",
+       "htmlform-int-toolow": "مقداری که وارد کردید کمتر از $1 است",
+       "htmlform-int-toohigh": "مقداری که وارد کردید بیشتر از $1 است",
+       "htmlform-required": "این مقدار مورد نیاز است",
+       "htmlform-submit": "ارسال/کِل کردن",
+       "htmlform-reset": "خنثی کردن تغییرات",
+       "htmlform-selectorother-other": "بۀقیۀ",
+       "htmlform-no": "نة-نةخئر",
+       "htmlform-yes": "أرێ-بةلئ",
+       "htmlform-chosen-placeholder": "یإگِلة گزینة انتخاب کةن",
+       "htmlform-cloner-create": " افزودن ویشتر/فرةتر",
+       "htmlform-cloner-delete": "پاکاکردن",
+       "htmlform-cloner-required": "حداقل یک مقدار مورد نیاز است.",
+       "htmlform-title-badnamespace": "[[:$1]] در فضای نام \"{{ns:$2}}\"  موجود نیست.",
+       "htmlform-title-not-creatable": "\"$1\" عنوان قابل ایجاد نیست",
+       "htmlform-title-not-exists": "$1 وجود ندارد.",
+       "htmlform-user-not-exists": "<strong>$1</strong> وجود ندارد.",
+       "htmlform-user-not-valid": "حساوو کاربةری <strong>$1</strong> معتبر نیة.",
+       "sqlite-has-fts": "$1 با پشتیبانی از جستجو در متن کامل",
+       "sqlite-no-fts": "$1 بدون پشتیبانی از جستجو در متن کامل",
+       "logentry-delete-delete": "$1 VALGA $3{{GENDER:$2|HAZF Kerdi}}",
+       "logentry-delete-restore": "$1 وةڵگة $3 را {{GENDER:$2|احیا کرد}}",
+       "logentry-delete-event": "$1 پیدایی {{PLURAL:$5|یک مورد سیاهه|$5 مورد سیاهه}} را در $3 {{GENDER:$2|تغییر داد}}: $4",
+       "logentry-delete-revision": "$1 پیدایی {{PLURAL:$5|یک نسخه|$5 نسخه}} صفحه $3 را {{GENDER:$2|تغییر داد}}: $4",
+       "logentry-delete-event-legacy": "$1 پیدایی موارد سیاهه را در $3 {{GENDER:$2|تغییر داد}}",
+       "logentry-delete-revision-legacy": "$1 پیدایی نسخه‌های $3 را {{GENDER:$2|تغییر داد}}",
+       "logentry-suppress-delete": "$1 $3 را {{GENDER:$2| فرونشانی کرد}}",
+       "logentry-suppress-event": "$1 پیدایی {{PLURAL:$5|یک مورد سیاهه|$5 مورد سیاهه}} را در $3 مخفیانه {{GENDER:$2|تغییر داد}}: $4",
+       "logentry-suppress-revision": "$1 پیدایی {{PLURAL:$5|یک نسخه|$5 نسخه}} صفحه $3 را مخفیانه {{GENDER:$2|تغییر داد}}: $4",
+       "logentry-suppress-event-legacy": "$1 پیدایی موارد سیاهه را در $3 مخفیانه {{GENDER:$2|تغییر داد}}",
+       "logentry-suppress-revision-legacy": "$1 پیدایی نسخه‌های $3 را مخفیانه {{GENDER:$2|تغییر داد}}",
+       "revdelete-content-hid": "محتوا شاردئا/پنهان کرد",
+       "revdelete-summary-hid": "خلاصه ویرایش را پنهان کرد",
+       "revdelete-uname-hid": "نام کاربری را پنهان کرد",
+       "revdelete-content-unhid": "محتوا را آشکار کرد",
+       "revdelete-summary-unhid": "خلاصه ویرایش را آشکار کرد",
+       "revdelete-uname-unhid": "نام کاربری را آشکار کرد",
+       "revdelete-restricted": "مدیران را محدود کرد",
+       "revdelete-unrestricted": "محدودیت مدیران را لغو کرد",
+       "logentry-block-block": "$1 {{GENDER:$4|$3}} را تا $5 {{GENDER:$2|بست}} $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|بازکرد}} {{GENDER:$4|$3}}",
+       "logentry-block-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن {{GENDER:$4|$3}} را به پایان قطع دسترسی $5 $6 تغییر داد.",
+       "logentry-suppress-block": "$1 {{GENDER:$2|بسته شد}} {{GENDER:$4|$3}} با پایان قطع دسترسی در زمان $5 $6",
+       "logentry-suppress-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن برای  {{GENDER:$4|$3}} به پایان قطع دسترسی  $5 $6 تغییر یافت",
+       "logentry-import-upload": "$1 $3 را توسط بارگذار پرونده {{GENDER:$2|درون‌ریزی کرد}}",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|imported}} $3 by file upload ($4 {{PLURAL:$4|revision|revisions}})",
+       "logentry-import-interwiki": "$1 $3 را از ویکی دیگر {{GENDER:$2|درون‌ریز کرد}}",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|imported}} $3 from $5 ($4 {{PLURAL:$4|revision|revisions}})",
+       "logentry-merge-merge": "$1  $3  را به  $4 {{GENDER:$2| ادغام کرد}} (نسخه تا  $5)",
+       "logentry-move-move": "$1 {{GENDER:$2|moved}} page $3 to $4",
+       "logentry-move-move-noredirect": "$1 وةڵگة $3 را بدون برجای‌گذاشتن تغییرمسیر به $4 {{GENDER:$2|منتقل کرد}}",
+       "logentry-move-move_redir": "$1 وةڵگة $3 را به $4 که تغییرمسیر بود {{GENDER:$2|منتقل کرد}}",
+       "logentry-move-move_redir-noredirect": "$1 وةڵگة $3 را بدون برجای‌گذاشتن تغییرمسیر به $4 که تغییرمسیر بود {{GENDER:$2|منتقل کرد}}",
+       "logentry-patrol-patrol": "$1 نسخه $4 صفحه $3 را به عنوان گشت خورده {{GENDER:$2|علامت زد}}",
+       "logentry-patrol-patrol-auto": "$1 نسخهٔ $4 صفحهٔ $3 را به‌طور خودکار به عنوان گشت‌خورده {{GENDER:$2|علامت زد}}",
+       "logentry-newusers-newusers": "حساوو کاربۀری $1 {{GENDER:$2|سازیا}}",
+       "logentry-newusers-create": "حساوو کاربۀری $1 {{GENDER:$2|سازیا}}",
+       "logentry-newusers-create2": "حساوو کاربةری $3 توسط $1 {{GENDER:$2|اسازیا}}",
+       "logentry-newusers-byemail": "حساب کاربری $3 توسط $1 {{GENDER:$2|ایجاد شد}} و رمز عبور به وسیلهٔ ایمیل ارسال شد",
+       "logentry-newusers-autocreate": "حساب $1  به شکل خودکار {{GENDER:$2|ایجاد شد}}",
+       "logentry-protect-move_prot": "$1 تنظیمات محافظت را از $4 به $3 {{GENDER:$2|منتقل کرد}}",
+       "logentry-protect-unprotect": "$1 $3 را از محافظت {{GENDER:$2|خارج کرد}}",
+       "logentry-protect-protect": "$1 $3 را {{GENDER:$2|محافظت کرد}} $4",
+       "logentry-protect-protect-cascade": "$1 $3 $4 {{GENDER:$2|محافظت کرد}} [آبشاری]",
+       "logentry-protect-modify": "$1 سطح محافظت $3 را {{GENDER:$2|تغییر داد}} $4",
+       "logentry-protect-modify-cascade": "$1 سطح حفاظت برای $3 $4 را {{GENDER:$2|تغییر داد}}[آبشاری]",
+       "logentry-rights-rights": "$1 عضویت $3 را از گروه $4 به $5 {{GENDER:$2|تغییر داد}}",
+       "logentry-rights-rights-legacy": "$1 گروه عضویت $3 را {{GENDER:$2|تغییر داد}}",
+       "logentry-rights-autopromote": "$1 به طور خودکار از $4 به $5 {{GENDER:$2|ارتقاء داد}}",
+       "logentry-upload-upload": "$1 $3 را {{GENDER:$2|بارگذاری کرد}}",
+       "logentry-upload-overwrite": "$1 نسخهٔ تازه‌ای از $3 را {{GENDER:$2|بارگذاری کرد}}",
+       "logentry-upload-revert": "$1 {{GENDER:$2|بارگذاری کرد}} $3",
+       "log-name-managetags": "تاریخچه مدیریت تگ",
+       "log-description-managetags": "این وةڵگة امور مدیریتی مربوط به [[Special:Tags|برچسب‌ها]] را فهرست می‌کند. سیاهه فقط حاوی فعالیت‌هایی است که توسط یک مدیر به صورت دستی انجام شده‌اند؛ برچسب‌ها ممکن است توسط نرم‌افزار ویکی ساخته یا حذف بشوند بدون اینکه هیچ ورودی در این سیاهه ثبت گردد.",
+       "logentry-managetags-create": "$1 برچسب «$4» را {{GENDER:$2|ایجاد کرد}}",
+       "logentry-managetags-delete": "$1 برچسب را از \"$4\" {{GENDER:$2|حذف کرد}} (حذف شده از $5 {{PLURAL:$5|نسخه یا ورودی سیاهه|نسخه یا/و ورودی سیاهه}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|برچسب}} فعال شده \"$4\" برای کاربران و ربات‌ها",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|برچسب}} غیرفعال شده \"$4\" برای کاربران و ربات‌ها",
+       "log-name-tag": "سیاهه برچسب",
+       "log-description-tag": "این وةڵگة  زمانی که کاربران [[Special:Tags|برچسب]] یک نسخه یا سیاهه ورودی را افزوده‌اند یا حذف‌کرده‌اند. سیاههٔ کار بر روی برچسب‌ها زمانی که بخشی از ویرایش یا حذف یا فعالیت‌های مشابه هستند، فهرست نمی‌شود.",
+       "logentry-tag-update-add-revision": "$1 {{PLURAL:$7|برچسب|برچسب ها}} $6 به نسخهٔ $4 از صفحهٔ $3 {{GENDER:$2|افزود}}",
+       "logentry-tag-update-add-logentry": "$1 {{PLURAL:$7|برچسب|برچسب ها}} $6 به سیاههٔ $5 صفحهٔ $3 {{GENDER:$2|افزود}}",
+       "logentry-tag-update-remove-revision": "$1 {{PLURAL:$9|برچسب|برچسب ها}} $8 را از نسخهٔ $4 صفحهٔ $3 {{GENDER:$2|حذف کرد}}",
+       "logentry-tag-update-remove-logentry": "$1 {{PLURAL:$9|برچسب|برچسب ها}} $8 را از سیاههٔ $5 صفحهٔ $3 {{GENDER:$2|حذف کرد}}",
+       "logentry-tag-update-revision": "$1 برچسب نسخهٔ $4 صفحهٔ $3 را {{GENDER:$2|به‌روز کرد}} ($6 {{PLURAL:$7|افزوده‌شد}}؛ $8 {{PLURAL:$9|حذف شد}})",
+       "logentry-tag-update-logentry": "$1 برچسب سیاههٔ $5 صفحهٔ $3 را {{GENDER:$2|به‌روز کرد}} ($6 {{PLURAL:$7|افزوده‌شد}}؛ $8 {{PLURAL:$9|حذف شد}})",
+       "rightsnone": "(هؤیچ کام)",
+       "revdelete-summary": "خلاصة دةسکاری",
+       "feedback-adding": "افزودن بازخورد به وةڵگة ...",
+       "feedback-back": "گِل آوردن/برگشت",
+       "feedback-bugcheck": "عالی‌است! فقط بررسی کنید که از [$1 ایرادهای شناخته‌شده] نباشد.",
+       "feedback-bugnew": "بررسی کردم. ایرادی تازه را گزارش بده",
+       "feedback-bugornote": "اگر آماده‌اید تا مشکلی فنی را با جزئیاتش شرح دهید لطفاً [$1 یک ایراد گزارش دهید]. در غیر این صورت می‌توانید از فرم سادهٔ زیر استفاده کنید. نظر شما به همراه نام کاربری و مرورگرتان به صفحهٔ «[$3 $2]» افزوده خواهد شد.",
+       "feedback-cancel": "ئآهووسانن/لغو",
+       "feedback-close": "انجؤم بی",
+       "feedback-external-bug-report-button": "پرونده‌سازی یک عمل فنی",
+       "feedback-dialog-title": "ارسال یک بازخورد",
+       "feedback-dialog-intro": "شما می توانید از فرم زیر برای بازخورد استفاده کنید. متن شما همراه با نام کاربریتان به وةڵگة \"$1\" افزوده خواهد شد.",
+       "feedback-error-title": "خطا",
+       "feedback-error1": "خطا: پاسخ‌های ناشناخته از رابط برنامه‌نویسی نرم‌افزار",
+       "feedback-error2": "خطا: شکست در ویرایش",
+       "feedback-error3": "خطا: عدم پاسخ از رابط برنامه‌نویسی نرم‌افزار",
+       "feedback-error4": "خطا:امکان ارسال به عنوان بازخورد داده‌شده، نیست",
+       "feedback-message": ":پیغام",
+       "feedback-subject": "عنوان:",
+       "feedback-submit": "ارسال/کِل کردن",
+       "feedback-terms": "من اطلاع دارم که اطلاعات یوز ایجنتم دربارهٔ مرورگر و نسخهٔ سیستم عاملی که استفاده می‌کنم، به صورت عمومی همراه با نام کاربریم به اشتراک گذاشته می‌شود.",
+       "feedback-termsofuse": "موافق با قرار دادن بازخورد بر پایهٔ شرایط استفاده هستم.",
+       "feedback-thanks": "سپاس! بازخورد شما در وةڵگة «[$1 $2]» ثبت شد.",
+       "feedback-thanks-title": "سپاس إژ هؤمة!",
+       "feedback-useragent": "رابط کاربر:",
+       "searchsuggest-search": "گئردین/مهِ نی",
+       "searchsuggest-containing": "وةڵگةل  دربردارنده...",
+       "api-error-badaccess-groups": "شما اجازهٔ بارگذاری پرونده‌ها را در این ویکی ندارید.",
+       "api-error-badtoken": "خطای داخلی: کد امنیتی اشتباه (Bad token).",
+       "api-error-copyuploaddisabled": "بارگذاری با استفاده از نشانی اینترنتی در این کارساز غیرفعال است.",
+       "api-error-duplicate": "{{PLURAL:$1|پروندهٔ دیگری|چند پروندهٔ دیگر}} در تارنما با محتوای یکسان وجود داشت.",
+       "api-error-duplicate-archive": "{{PLURAL:$1| پروندهٔ دیگری|چند پروندهٔ دیگر}} در تارنما با محتوای یکسان وجود داشت، ولی حذف {{PLURAL:$1|شده است|شده‌اند}}.",
+       "api-error-empty-file": "پرونده‌ای که شما ارسال کردید خالی بود.",
+       "api-error-emptypage": "ایجاد وةڵگةل خالی مجاز نیست.",
+       "api-error-fetchfileerror": "خطای داخلی: در هنگام گرفتن پرونده، یک چیزی درست پیش نرفت.",
+       "api-error-fileexists-forbidden": "یک پرونده با نام \"$1\" موجود است و امکان بازنویسی نیست.",
+       "api-error-fileexists-shared-forbidden": "یک پرونده با نام \"$1\" در انبار اشتراک پرونده موجود است و امکان بازنویسی نیست.",
+       "api-error-file-too-large": "پرونده‌ای که شما ارسال کردید بیش از اندازه بزرگ بود.",
+       "api-error-filename-tooshort": "نام پرونده بیش از اندازه کوتاه است.",
+       "api-error-filetype-banned": "این نوع پرونده ممنوع است.",
+       "api-error-filetype-banned-type": "&lrm;$1 {{PLURAL:$4|یک نوع پروندهٔ نامجاز است|انواع پروندهٔ نامجاز هستند}}. {{PLURAL:$3|نوع پروندهٔ مجاز|انواع پروندهٔ مجاز}} از این قرار است: $2.",
+       "api-error-filetype-missing": "پرونده فرمت ندارد.",
+       "api-error-hookaborted": "اصلاحیه‌ای که شما سعی در ایجاد آن بودید توسط افزونه‌ای به دام افتاد.",
+       "api-error-http": "خطای داخلی: قادر به اتصال به سرور نیست.",
+       "api-error-illegal-filename": "نام پرونده مجاز نیست.",
+       "api-error-internal-error": "خطای داخلی: با پردازش بارگذاری شما در ویکی، یک چیز اشتباه پیش رفت.",
+       "api-error-invalid-file-key": "خطای داخلی: پرونده در حافظهٔ موقت موجود نیست.",
+       "api-error-missingparam": "خطای داخلی: پارامترهای ناموجود در درخواست.",
+       "api-error-missingresult": "خطای داخلی: نمی‌توان فهمید کپی‌برداری موفق بوده‌است یا نه.",
+       "api-error-mustbeloggedin": "برای بارگذاری پرونده‌ها شما باید به سامانه وارد شوید.",
+       "api-error-mustbeposted": "خطای داخلی: درخواست باید از روش POST HTTP ارسال گردد.",
+       "api-error-noimageinfo": "بارگذاری موفق بود، ولی کارساز هیچ اطلاعاتی دربارهٔ پرونده به ما نداد.",
+       "api-error-nomodule": "خطای داخلی: پودمان بارگذاری تنظیم نشده‌است.",
+       "api-error-ok-but-empty": "خطای داخلی : پاسخی از سرور دریافت نشد.",
+       "api-error-overwrite": "جای نوشتن یک پرونده موجود مجاز نیست.",
+       "api-error-stashfailed": "خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.",
+       "api-error-publishfailed": "خطای داخلی: کارساز نمی‌تواند پرونده موقت را ذخیره کند.",
+       "api-error-stasherror": "هنگام انتقال پوشه برای ذخیره خطایی بود.",
+       "api-error-stashedfilenotfound": "زمانی که تلاش برای بارگذاری فایل استش بود، فایل استش یافت نشد.",
+       "api-error-stashpathinvalid": "مسیری که فایل استش در آن باید یافت می‌شد اشتباه است.",
+       "api-error-stashfilestorage": "برای ذخیرهٔ فایل استش خطایی رخ داده است.",
+       "api-error-stashzerolength": "سرور نمی‌تواند فایل استش را ذخیره کند چون حجم آن صفر است.",
+       "api-error-stashnotloggedin": "برای ذخیرهٔ فایل‌ها در بارگذاری استش باید وارد سامانه شده‌باشید.",
+       "api-error-stashwrongowner": "فایلی که در استش قصد داشتید به آن دسترسی داشته‌باشید متعلق به شما نیست.",
+       "api-error-stashnosuchfilekey": "کلیدی که در فایل استش می خواستید به آن دسترسی داشته‌باشید، وجود ندارد.",
+       "api-error-timeout": "کارساز در زمان انتظار هیچ پاسخی نداد.",
+       "api-error-unclassified": "یإگِلة خطا نادیاری/ناشناخته رخ داد.",
+       "api-error-unknown-code": "خطای نادیاری/ناشناخته: \" $1 \"",
+       "api-error-unknown-error": "خطای داخلی: در زمانی که شما در حال تلاش برای بارگذاری پروندهٔ‌تان بودید، یک چیز اشتباه پیش رفت.",
+       "api-error-unknown-warning": "هشدار نادیاری/ ناشناخته: $1",
+       "api-error-unknownerror": "خطای نادیاری/ناشناخته: \" $1 \"",
+       "api-error-uploaddisabled": "بارگذاری در این ویکی غیرفعال است.",
+       "api-error-verification-error": "ممکن است پرونده آسیب دیده باشد، یا دارای پسوند نادرست باشد.",
+       "duration-seconds": "$1 {{PLURAL:$1|ثانیه|ثانیه ها}} قبل",
+       "duration-minutes": "$1 {{PLURAL:$1|دیقه|دیقةلئ}} دماتر",
+       "duration-hours": "$1 {{PLURAL:$1|ساعت |ساعتةلئ}} دماتر",
+       "duration-days": "$1{{PLURAL:$1|رووژ|رووژةل}}",
+       "duration-weeks": "$1 {{PLURAL:$1|هفته|هفته ها}}",
+       "duration-years": "$1{{PLURAL:$1| سال|سال ها}}",
+       "duration-decades": "$1 {{PLURAL:$1|دھە|دھە ها}}",
+       "duration-centuries": "$1 {{PLURAL:$1|سده|سده ها}}",
+       "duration-millennia": "{{PLURAL:$1|هزار سال |$1 هزار سال}}",
+       "rotate-comment": "تصویر به دست $1 {{PLURAL:$1|درجهٔ|درجات}} ساعت‌گرد چرخانده شد",
+       "limitreport-title": "داده‌های رخ‌نمانگاری تجزیه‌کننده:",
+       "limitreport-cputime": "زمان مصرفی سی‌پی‌یو",
+       "limitreport-cputime-value": "$1 {{PLURAL:$1|ثانیه|ثانیه ها}}",
+       "limitreport-walltime": "زمان مصرفی واقعی",
+       "limitreport-walltime-value": "$1 {{PLURAL:$1|ثانیه|ثانیه ها}}",
+       "limitreport-ppvisitednodes": "شمارندهٔ گره بازدیدشدهٔ پیش‌پردازنده",
+       "limitreport-ppgeneratednodes": "شمارندهٔ گره تولیدی پیش‌پردازنده",
+       "limitreport-postexpandincludesize": "اندازهٔ دربرگیرنده پس از گسترش",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|بایت ها|بایت}}",
+       "limitreport-templateargumentsize": "اندازه آرگومان الگو",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بایت ها|بایت}}",
+       "limitreport-expansiondepth": "بیشترین عمق گسترش",
+       "limitreport-expensivefunctioncount": "تعداد تابع تجزیه‌گر پرمصرف",
+       "expandtemplates": "بسط‌دادن الگوها",
+       "expand_templates_intro": "این صفحهٔ ویژه متنی را دریافت کرده و تمام الگوهای به‌کاررفته در آن را به طور بازگشتی بسط می‌دهد. همچنین تابع‌های تجزیه چون <code><nowiki>{{</nowiki>#language:…}}</code> و متغیرهایی چون  <code><nowiki>{{</nowiki>CURRENTDAY}}</code> را هم بسط می‌دهد — در واقع تقریباً هرچه را که داخل دوآکولاد باشد. این کار با صدازدن مرحلهٔ تجزیهٔ مربوط در خود مدیاویکی صورت می‌گیرد.",
+       "expand_templates_title": "عنوان موضوع، برای {{FULLPAGENAME}} و غیره:",
+       "expand_templates_input": "متن ورودی:",
+       "expand_templates_output": "نتیجه",
+       "expand_templates_xml_output": "خروجی XML",
+       "expand_templates_html_output": "خروجی اچ‌تی‌ام‌ال خام",
+       "expand_templates_ok": "خوو/ باشد",
+       "expand_templates_remove_comments": "پاک کردن گةپةل/قِسةل",
+       "expand_templates_remove_nowiki": "خنثی کردن تگ‌های <nowiki> در نتیجه",
+       "expand_templates_generate_xml": "نمایش درخت تجزیهٔ XML",
+       "expand_templates_generate_rawhtml": "نمایش اچ‌تی‌ام‌ال خام",
+       "expand_templates_preview": "پیش‌نمایش",
+       "expand_templates_preview_fail_html": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروع است، لطفا دوباره سعی کنید. اگر هنوز کار نمی کند، سعی کنید [[Special:UserLogout|خروج از سیستم]] را کلیک نموده و دوباره وارد شوید.",
+       "expand_templates_preview_fail_html_anon": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروح است ، لطفا دوباره سعی کنید اگر هنوز کار میکند،سعی کنید  Following link is missing: [[Special:UserLogin|ورود|خروج]]را کلیک کنید و دوباره وارد شوید",
+       "pagelanguage": "وةڵگة انتخاب زوون",
+       "pagelang-name": "وةڵگة",
+       "pagelang-language": "زوون",
+       "pagelang-use-default": "استفاده إژ زوون پئش فرض",
+       "pagelang-select-lang": "زوون انتخاب کۀ",
+       "right-pagelang": "تغییر وةڵگة زوون",
+       "action-pagelang": "تغییر زوون وةڵگة",
+       "log-name-pagelang": "تغییر سیاههٔ زبان",
+       "log-description-pagelang": "ای پهرستنومه در بلگه زونا آلشت گرته.",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2| تغییریافت}} زبان صفحه برای  $3  از  $4  به  $5 .",
+       "default-skin-not-found": "Whoops! The default skin for your wiki, defined in <code dir=\"ltr\">$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYour installation seems to include the following {{PLURAL:$4|skin|skins}}. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable {{PLURAL:$4|it|them and choose the default}}.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Using Git to download skins].\n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n; If you have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following {{PLURAL:$5|line|lines}} into <code>LocalSettings.php</code> to enable {{PLURAL:$5|the|all}} installed {{PLURAL:$5|skin|skins}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>:\n: Double-check the skin names for typos.",
+       "default-skin-not-found-no-skins": "پوستهٔ پیش‌فرض برای ویکی شما تعریف‌شده در<code>$wgDefaultSkin</code> به عنوان <code>$1</code>، هست موجود نیست.\n\nشما پوسته‌ها را نصب نکرده‌اید.\n\n:اگر مدیاویکی را به‌روز یا نصب کرده‌اید:\n:ممکن است از گیت یا از کد منبع با روش‌های دیگر نصب کرده‌اید. انتظار می‌رود MediaWiki 1.24 یا جدیدتر در پوشهٔ اصلی هیچ پوسته‌ای نداشته باشند.\nسعی کنید تعدادی پوسته از [https://www.mediawiki.org/wiki/Category:All_skins پوشهٔ پوسته‌های مدیاویکی]، با:\n:*دریافت [https://www.mediawiki.org/wiki/Download نصب‌کننده تاربال]، که با چندین پوسته و افزونه هست. شما می توانید پوستهٔ <code>skins/</code> را از آن کپی و پیست کنید.\n:*کلون کردن یکی از <code dir=\"ltr\">mediawiki/skins/*</code> از مخزن در پوشهٔ <code>skins/</code> مدیاویکی‌تان.\n:اگر توسعه‌دهندهٔ مدیاویکی هستید، انجام این کار نباید تعارضی با مخزن گیت شما داشته باشد. برای اطلاعات بیشتر و فعال کردن پوسته‌ها و انتخاب آنها به عنوان پیش‌فرض [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: تنظیمات پوسته] را مشاهده کنید.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (فعال)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''غیر فعال''')",
+       "mediastatistics": "آمار رسانه‌ها",
+       "mediastatistics-summary": "آمارها دربارهٔ نوع‌های پرونده‌ای به روزشده. این فقط شامل آخرین نسخهٔ پرونده است. نسخه‌های قدیمی یا حذف‌شده مسثنی هستند.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 بایت}} ($2؛ $3٪)",
+       "mediastatistics-table-mimetype": "نوع mime",
+       "mediastatistics-table-extensions": "افزونه‌های محتمل",
+       "mediastatistics-table-count": "تعداد پرونده‌ها",
+       "mediastatistics-table-totalbytes": "حجم ترکیبی",
+       "mediastatistics-header-unknown": "ناشنا/نادیار",
+       "mediastatistics-header-bitmap": "تصاویر بیت‌مپ",
+       "mediastatistics-header-drawing": "طراحی‌ها (تصاویر برداری)",
+       "mediastatistics-header-audio": "دةنگ/صدا",
+       "mediastatistics-header-video": "ویدیوةل",
+       "mediastatistics-header-multimedia": "رسانه‌های غنی",
+       "mediastatistics-header-office": "دفتر",
+       "mediastatistics-header-text": "متنی",
+       "mediastatistics-header-executable": "اجرایی",
+       "mediastatistics-header-archive": "قالب‌های فشرده",
+       "json-warn-trailing-comma": "$1 کامای در انتها از جی‌سن {{PLURAL:$1|حذف شد}}.",
+       "json-error-unknown": "مشکلی با جی‌سن بود. خطا: $1",
+       "json-error-depth": "بیشینهٔ عمق پشته رد شده است",
+       "json-error-state-mismatch": "جی‌سن نادرست یا نافض",
+       "json-error-ctrl-char": "خطای نویسهٔ کنترلی، احتمالاً به نادرستی کدگذاری شده است",
+       "json-error-syntax": "خطای نحوی",
+       "json-error-utf8": "نویسه‌های نادرست یوتی‌اف-۸، احتمالاً نادرست کدگذاری شده است",
+       "json-error-recursion": "ارجاع بازگشتی یک یا بیشتر در مقداری که کذگذاری می‌شود",
+       "json-error-inf-or-nan": "مقادیر INF یا NAN یک یا بیشتر در مقداری که کدگذاری می‌شود",
+       "json-error-unsupported-type": "یک مقداری نوعی که نمی‌تواند کدگذاری شود داده شده است",
+       "headline-anchor-title": "پیوند به این بخش",
+       "special-characters-group-latin": "لاتین",
+       "special-characters-group-latinextended": "لاتین گسترش‌یافته",
+       "special-characters-group-ipa": "آوانگاری بین‌المللی",
+       "special-characters-group-symbols": "نیشانةل",
+       "special-characters-group-greek": "یونانی",
+       "special-characters-group-cyrillic": "سیریلیک",
+       "special-characters-group-arabic": "عِرةؤی/عربی",
+       "special-characters-group-arabicextended": "عربی گسترش‌یافته",
+       "special-characters-group-persian": "فارسی",
+       "special-characters-group-hebrew": "عبری",
+       "special-characters-group-bangla": "بنگالی",
+       "special-characters-group-tamil": "تامیلی",
+       "special-characters-group-telugu": "تالوگو",
+       "special-characters-group-sinhala": "سینهالی",
+       "special-characters-group-gujarati": "گجراتی",
+       "special-characters-group-devanagari": "دیواناگرى",
+       "special-characters-group-thai": "تایلندی",
+       "special-characters-group-lao": "لائو",
+       "special-characters-group-khmer": "خمر",
+       "special-characters-title-endash": "خط فاصله/کِڕ نام تاق",
+       "special-characters-title-emdash": "خط فاصله کشیده",
+       "special-characters-title-minus": "علامت منفی",
+       "mw-widgets-dateinput-no-date": "هیچ داده‌ای انتخاب نشده",
+       "mw-widgets-titleinput-description-new-page": "ئئ وةڵگة هنوز/حالی وجود نِئرێ",
+       "mw-widgets-titleinput-description-redirect": "تغییر مسیر به $1",
+       "api-error-blacklisted": "لطفاً یک عنوان توصیفی متفاوت انتخاب کنید."
+}
index fe0777e..3c51189 100644 (file)
        "movelogpage": "Register di San Martin",
        "movereason": "Mutìf:",
        "revertmove": "Riprìstina 'mè che l'era",
-       "delete_and_move": "Scancèla e möf",
        "delete_and_move_confirm": "Sé, surascrìf la pàgina che gh'è zà",
        "export": "Espurtá pagin",
        "allmessages": "Tücc i messacc dal sistéma",
index 810d2c3..10c2b71 100644 (file)
        "passwordreset-emailtext-ip": "یە کئسی(گاسی خوتوٙ، ڤا تیرنئشوٙن آی پی $1) د نۊ زئنە کئردئن رازینە گوڤاردئنئتوٙ د {{SITENAME}} حاستیتە($4).\nسی کاریار «$2» یئ گئل رازینە گوڤاردئن موڤأقتی رأڤأندیاری بییە و هومبأراڤأر «$3» ە.\nأر دالئتوٙ یە بییە ئیسئ ڤاس بیائیت ڤامین ساموٙنە و یئ گئل رازینە گوڤاردئن هأنی بئهایت.\n رازینە گوڤاردئن {{PLURAL:$3|ئی رازینە یا گوڤاردئن موڤأقأتی|ئی رازینە یا گوڤاردئن موڤأقأتی}} شوما د گات {{PLURAL:$5|یئ روٙ|$5 روٙ}} باطئل بوٙە.\n\nأر کأسی هأنی چئن حاستی داشتە یا یە کئ رازینە گوڤاردئن دئمایی شوما د ڤیرئتوٙ ئوٙما و دە نئمیهایت ڤئنە آلئشت کاری بأکیت، می توٙنیت د ئی پئیغوم تیە پوٙشی بأکیت و هأموٙ رازینە گوڤاردئن دئمایی نە بونیت د کار.",
        "passwordreset-emailtext-user": "کاریار $1 د {{SITENAME}} د نۊ زئنە کئردئن رازینە گوڤاردئن شومانە د{{SITENAME}} ($4) حاستە. {{PLURAL:$3|حئساڤ|حئساڤیا}} کاریاری کئ هان د هار و ڤا ئی تیرنئشوٙن أنجومانامە هان د ئرتئڤاط:\n\n$2\n\n رازینە گوڤاردئن {{PLURAL:$3|ئی رازینە یا گوڤاردئن موڤأقأتی|ئی رازینە یا گوڤاردئن موڤأقأتی}} شوما د گات {{PLURAL:$5|یئ روٙ|$5 روٙ}} باطئل بوٙە.\nأر کأسی هأنی چئن حاستی داشتە یا یە کئ رازینە گوڤاردئن دئمایی شوما د ڤیرئتوٙ ئوٙما و دە نئمیهایت ڤئنە آلئشت کاری بأکیت، می توٙنیت د ئی پئیغوم تیە پوٙشی بأکیت و هأموٙ رازینە گوڤاردئن دئمایی نە بونیت د کار.",
        "passwordreset-emailelement": "نوم کاریاری: \n$1\n\nرازینە گوڤاردئن موڤأقتی: \n$2",
-       "passwordreset-emailsent": "یئ گئل رازینە گوڤاردئن هأنی سی أنجومانامە کئل بییە.",
+       "passwordreset-emailsentemail": "یئ گئل رازینە گوڤاردئن هأنی سی أنجومانامە کئل بییە.",
        "passwordreset-emailsent-capture": "رازینە گوڤاردئن تازە توٙ سی أنجومانامە توٙ کئ ها د هار کئل بییە.",
        "passwordreset-emailerror-capture": "رازینە گوڤاردئن د أنجومانامە د نۊ زئنە کون کئل بییە،و ڤئ د هار دیاری میکە، ڤألی کئل بییئن ڤئ سی {{GENDER:$2|کاریار}} ناخوش سأرنجوم بییە:$1",
        "changeemail": "أنجومانامە توٙنە آلئشت کاری بأکیت",
        "permissionserrors": "خأطا صئلا دأئن",
        "permissionserrorstext": "شوما حأق ناریت ڤئنە أنجوم بئیت، سی{{PLURAL:$1|دألیل|دألیلیا}} نئھایی:",
        "permissionserrorstext-withaction": "شوما سی $2 صئلا \nنئھاگئری ناریت {{PLURAL:$1|دألیل|دألیلیا}}:",
-       "recreate-moveddeleted-warn": "'''زÙ\86Ù\87ار Ø´Ù\85ا Ø¨Ù\84Ú¯Ù\87 Ø§Û\8c Ú©Ù\87 Ù\88ادÙ\85ا Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÙ\87 Ù\87Ù\86Û\8c Ø±Ø§Ø³ Ú©Ø±Ø¯Û\8cتÙ\87'''\nØ´Ù\85ا Ø¨Ø§Û\8cد Ø¯Ù\88Ù\86سÙ\87 Ø¨Ø§Û\8cت Ú©Ù\87 Ø¢Û\8cا Ù\87Ù\86Û\8c Ø³Û\8c Ù\86Ù\87ا Ú¯Ø±ØªÙ\86 Ù\88Û\8cراÛ\8cشت Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ø®Ù\88ئÙ\87.\nپاکسا Ø¨Û\8cئÙ\86 Ù\88 Ø¬Ù\85شت Ø³Û\8c Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ø³Û\8c Ù\81راغتتÙ\88 Ø¢Ù\85ادÙ\87 Ø¨Û\8cÙ\87:",
-       "moveddeleted-notice": "اÛ\8c Ø¨Ù\84Ú¯Ù\87 Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÙ\87.\nپاکسا Ø¨Û\8cÙ\86 Ù\88 Ø¬Ù\85شت Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ø³Û\8c Ø³Ø±Ú\86Ø´Ù\85Ù\87 Ø¯Ø¦Û\8cÙ\86 Ø¢Ù\85ادÙ\87 Ø¨Û\8cÙ\87",
+       "recreate-moveddeleted-warn": "'''د Ú¤Û\8cرئتÙ\88Ù\99 Ø¨Ø§:Ø´Ù\88Ù\85ا Ø¨Ø£Ù\84Ú¯Û\95 Û\8cÛ\8c Ú©Ø¦ Ú¾Ø§ Ú¤Ø§Ø¯Ø¦Ù\85ا Ù\88 Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÛ\8cÛ\95 Ø¯ Ù\86Û\8a Ø±Ø§Ø³ Ú©Ø¦Ø±Ø¯Û\8cتÛ\95.'''\nباÛ\8cأد Ø¯ Ú¤Û\8cرئتÙ\88Ù\99 Ø¨Ø§ Ú©Ø¦ Ø¢Û\8cا Ú¾Ø£Ù\86Û\8c Ù\86ئھاگئرÛ\8c Ú¤Û\8cراÛ\8cئشت Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ø®Ù\88Ù\99Ø£.\nپاکسا Ú©Ø§Ø±Û\8c Ù\88 Ø¬Ø§ Ú¤Ø¦ Ø¬Ø§ Ú©Ø§Ø±Û\8c Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ø³Û\8c Ø­Ø§Ù\84 Ù\88 Ø¨Ø§Ù\84 Ø¢Ø³Ø§Û\8cئشت Ø´Ù\88Ù\85ا Ø¢Ù\85ادÛ\95 Ø¨Û\8cÛ\8cÛ\95:",
+       "moveddeleted-notice": "ئÛ\8c Ø¨Ø£Ù\84Ú¯Û\95 Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÛ\8cÛ\95.\nپاکسا Ú©Ø§Ø±Û\8c Ù\88 Ø¬Ø§ Ú¤Ø¦ Ø¬Ø§ Ú©Ø§Ø±Û\8c Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ø³Û\8c Ø­Ø§Ù\84 Ù\88 Ø¨Ø§Ù\84 Ø¢Ø³Ø§Û\8cئشت Ø´Ù\88Ù\85ا Ø¢Ù\85ادÛ\95 Ø¨Û\8cÛ\8cÛ\95.",
        "log-fulllog": "دیئن هأمە پئهئرستنوٙمە یا",
        "edit-hook-aborted": "ڤیرایئشت ڤا قولاڤ نئھاگئری بییە.\nھیچ توضیی سیش نی.",
-       "edit-gone-missing": "Ù\86بÙ\88ئÙ\87 Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ù\86Ù\87 Ù\88Ù\87 Ù\87Ù\86Ú¯Ù\88Ù\85 Ø¨Ú©Û\8cت.\nÙ\88Ù\87 Ù\86ظر Ù\85Û\8cا Ú©Ù\87 Ù\88Ù\87 Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÙ\87.",
+       "edit-gone-missing": "Ù\86أبÙ\88Ù\99Û\95 Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ù\86Û\95 Ú¤Ø¦ Ú¾Ø¦Ù\86Ú¯Ù\88Ù\85 Ø¨Ø£Ú©Û\8cت.\nÚ\86ئÙ\86Û\8c Ú¤Ø¦ Ù\86أظأر Ù\85Û\8cا Ú©Ø¦ Ú¤Ø¦ Ù¾Ø§Ú©Ø³Ø§ Ø¨Û\8cÛ\8cÛ\95.",
        "edit-conflict": "ری ڤئ ری کاری د ڤیرایئشت.",
-       "edit-no-change": "سی یه که آلشتیا د یه گل نیسسه دروس بیه د ویرایشت شما تیه پوشی بیه.",
+       "edit-no-change": "سی یە کئ ھیچ آلئشتکاری د نیسئسە أنجوم نأگئرئتە د ڤیرایئشتکای شوم تیە پوٙشی بییە.",
        "postedit-confirmation-created": "بألگە دوروس بییە.",
        "postedit-confirmation-restored": "بألگە د نۊ ئمایە بییە.",
        "postedit-confirmation-saved": "ڤیرایئشتئتوٙ ئمایە بی.",
-       "edit-already-exists": "Ù\86بÙ\88ئÙ\87 Û\8cÙ\87 Ú¯Ù\84 Ø¨Ù\84Ú¯Ù\87 ØªØ§Ø²Ù\87 Ø±Ø§Ø³ Ø¨Ú©Û\8cد.\nÙ\88Ù\87 Ù\87ئیش.",
-       "defaultmessagetext": "Ù\86Û\8cسسÙ\87 Ù¾Û\8cغÙ\88Ù\85 Ù¾Û\8cØ´ Ù\81رض",
-       "content-failed-to-parse": "د یک تیچیسن چیا مئن $2 د مدل $1:$3",
+       "edit-already-exists": "Ù\86أبÙ\88Ù\99Û\95 Û\8cئ Ú¯Ø¦Ù\84 Ø¨Ø£Ù\84Ú¯Û\95 ØªØ§Ø²Û\95 Ø¨Ø£Ú©Û\8cت .\nڤئ Ú¾یش.",
+       "defaultmessagetext": "Ù\86Û\8cسئسÛ\95 Ù¾Ø¦Û\8cغÙ\88Ù\85 Ù¾Û\8cØ´ Ù\81Ø£رض",
+       "content-failed-to-parse": "د یأک تیچئسئن چیا مین $2 د مودئل $1:$3",
        "invalid-content-data": "دونئسمأنی مینوٙنە نادیار",
-       "content-not-allowed-here": " Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87\"$1\" Ø³Û\8c Ø¨Ù\84Ú¯Ù\87 [[$2]] ØµÙ\84ا Ù\86Ù\87 Ø¯Ø¦Ù\87 Ø¨Û\8cÙ\87",
-       "editwarning-warning": "ار Ø§Û\8c Ø¨Ù\84Ú¯Ù\87 Ù\86Ù\87 Ù\88Ù\84 Ø¨Ú©Û\8cت Ù\87ر Ø¢Ù\84شتÛ\8c Ú©Ù\87 Ø¯Ø¦Û\8cتÙ\87 Ù¾Ø§Ú© Ø¨Ù\88ئÙ\87.\nار Ø´Ù\85ا Ù\87اÛ\8cÛ\8cت Ù\88ا Ù\85Û\8cÙ\86Ø\8cØ´Ù\85ا Ù\85Û\8c ØªÙ\88Ù\86Û\8cت Ø§Û\8c Ø²Ø¦Ù\86ار Ù\86Ù\87 Ø¯ \"{{int:prefs-editing}}\" Ú©Ù\87 Ù\87ا Ø¯ Ø¨Ø®Ø´ Ø§Ù\88Ù\84Ù\88Û\8cتÛ\8cا Ø´Ù\85ا Ù\86اکشتگر Ø¨کیت.",
-       "editpage-notsupportedcontentformat-title": "شلک مینونه دماگری نبیه",
-       "editpage-notsupportedcontentformat-text": "وضع و بار مینونه $1 د مدل مینونه $2 حامین نبوئه.",
+       "content-not-allowed-here": " Ù\85Û\8cÙ\86Ù\88Ù\99Ù\86Û\95 \"$1\" Ø³Û\8c Ø¨Ø£Ù\84Ú¯Û\95 [[$2]] ØµØ¦Ù\84ا Ø¯Ø£ Ù\86أبÛ\8cÛ\95",
+       "editwarning-warning": "أر Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ù\86ئ Ú¤Ø¦Ù\84 Ø¨Ø£Ú©Û\8cت Ú¾Ø£Ø± Ø¢Ù\84ئشتÛ\8c Ú©Ø¦ Ø£Ù\86جÙ\88Ù\85 Ø¯Ø£Ø¦Û\8cتÛ\95 Ù¾Ø§Ú© Ø¨Ù\88Ù\99Û\95.\nأر Ø´Ù\88Ù\85ا Ú¾Ø§Ø¦Û\8cت Ú¤Ø§Ù\85Û\8cÙ\86Ø\8c Ø´Ù\88Ù\85ا Ù\85Û\8c ØªÙ\88Ù\99Ù\86Û\8cت Ø¨ Ø²Ø¦Ù\86ار Ù\86Û\95 Ø¯ \"{{int:prefs-editing}}\" Ú©Ø¦ Ú¾Ø§ Ø¯ Ø¨Ø£Ø±Ø¬Ø§ Ú\86Û\8cا Ù\86ازار Ø´Ù\88Ù\85ا Ù\86اکÙ\88Ù\86ئشتگأر Ø¨Ø£کیت.",
+       "editpage-notsupportedcontentformat-title": "شئکل مینوٙنە حامینداری نأبییە",
+       "editpage-notsupportedcontentformat-text": "حال و بال مینوٙنە $1 د مودئل مینوٙنە $2 حامینداری نأبوٙە.",
        "content-model-wikitext": "ڤیکی نیسئسە",
        "content-model-text": "نیسئسە سادە",
        "content-model-javascript": "جاڤا ئسکئریپت",
        "mergehistory": "ویرگاریا بلگه نه یکی بکید",
        "mergehistory-header": "ای بلگه وه شما اجازه می ئه که وانیریانه ویرگار سرچشمه بلگه نه د یه گل بلگه تازه سریک سازی بکید.\nمطمئن بویت که ای آلشت د لحاظ ویرگاری د مین بلگه موندگاره.",
        "mergehistory-box": "دوواره دیئن دوبلگه ای نه سر یک سازی کو:",
-       "mergehistory-from": "بلگه سرچشمه:",
+       "mergehistory-from": "بألگە سأرچئشمە:",
        "mergehistory-into": "بلگه مقصد:",
        "mergehistory-list": "ویرگار ویرایشت سر یک سازی بیئنی",
        "mergehistory-merge": "نسقه یا هاری که د [[:$1]] وه یک شیوسنی وا[[:$2]] هئن.\nستین دگمه یا رادیویی نه به کار به ونیت سی یه که نسقه یایی نه که د گاتی دماتر دروس بینه انتخاو بکیت.\nد ویرتو با که پورسن ری پیوندیا باعث بوئه که ستین وه شکل اولیه خوش ؤرئرده.",
        "prefs-help-prefershttps": "کارگرایی ای ترجیح نها وامین اومائن نهایی شما وه کار گرته بوئه.",
        "prefswarning-warning": "آلشتیا شما ری ترجیحاتتو هنی اماییه نبیه.\nار ای بلگه نه بی یه که ری \"$1\" بپورنیت ول بکیت ترجیحیا شما اماییه نبوئن.",
        "prefs-tabs-navigation-hint": "نکته: شما می تونید د کلیتیا لادیار کن چپ و راست نه سی رئتن مین تبیا که هان د نوم گه تبیا وه کار بونیت.",
-       "email-address-validity-valid": "تÛ\8cرÙ\86Ø´Ù\88Ù\86 Ø§Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù\87 Ø¯Û\8cار Ø¨Û\8cÙ\87 Ø®Ù\88ئÙ\87",
-       "email-address-validity-invalid": "یه گل تیرنشون انجومانامه خو وارد بکید",
-       "userrights": "Ø­Ù\82Ù\88Ù\82 Ø¯Û\8cÙ\88Ù\88نداری کاریار",
-       "userrights-lookup-user": "دسÙ\87 Û\8cا Ú©Ø§Ø±Ù\88رÛ\8c Ù\86Ù\87 Ø¯Û\8cÙ\88Ù\88Ù\86 Ø¯Ø§Ø±Û\8c Ø¨کیت",
-       "userrights-user-editname": "یه گل نوم کاریاری وارد بکیت:",
-       "editusergroup": "ویرایشت گرویا کاریاری",
+       "email-address-validity-valid": "تÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95 Ø¯Û\8cار Ø¨Û\8cÛ\8cÛ\95 Ø®Ù\88Ù\99Ø£.",
+       "email-address-validity-invalid": "یئ گئل تیرنئشوٙن أنجوٙمانامە خوٙ بأزئنیت",
+       "userrights": "Ø­Ù\88Ù\82Ù\88Ù\99Ù\82 Ø¯Û\8cÚ¤Ù\88Ù\99نداری کاریار",
+       "userrights-lookup-user": "جأرغÛ\95 Û\8cا Ú©Ø§Ø±Û\8cارÛ\8c Ù\86Û\95 Ø¯Û\8cÚ¤Ù\88Ù\99Ù\86دارÛ\8c Ø¨Ø£کیت",
+       "userrights-user-editname": "یئ گئل نوم کاریاری ڤارئد بأکیت:",
+       "editusergroup": "ڤیرایئشت جأرغە یا کاریاری",
        "editinguser": "آلئشت دأئن حوقوٙق کاریاری کاریار '''[[کاریار:$1|$1]]''' $2",
-       "userrights-editusergroup": "ویرایشت گرویا کاریاری",
-       "saveusergroups": "اÙ\85اÛ\8cÛ\8cÙ\87 Ú©Ø±Ø¯Ù\86 Ú¯Ø±Ù\88یا کاریاری",
-       "userrights-groupsmember": "اندوم:",
-       "userrights-groupsmember-auto": "اÙ\86دÙ\88Ù\85 Ø¶Ù\85Ù\86Û\8c:",
+       "userrights-editusergroup": "ڤیرایئشت جأرغە یا کاریاری",
+       "saveusergroups": "ئÙ\85اÛ\8cÛ\95 Ú©Ø¦Ø±Ø¯Ø¦Ù\86 Ø¬Ø£Ø±ØºÛ\95 یا کاریاری",
+       "userrights-groupsmember": "Ø£ندوم:",
+       "userrights-groupsmember-auto": "Ø£Ù\86دÙ\88Ù\85 Ù\86ادÛ\8cار:",
        "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "شما می تونیت دسه یای که ای کاریار ها دشو آلشت بئیتو:\n* جعوه نشودار وه ای مئنیه که کاریار ها د او دسه.\n* جعوه بی نشون وه ای مئنیه که کاریار د او دسه نئ.\n* نشون* د ای مئنیه که ار شما او دسه نه اضاف بکیتو د نهاتر نموئه ؤردارینش یا برعسگش.",
        "userrights-reason": "دألیل:",
        "group-autoconfirmed": "کاریاریا خود پوشت راس بییە",
        "group-bot": "بوتیا",
        "group-sysop": "سأردیڤوٙنکاریا",
-       "group-bureaucrat": "بروکراتیا",
+       "group-bureaucrat": "بوروکراتیا",
        "group-suppress": "تیە پایا",
        "group-all": "(هأمە)",
        "group-user-member": "{{GENDER:$1|کاریار}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|کارÛ\8cار Ø®Ù\88دانجومکار}}",
-       "group-bot-member": "{{حنس:$1|بوت}}",
-       "group-sysop-member": "{{GENDER:$1|دیووندار}}",
-       "group-bureaucrat-member": "{{GENDER:$1|بروکرات}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|کارÛ\8cار Ø®Ù\88دأنجومکار}}",
+       "group-bot-member": "{{GENDER:$1|بوت}}",
+       "group-sysop-member": "{{GENDER:$1|دیڤوٙندار}}",
+       "group-bureaucrat-member": "{{GENDER:$1|بوروکرات}}",
        "group-suppress-member": "{{GENDER:$1|تیە پا}}",
        "grouppage-user": "{{ns:project}}:کاریاریا",
-       "grouppage-autoconfirmed": "{{ns:project}}:کارÛ\8cار Ø®Ù\88دانجومکار",
+       "grouppage-autoconfirmed": "{{ns:project}}:کارÛ\8cار Ø®Ù\88دأنجومکار",
        "grouppage-bot": "{{ns:project}}:بوت یا",
-       "grouppage-sysop": "{{ns:project}}:دیوونداریا",
-       "grouppage-bureaucrat": "{{ns:project}}:دیوونداریا",
+       "grouppage-sysop": "{{ns:project}}:دیڤوٙنداریا",
+       "grouppage-bureaucrat": "{{ns:project}}:دیڤوٙنداریا",
        "grouppage-suppress": "{{ns:project}}:تیە پا",
-       "right-read": "حنن بلگیا",
-       "right-edit": "ویرایشت بلگیا",
+       "right-read": "حأنئن بألگە یا",
+       "right-edit": "ڤیرایئشت بألگە یا",
        "right-createpage": "بلگه یا نه راس بکیت(ونو که دشو بلگه یا چک چنه نئ)",
        "right-createtalk": "بلگه یا چک چنه نه راس بکید",
        "right-createaccount": "یه گل حساو کاروری تازه راس بکیت",
        "movenosubpage": "ای بلگه زیر بلگه نئ.",
        "movereason": "دلیل:",
        "revertmove": "لرستن",
-       "delete_and_move": "پاکسا و جا وه جا بوئه",
        "delete_and_move_text": "== پاکساکاری میها ==\n\nگوتار ها د مقصد «[[:$1]]» . آیا میهایت ونه پاکسا بکیت  تا جا وه جاکاری دروس بوئه؟",
        "delete_and_move_confirm": "هری بلگه نه پاکسا کو",
        "delete_and_move_reason": "پاکساکاری سی ممکن بیین جا وه جایی «[[$1]]»",
index 4c53150..6c22aee 100644 (file)
        "morenotlisted": "Šis sąrašas nėra išsamus.",
        "mypage": "Puslapis",
        "mytalk": "Aptarimas",
-       "anontalk": "Šio IP aptarimas",
+       "anontalk": "Aptarimas",
        "navigation": "Naršymas",
        "and": "&#32;ir",
        "qbfind": "Paieška",
        "passwordreset-emailtext-ip": "Kažkas (tikriausiai jūs, IP adresu $1) paprašė priminti jūsų slaptažodį svetainėje {{SITENAME}} ($4). Šio naudotojo {PLURAL:$3|paskyra|paskyros}} yra susietos su šiuo elektroninio pašto adresu:\n\n$2\n\n{{PLURAL:$3|Šis laikinas slaptažodis |Šie laikini slaptažodžiai}} baigs galiot po {{PLURAL:$5|vienos dienos|$5 dienų}}. \n\nJūs turėtumėte prisijungti ir pasirinkti naują slaptažodį. Jei kažkas kitas padarė šį prašymą arba jūs prisiminėte savo pirminį slaptažodį, ir jums nebereikia jo pakeisti, galite ignoruoti šį pranešimą ir toliau naudotis savo senuoju slaptažodžiu.",
        "passwordreset-emailtext-user": "Naudotojas $1 svetainėje {{SITENAME}} sukūrė užklausą slaptažodžio priminimui svetainėje {{SITENAME}}\n($4). Šio naudotojo {{PLURAL:$3|paskyra|paskyros}} susieto su šiuo elektroniniu paštu $2. \n\n{{PLURAL:$3|Šis laikinas slaptažodis|Šie laikini slaptažodžiai}} baigs galioti po {{PLURAL:$5|vienos dienos|$5 dienų}}. Jūs turėtumėte prisijungti ir pasirinkti naują slaptažodį. Jei kažkas padarė tai be jūsų žinios arba jūs prisiminėte savo pirminį slaptažodį, ir jūs nebenorite jo pakeisti, galite ignoruoti šį pranešimą ir toliau naudotis savo senuoju slaptažodžiu.",
        "passwordreset-emailelement": "Naudotojo vardas: \n$1\n\nLaikinas slaptažodis: \n$2",
-       "passwordreset-emailsent": "Jeigu tai yra jūsų paskyros registruotas el. pašto adresas, tada slaptažodžio atkūrimo laiškas bus išsiųstas.",
+       "passwordreset-emailsentemail": "Jeigu tai yra jūsų paskyros registruotas el. pašto adresas, tada slaptažodžio atkūrimo laiškas bus išsiųstas.",
        "passwordreset-emailsent-capture": "Slaptažodžio priminimo laiškas bus išsiųstas, toks koks parodytas.",
        "passwordreset-emailerror-capture": "Priminimo elektroninis laiškas buvo sukurtas, toks, koks parodytas žemiau, bet pasiuntimas naudotojui buvo nesėkmingas: $1",
        "changeemail": "Pakeisti ar pašalinti el. pašto adresą",
        "recentchanges-label-plusminus": "Šiuo baitų skaičiumi pakeista puslapio apimtis",
        "recentchanges-legend-heading": "'''Paaiškinimai:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (taip pat žiūrėkite [[Special:NewPages|naujausių straipsnių sąrašą]])",
+       "recentchanges-submit": "Rodyti",
        "rcnotefrom": "Žemiau yra {{PLURAL:$5|pakeitimas|pakeitimai}} pradedant <strong>$3, $4</strong> (rodoma iki <strong>$1</strong> pakeitimų).",
        "rclistfrom": "Rodyti naujus pakeitimus pradedant $3 $2",
        "rcshowhideminor": "$1 smulkius keitimus",
        "mostrevisions": "Puslapiai su daugiausiai keitimų",
        "prefixindex": "Visi puslapiai pagal pavadinimo pradžią",
        "prefixindex-namespace": "Visi puslapiai prasidedantys ($1 vardų sritis)",
+       "prefixindex-submit": "Rodyti",
        "prefixindex-strip": "Paslėpti priešdėlį gavinių sąraše",
        "shortpages": "Trumpiausi puslapiai",
        "longpages": "Ilgiausi puslapiai",
        "protectedpages-performer": "Užrakinantis naudotojas",
        "protectedpages-params": "Užrakinimo nuostatos",
        "protectedpages-reason": "Priežastis",
+       "protectedpages-submit": "Rodyti puslapius",
        "protectedpages-unknown-timestamp": "Nežinomas",
        "protectedpages-unknown-performer": "Nežinomas vartotojas",
        "protectedtitles": "Apsaugoti pavadinimai",
        "protectedtitles-summary": "Tai pavadinimų, kuriais uždrausta kurti puslapius, sąrašas. Šiuo metu užrakintų puslapių sąrašą žiūrėkite čia: [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Šiuo metu nėra jokių pavadinimų apsaugotų šiais parametrais.",
+       "protectedtitles-submit": "Rodyti pavadinimus",
        "listusers": "Naudotojų sąrašas",
        "listusers-editsonly": "Rodyti tik keitimus atlikusius naudotojus",
        "listusers-creationsort": "Rodyti pagal paskyros sukūrimo datą",
        "wlshowlast": "Rodyti paskutinių $1 valandų, $2 dienų",
        "watchlistall2": "visi",
        "watchlist-hide": "Slėpti",
+       "watchlist-submit": "Rodyti",
        "wlshowtime": "Rodyti paskutinį:",
        "wlshowhideminor": "smulkūs pakeitimai",
        "wlshowhidebots": "robotai",
        "contributions": "{{GENDER:$1|Naudotojo}} indėlis",
        "contributions-title": "{{GENDER:$1|Naudotojo|Naudotojos}} $1 indėlis",
        "mycontris": "Įnašai",
+       "anoncontribs": "Įnašai",
        "contribsub2": "Dėl {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Naudotojo paskyra „$1“ neužregistruota.",
        "nocontribs": "Jokie keitimai neatitiko šių kriterijų.",
        "whatlinkshere-hidelinks": "$1 nuorodas",
        "whatlinkshere-hideimages": "$1 failų nuorodos",
        "whatlinkshere-filters": "Filtrai",
+       "whatlinkshere-submit": "Eiti",
        "autoblockid": "Automatinis blokavimas # $1",
        "block": "Blokuoti naudotoją",
        "unblock": "Atblokuoti naudotoją",
        "movenosubpage": "Šis puslapis neturi subpuslapių.",
        "movereason": "Priežastis:",
        "revertmove": "atmesti",
-       "delete_and_move": "Ištrinti ir perkelti",
        "delete_and_move_text": "==Reikia ištrinti==\n\nPaskirties puslapis „[[:$1]]“ jau yra. Ar norite jį ištrinti, kad galėtumėte pervardinti?",
        "delete_and_move_confirm": "Taip, trinti puslapį",
        "delete_and_move_reason": "Ištrinta dėl perkėlimo iš \"[[$1]]\"",
        "tooltip-pt-preferences": "Mano nustatymai",
        "tooltip-pt-watchlist": "Puslapių sąrašas, kuriuos jūs pasirinkote stebėti",
        "tooltip-pt-mycontris": "Jūsų darytų keitimų sąrašas",
+       "tooltip-pt-anoncontribs": "Keitimų sąrašas, padarytų iš šio IP adreso",
        "tooltip-pt-login": "Rekomenduojame prisijungti, nors tai nėra privaloma",
        "tooltip-pt-logout": "Atsijungti",
        "tooltip-pt-createaccount": "Skatiname susikurti paskyrą ir prisijungti, tačiau, tai nėra privaloma",
index bdab40a..3e02d67 100644 (file)
@@ -51,6 +51,7 @@
        "tog-watchlisthidebots": "Скриј ботовски уредувања од набљудуваните",
        "tog-watchlisthideminor": "Скриј ги ситните уредувања во набљудуваните",
        "tog-watchlisthideliu": "Скриј ги уредувањата на најавените корисници во набљудуваните",
+       "tog-watchlistreloadautomatically": "Превчитувај ги набљудувањата автоматски кога ќе се смени филтерот (бара JavaScript)",
        "tog-watchlisthideanons": "Скриј ги уредувањата од анонимни корисници во набљудуваните",
        "tog-watchlisthidepatrolled": "Скриј испатролирани уредувања од мојот список на набљудувања",
        "tog-watchlisthidecategorization": "Сокриј ја категоризацијата на страниците",
        "morenotlisted": "Овој список не е целосен.",
        "mypage": "Страница",
        "mytalk": "разговор",
-       "anontalk": "Разговор за оваа IP-адреса",
+       "anontalk": "Разговор",
        "navigation": "Навигација",
        "and": "&#32;и",
        "qbfind": "Најди",
        "databaseerror-query": "Барање: $1",
        "databaseerror-function": "Функција: $1",
        "databaseerror-error": "Грешка: $1",
+       "transaction-duration-limit-exceeded": "За да се избегне голем заостаток на одговори, трансакцијата е откажана бидејќи е надминато траењето на записот ($1), ограничено на $2 секунди.\nАко менувате повеќе ставки наеднаш, правете го тоа на повеќе наврати наместо заеднички.",
        "laggedslavemode": "Предупредување: Страницата може да не ги содржи скорешните поднови.",
        "readonly": "Базата е заклучена",
        "enterlockreason": "Внесете причина за заклучувањето, вклучувајќи и приближно време на отклучување",
        "wrongpasswordempty": "Внесената лозинка е празна. Обидете се повторно.",
        "passwordtooshort": "Лозинката мора да има најмалку {{PLURAL:$1|1 знак|$1 знаци}}.",
        "passwordtoolong": "Лозинката не треба да има повеќе од {{PLURAL:$1|1 знак|$1 знаци}}.",
+       "passwordtoopopular": "Не користете пречесто застапени лозинки. Одберете некоја поинаква од вообичаените.",
        "password-name-match": "Лозинката мора да се разликува од корисничкото име.",
        "password-login-forbidden": "Употребата на ова корисничко име и лозинка е забранета.",
        "mailmypassword": "Нова лозинка",
        "passwordreset-emailtext-ip": "Некој (веројатно вие, од IP-адресата $1) побара измена на вашата\nлозинка за {{SITENAME}} ($4). Оваа е-поштенска адреса е наведена во\n{{PLURAL:$3|следнава корисничка сметка|следниве кориснички сметки}}:\n\n$2\n\n{{PLURAL:$3|Оваа привремена лозинка ќе истече|Овие привремени лозинки ќе истечат}} во рок од {{PLURAL:$5|еден ден|$5 дена}}.\nСега треба да се најавите и да внесете нова лозинка. Ако ова барање го\nпоставил некој друг, или пак во меѓувреме сте се сетиле на лозинката, и не сакате\nда ја менувате, тогаш слободно занемарете ја поракава и продолжете да ја користите старата.",
        "passwordreset-emailtext-user": "Корисникот $1 на {{SITENAME}} побара измена на вашата лозинка на {{SITENAME}}\n($4). Оваа е-поштенска адреса е наведена во {{PLURAL:$3|следнава корисничка сметка|следниве кориснички сметки}}:\n\n$2\n\n{{PLURAL:$3|Оваа привремена лозинка ќе истече|Овие привремени лозинки ќе истечат}} во рок од {{PLURAL:$5|еден ден|$5 дена}}.\nСега треба да се најавите и да внесете нова лозинка. Ако ова барање го\nпоставил некој друг, или пак во меѓувреме сте се сетиле на лозинката, и не сакате\nда ја менувате, тогаш слободно занемарете ја поракава и продолжете да ја користите старата.",
        "passwordreset-emailelement": "Корисничко име: \n$1\n\nПривремена лозинка: \n$2",
-       "passwordreset-emailsent": "Ако ова е регистрираната е-пошта за вашата сметка, тогаш ќе ви биде испратено писмо за задавање на нова лозинка.",
+       "passwordreset-emailsentemail": "Ако ова е регистрираната е-пошта за вашата сметка, тогаш ќе ви биде испратено писмо за задавање на нова лозинка.",
+       "passwordreset-emailsentusername": "Ако има соодветна регистрирана е-пошта, тогаш ќе ви биде испратена порака за промена на лозинката.",
        "passwordreset-emailsent-capture": "Испратено е писмо за измена на лозинката (прикажано подолу).",
        "passwordreset-emailerror-capture": "Создадено е писмо за измена на лозинката (прикажано подолу), но не успеав да го испратам на {{GENDER:$2|корисникот}}: $1",
        "changeemail": "Смени или отстрани е-пошта",
        "recentchanges-legend-heading": "'''Легенда:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (погл. и [[Special:NewPages|списокот на нови страници]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Прикажи",
        "rcnotefrom": "Подолу {{PLURAL:$5|е прикажана промената|се прикажани промените}} почнувајќи од <strong>$3, $4</strong>  (се прикажуваат до <b>$1</b>).",
        "rclistfrom": "Прикажи нови промени почнувајќи од $3 $2",
        "rcshowhideminor": "$1 ситни промени",
        "mostrevisions": "Статии со најмногу верзии",
        "prefixindex": "Сите страници (со претставка)",
        "prefixindex-namespace": "Сите страници со претставка (именски простор $1)",
+       "prefixindex-submit": "Прикажи",
        "prefixindex-strip": "Отстрани ја претставката во списокот",
        "shortpages": "Кратки страници",
        "longpages": "Долги страници",
        "protectedpages-performer": "Заштитувач",
        "protectedpages-params": "Параметри на заштитата",
        "protectedpages-reason": "Причина",
+       "protectedpages-submit": "Прикажи страници",
        "protectedpages-unknown-timestamp": "Непознато",
        "protectedpages-unknown-performer": "Непознат корисник",
        "protectedtitles": "Заштитени наслови",
        "protectedtitles-summary": "На страницата се наведени наслови што се моментално заштитени од создавање. За список на постоечки страници што се заштитени, погледајте [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Во овој момент нема заштитени наслови кои ги задоволуваат наведените критериуми.",
+       "protectedtitles-submit": "Прикажи наслови",
        "listusers": "Список на корисници",
        "listusers-editsonly": "Прикажи само корисници кои уредувале",
        "listusers-creationsort": "Подреди по датум на создавање",
        "activeusers-hidebots": "Скриј ботови",
        "activeusers-hidesysops": "Скриј администратори",
        "activeusers-noresult": "Не пронајдов ниеден корисник.",
+       "activeusers-submit": "Прикажи активни корисници",
        "listgrouprights": "Права на кориснички групи",
        "listgrouprights-summary": "Следи список на кориснички групи утврдени на ова вики, заедно со нивните придружни права на пристап.\nМожно е да има [[{{MediaWiki:Listgrouprights-helppage}}|дополнителни информации]] за некои права.",
        "listgrouprights-key": "Легенда:\n* <span class=\"listgrouprights-granted\">Доделено право</span>\n* <span class=\"listgrouprights-revoked\">Одземено право</span>",
        "wlshowlast": "Прикажи ги последните $1 часа, $2 дена,",
        "watchlistall2": "сè",
        "watchlist-hide": "Скриј",
-       "wlshowtime": "Прикажи ги последните:",
+       "watchlist-submit": "Прикажи",
+       "wlshowtime": "Период за приказ:",
        "wlshowhideminor": "ситни уредувања",
        "wlshowhidebots": "ботови",
        "wlshowhideliu": "регистрирани корисници",
        "contributions": "{{GENDER:$1|Придонеси на корисникот}}",
        "contributions-title": "Придонеси на корисникот $1",
        "mycontris": "придонеси",
+       "anoncontribs": "Придонеси",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Корисничката сметка „$1“ не е регистрирана.",
        "nocontribs": "Не се пронајдени промени што одговараат на овој критериум.",
        "whatlinkshere-hidelinks": "$1 врски",
        "whatlinkshere-hideimages": "$1 врски кон податотека",
        "whatlinkshere-filters": "Филтри",
+       "whatlinkshere-submit": "Дај",
        "autoblockid": "Автоблок бр. $1",
        "block": "Блокирај корисник",
        "unblock": "Одблокирај корисник",
        "movenosubpage": "Оваа страница нема потстраници.",
        "movereason": "Причина:",
        "revertmove": "врати",
-       "delete_and_move": "Избриши и премести",
        "delete_and_move_text": "==Потребно бришење==\nЦелната статија „[[:$1]]“ веќе постои.\nДали сакате да ја избришете за да ослободите место за преместувањето?",
        "delete_and_move_confirm": "Да, избриши ја страницата",
        "delete_and_move_reason": "Избришано за да се ослободи место за преместувањето од „[[$1]]“",
        "tooltip-pt-preferences": "Ваши нагодувања",
        "tooltip-pt-watchlist": "Список на страници кои сте избрале да ги набљудувате.",
        "tooltip-pt-mycontris": "Список на ваши придонеси",
+       "tooltip-pt-anoncontribs": "Список на уредувања направени од оваа IP-адреса",
        "tooltip-pt-login": "Ви препорачуваме да се најавите, иако тоа не е задолжително.",
        "tooltip-pt-logout": "Одјавување",
        "tooltip-pt-createaccount": "Ви препорачуваме да направите сметка и да се најавите, иако тоа не е задолжително",
index ca49657..b783957 100644 (file)
@@ -65,6 +65,7 @@
        "tog-watchlisthidebots": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്ന് യന്ത്രങ്ങൾ വരുത്തിയ തിരുത്തുകൾ മറയ്ക്കുക",
        "tog-watchlisthideminor": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്ന് ചെറുതിരുത്തുകൾ മറയ്ക്കുക",
        "tog-watchlisthideliu": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളിലെ മാറ്റങ്ങളിൽ നിന്നും ലോഗിൻ ചെയ്തിട്ടുള്ളവരുടെ തിരുത്തുകൾ മറയ്ക്കുക",
+       "tog-watchlistreloadautomatically": "ഒരു അരിപ്പയിൽ മാറ്റമുണ്ടായാൽ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക സ്വയം വീണ്ടുമെടുക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)",
        "tog-watchlisthideanons": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളിലെ മാറ്റങ്ങളിൽ നിന്നും അജ്ഞാത ഉപയോക്താക്കളുടെ തിരുത്തുകൾ മറയ്ക്കുക",
        "tog-watchlisthidepatrolled": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്ന് റോന്തുചുറ്റിയ തിരുത്തുകൾ മറയ്ക്കുക",
        "tog-watchlisthidecategorization": "താളുകളുടെ വർഗ്ഗീകരണം മറയ്ക്കുക",
        "morenotlisted": "ഈ പട്ടിക പൂർണ്ണമല്ല.",
        "mypage": "താൾ",
        "mytalk": "സംവാദത്താൾ",
-       "anontalk": "à´\88 à´\90.പി.à´¯àµ\81à´\9fàµ\86 à´¸à´\82â\80\8cവാദതàµ\8dതാൾ",
+       "anontalk": "à´¸à´\82വാദà´\82",
        "navigation": "ഉള്ളടക്കം",
        "and": "&#32;ഒപ്പം",
        "qbfind": "കണ്ടെത്തുക",
        "wrongpasswordempty": "രഹസ്യവാക്ക് നൽകിയിരുന്നില്ല. വീണ്ടും ശ്രമിക്കുക.",
        "passwordtooshort": "രഹസ്യവാക്കിൽ കുറഞ്ഞതു {{PLURAL:$1|ഒരു അക്ഷരം|$1 അക്ഷരങ്ങൾ}} ഉണ്ടായിരിക്കണം.",
        "passwordtoolong": "രഹസ്യവാക്കിൽ പരമാവധി {{PLURAL:$1|ഒരു അക്ഷരം|$1 അക്ഷരങ്ങൾ}} മാത്രമേ പാടുള്ളു.",
+       "passwordtoopopular": "പരക്കെ ഉപയോഗിക്കുന്ന രഹസ്യവാക്കുകൾ ഉപയോഗിക്കരുത്. ദയവായി കൂടുതൽ അനന്യമായ രഹസ്യവാക്ക് തിരഞ്ഞെടുക്കുക.",
        "password-name-match": "താങ്കളുടെ രഹസ്യവാക്ക് ഉപയോക്തൃനാമത്തിൽ നിന്നും വ്യത്യസ്തമായിരിക്കണം.",
        "password-login-forbidden": "ഈ ഉപയോക്തൃനാമത്തിന്റെയും രഹസ്യവാക്കിന്റെയും ഉപയോഗം നിരോധിച്ചിരിക്കുന്നു.",
        "mailmypassword": "രഹസ്യവാക്ക് പുനഃക്രമീകരിക്കുക",
        "passwordreset-emailtext-ip": "ആരോ ഒരാൾ (മിക്കവാറും താങ്കളായിരിക്കും, $1 എന്ന ഐ.പി. വിലാസത്തിൽ നിന്നും) {{SITENAME}} സംരംഭത്തിലെ ($4) താങ്കളുടെ രഹസ്യവാക്ക് പുനർസജ്ജീകരിക്കാൻ അഭ്യർത്ഥിച്ചിരിക്കുന്നു. ഈ ഇമെയിൽ വിലാസവുമായി ബന്ധപ്പെട്ടിരിക്കുന്ന {{PLURAL:$3|അംഗത്വം|അംഗത്വങ്ങൾ}} താഴെക്കൊടുത്തിരിക്കുന്നു:\n\n$2\n\n\nഈ {{PLURAL:$3|താത്കാലിക രഹസ്യവാക്ക്|താത്കാലിക രഹസ്യവാക്കുകൾ}} {{PLURAL:$5|ഒരു ദിവസം|$5 ദിവസങ്ങൾ}} കൊണ്ട് കാലഹരണപ്പെട്ട് പോകുന്നവയാണ്.\nതാങ്കൾ ഇപ്പോൾ തന്നെ പ്രവേശിച്ച് രഹസ്യവാക്ക് മാറ്റുന്നതാണ് ഉചിതം. ഈ അഭ്യർത്ഥന മറ്റാരോ ആണ് നടത്തിയത് അല്ലെങ്കിൽ, യഥാർത്ഥ രഹസ്യവാക്ക് താങ്കൾ ഓർമ്മിക്കുകയും അത് മാറ്റാൻ ആഗ്രഹിക്കാതിരിക്കുകയും ആണെങ്കിൽ, ഈ സന്ദേശം അവഗണിച്ച് താങ്കളുടെ പഴയ രഹസ്യവാക്ക് തുടർന്നും ഉപയോഗിക്കാവുന്നതാണ്.",
        "passwordreset-emailtext-user": "{{SITENAME}} സംരംഭത്തിലെ ഉപയോക്താവായ $1 {{SITENAME}} സംരംഭത്തിലെ ($4) രഹസ്യവാക്ക് പുനർസജ്ജീകരിക്കാൻ അഭ്യർത്ഥിച്ചിരിക്കുന്നു. ഈ ഇമെയിൽ വിലാസവുമായി ബന്ധപ്പെട്ടിരിക്കുന്ന {{PLURAL:$3|അംഗത്വം|അംഗത്വങ്ങൾ}} താഴെക്കൊടുത്തിരിക്കുന്നു:\n\n$2\n\n\nഈ {{PLURAL:$3|താത്കാലിക രഹസ്യവാക്ക്|താത്കാലിക രഹസ്യവാക്കുകൾ}} {{PLURAL:$5|ഒരു ദിവസം|$5 ദിവസങ്ങൾ}} കൊണ്ട് കാലഹരണപ്പെട്ട് പോകുന്നവയാണ്.\nതാങ്കൾ ഇപ്പോൾ തന്നെ പ്രവേശിച്ച് രഹസ്യവാക്ക് മാറ്റുന്നതാണ് ഉചിതം. ഈ അഭ്യർത്ഥന മറ്റാരോ ആണ് നടത്തിയത് അല്ലെങ്കിൽ, യഥാർത്ഥ രഹസ്യവാക്ക് താങ്കൾ ഓർമ്മിക്കുകയും അത് മാറ്റാൻ ആഗ്രഹിക്കാതിരിക്കുകയും ആണെങ്കിൽ, ഈ സന്ദേശം അവഗണിച്ച് താങ്കളുടെ പഴയ രഹസ്യവാക്ക് തുടർന്നും ഉപയോഗിക്കാവുന്നതാണ്.",
        "passwordreset-emailelement": "ഉപയോക്തൃനാമം: \n$1\n\nതാത്കാലിക രഹസ്യവാക്ക്: \n$2",
-       "passwordreset-emailsent": "താങ്കളുടെ അംഗത്വവുമായി ബന്ധിപ്പിച്ചിട്ടുള്ള ഇമെയിൽ വിലാസം ഇതാണെങ്കിൽ,  രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയക്കുന്നതാണ്.",
+       "passwordreset-emailsentemail": "താങ്കളുടെ അംഗത്വവുമായി ബന്ധിപ്പിച്ചിട്ടുള്ള ഇമെയിൽ വിലാസം ഇതാണെങ്കിൽ,  രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയക്കുന്നതാണ്.",
        "passwordreset-emailsent-capture": "രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയച്ചിട്ടുണ്ട്, അത് താഴെക്കൊടുക്കുന്നു.",
        "passwordreset-emailerror-capture": "താഴെക്കൊടുത്തിരിക്കുന്ന, രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ സൃഷ്ടിക്കാനായെങ്കിലും, അത് {{GENDER:$2|ഉപയോക്താവിന്}} അയയ്ക്കുന്നത് പരാജയപ്പെട്ടു: $1",
        "changeemail": "ഇമെയിൽ വിലാസം മാറ്റുക അല്ലെങ്കിൽ നീക്കംചെയ്യുക",
        "wlshowlast": "ഒടുവിലത്തെ $1 മണിക്കൂറുകൾ $2 ദിനങ്ങൾ പ്രദർശിപ്പിക്കുക",
        "watchlistall2": "എല്ലാം",
        "watchlist-hide": "മറയ്ക്കുക",
-       "wlshowtime": "à´\85വസാനതàµ\8dà´¤àµ\87à´¤àµ\8d à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\81à´\95:",
+       "wlshowtime": "à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9f à´\95ാലാവധി:",
        "wlshowhideminor": "ചെറുതിരുത്തുകൾ",
        "wlshowhidebots": "യന്ത്രങ്ങൾ",
        "wlshowhideliu": "അംഗത്വമെടുത്ത ഉപയോക്താക്കൾ",
        "contributions": "{{GENDER:$1|ഉപയോക്താവിന്റെ}} സംഭാവനകൾ",
        "contributions-title": "$1 എന്ന ഉപയോക്താവിന്റെ സംഭാവനകൾ",
        "mycontris": "സംഭാവനകൾ",
+       "anoncontribs": "സംഭാവനകൾ",
        "contribsub2": "ഉപയോക്താവ് {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "\"$1\" എന്ന ഉപയോക്തൃ അം‌ഗത്വം നിലവിലില്ല.",
        "nocontribs": "ഈ മാനദണ്ഡങ്ങളുമായി യോജിക്കുന്ന മാറ്റങ്ങൾ ഒന്നും കണ്ടില്ല.",
        "movenosubpage": "ഈ താളിന്‌ ഉപതാളുകൾ ഇല്ല",
        "movereason": "കാരണം:",
        "revertmove": "പൂർവ്വസ്ഥിതിയിലാക്കുക",
-       "delete_and_move": "മായ്ക്കുകയും മാറ്റുകയും ചെയ്യുക",
        "delete_and_move_text": "==താൾ മായ്ക്കേണ്ടിയിരിക്കുന്നു==\n\nമാറ്റാനായി നൽകിയ \"[[:$1]]\" എന്ന താൾ നിലവിലുണ്ട്. ഈ മാറ്റം നടത്തുന്നതിനുവേണ്ടി ആ താൾ മായ്ക്കേണ്ടതുണ്ടോ?",
        "delete_and_move_confirm": "ശരി, താൾ നീക്കം ചെയ്യുക",
        "delete_and_move_reason": "\"[[$1]]\" എന്നതിൽ നിന്നും മാറ്റാനുള്ള സൗകര്യത്തിനായി മായ്ച്ചു",
        "tooltip-pt-preferences": "താങ്കളുടെ ക്രമീകരണങ്ങൾ",
        "tooltip-pt-watchlist": "താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളിലെ മാറ്റങ്ങൾ",
        "tooltip-pt-mycontris": "താങ്കളുടെ സേവനങ്ങളുടെ പട്ടിക",
+       "tooltip-pt-anoncontribs": "ഈ ഐ.പി. വിലാസത്തിൽ നിന്നും ചെയ്തിട്ടുള്ള തിരുത്തുകളുടെ പട്ടിക",
        "tooltip-pt-login": "ലോഗിൻ ചെയ്യുവാൻ താല്പര്യപ്പെടുന്നു; പക്ഷേ നിർബന്ധമല്ല",
        "tooltip-pt-logout": "ലോഗൗട്ട് ചെയ്യാനുള്ള കണ്ണി",
        "tooltip-pt-createaccount": "നിർബന്ധമില്ലെങ്കിലും, താങ്കൾ ഒരു അംഗത്വമെടുക്കണമെന്നും പ്രവേശിക്കണമെന്നും താത്പര്യപ്പെടുന്നു",
index 7b43fd4..2d61892 100644 (file)
@@ -84,6 +84,7 @@
        "tog-watchlisthidebots": "पहाऱ्याच्या सूचीतून सांगकाम्यांचे बदल लपवा",
        "tog-watchlisthideminor": "माझ्या पहाऱ्याच्या सूचीतून छोटे बदल लपवा",
        "tog-watchlisthideliu": "पहाऱ्याच्या सूचीतून प्रवेश केलेल्या सदस्यांची संपादने लपवा",
+       "tog-watchlistreloadautomatically": "एखादी गाळणी बदलल्यावर,निरीक्षणसूचीचे आपोआप पुनर्भारण करा(जावास्क्रिप्ट हवी)",
        "tog-watchlisthideanons": "निरीक्षणसूचीतून अनामिक सदस्यांची संपादने लपवा",
        "tog-watchlisthidepatrolled": "निरीक्षणसूचीतून तपासलेली संपादने लपवा",
        "tog-watchlisthidecategorization": "पानांचे वर्गीकरण लपवा",
        "morenotlisted": "ही यादी पूर्ण नाही.",
        "mypage": "पान",
        "mytalk": "चर्चा",
-       "anontalk": "या à¤\85à¤\82à¤\95पतà¥\8dतà¥\8dयाà¤\9aà¥\87 à¤\9aरà¥\8dà¤\9aा à¤ªà¤¾à¤¨ à¤\89à¤\98डा",
+       "anontalk": "à¤\9aरà¥\8dà¤\9aा à¤ªà¤¾à¤¨",
        "navigation": "सुचालन",
        "and": "&#32;आणि",
        "qbfind": "शोधा",
        "viewsourceold": "स्रोत पहा",
        "editlink": "संपादन",
        "viewsourcelink": "स्रोत पहा",
-       "editsectionhint": "हà¥\8dया à¤µà¤¿à¤­à¤¾à¤\97ाà¤\9aà¥\87 à¤¸à¤\82पादन à¤\95रा: $1",
+       "editsectionhint": "या विभागाचे संपादन करा: $1",
        "toc": "अनुक्रमणिका",
        "showtoc": "दाखवा",
        "hidetoc": "लपवा",
        "wrongpasswordempty": "परवलीचा शब्द कोरा आहे; पुन्हा प्रयत्न करा.",
        "passwordtooshort": "तुमच्या परवलीच्या शब्दात किमान {{PLURAL:$1|१ अक्षर |$1 अक्षरे}} हवीत.",
        "passwordtoolong": "परवलीचा शब्द हा {{PLURAL:$1|१ वर्ण पेक्षा|$1 वर्णांपेक्षा}} लांबीचा नको.",
+       "passwordtoopopular": "सर्वसामान्यपणे वापरण्यात येणारे परवलीचे शब्द वापरल्या जाऊ शकत नाहीत.कृपया अधिक अनन्य शब्द वापरा.",
        "password-name-match": "आपला परवलीचा शब्द हा आपल्या सदस्यनावापेक्षा वेगळा हवा.",
        "password-login-forbidden": "या सदस्यनामाचा व परवलीच्या शब्दाचा वापर निषिद्ध आहे.",
        "mailmypassword": "नवीन परवलीचा शब्द पुनर्स्थापित(रिसेट) करा",
        "passwordreset-emailtext-ip": "कुणीतरी (कदाचित तुम्ही, अंकपत्ता $1 वरुन) {{SITENAME}}($4) करिता नविन 'परवलीचा शब्द' पुनर्स्थापनेबद्दल विनंती केली आहे.\nखालील{{PLURAL:$3|सदस्यखाते}}या विपत्रपत्त्याशी निगडीत आहे: \n\"$2\"\n{{PLURAL:$3|हा तात्पुरता परवलीचा शब्द|हे तात्पुरते परवलीचे शब्द}}{{PLURAL:$5|एक दिवस|$5 दिवसात}} मुदतबाह्य होतील.आता आपण लॉग-ईन करून  नविन परवलीचा शब्द निवडा.जर ईतर कोणी ही विनंती केली असेल,किंवा जर आपणास परवलीच शब्द आठवला असेल तर,व जर आपण तो बदलु इच्छित नसाल तर आपण हा संदेश टाळा व आपला जुना परवलीचा शब्द वापरणे सुरू ठेवा.",
        "passwordreset-emailtext-user": " {{SITENAME}}वरील सदस्य $1ने {{SITENAME}}($4) करिता नविन 'परवलीचा शब्द' पुनर्स्थापनेबद्दल विनंती केली आहे.\nखालील{{PLURAL:$3|सदस्यखाते}}या विपत्रपत्त्याशी निगडीत आहे: \n\n\"$2\"\n\n{{PLURAL:$3|हा तात्पुरता परवलीचा शब्द|हे तात्पुरते परवलीचे शब्द}}{{PLURAL:$5|एक दिवस|$5 दिवसात}} मुदतबाह्य होतील.आता आपण लॉग-ईन करून  नविन परवलीचा शब्द निवडा.जर ईतर कोणी ही विनंती केली असेल,किंवा जर आपणास परवलीच शब्द आठवला असेल तर,व, जर आपण तो बदलु इच्छित नसाल तर आपण हा संदेश टाळा व आपला जुना परवलीचा शब्द वापरणे सुरू ठेवा.",
        "passwordreset-emailelement": "सदस्यनाव: \n$1\n\nअस्थायी परवलीचा शब्द: \n$2",
-       "passwordreset-emailsent": "जर हा आपल्या खात्याचा नोंदणिकृत विपत्रपत्ता असेल तर, परवलीच्या शब्दाच्या पुनर्स्थापनेबाबत एक विपत्र पाठवण्यात येईल.",
+       "passwordreset-emailsentemail": "जर हा आपल्या खात्याचा नोंदणिकृत विपत्रपत्ता असेल तर, परवलीच्या शब्दाच्या पुनर्स्थापनेबाबत एक विपत्र पाठवण्यात येईल.",
+       "passwordreset-emailsentusername": "जर तदनुरूप नोंदीकृत विपत्रपत्ता असेल तर, परवलीचा शब्द पुनर्स्थापन विपत्र पाठविल्या जाईल.",
        "passwordreset-emailsent-capture": "'परवलीचा शब्द' पुनर्स्थापनेबाबत एक विपत्र पाठवण्यात आले आहे जे खाली दर्शविण्यात आले आहे.",
        "passwordreset-emailerror-capture": "'परवलीचा शब्द' पुनर्स्थापनेबाबत एक विपत्र निर्माण करण्यात आले, जे खाली दर्शविण्यात आले आहे.परंतु,{{GENDER:$2|सदस्य}}ला पाठविणे असफल झाले: $1",
        "changeemail": "विपत्रपत्ता बदला किंवा हटवा",
        "missing-revision": "\"{{FULLPAGENAME}}\" या लेखाचे #$1 हे संस्करण अस्तित्वात नाही.वगळल्या गेलेल्या लेखपानाच्या जुन्या इतिहास-दुव्याचे अनुसरण केल्यामुळे असे होते.याबाबत विस्तृत माहिती  [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळलेल्या नोंदी]येथे बघता येईल.",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" सदस्य खात्याची नोंद नाही. कृपया हे पान तुम्ही संपादित किंवा नव्याने तयार करू इच्छिता काय याबद्दल विचार करा.",
        "userpage-userdoesnotexist-view": "सदस्यखाते \"$1\"  हे नोंदलेले नाही.",
-       "blocked-notice-logextract": "हा à¤¸à¤¦à¤¸à¥\8dय à¤¸à¤§à¥\8dया à¤ªà¥\8dरतिबà¤\82धित à¤\86हà¥\87.\nसरà¥\8dवाà¤\82त à¤¨à¤µà¥\80न à¤ªà¥\8dरतिबà¤\82धन à¤¯à¤¾à¤¦à¥\80 à¤\96ाली संदर्भासाठी दिली आहे:",
+       "blocked-notice-logextract": "हा à¤¸à¤¦à¤¸à¥\8dय à¤¸à¤§à¥\8dया à¤ªà¥\8dरतिबà¤\82धित à¤\86हà¥\87.\nà¤\96ालà¥\80, à¤¸à¤°à¥\8dवाà¤\82त à¤¨à¤µà¥\80नतम à¤ªà¥\8dरतिबà¤\82धन à¤¨à¥\8bà¤\82दपà¥\8dरविषà¥\8dà¤\9fी संदर्भासाठी दिली आहे:",
        "clearyourcache": "'''सूचना:''' जतन केल्यावर बदल दिसण्यासाठी तुम्हाला कदाचित न्याहाळकाची सय टाळायला लागेल. असे करण्यासाठी - \n\n*'''फायरफॉक्स / सफारी:''' साठी ''Reload'' हे टिचकतांना ''Shift'' ही कळ दाबून ठेवा, किंवा ''Ctrl-F5'' अथवा ''Ctrl-R'' कळा एकत्रितपणे दाबा (मॅकसाठी ''⌘-R'').\n\n*'''गूगल क्रोम:''' साठी ''Ctrl-Shift-R'' कळा एकत्रितपणे दाबा (मॅकसाठी ''⌘-Shift-R'')\n\n*'''इंटरनेट एक्सप्लोअरर:''' ''Refresh'' करतांना ''Ctrl'' कळ दाबून ठेवा, किंवा त्याऐवजी ''Ctrl-F5'' दाबा.\n\n*'''कॉन्क्वरर:''' '''Reload''' दाबा किंवा ''F5'' दाबा\n\n*'''ऑपेरा:''' ''Tools → Preferences'' मधून सय रिकामी करा",
        "usercssyoucanpreview": "'''टीप:'''तुमचे नवे सीएसएस जतन करण्यापूर्वी 'झलक पहा' कळ वापरा.",
        "userjsyoucanpreview": "'''टीप:''' तुमचा नवा जावास्क्रिप्ट जतन करण्यापूर्वी 'झलक पहा' कळ वापरा.",
        "editingsection": "$1 (विभाग) संपादन",
        "editingcomment": "$1 चे संपादन (प्रतिक्रिया)",
        "editconflict": "संपादन मतभेद: $1",
-       "explainconflict": "तà¥\81मà¥\8dहà¥\80 à¤¸à¤\82पादनाला à¤¸à¥\81रà¥\82वात à¤\95à¥\87लà¥\8dयानà¤\82तर à¤\87तर à¤\95à¥\8bणà¥\80तरà¥\80 à¤¬à¤¦à¤² à¤\95à¥\87ला à¤\86हà¥\87.\nवरà¥\80ल à¤ªà¤¾à¤ à¥\8dयभाà¤\97ामधà¥\8dयà¥\87 à¤¸à¤§à¥\8dया à¤\85सà¥\8dतिवात à¤\85सलà¥\87लà¥\8dया à¤ªà¥\83षà¥\8dठातà¥\80ल à¤ªà¤¾à¤ à¥\8dय à¤\86हà¥\87, à¤¤à¤° à¤¤à¥\81मà¤\9aà¥\87 à¤¬à¤¦à¤² à¤\96ालà¥\80ल à¤ªà¤¾à¤ à¥\8dयभाà¤\97ात à¤¦à¤°à¥\8dशविलà¥\87लà¥\87 à¤\86हà¥\87त.\nतà¥\81मà¥\8dहाला à¤¹à¥\87 à¤¬à¤¦à¤² à¤¸à¤§à¥\8dया à¤\85सà¥\8dतिवात à¤\85सणाऱà¥\8dया à¤ªà¤¾à¤ à¥\8dयासà¥\8bबत à¤\8fà¤\95तà¥\8dरित à¤\95रावà¥\87 à¤²à¤¾à¤\97तà¥\80ल.\n'''à¤\95à¥\87वळ''' à¤µà¤°à¥\80ल à¤ªà¤¾à¤ à¥\8dयभाà¤\97ामधà¥\8dयà¥\87 à¤\85सलà¥\87लà¥\87 à¤ªà¤¾à¤ à¥\8dय à¤¸à¤¾à¤ à¤µà¤¿à¤£à¥\8dयात à¤¯à¥\87à¤\88ल à¤\9cर à¤¤à¥\81मà¥\8dहà¥\80 \"{{int:savearticle}}\" à¤¹à¥\80 à¤\95ळ à¤¦à¤¾à¤¬à¤²à¥\80.",
+       "explainconflict": "à¤\86पण à¤¸à¤\82पादनाला à¤¸à¥\81रà¥\82वात à¤\95à¥\87लà¥\8dयानà¤\82तर à¤\87तर à¤\95à¥\8bणà¥\80तरà¥\80 à¤¯à¤¾ à¤ªà¤¾à¤¨à¤¾à¤¤ à¤¬à¤¦à¤² à¤\95à¥\87ला à¤\86हà¥\87.\nयातà¥\80ल à¤µà¤°à¤\9aà¥\8dया à¤ªà¤¾à¤ à¥\8dयभाà¤\97ामधà¥\8dयà¥\87 à¤¸à¤§à¥\8dया à¤\85सà¥\8dतिवात à¤\85सलà¥\87लà¥\8dया à¤ªà¥\83षà¥\8dठातà¥\80ल à¤ªà¤¾à¤ à¥\8dय à¤\86हà¥\87. à¤\86पलà¥\87 à¤¬à¤¦à¤² à¤¹à¥\87 à¤\96ालà¤\9aà¥\8dया à¤¬à¤¾à¤\9cà¥\82तà¥\80ल à¤ªà¤¾à¤ à¥\8dयभाà¤\97ात à¤¦à¤°à¥\8dशविलà¥\87लà¥\87 à¤\86हà¥\87त.\nà¤\86पलà¥\8dयाला à¤¹à¥\87 à¤¬à¤¦à¤² à¤¸à¤§à¥\8dया à¤\85सà¥\8dतिवात à¤\85सणाऱà¥\8dया à¤ªà¤¾à¤ à¥\8dयासà¥\8bबत à¤\8fà¤\95तà¥\8dरित à¤\95रावà¥\87 à¤²à¤¾à¤\97तà¥\80ल.\nà¤\9cर à¤¤à¥\81मà¥\8dहà¥\80 \"{{int:savearticle}}\" à¤¹à¥\80 à¤\95ळ à¤¦à¤¾à¤¬à¤²à¥\80 à¤¤à¤°,'''à¤\95à¥\87वळ''' à¤µà¤°à¤\9aà¥\8dया à¤ªà¤¾à¤ à¥\8dयभाà¤\97ामधà¥\8dयà¥\87 à¤\85सलà¥\87लà¥\87 à¤ªà¤¾à¤ à¥\8dयà¤\9a à¤¸à¤¾à¤ à¤µà¤¿à¤£à¥\8dयात à¤¯à¥\87à¤\88ल .",
        "yourtext": "तुमचा मजकूर",
        "storedversion": "साठविलेली आवृत्ती",
        "nonunicodebrowser": "'''सावधान: तुमचा न्याहाळक युनिकोड आधारित नाही. ASCII नसलेली  अक्षरचिन्हे संपादन खिडकीत सोळाअंकी कूटसंकेत (हेक्झाडेसीमल कोड) स्वरूपात दिसण्याची, सुरक्षितपणे संपादन करू देणारी,  पळवाट उपलब्ध आहे.'''",
        "protectedpagewarning": "'''सूचना: हे सुरक्षित पान आहे. फक्त प्रचालक याच्यात बदल करू शकतात.'''",
        "semiprotectedpagewarning": "'''सूचना:''' हे पान सुरक्षित आहे. फक्त नोंदणीकृत सदस्य याच्यात बदल करू शकतात.",
        "cascadeprotectedwarning": "<strong>ताकिद:</strong>हे पान निम्न-लिखीत निपतन-प्रतिबंधीत {{PLURAL:$1|पानात|पानांत}} आंतरभूत असल्यामुळे,केवळ प्रचालक-सुविधाप्राप्त सदस्यांनाच संपादन करता यावे असे ताळे त्यास ठोकलेले आहे :",
-       "titleprotectedwarning": "”’सावधान: फक्त काही सदस्यानांच [[Special:ListGroupRights|विशेष आधिकार]] तयार करता यावे म्हणून ह्या पानास ताळे आहे.'''",
+       "titleprotectedwarning": "”’सावधान: फक्त काही सदस्यानांच [[Special:ListGroupRights|विशेष आधिकार]] तयार करता यावेत म्हणून या पानास ताळे आहे.'''",
        "templatesused": "या पानामध्ये {{PLURAL:$1|वापरलेला साचा|वापरलेले साचे}}:",
        "templatesusedpreview": "या झलकेमध्ये {{PLURAL:$1|वापरलेला साचा|वापरलेले साचे}}:",
        "templatesusedsection": "या विभागामध्ये {{PLURAL:$1|वापरलेला साचा|वापरलेले साचे}}:",
        "rev-deleted-text-view": "या पानाची आवृत्ती '''वगळण्यात आली आहे'''.\nती तुम्ही बघू शकता; अधिक तपशील  [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळल्याच्या नोंदी] येथे मिळेल.",
        "rev-suppressed-text-view": "या पानाची आवृत्ती '''दडपली'''.\nआपण ती बघू शकता; [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} दडपलेल्यांचा क्रमलेख] येथे त्याची विस्तृत माहिती सापडेल.",
        "rev-deleted-no-diff": "आपण यातील फरक बघू शकत नाही कारण, त्यापैकी एक संस्करण '''वगळले''' आहे.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळल्याचा क्रमलेख] येथे त्याचा तपशील सापडेल.",
-       "rev-suppressed-no-diff": "तà¥\81मà¥\8dहà¥\80 à¤¹à¤¾ à¤«à¤°à¤\95 à¤ªà¤¾à¤¹à¥\82 à¤¶à¤\95त à¤¨à¤¾à¤¹à¥\80 à¤\95ारण à¤¯à¤¾ à¤\86वà¥\83तà¥\8dतà¥\8dयाà¤\82मधà¥\80ल à¤\8fà¤\95 à¤¸à¤\82सà¥\8dà¤\95रण â\80\9dâ\80\99वà¤\97ळणà¥\8dयात à¤\86लà¥\87 à¤\86हà¥\87\80\9dâ\80\99",
+       "rev-suppressed-no-diff": "à¤\86पण à¤¹à¤¾ à¤«à¤°à¤\95 à¤ªà¤¾à¤¹à¥\82 à¤¶à¤\95त à¤¨à¤¾à¤¹à¥\80 à¤\95ारण à¤¯à¤¾ à¤\86वà¥\83तà¥\8dतà¥\8dयाà¤\82मधà¥\80ल à¤\8fà¤\95 à¤\86वà¥\83तà¥\8dतà¥\80 <strong>वà¤\97ळणà¥\8dयात à¤\86लà¥\80 à¤\86हà¥\87</strong>.",
        "rev-deleted-unhide-diff": "या फरकाच्या आवृत्तींपैकी एक आवृत्ती  '''वगळण्यात आली आहे'''.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळण्याच्या नोंदी] येथे अधिक तपशिल मिळू शकेल.जर आपणास काम पुढे चालू ठेवायचे असेल तर आपण आत्ता सुद्धा [$1 हा फरक बघु शकता].",
        "rev-suppressed-unhide-diff": "या फरकाच्या आवृत्तींपैकी एक आवृत्ती '''दडपण्यात आली आहे'''. [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} दडपण्याच्या  नोंदी] येथे अधिक तपशिल मिळू शकेल.जर आपणास काम पुढे चालू ठेवायचे असेल तर, आपण आत्ता सुद्धा [$1 हा फरक बघु शकता].",
        "rev-deleted-diff-view": "या फरकाच्या आवृत्तींपैकी एक आवृत्ती '''वगळण्यात आली आहे'''. आपण हा फरक बघु शकता; [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळण्याच्या नोंदी] येथे अधिक तपशिल मिळू शकेल.",
        "revdelete-selected-text": "[[:$2]] ची/च्या {{PLURAL:$1|निवडलेली आवृत्ती|निवडलेल्या आवृत्त्या}} :",
        "revdelete-selected-file": "[[:$2]] ची/च्या {{PLURAL:$1|निवडलेली संचिका आवृत्ती|निवडलेल्या संचिका आवृत्त्या}} :",
        "logdelete-selected": "{{PLURAL:$1|निवडलेली नोंदीकृत घटना|निवडलेल्या नोंदीकृत घटना}}:",
-       "revdelete-text-text": "वà¤\97ळलà¥\87लà¥\8dया à¤\86वà¥\83तà¥\8dतà¥\8dया à¤¹à¥\8dया à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\8dया à¤\87तिहासात à¤¦à¤¿à¤¸à¤£à¤¾à¤° à¤¨à¤¾à¤¹à¥\80त, à¤ªà¤£ à¤¤à¥\8dयाà¤\9aà¥\8dया à¤\86शयाà¤\9aा à¤\95ाहà¥\80 à¤­à¤¾à¤\97 à¤¹à¤¾ à¤\9cनतà¥\87च्या पोहोचीबाहेर असेल.",
-       "revdelete-text-file": "वà¤\97ळलà¥\87लà¥\8dया à¤¸à¤\82à¤\9aिà¤\95à¥\87à¤\9aà¥\8dया à¤\86वà¥\83तà¥\8dतà¥\8dया à¤¹à¥\8dया à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\8dया à¤\87तिहासात à¤\85दà¥\8dयापहà¥\80 à¤¦à¤¿à¤¸à¤¤à¥\80ल, à¤ªà¤£ à¤¤à¥\8dयाà¤\9aà¥\8dया à¤\86शयाà¤\9aा à¤\95ाहà¥\80 à¤­à¤¾à¤\97 à¤¹à¤¾ à¤\9cनतà¥\87च्या पोहोचीबाहेर असेल.",
-       "logdelete-text": "वगळलेल्या नोंदी ह्या पानाच्या इतिहासात अजूनही दिसतील, पण त्याच्या आशयाचा काही भाग हा जनतेच्या पोहोचीबाहेर असेल.",
+       "revdelete-text-text": "वà¤\97ळलà¥\87लà¥\8dया à¤\86वà¥\83तà¥\8dतà¥\8dया à¤¯à¤¾ à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\8dया à¤\87तिहासात à¤¦à¤¿à¤¸à¤£à¤¾à¤° à¤¨à¤¾à¤¹à¥\80त, à¤ªà¤£ à¤¤à¥\8dयाà¤\9aà¥\8dया à¤\86शयाà¤\9aा à¤\95ाहà¥\80 à¤­à¤¾à¤\97 à¤¹à¤¾ à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dयाच्या पोहोचीबाहेर असेल.",
+       "revdelete-text-file": "वà¤\97ळलà¥\87लà¥\8dया à¤¸à¤\82à¤\9aिà¤\95à¥\87à¤\9aà¥\8dया à¤\86वà¥\83तà¥\8dतà¥\8dया à¤¯à¤¾ à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\8dया à¤\87तिहासात à¤\85दà¥\8dयापहà¥\80 à¤¦à¤¿à¤¸à¤¤à¥\80ल, à¤ªà¤£ à¤¤à¥\8dयाà¤\9aà¥\8dया à¤\86शयाà¤\9aा à¤\95ाहà¥\80 à¤­à¤¾à¤\97 à¤¹à¤¾ à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dयाच्या पोहोचीबाहेर असेल.",
+       "logdelete-text": "वगळलेल्या नोंद-घटना या, पानाच्या नोंदीत अजूनही दिसतील, पण त्याच्या आशयाचा काही भाग हा सामान्याच्या पोहोचीबाहेर असेल.",
        "revdelete-text-others": "अतिरिक्त बंधने स्थापिल्या गेली नसतील तर,दुसरे प्रशासक हे अजूनही लपविलेल्या आशयावर पोहोचु शकतील व त्याचे वगळणे पुनर्स्थापन करु शकतील.",
        "revdelete-confirm": "कृपया '''याची खात्री करा''' की तुम्ही जे करीत आहात, त्याचे परिणाम आपण जाणत आहात आणि, ते काम [[{{MediaWiki:Policy-url}}|मीडियाविकीच्या नीती]]नुसार आहे.",
        "revdelete-suppress-text": "लपवण्याचा वापर '''फक्त''' पुढील बाबतीत होतो:\n* उच्च दर्जाची बदनामीकारक माहिती\n* अयोग्य व्यक्तिगत माहिती\n*: ''गृहपत्ते, दूरध्वनी क्रमांक व राष्ट्रीय ओळख क्रमांक वगैरे''",
        "pagehist": "पानाचा इतिहास",
        "deletedhist": "वगळलेला इतिहास",
        "revdelete-hide-current": "$2 या दिनांकाची बाब लपविण्यात त्रुटी, $1: हे सद्य पुनरावर्तन आहे.\nते लपवता येत नाही.",
-       "revdelete-show-no-access": "$2, $1 ची बाब दाखवताना अडचण: ती \"प्रतिबंधित\" खूण असलेली आहे.\nतुम्ही तिच्यापर्यंत पोचू शकत नाही.",
+       "revdelete-show-no-access": "$2'दिनांकाची बाब दाखवितांना त्रुटी, $1:  त्या बाबीवर \"निर्बंधित\" अशी खूण आहे.\nआपणास त्यावर पोहोच नाही.",
        "revdelete-modify-no-access": "$2, $1 ची बाब संपादताना अडचण: ती \"प्रतिबंधित\" खूण असलेली आहे.\nतुम्ही तिच्यापर्यंत पोचू शकत नाही.",
        "revdelete-modify-missing": "बाब क्र. $1 ला संपादताना त्रुटी: ती माहितीकोषात नाही!",
        "revdelete-no-change": "'''सूचना:''' $2, $1 च्या बाबीने अगोदरच दृश्यता रुपरेषा मागितल्या आहेत.",
        "revdelete-edit-reasonlist": "वगळण्याची कारणे संपादित करा",
        "revdelete-offender": "आवर्तन निर्माता:",
        "suppressionlog": "दडपण्याची नोंद",
-       "suppressionlogtext": "à¤\96ालà¥\80ल à¤¦à¤¿à¤²à¥\87लà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤¹à¥\80 à¤µà¤\97ळणà¥\8dयाà¤\9aà¥\80 à¤µ à¤ªà¥\8dरतिबà¤\82धनाà¤\9aà¥\80 à¤\86हà¥\87 à¤\9cà¥\8dयाà¤\9aा à¤\86शय à¤¹à¤¾ à¤ªà¥\8dरशासà¤\95ाà¤\82पासà¥\82न à¤²à¤ªà¤µà¤¿à¤£à¥\8dयात à¤\86ला à¤\86हà¥\87.सधà¥\8dया à¤\85सà¥\8dतितà¥\8dवात à¤\85सलà¥\87लà¥\80 à¤¬à¤\82दà¥\80 à¤µ à¤ªà¥\8dरतिबà¤\82धनाà¤\82à¤\9aà¥\80   \nयादी [[Special:BlockList|प्रतिबंधनांची यादी]] बघा.",
+       "suppressionlogtext": "à¤\96ालà¥\80ल à¤¦à¤¿à¤²à¥\87लà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤¹à¥\80 à¤µà¤\97ळणà¥\8dयाà¤\9aà¥\80 à¤µ à¤ªà¥\8dरतिबà¤\82धनाà¤\9aà¥\80 à¤\86हà¥\87 à¤\9cà¥\8dयाà¤\9aा à¤\86शय à¤¹à¤¾ à¤ªà¥\8dरशासà¤\95ाà¤\82पासà¥\82न à¤²à¤ªà¤µà¤¿à¤£à¥\8dयात à¤\86ला à¤\86हà¥\87.सधà¥\8dया à¤\85सà¥\8dतितà¥\8dवात à¤\85सलà¥\87लà¥\8dया à¤¬à¤\82दà¥\80 à¤µ à¤ªà¥\8dरतिबà¤\82धनाà¤\82à¤\9aà¥\8dया   \nयादà¥\80साठी [[Special:BlockList|प्रतिबंधनांची यादी]] बघा.",
        "mergehistory": "पान इतिहासांचे एकत्रीकरण करा",
        "mergehistory-header": "हे पान एका स्रोत पानाचा इतिहास एखाद्या नवीन पानात समाविष्ट करू देते.\nहा बदल पानाचे ऐतिहासिक सातत्य राखेल याची दक्षता घ्या.",
        "mergehistory-box": "दोन पानांची आवर्तने संमिलीत करा:",
        "recentchanges-legend-heading": "'''विवरण:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नविन पानांची यादी]] हेही पाहा)",
        "recentchanges-legend-plusminus": "(''±१२३'')",
+       "recentchanges-submit": "दाखवा",
        "rcnotefrom": "खाली {{PLURAL:$5|हा बदल आहे|हे बदल आहेत}} <strong>$3, $4</strong>पासून ते(<strong>$1</strong>पर्यंतचे  बदल दाखविले आहेत).",
        "rclistfrom": "$2,$3 पासून सुरुवात करुन, नविन केल्या गेलेले बदल दाखवा.",
        "rcshowhideminor": "छोटे बदल $1",
        "filetype-badmime": "विविधामाप(माईम) \"$1\" प्रकारच्या संचिका चढवण्यास परवानगी नाही.",
        "filetype-bad-ie-mime": "ही संचिका चढवता येत नाही कारण इंटरनेट एक्स्प्लोरर तिला \"$1\" म्हणून ओळखेल. हा संचिकाप्रकार प्रतिबंधित व संभाव्य धोकादायक संचिकाप्रकार आहे.",
        "filetype-unwanted-type": "'''\".$1\"''' हा अवांछित संचिका प्रकार आहे. प्राधान्याने $2 {{PLURAL:$3|या प्रकारच्या |या प्रकारांच्या}} संचिका हव्या आहेत.",
-       "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|ही परवानगी नसलेल्या प्रकारची संचिका आहे.|ह्या परवानगी नसलेल्या प्रकारच्या संचिका आहेत.}} $2 {{PLURAL:$3|ही परवानगी असलेल्या प्रकारची संचिका आहे|ह्या परवानगी असलेल्या प्रकारच्या संचिका आहेत}}.",
+       "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|ही परवानगी नसलेल्या प्रकारची संचिका आहे|या परवानगी नसलेल्या प्रकारच्या संचिका आहेत.}} $2 {{PLURAL:$3|ही परवानगी असलेल्या प्रकारची संचिका आहे|या परवानगी असलेल्या प्रकारच्या संचिका आहेत}}.",
        "filetype-missing": "या संचिकेला विस्तारक(एक्सटेंशन) दिलेले नाही (उदा. \".jpg\").",
        "empty-file": "तुम्ही प्रस्तुत केलेली संचिका रिकामी होती.",
        "file-too-large": "तुम्ही प्रस्तुत केलेली संचिका आकाराने खूप जास्त होती.",
        "uploaded-hostile-svg": "अपभारीलेल्या SVG संचिकेत,असुरक्षित CSS स्टाईल अवयव आढळले.",
        "uploadscriptednamespace": "या SVG संचिकेत \"$1\" हे अवैध नामविश्व आहे.",
        "uploadinvalidxml": "अपभारीत संचिकेतील XML पार्स करता आले नाही.",
-       "uploadvirus": "हà¥\8dया à¤¸à¤\82à¤\9aिà¤\95à¥\87त à¤µà¥\8dहायरस आहे. अधिक माहिती: $1",
+       "uploadvirus": "या à¤¸à¤\82à¤\9aिà¤\95à¥\87त à¤µà¤¿à¤·à¤¾à¤£à¥\82(वà¥\8dहायरस) आहे. अधिक माहिती: $1",
        "uploadjava": "ही फाईल झीप ह्या प्रकारातील आहे ज्यामधे जावा .क्लास फाईल. आहे,जावा फाईलचे अपभारणास परवानगी नाही कारण त्याने सुरक्षा-बंधने टाळल्या जाऊ शकतात.",
        "upload-source": "स्रोत संचिका",
        "sourcefilename": "स्रोत-संचिकानाम:",
        "mostrevisions": "सर्वाधिक बदललेले लेख",
        "prefixindex": "उपसर्ग असणाऱ्या लेखांची यादी",
        "prefixindex-namespace": "($1 नामविश्व) हा  उपसर्ग असणारी सर्व पाने",
+       "prefixindex-submit": "दर्शवा",
        "prefixindex-strip": "यादीतील उपसर्ग काढा",
        "shortpages": "छोटी पाने",
        "longpages": "मोठी पाने",
        "protectedpages-performer": "सदस्याचे रक्षण करीत आहे",
        "protectedpages-params": "रक्षणाची प्राचले",
        "protectedpages-reason": "कारण",
+       "protectedpages-submit": "पाने दर्शवा",
        "protectedpages-unknown-timestamp": "अज्ञात",
        "protectedpages-unknown-performer": "अनामिक सदस्य",
        "protectedtitles": "सुरक्षीत शीर्षके",
        "protectedtitles-summary": "या पानात अशा शीर्षकांची यादी आहे, जी नविन तयार करता येउ  शकणार नाहीत.अस्तित्वात असणाऱ्या संरक्षित पानांच्या यादीसाठी [[{{#special:ProtectedPages}}|{{int:protectedpages}}]] बघा.",
        "protectedtitlesempty": "या नियमावलीने सध्या कोणतीही शीर्षके सुरक्षित केलेली नाहीत.",
+       "protectedtitles-submit": "शीर्षके दर्शवा",
        "listusers": "सदस्यांची यादी",
        "listusers-editsonly": "फक्त संपादनांसहित सदस्य दाखवा",
        "listusers-creationsort": "निर्मितीच्या तारखेप्रमाणे लावा",
        "activeusers-hidebots": "सांगकामे लपवा",
        "activeusers-hidesysops": "प्रचालक लपवा",
        "activeusers-noresult": "एकही सदस्य सापडला नाही.",
+       "activeusers-submit": "सक्रिय सदस्य दर्शवा",
        "listgrouprights": "सदस्य गट अधिकार",
-       "listgrouprights-summary": "à¤\96ालà¥\80 à¤¯à¤¾ à¤µà¤¿à¤\95िवर à¤¦à¤¿à¤²à¥\87लà¥\80 à¤¸à¤¦à¤¸à¥\8dय à¤\97à¤\9fाà¤\82à¤\9aà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤¤à¥\8dयाà¤\82à¤\9aà¥\8dया à¤\85धिà¤\95ाराà¤\82सà¤\95à¤\9f à¤¦à¤°à¥\8dशविलà¥\87लà¥\80 à¤\86हà¥\87. à¤ªà¥\8dरतà¥\8dयà¥\87à¤\95ाà¤\9aà¥\8dया à¤\85धिà¤\95ाराà¤\82à¤\9aà¥\80 à¤\85धिà¤\95 à¤®à¤¾à¤¹à¤¿à¤¤à¥\80 [[{{MediaWiki:Listgrouprights-helppage}}|à¤\87थà¥\87]] à¤¦à¤¿à¤²à¥\87लà¥\80 à¤\86हे.",
+       "listgrouprights-summary": "या à¤µà¤¿à¤\95िवर à¤¦à¤¿à¤²à¥\87लà¥\80 à¤¸à¤¦à¤¸à¥\8dय à¤\97à¤\9fाà¤\82à¤\9aà¥\80 à¤µà¥\8dयाà¤\96à¥\8dयिà¤\95à¥\83त à¤¯à¤¾à¤¦à¥\80 à¤¤à¥\8dयाà¤\82à¤\9aà¥\8dया à¤\85धिà¤\95ाराà¤\82सà¤\95à¤\9f à¤\96ालà¥\80 à¤¦à¤°à¥\8dशविलà¥\87लà¥\80 à¤\86हà¥\87. à¤ªà¥\8dरतà¥\8dयà¥\87à¤\95ाà¤\9aà¥\8dया à¤µà¥\88यà¤\95à¥\8dतिà¤\95 à¤\85धिà¤\95ाराà¤\82à¤\9aà¥\80 [[{{MediaWiki:Listgrouprights-helppage}}|à¤\85धिà¤\95 à¤®à¤¾à¤¹à¤¿à¤¤à¥\80]] à¤¯à¥\87थà¥\87 à¤\85सà¥\81 à¤¶à¤\95ते.",
        "listgrouprights-key": "विवरण:\n* <span class=\"listgrouprights-granted\">प्रदत्त अधिकार</span>\n* <span class=\"listgrouprights-revoked\">रद्द अधिकार</span>",
        "listgrouprights-group": "गट",
        "listgrouprights-rights": "अधिकार",
        "wlshowlast": "मागील $1 तास $2 दिवस दाखवा",
        "watchlistall2": "सर्व",
        "watchlist-hide": "लपवा",
+       "watchlist-submit": "दर्शवा",
        "wlshowtime": "शेवटचे दाखवा:",
        "wlshowhideminor": "छोटी संपादने",
        "wlshowhidebots": "सांगकामे",
        "exbeforeblank": "वगळण्यापूर्वीचा मजकूर पुढीलप्रमाणे: '$1'",
        "delete-confirm": "\"$1\" वगळा",
        "delete-legend": "वगळा",
-       "historywarning": "<strong>à¤\88शारा:</strong> à¤¤à¥\81मà¥\8dहà¥\80 वगळत असलेल्या पानाला $1 {{PLURAL:$1|आवर्तनाचा|आवर्तनांचा}} इतिहास आहे:",
-       "confirmdeletetext": "तà¥\81मà¥\8dहà¥\80 à¤\8fà¤\95 à¤²à¥\87à¤\96पान à¤¤à¥\8dयाà¤\9aà¥\8dया à¤¸à¤°à¥\8dव à¤\87तिहासासà¥\8bबत à¤µà¤\97ळणà¥\8dयाà¤\9aà¥\8dया à¤¤à¤¯à¤¾à¤°à¥\80त à¤\86हात.\nà¤\95à¥\83पया, à¤¤à¥\81मà¥\8dहà¥\80 à¤\95रà¥\80त à¤\85सलà¥\87लà¥\80 à¤\95à¥\83तà¥\80 à¤¹à¥\80 à¤®à¥\80डियाविà¤\95à¥\80à¤\9aà¥\8dया [[{{MediaWiki:Policy-url}}|नà¥\80तà¥\80नà¥\81सार]] à¤\86हà¥\87 à¤¹à¥\8dयाà¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95रा. à¤¤à¤¸à¥\87à¤\9a, à¤¤à¥\81मà¥\8dहà¥\80 à¤\95रà¥\80त à¤\85सलà¥\87लà¥\8dया à¤\95à¥\83तà¥\80à¤\9aà¥\87 à¤ªà¤°à¤¿à¤£à¤¾à¤®, à¤\95à¥\83तà¥\80 à¤\95रणà¥\8dयापà¥\82रà¥\8dवà¥\80 à¤\9cाणà¥\82न à¤\98à¥\8dया.",
+       "historywarning": "<strong>à¤\87शारा:</strong> à¤\86पण वगळत असलेल्या पानाला $1 {{PLURAL:$1|आवर्तनाचा|आवर्तनांचा}} इतिहास आहे:",
+       "confirmdeletetext": "à¤\86पण à¤\8fà¤\95 à¤²à¥\87à¤\96पान à¤¤à¥\8dयाà¤\9aà¥\8dया à¤¸à¤°à¥\8dव à¤\87तिहासासà¥\8bबत à¤µà¤\97ळणà¥\8dयाà¤\9aà¥\8dया à¤¤à¤¯à¤¾à¤°à¥\80त à¤\86हात.\nà¤\95à¥\83पया, à¤¯à¤¾à¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95ि, à¤\95रà¥\80त à¤\85सलà¥\87लà¥\8dया à¤\95à¥\83तà¥\80à¤\9aà¥\87 à¤ªà¤°à¤¿à¤£à¤¾à¤®, à¤\86पण à¤\95à¥\83तà¥\80 à¤\95रणà¥\8dयापà¥\82रà¥\8dवà¥\80 à¤\9cाणà¥\82न à¤\98à¥\87तलà¥\87 à¤\86हà¥\87त à¤µ à¤\86पण à¤¹à¥\87   [[{{MediaWiki:Policy-url}}|मà¥\80डियाविà¤\95à¥\80à¤\9aà¥\8dया à¤¨à¥\80तà¥\80नà¥\81सारà¤\9a]] à¤\95रà¥\80त à¤\86हात.",
        "actioncomplete": "काम पूर्ण",
        "actionfailed": "कृती अयशस्वी झाली",
        "deletedtext": "\"$1\" हा लेख वगळला. अलीकडे वगळलेले लेख पाहण्यासाठी $2 पहा.",
        "contributions": "{{GENDER:$1|सदस्य}} योगदान",
        "contributions-title": "$1 साठी सदस्य-योगदान",
        "mycontris": "योगदान",
+       "anoncontribs": "योगदान",
        "contribsub2": "{{GENDER:$3|$1}} ($2) साठी",
        "contributions-userdoesnotexist": "सदस्यखाते \"$1\"  हे नोंदलेले नाही.",
        "nocontribs": "या मानदंडाशी जुळणारे बदल सापडले नाहीत.",
        "sp-contributions-talk": "चर्चा",
        "sp-contributions-userrights": "सदस्य अधिकार व्यवस्थापन",
        "sp-contributions-blocked-notice": "हा सदस्य सध्या प्रतिबंधित आहे.\nसर्वांत नवीन प्रतिबंधन यादी खाली संदर्भासाठी दिली आहे:",
-       "sp-contributions-blocked-notice-anon": "हा à¤\85à¤\82à¤\95पतà¥\8dता à¤¸à¤§à¥\8dया à¤ªà¥\8dरतिबà¤\82धित à¤\86हà¥\87.\nसरà¥\8dवाà¤\82त à¤¨à¤µà¥\80न à¤ªà¥\8dरतिबà¤\82धन à¤¯à¤¾à¤¦à¥\80 à¤\96ाली संदर्भासाठी दिली आहे:",
+       "sp-contributions-blocked-notice-anon": "हा à¤\85à¤\82à¤\95पतà¥\8dता à¤¸à¤§à¥\8dया à¤ªà¥\8dरतिबà¤\82धित à¤\86हà¥\87.\nà¤\96ालà¥\80, à¤¸à¤°à¥\8dवाà¤\82त à¤¨à¤µà¥\80नतम à¤ªà¥\8dरतिबà¤\82धन à¤¨à¥\8bà¤\82दपà¥\8dरविषà¥\8dà¤\9fी संदर्भासाठी दिली आहे:",
        "sp-contributions-search": "योगदान शोधयंत्र",
        "sp-contributions-username": "आंतरजाल अंकपत्ता किंवा सदस्यनाम:",
        "sp-contributions-toponly": "केवळ नवीनतम आवर्तने असलेलीच संपादने दाखवा",
        "whatlinkshere-hidelinks": "$1 दुवे",
        "whatlinkshere-hideimages": "$1 संचिका दुवे",
        "whatlinkshere-filters": "गाळण्या",
+       "whatlinkshere-submit": "जा",
        "autoblockid": "स्वयंचलितपणे #$1ला प्रतिबंधित करा",
        "block": "सदस्यास प्रतिबंध करा",
        "unblock": "सदस्यप्रतिबंध काढा",
        "movepage-page-moved": "$1 हे पान $2 या मथळ्याखाली स्थानांतरीत केले.",
        "movepage-page-unmoved": "$1 हे पान $2 या मथळ्याखाली स्थानांतरीत करता आलेले नाही.",
        "movepage-max-pages": "जास्तीत जास्त $1 {{PLURAL:$1|पान|पाने}} स्थानांतरीत करण्यात {{PLURAL:$1|आलेले आहे|आलेली आहेत}} व आता आणखी पाने आपोआप स्थानांतरीत होणार नाहीत.",
-       "movelogpage": "सà¥\8dथाà¤\82नाà¤\82तराà¤\9aà¥\80 à¤¨à¥\8bà¤\82द",
+       "movelogpage": "स्थानांतराची नोंद",
        "movelogpagetext": "स्थानांतरित केलेल्या पानांची यादी.",
        "movesubpage": "{{PLURAL:$1|उपपान|उपपाने}}",
        "movesubpagetext": "या पानास $1 {{PLURAL:$1|उपपान|उपपाने}} असून ती पुढे दर्शवली आहेत:",
        "movenosubpage": "या पानात उपपाने नाहीत.",
        "movereason": "कारण:",
        "revertmove": "पूर्वपदास न्या",
-       "delete_and_move": "वगळा आणि स्थानांतरित करा",
        "delete_and_move_text": "==वगळण्याची आवश्यकता==\n\nलक्ष्यपान  \"[[:$1]]\" आधीच अस्तित्वात आहे.स्थानांतराचा मार्ग मोकळा करण्याकरिता तुम्हाला ते वगळावयाचे आहे काय?",
        "delete_and_move_confirm": "होय, पान वगळा",
        "delete_and_move_reason": "\"[[$1]]\" पासून वगळून स्थानांतर केले.",
        "tooltip-pt-anontalk": "या अंकपत्त्यापासून झालेल्या संपादनांबद्दल चर्चा",
        "tooltip-pt-preferences": "तुमचा पसंतीक्रम",
        "tooltip-pt-watchlist": "तुम्ही पहारा दिलेल्या पानांची यादी",
-       "tooltip-pt-mycontris": "तुमच्या योगदानांची यादी",
+       "tooltip-pt-mycontris": "आपल्या योगदानांची यादी",
+       "tooltip-pt-anoncontribs": "या अंकपत्त्यावरुन झालेले संपादन",
        "tooltip-pt-login": "आपणांस सनोंद प्रवेशासाठी प्रोत्साहीत करण्यात येत आहे;अर्थातच, ते अनिवार्य नाही.",
        "tooltip-pt-logout": "सनोंद निर्गम",
        "tooltip-pt-createaccount": "आम्ही आपणास खाते उघडून सनोंद-प्रवेशास प्रोत्साहीत करत आहे;अर्थातच, ते अनिवार्य नाही.",
        "exif-bitspersample": "प्रती घटक बीट्स",
        "exif-compression": "आकुंचन योजना",
        "exif-photometricinterpretation": "चित्रांश विन्यास (पिक्सेल कॉम्पोझीशन)",
-       "exif-orientation": "वळण",
+       "exif-orientation": "à¤\85भिमà¥\81à¤\96न",
        "exif-samplesperpixel": "घटकांची संख्या",
        "exif-planarconfiguration": "विदा रचना",
        "exif-ycbcrsubsampling": "Y चे C शी  उपनमुनातपासणी (सबसॅम्पलींग) गुणोत्तर",
        "exif-ycbcrpositioning": "Y आणि C प्रतिस्थापना (पोझीशनींग)",
-       "exif-xresolution": "समाà¤\82तर रिझोल्यूशन",
+       "exif-xresolution": "à¤\86डवà¥\87 रिझोल्यूशन",
        "exif-yresolution": "उभे रिझोल्यूशन",
        "exif-stripoffsets": "चित्रविदा स्थान",
        "exif-rowsperstrip": "प्रत्येक पट्टीतील ओळींची संख्या",
        "exif-datetime": "संचिका बदल तारीख आणि वेळ",
        "exif-imagedescription": "चित्र शीर्षक",
        "exif-make": "कॅमेरा उत्पादक",
-       "exif-model": "à¤\95à¥\85मà¥\87रा à¤\89पà¤\95रण",
+       "exif-model": "à¤\95à¥\85मà¥\87रा à¤¨à¤®à¥\82ना",
        "exif-software": "वापरलेली संगणन आज्ञावली",
        "exif-artist": "लेखक",
        "exif-copyright": "प्रताधिकार धारक",
        "confirmemail_success": "तुमचा विपत्र (ई-मेल) पत्ता प्रमाणित झाला आहे.तुम्ही आता [[Special:UserLogin|दाखल]] होऊ शकता आणि विकिचा आनंद घेऊ शकता.",
        "confirmemail_loggedin": "तुमचा विपत्र (ई-मेल) पत्ता आता प्रमाणित झाला आहे.",
        "confirmemail_subject": "{{SITENAME}} विपत्र (ई-मेल) पत्ता प्रमाणित",
-       "confirmemail_body": "à¤\95à¥\81णà¥\80तरà¥\80, à¤¬à¤¹à¥\81तà¥\87à¤\95 à¤¤à¥\81मà¥\8dहà¥\80, $1 à¤¯à¤¾ à¤ªà¤¤à¥\8dतà¥\8dयावारà¥\82न, \"$2\" à¤\96ातà¥\87 à¤¹à¤¾ à¤\88मà¥\87ल à¤ªà¤¤à¥\8dता à¤µà¤¾à¤ªà¤°à¥\82न {{SITENAME}} à¤¯à¤¾ à¤¸à¤\82à¤\95à¥\87तसà¥\8dथळावर à¤\89à¤\98डलà¥\87 à¤\86हà¥\87.\n\nहà¥\87 à¤\96ातà¥\87 à¤\96रà¥\8bà¤\96र à¤¤à¥\81मà¤\9aà¥\87 à¤\86हà¥\87 à¤¯à¤¾à¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95रणà¥\8dयासाठà¥\80 à¤\86णि {{SITENAME}} à¤µà¤° à¤\88मà¥\87ल à¤ªà¤°à¥\8dयाय à¤\89तà¥\8dतà¥\87à¤\9cित (à¤\89पलबà¥\8dध) à¤\95रणà¥\8dयासाठà¥\80, à¤¹à¤¾ à¤¦à¥\81वा à¤¤à¥\81मà¤\9aà¥\8dया à¤¬à¥\8dराà¤\89à¤\9cर à¤®à¤§à¥\87 à¤\89à¤\98डा:\n\n$3\n\nà¤\9cर à¤¤à¥\81मà¥\8dहà¥\80 à¤¹à¥\87 à¤\96ातà¥\87 à¤\89à¤\98डलà¥\87 *नसà¥\87ल* à¤¤à¤° à¤¹à¥\80 à¤®à¤¾à¤\97णà¥\80 à¤°à¤¦à¥\8dद à¤\95रणà¥\8dयासाठà¥\80 à¤\96ालà¥\80ल à¤¦à¥\81वा à¤\89à¤\98डा:\n\n$5\n\nहा à¤¹à¤®à¥\80 à¤\95लम $4 à¤²à¤¾ à¤¨à¤·à¥\8dà¤\9f होईल.",
+       "confirmemail_body": "à¤\95à¥\81णà¥\80तरà¥\80, à¤¬à¤¹à¥\81तà¥\87à¤\95 à¤\86पणà¤\9a, $1 à¤¯à¤¾ à¤\85à¤\82à¤\95पतà¥\8dतà¥\8dयावरà¥\82न, à¤¹à¤¾ à¤µà¤¿à¤ªà¤¤à¥\8dरपतà¥\8dता(à¤\88मà¥\87ल) à¤µà¤¾à¤ªà¤°à¥\82न,, {{SITENAME}} à¤µà¤° \"$2\" à¤\96ातà¥\87 à¤\89à¤\98डलà¥\87 à¤\86हà¥\87.\n\nहà¥\87 à¤\96ातà¥\87 à¤\96रà¥\8bà¤\96र à¤\86पलà¥\87 à¤\86हà¥\87 à¤¯à¤¾à¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95रणà¥\8dयासाठà¥\80 à¤\86णि {{SITENAME}} à¤µà¤° à¤µà¤¿à¤ªà¤¤à¥\8dर à¤ªà¥\8dरारà¥\81प à¤¸à¤\95à¥\8dरिय (à¤\89पलबà¥\8dध) à¤\95रणà¥\8dयासाठà¥\80, à¤¹à¤¾ à¤¦à¥\81वा à¤¤à¥\81मà¤\9aà¥\8dया à¤¨à¥\8dयाहाळà¤\95ात(बà¥\8dराà¤\89à¤\9cर) à¤\89à¤\98डा:\n\n$3\n\nà¤\9cर à¤\86पण à¤¹à¥\87 à¤\96ातà¥\87 à¤\89à¤\98डलà¥\87 *नसà¥\87ल* à¤¤à¤° à¤¹à¤¾ à¤µà¤¿à¤ªà¤¤à¥\8dरपतà¥\8dता à¤µà¤\97ळणà¥\8dयासाठà¥\80,à¤\96ालà¥\80ल à¤¦à¥\81वा à¤\85नà¥\81सरा:\n\n$5\n\nनिशà¥\8dà¤\9aितà¥\80à¤\95रण à¤¸à¤\82à¤\95à¥\87त(à¤\95नà¥\8dफरà¥\8dमà¥\87शन à¤\95à¥\8bड) $4 à¤²à¤¾ à¤\95ालबाहà¥\8dय होईल.",
        "confirmemail_body_changed": "\n\n{{SITENAME}} या संकेतस्थळावर कुणीतरी, बहुतेक तुम्ही, $1 या अंकपत्त्यावारून, \"$2\" खात्याकरिताचा  ईमेल   आपल्या या ई-मेल पत्त्यावर बदलला आहे.\n\nहे खाते खरोखर तुमचे आहे याची खात्री करण्यासाठी आणि {{SITENAME}} वर ईमेल पर्याय उत्तेजित (उपलब्ध) करण्यासाठी, हा दुवा तुमच्या ब्राउजर मधे उघडा:\n\n$3\n\nजर तुम्ही हे खाते तुमचे *नसेल* तर ही ई-मेल पत्त्याच्या बदलाची मागणी रद्द करण्यासाठी खालील दुवा उघडा:\n\n$5\n\nहा  निश्चितीकरण संदेश  $4 ला नष्ट होईल.",
-       "confirmemail_body_set": "{{SITENAME}} à¤¯à¤¾ à¤¸à¤\82à¤\95à¥\87तसà¥\8dथळावर à¤\95à¥\81णà¥\80तरà¥\80, à¤¬à¤¹à¥\81तà¥\87à¤\95 à¤¤à¥\81मà¥\8dहà¥\80, $1 à¤¯à¤¾ à¤\85à¤\82à¤\95पतà¥\8dतà¥\8dयावरà¥\82न, \"$2\" à¤\96ातà¥\8dयाà¤\95रिताà¤\9aा  à¤\88-मà¥\87ल,  à¤\86पलà¥\8dया à¤¯à¤¾ à¤\88-मà¥\87ल à¤ªà¤¤à¥\8dतà¥\8dयानà¥\81सार à¤¦à¤¿à¤²à¤¾ à¤\86हà¥\87.\n\nहà¥\87 à¤\96ातà¥\87 à¤\96रà¥\8bà¤\96र à¤¤à¥\81मà¤\9aà¥\87 à¤\86हà¥\87 à¤¯à¤¾à¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95रणà¥\8dयासाठà¥\80 à¤\86णि {{SITENAME}} à¤µà¤° à¤\88-मà¥\87ल à¤ªà¤°à¥\8dयाय à¤\89तà¥\8dतà¥\87à¤\9cित (à¤\89पलबà¥\8dध) à¤\95रणà¥\8dयासाठà¥\80, à¤¹à¤¾ à¤¦à¥\81वा à¤¤à¥\81मà¤\9aà¥\8dया à¤¬à¥\8dराà¤\89à¤\9cर à¤®à¤§à¥\87 à¤\89à¤\98डा:\n\n$3\n\nà¤\9cर à¤¤à¥\81मà¥\8dहà¥\80 à¤¹à¥\87 à¤\96ातà¥\87 à¤¤à¥\81मà¤\9aà¥\87 *नसà¥\87ल* à¤¤à¤° à¤¹à¥\80 à¤\88-मà¥\87ल à¤ªà¤¤à¥\8dतà¥\8dयाà¤\9aà¥\8dया à¤¬à¤¦à¤²à¤¾à¤\9aà¥\80 à¤®à¤¾à¤\97णà¥\80 à¤°à¤¦à¥\8dद à¤\95रणà¥\8dयासाठà¥\80 à¤\96ालà¥\80ल à¤¦à¥\81वा à¤\89à¤\98डा:\n\n$5\n\nहा à¤\96ातà¥\8dरà¥\80à¤\95रण à¤¸à¤\82दà¥\87श  $4 à¤µà¥\87ळà¥\87त à¤¨à¤·à¥\8dà¤\9f होईल.",
+       "confirmemail_body_set": "{{SITENAME}} à¤µà¤° à¤\95à¥\81णà¥\80तरà¥\80, à¤¬à¤¹à¥\81तà¥\87à¤\95 à¤\86पणà¤\9a, $1 à¤¯à¤¾ à¤\85à¤\82à¤\95पतà¥\8dतà¥\8dयावरà¥\82न, \"$2\" à¤¯à¤¾  à¤\96ातà¥\8dयाà¤\95रिताà¤\9aा à¤µà¤¿à¤ªà¤¤à¥\8dरपतà¥\8dता (à¤\88-मà¥\87ल), à¤¯à¤¾ à¤ªà¤¤à¥\8dतà¥\8dयास à¤¸à¥\8dथापिलà¥\87ला à¤\86हà¥\87.\n\nहà¥\87 à¤\96ातà¥\87 à¤\96रà¥\8bà¤\96र à¤\86पलà¥\87à¤\9a à¤\86हà¥\87 à¤¯à¤¾à¤\9aà¥\80 à¤\96ातà¥\8dरà¥\80 à¤\95रणà¥\8dयासाठà¥\80 à¤\86णि {{SITENAME}} à¤µà¤° à¤µà¤¿à¤ªà¤¤à¥\8dरपतà¥\8dता à¤ªà¥\8dरारà¥\81प à¤¸à¤\95à¥\8dरिय(à¤\89पलबà¥\8dध) à¤\95रणà¥\8dयासाठà¥\80, à¤¹à¤¾ à¤¦à¥\81वा à¤\86पलà¥\8dया à¤¨à¥\8dयाहाळà¤\95ात(बà¥\8dराà¤\89à¤\9cर) à¤\89à¤\98डा:\n\n$3\n\nà¤\9cर à¤¹à¥\87 à¤\96ातà¥\87 à¤\86पलà¥\87 *नसà¥\87ल* à¤¤à¤°, à¤¹à¥\80 à¤µà¤¿à¤ªà¤¤à¥\8dरपतà¥\8dयाà¤\9aà¥\87 à¤¨à¤¿à¤¶à¥\8dà¤\9aितà¥\80à¤\95रण à¤µà¤\97ळणà¥\8dयासाठà¥\80,à¤\96ालà¥\80ल à¤¦à¥\81वà¥\8dयास à¤\85नà¥\81सरा:\n\n$5\n\nहा à¤¨à¤¿à¤¶à¥\8dà¤\9aितà¥\80à¤\95रण à¤¸à¤\82à¤\95à¥\87त(à¤\95नà¥\8dफरà¥\8dमà¥\87शन à¤\95à¥\8bड) $4 à¤²à¤¾ à¤\95ालबाहà¥\8dय होईल.",
        "confirmemail_invalidated": "इ-मेल पत्ता तपासणी रद्द करण्यात आलेली आहे",
        "invalidateemail": "इ-मेल तपासणी रद्द करा",
        "scarytranscludedisabled": "[आंतरविकि आंतरन्यास अनुपलब्ध केले आहे]",
        "lag-warn-high": "विदा विदादात्यास लागणाऱ्या अत्युच्च कालावधी मुळे, $1 {{PLURAL:$1|सेकंदापेक्षा|सेकंदांपेक्षा}} नवे बदल या सूचित कदाचित दाखवले नाही जाणार.",
        "watchlistedit-normal-title": "पहाऱ्याची सूचीचे संपादन करा",
        "watchlistedit-normal-legend": "शीर्षकपाने नित्य पहाण्याच्या सूचीतून काढा",
-       "watchlistedit-normal-explain": "तà¥\81मà¤\9aà¥\8dया à¤ªà¤¹à¤¾à¤°à¥\8dâ\80\8dयाà¤\9aà¥\8dया à¤¸à¥\82à¤\9aà¥\80तà¥\80ल à¤\85à¤\82तरà¥\8dभà¥\82त à¤¨à¤¾à¤®à¤¾à¤µà¤³à¥\80 à¤\96ालà¥\80 à¤¨à¤¿à¤°à¥\8dदà¥\87शित à¤\95à¥\87लà¥\80 à¤\86हà¥\87. à¤¶à¥\80रà¥\8dषà¤\95 à¤µà¤\97ळणà¥\8dयाà¤\95रिता, à¤¤à¥\8dया à¤ªà¥\81ढà¥\80ल à¤\96िडà¤\95à¥\80 à¤¨à¤¿à¤µà¤¡à¤¾, à¤\86णि à¤¶à¥\80रà¥\8dषà¤\95 à¤µà¤\97ळावर à¤\9fिà¤\9aà¤\95à¥\80 à¤®à¤¾à¤°à¤¾. à¤¤à¥\81मà¥\8dहà¥\80 [[Special:EditWatchlist/raw|कच्ची यादी सुद्धा संपादित]] करू शकता.",
+       "watchlistedit-normal-explain": "à¤\86पलà¥\8dया à¤ªà¤¹à¤¾à¤°à¥\8dâ\80\8dयाà¤\9aà¥\8dया à¤¸à¥\82à¤\9aà¥\80तà¥\80ल à¤¶à¥\80रà¥\8dषà¤\95à¥\87 à¤\96ालà¥\80 à¤¦à¤°à¥\8dशविणà¥\8dयात à¤\86लà¥\87लà¥\80 à¤\86हà¥\87त.à¤\8fà¤\96ादà¥\87 à¤¶à¥\80रà¥\8dषà¤\95 à¤¹à¤\9fविणà¥\8dयाà¤\95रà¥\80ता, à¤¤à¥\8dया à¤ªà¥\81ढà¥\80ल à¤ªà¥\87à¤\9fà¥\80(बà¥\89à¤\95à¥\8dस) à¤¨à¤¿à¤µà¤¡à¤¾(à¤\9aà¥\87à¤\95), à¤\86णि \"{{int:Watchlistedit-normal-submit}}\" à¤µà¤° à¤\9fिà¤\9aà¤\95à¥\80 à¤®à¤¾à¤°à¤¾. à¤\86पण [[Special:EditWatchlist/raw|कच्ची यादी सुद्धा संपादित]] करू शकता.",
        "watchlistedit-normal-submit": "शिर्षक वगळा",
        "watchlistedit-normal-done": "तुमच्या नित्य पहाण्या सूचीतून वगळलेली {{PLURAL:$1|1 शीर्षक होते |$1 शीर्षके होती }}:",
        "watchlistedit-raw-title": "कच्ची नित्य पहाण्याची सूची संपादित करा",
        "htmlform-invalid-input": "तुम्ही दिलेल्या माहितीत काहीतरी गडबड आहे",
        "htmlform-select-badoption": "आपण नमूद करत असलेली व्हॅल्यू ग्राह्य पर्याय ठरत नाही",
        "htmlform-int-invalid": "आपण नमूद केलेली व्हॅल्यू पूर्णांक (इंटीजर) नाही.",
-       "htmlform-float-invalid": "तà¥\81मà¥\8dहà¥\80 à¤¦à¤¿à¤²à¥\87लà¥\80 à¤\95िà¤\82मत à¤\86à¤\95डा नाही.",
+       "htmlform-float-invalid": "à¤\86पण à¤¦à¤¿à¤²à¥\87लà¥\80 à¤\95िà¤\82मत à¤¹à¥\80 à¤\8fà¤\95 'सà¤\82à¤\96à¥\8dया नाही.",
        "htmlform-int-toolow": "$1 किंवा मोठा आकडा द्या.",
        "htmlform-int-toohigh": "$1 किंवा त्याहून छोटा आकडा द्या.",
        "htmlform-required": "ही किंमत आवश्यक आहे",
        "api-error-file-too-large": "तुम्ही प्रस्तुत केलेली संचिका आकाराने खूप मोठी होती.",
        "api-error-filename-tooshort": "संचिकेचे नाव खूपच छोटे आहे.",
        "api-error-filetype-banned": "याप्रकारची संचिका प्रतिबंधित आहे.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|हà¥\80 à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤¨à¤¸à¤²à¥\87ला  à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87.|हà¥\8dया à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤¨à¤¸à¤²à¥\87लà¥\8dया à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87त.}} $2 {{PLURAL:$3|हà¥\80 à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤\85सलà¥\87ला à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87|हà¥\8dया परवानगी असलेल्या संचिका-प्रकार आहेत}}.",
+       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|हा à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤¨à¤¸à¤²à¥\87ला  à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87|या à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤¨à¤¸à¤²à¥\87लà¥\8dया à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87त}}. $2 {{PLURAL:$3|हा à¤ªà¤°à¤µà¤¾à¤¨à¤\97à¥\80 à¤\85सलà¥\87ला à¤¸à¤\82à¤\9aिà¤\95ा-पà¥\8dरà¤\95ार à¤\86हà¥\87|या परवानगी असलेल्या संचिका-प्रकार आहेत}}.",
        "api-error-filetype-missing": "या संचिकेस विस्तार(एक्सटेंशन) नाही.",
        "api-error-hookaborted": "तुम्ही केलेला बदल extension ने उलटवला आहे",
        "api-error-http": "अंतर्गत त्रुटी: सर्व्हरशी जोडणी होऊ शकली नाही.",
index dfcb78a..481a7ab 100644 (file)
@@ -55,6 +55,7 @@
        "tog-watchlisthidebots": "Sembunyikan suntingan bot daripada senarai pantau",
        "tog-watchlisthideminor": "Sembunyikan suntingan kecil daripada senarai pantau",
        "tog-watchlisthideliu": "Sembunyikan suntingan oleh pengguna yang telah log masuk daripada senarai pantau",
+       "tog-watchlistreloadautomatically": "Muat semula senarai pantau secara automatik setiap kali penapis berubah (perlu JavaScript)",
        "tog-watchlisthideanons": "Sembunyikan suntingan oleh pengguna tanpa nama daripada senarai pantau",
        "tog-watchlisthidepatrolled": "Sembunyikan suntingan yang telah dironda daripada senarai pantau",
        "tog-watchlisthidecategorization": "Sorokkan pengkategorian laman",
        "morenotlisted": "Senarai ini tidak lengkap.",
        "mypage": "Halaman",
        "mytalk": "Perbincangan",
-       "anontalk": "Perbincangan bagi IP ini",
+       "anontalk": "Perbincangan",
        "navigation": "Pandu arah",
        "and": "&#32;dan",
        "qbfind": "Cari",
        "databaseerror-query": "Pertanyaan: $1",
        "databaseerror-function": "Fungsi: $1",
        "databaseerror-error": "Ralat: $1",
+       "transaction-duration-limit-exceeded": "Demi mengelakkan terjadinya jeda pengulangan yang tinggi, transaksi ini dibatalkan kerana tempoh menulis ($1) telah melebihi had $2 saat.",
        "laggedslavemode": "Amaran: Laman ini mungkin bukan yang terkini.",
        "readonly": "Pangkalan data dikunci",
        "enterlockreason": "Sila nyatakan sebab penguncian dan jangkaan\nbila kunci ini akan dibuka.",
        "missingarticle-rev": "(semakan $1)",
        "missingarticle-diff": "(Beza: $1, $2)",
        "readonly_lag": "Pangkalan data telah dikunci secara automatik sementara semua pelayan pangkalan data diselaraskan.",
+       "nonwrite-api-promise-error": "Pengepala 'Promise-Non-Write-API-Action' telah dihantar tetapi permintaan dibuat kepada modul menulis API.",
        "internalerror": "Ralat dalaman",
        "internalerror_info": "Ralat dalaman: $1",
        "internalerror-fatal-exception": "Pengecualian fatal jenis \"$1\"",
        "wrongpasswordempty": "Kata laluan yang dimasukkan adalah kosong. Sila cuba lagi.",
        "passwordtooshort": "Kata laluan mestilah sekurang-kurangnya {{PLURAL:$1|1 aksara|$1 aksara}}.",
        "passwordtoolong": "Kata laluan tidak boleh melebihi $1 aksara.",
+       "passwordtoopopular": "Kata laluan yang biasa dipilih tidak boleh diguna. Sila pilih kata laluan yang lebih unik.",
        "password-name-match": "Kata laluan anda mesti berbeza daripada nama pengguna anda.",
        "password-login-forbidden": "Penggunaan nama pengguna dan kata laluan ini adalah dilarang.",
        "mailmypassword": "Set semula kata laluan",
        "passwordreset-emailtext-ip": "Seseorang (mungkin anda, dari alamat IP $1) telah memohon supaya kata laluan diset semula untuk {{SITENAME}} anda ($4). {{PLURAL:$3|Akaun|Akaun-akaun}} pengguna yang berikut\ndikaitkan dengan alamat e-mel ini:\n\n$2\n\n{{PLURAL:$3|Kata|Kata-kata}} laluan sementara ini akan luput dalam masa $5 hari. Anda harus log masuk dan membuat kata laluan yang baru sekarang. Jika permohonan ini dibuat oleh orang lain, atau jika anda teringat kembali kata laluan asal anda dan anda tidak lagi berhasrat untuk mengubahnya, anda boleh mengabaikan pesanan ini dan terus menggunakan kata laluan lama anda.",
        "passwordreset-emailtext-user": "Pengguna $1 telah memohon supaya kata laluan diset semula untuk {{SITENAME}} anda ($4). {{PLURAL:$3|Akaun|Akaun-akaun}} pengguna yang berikut\ndikaitkan dengan alamat e-mel ini:\n\n$2\n\n{{PLURAL:$3|Kata|Kata-kata}} laluan sementara ini akan luput dalam masa $5 hari. Anda harus log masuk dan membuat kata laluan yang baru sekarang. Jika permohonan ini dibuat oleh orang lain, atau jika anda teringat kembali kata laluan asal anda dan anda tidak lagi berhasrat untuk mengubahnya, anda boleh mengabaikan pesanan ini dan terus menggunakan kata laluan lama anda.",
        "passwordreset-emailelement": "Nama pengguna: \n$1\n\nKata laluan sementara: \n$2",
-       "passwordreset-emailsent": "Jika ini ialah alamat e-mel yang terdaftar untuk akaun anda, maka e-mel set semula kata laluan akan dihantar.",
+       "passwordreset-emailsentemail": "Jika ini ialah alamat e-mel yang terdaftar untuk akaun anda, maka e-mel set semula kata laluan akan dihantar.",
        "passwordreset-emailsent-capture": "E-mel set semula kata laluan telah dihantar, seperti yang dipaparkan di bawah.",
        "passwordreset-emailerror-capture": "E-mel set semula kata laluan telah dihasilkan, seperti yang dipaparkan di bawah, tetapi tidak berjaya dihantar kepada {{GENDER:$2|pengguna}} berkenaan: $1",
        "changeemail": "Tukar atau padamkan alamat e-mel",
        "group-bot": "Bot",
        "group-sysop": "Penyelia",
        "group-bureaucrat": "Birokrat",
-       "group-suppress": "Penyemak",
+       "group-suppress": "Peredam",
        "group-all": "(semua)",
        "group-user-member": "{{GENDER:$1|pengguna}}",
        "group-autoconfirmed-member": "{{GENDER:$1|pengguna sah automatik}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|penyelia}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat}}",
-       "group-suppress-member": "{{GENDER:$1|penyemak}}",
+       "group-suppress-member": "{{GENDER:$1|peredam}}",
        "grouppage-user": "{{ns:project}}:Pengguna",
        "grouppage-autoconfirmed": "{{ns:project}}:Pengguna yang disahkan secara automatik",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Penyelia",
        "grouppage-bureaucrat": "{{ns:project}}:Birokrat",
-       "grouppage-suppress": "{{ns:project}}:Penyemak",
+       "grouppage-suppress": "{{ns:project}}:Peredam",
        "right-read": "Membaca laman",
        "right-edit": "Menyunting laman",
        "right-createpage": "Mencipta laman (selain laman perbincangan)",
        "uploaded-setting-href-svg": "Dilarang menggunakan teg \"set\" untuk menambahkan atribut \"href\" kepada elemen induk.",
        "uploaded-wrong-setting-svg": "Dilarang menggunakan teg \"set\" untuk menambah sasaran jauh/data/skrip ke sebarang atribut. Terdapat <code>&lt;set to=\"$1\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-setting-handler-svg": "SVG yang menentukan atribut \"handler\" dengan remote/data/script disekat. Terdapat <code>$1=\"$2\"</code> dalam fail SVG yang dimuat naik.",
+       "uploaded-remote-url-svg": "SVG yang menetapkan sebarang atribut style dengan URL luar dikekang. <code>$1=\"$2\"</code> ditemui di dalam fail SVG yang dimuat naik.",
        "uploaded-image-filter-svg": "Terdapat penapis imej dengan URL: <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploadscriptednamespace": "Fail SVG ini mengandungi ruang nama terlarang \"$1\"",
        "uploadinvalidxml": "XML dalam fail yang dimuat naik ini tidak dapat dihuraikan.",
        "upload-options": "Pilihan muat naik",
        "watchthisupload": "Pantau fail ini",
        "filewasdeleted": "Sebuah fail dengan nama ini pernah dimuat naik, tetapi kemudiannya dihapuskan. Anda seharusnya menyemak $1 sebelum meneruskan percubaan untuk memuat naik fail ini.",
+       "filename-thumb-name": "Nampaknya macam tajuk gambar kenit (thumbnail). Tolong jangan muat naik gambar kenit balik ke dalam wiki yang sama. Selain itu, sila betulkan nama fail supaya ia nampak lebih bererti dan tiada awalan gambar kenit.",
        "filename-bad-prefix": "Nama bagi fail yang dimuat naik bermula dengan '''\"$1\"''', yang mana merupakan nama yang tidak deskriptif yang biasanya ditetapkan oleh kamera digital secara automatik. Sila berikan nama yang lebih deskriptif bagi fail tersebut.",
        "filename-prefix-blacklist": " #<!-- biarkan baris ini seperti sediakala --> <pre>\n# Sintaks adalah seperti berikut:\n#   * Segalanya mulai aksara \"#\" hingga akhir baris ialah komen\n#   * Setiap baris bukan kosong ialah awalan bagi nama-nama fail biasa yang ditetapkan secara automatik oleh kamera digital\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # sesetengah telefon bimbit\nIMG # generik\nJD # Jenoptik\nMGP # Pentax\nPICT # dll.\n #</pre> <!-- biarkan baris ini seperti sediakala -->",
        "upload-success-subj": "Muat naik berjaya",
        "foreign-structured-upload-form-label-own-work": "Ini ialah karya saya sendiri",
        "foreign-structured-upload-form-label-infoform-categories": "Kategori",
        "foreign-structured-upload-form-label-infoform-date": "Tarikh",
+       "foreign-structured-upload-form-label-own-work-message-local": "Saya mengesahkan bahawa saya memuat naik fail ini dengan mengikut terma perkhidmatan dan dasar perlesenan di {{SITENAME}}.",
        "foreign-structured-upload-form-label-not-own-work-local-local": "Anda mungkin juga mahu mencuba [[Special:Upload|laman muat naik yang asal]].",
        "backend-fail-stream": "Fail $1 tidak dapat distrimkan.",
        "backend-fail-backup": "Fail $1 tidak dapat disandarkan.",
        "booksources-text": "Yang berikut ialah senarai pautan ke tapak web lain yang menjual buku baru dan terpakai,\nserta mungkin mempunyai maklumat lanjut mengenai buku yang anda cari:",
        "booksources-invalid-isbn": "ISBN yang dinyatakan tidak sah. Sila semak sekali lagi.",
        "specialloguserlabel": "Pelaku:",
-       "speciallogtitlelabel": "Sasaran (tajuk atau pengguna):",
+       "speciallogtitlelabel": "Sasaran (tajuk atau {{ns:user}}:nama pengguna):",
        "log": "Log",
        "all-logs-page": "Semua log awam",
        "alllogstext": "Yang berikut ialah gabungan bagi semua log yang ada bagi {{SITENAME}}. Anda boleh menapis senarai ini dengan memilih jenis log, nama pengguna (peka huruf besar), atau nama laman yang terjejas (juga peka huruf besar).",
        "emailccsubject": "Salinan bagi mesej anda kepada $1: $2",
        "emailsent": "E-mel dikirim",
        "emailsenttext": "E-mel anda telah dikirim.",
-       "emailuserfooter": "E-mel ini telah dikirim oleh $1 kepada $2 oleh fungsi \"{{int:emailuser}}\" di {{SITENAME}}.",
+       "emailuserfooter": "E-mel ini telah {{GENDER:$1|dikirim}} oleh $1 kepada {{GENDER:$2|$2}} oleh fungsi \"{{int:emailuser}}\" di {{SITENAME}}.",
        "usermessage-summary": "Meninggalkan pesanan sistem.",
        "usermessage-editor": "Utusan sistem",
        "watchlist": "Senarai pantau",
        "wlnote": "Yang berikut ialah <strong>$1</strong> perubahan terakhir sejak $2 jam yang lalu, sehingga $3, $4.",
        "wlshowlast": "Tunjukkan $2 hari $1 jam yang lalu",
        "watchlistall2": "semua",
+       "watchlist-hide": "Sorok",
+       "wlshowtime": "Tempoh masa untuk dipaparkan:",
+       "wlshowhideminor": "suntingan kecil",
+       "wlshowhidebots": "bot",
+       "wlshowhideliu": "pengguna berdaftar",
+       "wlshowhideanons": "pengguna awanama",
+       "wlshowhidemine": "suntingan saya",
        "watchlist-options": "Pilihan senarai pantau",
        "watching": "Memantau...",
        "unwatching": "Menyahpantau...",
        "deletepage": "Hapus laman",
        "confirm": "Sahkan",
        "excontent": "kandungan: '$1'",
-       "excontentauthor": "Kandungan: '$1' (dan satu-satunya penyumbang ialah '[[Special:Contributions/$2|$2]]')",
+       "excontentauthor": "kandungan dahulu: \"$1\", dan penyumbang tunggalnya ialah \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|bincang]])",
        "exbeforeblank": "kandungan sebelum pengosongan ialah: '$1'",
        "delete-confirm": "Hapus \"$1\"",
        "delete-legend": "Hapuskan",
        "rollback-success": "Membalikkan suntingan oleh $1 kepada versi terakhir oleh $2.",
        "sessionfailure-title": "Kegagalan sesi",
        "sessionfailure": "Terdapat sedikit masalah pada sesi log masuk anda.\nTindakan ini telah dibatalkan untuk mencegah perampasan sesi.\nSila tekan butang \"back\" dan muatkan semula laman yang telah anda kunjungi sebelum ini, kemudian cuba lagi.",
+       "changecontentmodel-title-label": "Tajuk laman",
+       "changecontentmodel-model-label": "Model kandungan baharu",
+       "changecontentmodel-reason-label": "Alasan:",
+       "changecontentmodel-success-title": "Model kandungan ini telah diubah",
+       "changecontentmodel-success-text": "Jenis kandungan [[:$1]] telah diubah.",
+       "changecontentmodel-cannot-convert": "Kandungan di [[:$1]] tidak dapat ditukar kepada jenis $2.",
+       "changecontentmodel-nodirectediting": "Model kandungan $1 tidak menyokong suntingan langsung",
+       "log-name-contentmodel": "Log perubahan model kandungan",
+       "logentry-contentmodel-change-revertlink": "undur",
+       "logentry-contentmodel-change-revert": "undur",
        "protectlogpage": "Log perlindungan",
        "protectlogtext": "Berikut ialah senarai perubahan pada perlindungan laman.\nLihat [[Special:ProtectedPages|senarai laman terlindung]] untuk senarai laman-laman yang sedang dilindungi.",
        "protectedarticle": "melindungi \"[[$1]]\"",
        "contributions": "Sumbangan {{GENDER:$1|pengguna}}",
        "contributions-title": "Sumbangan oleh $1",
        "mycontris": "Sumbangan",
+       "anoncontribs": "Sumbangan",
        "contribsub2": "Untuk {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Akaun pengguna \"$1\" tidak berdaftar.",
        "nocontribs": "Tiada sebarang perubahan yang sepadan dengan kriteria-kriteria ini.",
        "movenosubpage": "Laman ini tiada sublaman.",
        "movereason": "Sebab:",
        "revertmove": "balik",
-       "delete_and_move": "Hapus dan pindah",
        "delete_and_move_text": "==Penghapusan diperlukan==\n\nLaman destinasi \"[[:$1]]\" telah pun wujud. Adakah anda mahu menghapuskannya supaya laman ini dapat dipindahkan?",
        "delete_and_move_confirm": "Ya, hapuskan laman ini",
        "delete_and_move_reason": "Dihapuskan untuk membuka laluan untuk pemindahan dari \"[[$1]]\"",
index 2373ab7..9b7557e 100644 (file)
        "createaccountreason": "Lí-iû:",
        "createacct-reason": "理由:",
        "createacct-reason-ph": "為啥物你欲開一另外一个口座?",
-       "createacct-captcha": "An-choân kiám-cha",
-       "createacct-imgcaptcha-ph": "Kā ē-kha lí khoàⁿ tio̍h--ê bûn-jī phah ji̍p lâi",
        "createacct-submit": "Khui lí--ê kháu-chō",
        "createacct-another-submit": "開另外一个口座",
        "createacct-benefit-heading": "{{SITENAME}} sī uī tio̍h chhin-chhiūⁿ lí--ê lâng chiah lâi kiàn-li̍p--ê.",
        "search-section": "(toān-lo̍h $1)",
        "searchall": "choân-pō·",
        "showingresults": "Ē-kha tùi #<b>$2</b> khai-sí hián-sī <b>$1</b> hāng kiat-kó.",
+       "search-nonefound": "揣無",
        "powersearch-legend": "Kiám-sek",
        "preferences": "Siat-tēng",
        "mypreferences": "Góa ê siat-tēng",
        "rightslogtext": "Chit-ê log lia̍t-chhut kái-piàn iōng-chiá koân-lī ê tōng-chok.",
        "action-edit": "Siu-kái chit ia̍h",
        "nchanges": "$1 {{PLURAL:$1|kái|kái}}",
+       "enhancedrc-history": "歷史",
        "recentchanges": "Chòe-kīn ê kái-piàn",
+       "recentchanges-legend": "最近改的選定",
        "recentchanges-summary": "Tī chiah wiki ia̍h tui-cha chòe-kīn ê kái-piàn.",
        "recentchanges-label-newpage": "Chit ê siu-kái ē sán-seng sin ia̍h",
        "recentchanges-label-minor": "Che sī sió siu-kái",
        "recentchanges-label-bot": "Che sī ki-khì-lâng kái--ê",
+       "recentchanges-label-unpatrolled": "這个編輯抑無巡視過",
+       "recentchanges-label-plusminus": "彼頁改了;精差的位元組",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (請參考[[Special:NewPages|新頁清單]])",
        "rcnotefrom": "Ē-kha sī <b>$2</b> kàu taⁿ ê kái-piàn (ke̍k-ke hián-sī <b>$1</b> hāng).",
        "rclistfrom": "Hián-sī tùi $3 $2 kàu taⁿ ê sin kái-piàn",
        "rcshowhideminor": "$1 sió siu-kái",
+       "rcshowhideminor-hide": "藏起來",
        "rcshowhidebots": "$1 機器儂",
+       "rcshowhidebots-show": "開",
        "rcshowhideliu": "$1 teng-ji̍p ê iōng-chiá",
+       "rcshowhideliu-hide": "藏起來",
        "rcshowhideanons": "$1 bû-bêng-sī",
+       "rcshowhideanons-hide": "藏起來",
        "rcshowhidemine": "$1 góa ê pian-chi̍p",
+       "rcshowhidemine-hide": "藏起來",
        "rclinks": "Hían-sī $2 ji̍t lāi siōng sin ê $1 hāng kái-piàn<br />$3",
        "diff": "Cheng-chha",
        "hist": "ls",
        "recentchangeslinked": "Siong-koan ê kái-piàn",
        "recentchangeslinked-feed": "Siong-koan ê kái-piàn",
        "recentchangeslinked-toolbox": "Siong-koan ê kái-piàn",
+       "recentchangeslinked-title": "佮 \"$1\" 相關的改變",
        "recentchangeslinked-summary": "這是有相接到指定頁(抑是指定分類的所有成員),而且最近家己頁的內容有改過的清單。\n遐的頁[[Special:Watchlist|佇你的監視清單]]會用<strong>粗體</strong> 標示。",
        "recentchangeslinked-page": "Ia̍h ê miâ:",
        "upload": "Kā tóng-àn chiūⁿ-bāng",
        "linkstoimage": "ē-kha {{PLURAL:$1|ê ia̍h}} ū iōng tio̍h chit ê iáⁿ-siōng:",
        "nolinkstoimage": "Bô poàⁿ ia̍h liân kàu chit tiuⁿ iáⁿ-siōng.",
        "sharedupload-desc-here": "Chit--ê $1--ê tóng-àn ū khó-lêng hō͘ kî-thaⁿ--ê choan-àn ēng tio̍h.\nChia sī chit--ê tóng-àn i--ê [$2 soat-bêng].",
+       "upload-disallowed-here": "你袂使換掉个檔案",
        "mimesearch": "MIME chhiau-chhoē",
        "unwatchedpages": "Bô lâng kàm-sī ê ia̍h",
        "listredirects": "Lia̍t-chhut choán-ia̍h",
        "watchlist-details": "Kàm-sī-toaⁿ ū {{PLURAL:$1|$1 ia̍h|$1 ia̍h}}, thó-lūn-ia̍h bô sǹg chāi-lāi.",
        "wlnote": "$3 $4: Ē-kha sī <strong>$2</strong> tiám-cheng í-lāi siōng sin ê <strong>$1</strong> ê kái-piàn.",
        "wlshowlast": "Hián-sī chêng $1 tiám-cheng $2 ji̍t",
+       "watchlistall2": "choân-pō͘",
        "deletepage": "Thâi ia̍h",
        "confirm": "Khak-tēng",
        "excontent": "lōe-iông sī: '$1'",
        "move-page-legend": "Sóa ia̍h",
        "movepagetext": "Ē-kha chit ê form> iōng lâi kái 1 ê ia̍h ê piau-tê (miâ-chheng); só·-ū siong-koan ê le̍k-sú ē tòe leh sóa khì sin piau-tê.\nKū piau-tê ē chiâⁿ-chò 1 ia̍h choán khì sin piau-tê ê choán-ia̍h.\nLiân khì kū piau-tê ê liân-kiat (link) bē khì tāng--tio̍h; ē-kì-tit chhiau-chhōe siang-thâu (double) ê a̍h-sī kò·-chiòng ê choán-ia̍h.\nLí ū chek-jīm khak-tēng liân-kiat kè-sio̍k liân tio̍h ūi.\n\nSin piau-tê nā í-keng tī leh (bô phian-chi̍p koè ê khang ia̍h, choán-ia̍h bô chún-sǹg), tō bô-hoat-tō· soá khì hia.\nChe piaú-sī nā ū têng-tâⁿ, ē-sái kā sin ia̍h soà tńg-khì goân-lâi ê kū ia̍h.\n\n'''SÈ-JĪ!'''\nTùi chē lâng tha̍k ê ia̍h lâi kóng, soá-ūi sī toā tiâu tāi-chì.\nLiâu--lo̍h-khì chìn-chêng, chhiáⁿ seng khak-tēng lí ū liáu-kái chiah-ê hiō-kó.",
        "movepagetalktext": "Siong-koan ê thó-lūn-ia̍h (chún ū) oân-nâ ē chū-tōng tòe leh sóa-ūi. Í-hā ê chêng-hêng '''bô chún-sǹg''': *Beh kā chit ia̍h tùi 1 ê miâ-khong-kan (namespace) soá khì lēng-gōa 1 ê miâ-khong-kan, *Sin piau-tê í-keng ū iōng--kòe ê thó-lūn-ia̍h, he̍k-chiá *Ē-kha ê sió-keh-á bô phah-kau. Í-siōng ê chêng-hêng nā-chún tī leh, lí chí-hó iōng jîn-kang ê hong-sek sóa ia̍h a̍h-sī kā ha̍p-pèng (nā ū su-iàu).",
-       "movearticle": "Sóa ia̍h:",
        "movenologintext": "Lí it-tēng ài sī chù-chheh ê iōng-chiá jī-chhiáⁿ ū [[Special:UserLogin|teng-ji̍p]] chiah ē-tàng sóa ia̍h.",
        "newtitle": "Khì sin piau-tê:",
        "move-watch": "Kàm-sī chit ia̍h",
        "tooltip-t-permalink": "Chi̍t ia̍h kái--koè pán-pún ê éng-kiú liân-kiat",
        "tooltip-ca-nstab-main": "khoàⁿ ia̍h ê loē-iông",
        "tooltip-ca-nstab-user": "Khoàⁿ iōng-chiá ê Ia̍h",
-       "tooltip-ca-nstab-special": "這是一个特殊頁,你袂使改這頁。",
+       "tooltip-ca-nstab-special": "這是一个特殊頁,袂使改得。",
        "tooltip-ca-nstab-image": "Khoàⁿ tóng-àn ia̍h",
        "tooltip-ca-nstab-category": "Khoàⁿ lūi-pia̍t ia̍h",
        "tooltip-minoredit": "記這是一个小改",
        "ilsubmit": "Kiám-sek",
        "bydate": "chiàu ji̍t-kî",
        "metadata": "元資料",
+       "metadata-help": "這个檔案有伊的資訊,可能是相機抑掃描機用的。\n若改過這个檔案,資訊就無完全對著。",
        "metadata-expand": "Hián-sī iù-chiat",
        "metadata-collapse": "Am iù-chiat",
        "metadata-fields": "佇顯示圖片的頁,若掀開元資料,下跤的EXIF資料會儂看著。其他的元資料是先看無。\n* 廠商\n* 機型\n* 翕像的時陣\n* 曝光\n* 光圈\n* ISO 速率\n* 焦距\n* 作者\n* 版權\n* 說明\n* 緯度(GPS)\n* 經度(GPS)\n* 海拔(GPS)",
index 70e4609..26c2858 100644 (file)
@@ -47,6 +47,7 @@
        "tog-watchlisthidebots": "Annasconne 'e cagnamiènte d' 'e bot ncopp'a l'elenco 'e cuntrollo",
        "tog-watchlisthideminor": "Annascunne 'e cagnamiente piccerille d' 'a lista 'e cuntrollo mia",
        "tog-watchlisthideliu": "Annascunne 'e cagnamiénte 'e l'utente riggistrate 'a l'elenco 'e cuntrollo",
+       "tog-watchlistreloadautomatically": "Recarreca l'elenco 'e paggene cuntrullate automaticamente quanno nu filtro se fosse cagnato (ce buò 'o JavaScript)",
        "tog-watchlisthideanons": "Annascunne 'e cagnamiente fatte d'anonime 'a l'elenco 'e cuntrollo",
        "tog-watchlisthidepatrolled": "Annascunne 'e modifiche cuntrullate 'a l'elenco 'e cuntrollo",
        "tog-watchlisthidecategorization": "Annascunne 'a categorizzazione d' 'e paggene",
        "morenotlisted": "Chisto elenco nun è cumpreto.",
        "mypage": "Paggena",
        "mytalk": "'E chiàcchieriate mmie",
-       "anontalk": "Chiacchierate pe chisto IP",
+       "anontalk": "Chiacchierate",
        "navigation": "Navigazzione",
        "and": "&#32;e",
        "qbfind": "Truòva",
        "databaseerror-query": "Richiesta: $1",
        "databaseerror-function": "Funzione: $1",
        "databaseerror-error": "Sbaglio: $1",
+       "transaction-duration-limit-exceeded": "Pe' putè scanzà 'e crià n'auto tiempo e replica, sta transazziona fuje fernuta pecché pe' tramente ca se faceva chesto ($1) s'appassaje 'o lemmeto $2 secondo.\nSi state a cagnà nu cuofeno 'elemente a na vota, tentate e fà nu cuofeno 'operaziune cchiù piccerille mmece.",
        "laggedslavemode": "'''Attenzione:''' 'a paggena putesse nun fà vedé ll'aggiornamente cchiù recente.",
        "readonly": "Database bloccato",
        "enterlockreason": "Miette 'o mutivo 'e blocco, nzieme a 'o mumento quanno se penza ca 'o blocco se sarrà fernuto",
        "wrongpasswordempty": "'A password nzertàta è abbacante.\nPe' piacere pruvate n'ata vota.",
        "passwordtooshort": "'E password hann'avé minimo {{PLURAL:$1|nu carattere|$1 carattere}}.",
        "passwordtoolong": "'E password nun ponno essere cchiù luonghe 'e {{PLURAL:$1|nu carattere|$1 carattere}}.",
+       "passwordtoopopular": "'E parole comune nun se ponno ausà pe' ve fà na password. Sciglite na password cchiù unica.",
        "password-name-match": "'A password adda essere diverza 'a 'o nomme utente.",
        "password-login-forbidden": "L'uso 'e stu nomme utente e password è stato proibito.",
        "mailmypassword": "Riabbìa 'a password",
        "passwordreset-emailtext-ip": "Coccherun (può darse ca sì tu, cu n'indirizzo IP $1) ha addimannato na mmasciata c' 'a password nova pe' putè trasì a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associato|L'utente associate}} a st'indirizze e-mail songo:\n\n$2\n\n{{PLURAL:$3|Sta password temporanea ammaturarrà|Sti password temporanee ammaturarranno}} aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\nHè 'a trasì e scegliere na password nova mò. \n\nSi nun sì stato tu a fà sta richiesta, o te sì scurdat' 'a password origginale e nun 'a buò cagnà cchiù, lassa perde sta mmasciata e usa 'a password viecchia.",
        "passwordreset-emailtext-user": "L'utente $1 di {{SITENAME}} ha addimannato na mmasciata c' 'a password nova pe' putè trasì a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associato|L'utente associate}} a st'indirizze e-mail songo:\n\n$2\n\n{{PLURAL:$3|Sta password temporanea ammaturarrà|Sti password temporanee ammaturarranno}} aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\nHè 'a trasì e scegliere na password nova mò. \n\nSi nun sì stato tu a fà sta richiesta, o te sì scurdat' 'a password origginale e nun 'a buò cagnà cchiù, lassa perde sta mmasciata e usa 'a password viecchia.",
        "passwordreset-emailelement": "Nomme utente: \n$1\n\nPassword temporanea: \n$2",
-       "passwordreset-emailsent": "Si chesto fosse nu cunto riggistrato e-mail, allora buò dicere ca se mannarrà na mmasciata e-mail pe' riabbià 'a password.",
+       "passwordreset-emailsentemail": "Si chesto fosse nu cunto e-mail riggistrato, allora buò dicere ca se mannarrà na mmasciata e-mail pe' riabbià 'a password.",
+       "passwordreset-emailsentusername": "Si esistesse nu cunto e-mail riggistrato ca currispunnesse a chesto, allora se mannarrà na mmasciata pe' riabbià 'a password.",
        "passwordreset-emailsent-capture": "Na mmasciata e-mail pe' riabbià 'a password è stata mannata, chista mmasciata 'a putite vedé ccà abbascio.",
        "passwordreset-emailerror-capture": "Na mmasciata e-mail pe' riabbià 'a password è stata mannata, 'a putite vedé ccà abbascio, ma aita sapé ca nun s'è mannata a {{GENDER:$2|l'utente}} pecché c'è stato cocch'errore: $1",
        "changeemail": "Cagna o lèva l'indirizzo e-mail",
        "media_tip": "Cullegamente a file multimediale",
        "sig_tip": "Firma cu data e ora",
        "hr_tip": "Linea orizzontale (ausà cu gedizzio)",
-       "summary": "Innece",
+       "summary": "Riepilego:",
        "subject": "Suggietto:",
        "minoredit": "Chisto è nu cagnamiénto piccerillo",
        "watchthis": "Tiene d'uocchio chesta paggena",
        "recentchanges-label-plusminus": "'A grannezza d' 'a paggena s'è cagnata pe' bbia 'e stu nummero 'e bytes",
        "recentchanges-legend-heading": "'''Liggenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide [[Special:NewPages|'e paggene nove]])",
+       "recentchanges-submit": "Faje vedé",
        "rcnotefrom": "Ccà abbascio {{PLURAL:$5|è alencato 'o cagnamiento appurtato|song' alincate 'e cagnamiente appurtate}} 'a <strong>$3, $4</strong> (mmustate nfin'a <strong>$1</strong>).",
        "rclistfrom": "Faje vedé 'e cagnamiénte fatte a partì 'a $3 $2",
        "rcshowhideminor": "$1 'e cagnamiénte piccerille",
        "mostrevisions": "Paggene cu cchiù cagnamiente",
        "prefixindex": "Tutte 'e paggene cu prefisso",
        "prefixindex-namespace": "Tutte 'e paggene cu prefisso d' 'o namespace $1",
+       "prefixindex-submit": "Faje vedé",
        "prefixindex-strip": "Annascunne 'o prefisso int' 'a lista",
        "shortpages": "Paggene curte",
        "longpages": "Paggene cchiú longhe",
        "protectedpages-performer": "Prutetta 'a ll'utente",
        "protectedpages-params": "Parametre 'e prutezione",
        "protectedpages-reason": "Mutivo",
+       "protectedpages-submit": "Mmusta paggene",
        "protectedpages-unknown-timestamp": "Scanusciuto",
        "protectedpages-unknown-performer": "Utente scanusciuto",
        "protectedtitles": "Paggene prutette",
        "protectedtitles-summary": "Sta paggena elenca 'e titule ca song'attualmente prutette 'a criazione. Pe' n'avé n'elenco 'e paggene prutette ch'esisteno, vedite [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Nisciunu titolo è prutetto pe mò cu sti parametre.",
+       "protectedtitles-submit": "Mmusta titule",
        "listusers": "Lista 'e l'utente",
        "listusers-editsonly": "Fà vedé sulamente l'utente cu cagnamiente fatte",
        "listusers-creationsort": "Arrecetta pe' data 'e criazione",
        "activeusers-hidebots": "Annascunne 'e bot",
        "activeusers-hidesysops": "Annascunne l'ammenistrature",
        "activeusers-noresult": "Nisciun'utente truvato.",
+       "activeusers-submit": "Mmusta cunte attive",
        "listgrouprights": "Deritte d' 'e gruppe utente",
        "listgrouprights-summary": "'A lista ccà abbascio è na lista d' 'e gruppe utente criate int'a sta wiki, ch' 'e diritte associate.\nPonno esistere [[{{MediaWiki:Listgrouprights-helppage}}|nfurmaziune cchiù ndettaglie]] ncopp' 'e deritte ndividuale.",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Deritto dato</span>\n* <span class=\"listgrouprights-revoked\">Deritto luvato</span>",
        "wlshowlast": "Mmusta ll'urdeme $1 ore $2 ghiuorne",
        "watchlistall2": "tuttuquante",
        "watchlist-hide": "Annascunne",
-       "wlshowtime": "Mmusta ll'urdeme:",
+       "watchlist-submit": "Faje vedé",
+       "wlshowtime": "Periodo 'e tiempo a mmustà:",
        "wlshowhideminor": "cagnamiente piccerille",
        "wlshowhidebots": "bot",
        "wlshowhideliu": "utente riggistrate",
        "contributions": "Contribbute {{GENDER:$1|utente}}",
        "contributions-title": "Cuntribbute 'a l'utente pe' $1",
        "mycontris": "'E ffatiche d''e mmeje",
+       "anoncontribs": "Cuntribbute",
        "contribsub2": "Ppe {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "'O cunto utente \"$1\" nun è riggistrato.",
        "nocontribs": "Nisciunu cagnamiento è stato truvato cu sti criterie.",
        "whatlinkshere-hidelinks": "$1 jonte",
        "whatlinkshere-hideimages": "$1 links d' 'o file",
        "whatlinkshere-filters": "Filtre",
+       "whatlinkshere-submit": "Vaje",
        "autoblockid": "Autoblocco #$1",
        "block": "Blocca l'utente",
        "unblock": "Sblocca l'utente",
        "movenosubpage": "Sta paggena nun tene sottopaggene.",
        "movereason": "Raggióne",
        "revertmove": "arrepiglia",
-       "delete_and_move": "Scancèlla e mòve",
        "delete_and_move_text": "== Scancellamiento richiesto ==\n'A paggena 'e destinazione \"[[:$1]]\" esiste già.\n'A vulite scancellà pe' ne putè ffà 'o spazio abbacante necessario?",
        "delete_and_move_confirm": "Sì, suprascrivi 'a paggena asistente",
        "delete_and_move_reason": "Scancellata pe ne fà spazio abbacante e putè spustà 'a \"[[$1]]\"",
        "tooltip-pt-preferences": "Preferenze d''e mmeje",
        "tooltip-pt-watchlist": "'A lista d' 'e paggene ca state a cuntrullà",
        "tooltip-pt-mycontris": "Elenco dde tuje contributte",
+       "tooltip-pt-anoncontribs": "N'elenco 'e cagnamiente fatte 'a st'indirizzo IP",
        "tooltip-pt-login": "A reggistrazione è cunsigliata",
        "tooltip-pt-logout": "Jésce (logout)",
        "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; ancora ca chisto nun s'avesse 'a ffà pe' fforza",
index 3f98ba4..02c27d5 100644 (file)
        "passwordreset-emailtext-ip": "Noen (sannsynligvis deg fra IP-adressen $1) ba om en tilbakestilling av ditt passord for {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brukerkontoen|De følgende brukerkontoene}} er\ntilknyttet denne e-postadressen:\n\n$2\n\n{{PLURAL:$3|Dette midlertidige passordet|Disse midlertidige passordene}} utløper om {{PLURAL:$5|én dag|$5 dager}}.\nDu bør logge på og velge et nytt passord nå. Dersom noen andre kom med denne\nforespørselen, eller du har kommet på ditt opprinnelige passord, og ikke lenger\nønsker å endre det, kan du ignorere denne meldingen og fortsette å bruke ditt gamle\npassord.",
        "passwordreset-emailtext-user": "Brukeren $1 på {{SITENAME}} ba om en tilbakestilling av passordet ditt for {{SITENAME}}\n($4). {{PLURAL:$3|Den følgende brukerkontoen|De følgende brukerkontoene}} er tilknyttet denne e-postadressen:\n\n$2\n\n{{PLURAL:$3|Dette midlertidige passordet|Disse midlertidige passordene}} utløper om {{én dag|$5 dager}}.\nDu bør logge på og velge et nytt passord nå. Dersom noen andre kom med denne\nforespørselen, eller du har kommet på ditt opprinnelige passord, og ikke lenger\nønsker å endre det, kan du ignorere denne meldingen og fortsette å bruke ditt gamle\npassord.",
        "passwordreset-emailelement": "Brukernavn: \n$1\n\nMidlertidig passord: \n$2",
-       "passwordreset-emailsent": "Hvis dette er en registrert epostadresse vil en passordtilbakestillingsepost bli sendt.",
+       "passwordreset-emailsentemail": "Hvis dette er en registrert epostadresse vil en passordtilbakestillingsepost bli sendt.",
        "passwordreset-emailsent-capture": "Passordtilbakestillingseposten vist under har blitt sendt ut.",
        "passwordreset-emailerror-capture": "En passordtilbakestillingsepost ble laget, men det lyktes ikke å sende denne til {{GENDER:$2|brukeren}}: $1",
        "changeemail": "Endre eller fjerne epostadresse",
        "activeusers-hidebots": "Skjul roboter",
        "activeusers-hidesysops": "Skjul administratorer",
        "activeusers-noresult": "Ingen brukere funnet.",
+       "activeusers-submit": "Vis",
        "listgrouprights": "Rettigheter for brukergrupper",
        "listgrouprights-summary": "Følgende er en liste over brukergrupper som er definert på denne wikien, og hvilke rettigheter de har.\nMer informasjon om de enkelte rettighetstypene kan finnes [[{{MediaWiki:Listgrouprights-helppage}}|her]].",
        "listgrouprights-key": "Tegnforklaring:\n* <span class=\"listgrouprights-granted\">Innvilget rettighet</span>\n* <span class=\"listgrouprights-revoked\">Tilbaketrukket rettighet</span>",
        "contributions": "{{GENDER:$1|Brukerbidrag}}",
        "contributions-title": "Brukerbidrag av $1",
        "mycontris": "Bidrag",
+       "anoncontribs": "Bidrag",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Brukerkontoen «$1» er ikke registrert.",
        "nocontribs": "Ingen endringer er funnet som passer disse kriteriene.",
        "movenosubpage": "Denne siden har ingen undersider.",
        "movereason": "Årsak:",
        "revertmove": "tilbakestill",
-       "delete_and_move": "Slett og flytt",
        "delete_and_move_text": "==Sletting nødvendig==\nMålsiden «[[:$1]]» finnes allerede. Vil du slette den så denne siden kan flyttes dit?",
        "delete_and_move_confirm": "Ja, slett siden",
        "delete_and_move_reason": "Slettet for å muliggjøre flytting fra \"[[$1]]\"",
        "mw-widgets-dateinput-no-date": "Ingen dato valgt",
        "mw-widgets-dateinput-placeholder-day": "ÅÅÅÅ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
-       "mw-widgets-titleinput-description-new-page": "siden eksisterer ikke enda",
+       "mw-widgets-titleinput-description-new-page": "siden eksisterer ikke en",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "api-error-blacklisted": "Vennligst velg en annen beskrivende tittel."
 }
index 7146964..ea4676e 100644 (file)
@@ -70,7 +70,8 @@
                        "Mbch331",
                        "Esketti",
                        "M!dgard",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Robin van der Vliet"
                ]
        },
        "tog-underline": "Koppelingen onderstrepen:",
        "tog-watchlisthidebots": "Botbewerkingen op mijn volglijst verbergen",
        "tog-watchlisthideminor": "Kleine bewerkingen op mijn volglijst verbergen",
        "tog-watchlisthideliu": "Bewerkingen van aangemelde gebruikers op mijn volglijst verbergen",
+       "tog-watchlistreloadautomatically": "Herlaad de volglijst automatisch wanneer er een filter is veranderd (JavaScript vereist)",
        "tog-watchlisthideanons": "Bewerkingen van anonieme gebruikers op mijn volglijst verbergen",
        "tog-watchlisthidepatrolled": "Gemarkeerde wijzigingen op mijn volglijst verbergen",
        "tog-watchlisthidecategorization": "Categorisatie van pagina's verbergen",
        "morenotlisted": "Deze lijst is niet compleet.",
        "mypage": "Gebruikerspagina",
        "mytalk": "Overleg",
-       "anontalk": "Overlegpagina voor dit IP-adres",
+       "anontalk": "Overleg",
        "navigation": "Navigatie",
        "and": "&#32;en",
        "qbfind": "Zoeken",
        "wrongpasswordempty": "Het opgegeven wachtwoord was leeg.\nProbeer het opnieuw.",
        "passwordtooshort": "Wachtwoorden moeten uit minstens {{PLURAL:$1|$1 teken|$1 tekens}} bestaan.",
        "passwordtoolong": "Wachtwoorden kunnen niet langer zijn dan {{PLURAL:$1|één teken|$1 tekens}}.",
+       "passwordtoopopular": "Vaak gekozen wachtwoorden kunnen niet worden gebruikt. Kies een unieker wachtwoord.",
        "password-name-match": "Uw wachtwoord en uw gebruikersnaam mogen niet overeenkomen.",
        "password-login-forbidden": "Het gebruik van deze gebruikersnaam met dit wachtwoord is niet toegestaan.",
        "mailmypassword": "Nieuw wachtwoord e-mailen",
        "passwordreset-emailtext-ip": "Iemand, waarschijnlijk u, heeft vanaf het IP-adres $1 een aanvraag gedaan om uw wachtwoord voor {{SITENAME}} ($4) opnieuw in te stellen. De volgende {{PLURAL:$3|gebruiker is|gebruikers zijn}} gekoppeld aan dit e-mailadres:\n\n$2\n\n{{PLURAL:$3|Dit tijdelijke wachtwoord vervalt|Deze tijdelijke wachtwoorden vervallen}} over {{PLURAL:$5|een dag|$5 dagen}}. Meld u aan en wijzig het wachtwoord nu. Als u dit verzoek niet zelf heeft gedaan, of als u het oorspronkelijke wachtwoord nog kent en het niet wilt wijzigen, negeer dit bericht dan en blijf uw oude wachtwoord gebruiken.",
        "passwordreset-emailtext-user": "Gebruiker $1 op de site {{SITENAME}} heeft een aanvraag gedaan om uw wachtwoord voor {{SITENAME}} ($4) opnieuw in te stellen. De volgende {{PLURAL:$3|gebruiker is|gebruikers zijn}} gekoppeld aan dit e-mailadres:\n\n$2\n\n{{PLURAL:$3|Dit tijdelijke wachtwoord vervalt|Deze tijdelijke wachtwoorden vervallen}} over {{PLURAL:$5|een dag|$5 dagen}}.\nMeld u aan en wijzig het wachtwoord nu. Als u dit verzoek niet zelf heeft gedaan, of als u het oorspronkelijke wachtwoord nog kent en het niet wilt wijzigen, negeer dit bericht dan en blijf uw oude wachtwoord gebruiken.",
        "passwordreset-emailelement": "Gebruikersnaam: \n$1\n\nTijdelijk wachtwoord: \n$2",
-       "passwordreset-emailsent": "Als dit een geregistreerd e-mailadres is voor uw account, dan wordt er een e-mail verzonden om uw wachtwoord opnieuw in te stellen.",
+       "passwordreset-emailsentemail": "Als dit een geregistreerd e-mailadres is voor uw account, dan wordt er een e-mail verzonden om uw wachtwoord opnieuw in te stellen.",
        "passwordreset-emailsent-capture": "Er is een e-mail voor het opnieuw instellen van een wachtwoord verzonden. Deze wordt hieronder weergegeven.",
        "passwordreset-emailerror-capture": "Er is een e-mail voor het opnieuw instellen van een wachtwoord aangemaakt. Deze wordt hieronder weergegeven. Het verzenden naar de {{GENDER:$2|gebruiker}} is mislukt om de volgende reden: $1",
        "changeemail": "E-mailadres wijzigen of verwijderen",
        "activeusers-hidebots": "Bots verbergen",
        "activeusers-hidesysops": "Beheerders verbergen",
        "activeusers-noresult": "Geen actieve gebruikers gevonden.",
+       "activeusers-submit": "Weergeven",
        "listgrouprights": "Rechten van gebruikersgroepen",
        "listgrouprights-summary": "Op deze pagina staan de gebruikersgroepen in deze wiki beschreven, met hun bijbehorende rechten.\nEr kan [[{{MediaWiki:Listgrouprights-helppage}}|extra informatie]] over individuele rechten aanwezig zijn.",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Toegewezen recht</span>\n* <span class=\"listgrouprights-revoked\">Ingetrokken recht</span>",
        "wlshowlast": "Laatste $1 uur, $2 dagen bekijken",
        "watchlistall2": "alles",
        "watchlist-hide": "Verbergen",
-       "wlshowtime": "Tijdspanne:",
+       "wlshowtime": "Periode om te weergeven:",
        "wlshowhideminor": "kleine bewerkingen",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "geregistreerde gebruikers",
        "contributions": "{{GENDER:$1|Gebruikersbijdragen}}",
        "contributions-title": "Bijdragen van $1",
        "mycontris": "Bijdragen",
+       "anoncontribs": "Bijdragen",
        "contribsub2": "Voor {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "De account \"$1\" is niet geregistreerd.",
        "nocontribs": "Geen wijzigingen gevonden die aan de gestelde criteria voldoen.",
        "movenosubpage": "Deze pagina heeft geen subpagina's.",
        "movereason": "Reden:",
        "revertmove": "terugdraaien",
-       "delete_and_move": "Verwijderen en hernoemen",
        "delete_and_move_text": "==Verwijdering nodig==\nOnder de naam \"[[:$1]]\" bestaat al een pagina.\nWilt u deze verwijderen om plaats te maken voor de te hernoemen pagina?",
        "delete_and_move_confirm": "Ja, de pagina verwijderen",
        "delete_and_move_reason": "Verwijderd in verband met hernoeming van \"[[$1]]\"",
        "tooltip-pt-preferences": "Mijn voorkeuren",
        "tooltip-pt-watchlist": "Overzicht van pagina's die u volgt",
        "tooltip-pt-mycontris": "Overzicht van uw bijdragen",
+       "tooltip-pt-anoncontribs": "Een lijst van bewerkingen gemaakt door dit IP-adres",
        "tooltip-pt-login": "U wordt van harte uitgenodigd om aan te melden, maar dit is niet verplicht",
        "tooltip-pt-logout": "Afmelden",
        "tooltip-pt-createaccount": "Registreer u vooral en meld u aan. Dit is echter niet vereist.",
index 0825cc0..6bfd094 100644 (file)
        "passwordreset-emailtext-ip": "Nokon (sannsynlegvis deg, frå IP-adressa $1) bad om ei påminning for kontodetaljane dine for {{SITENAME}} ($4). {{PLURAL:$3|Den fylgjande brukarkontoen|Dei fylgjande brukarkontoane}} er assosierte med denne e-postadressa:\n\n$2\n\n{{PLURAL:$3|Dette mellombels passordet|Desse mellombels passorda}} vil verta ugilde om {{PLURAL:$5|éin dag|$5 dagar}}.\nDu bør logga inn og velja eit nytt passord no. Om nokon andre enn deg bad om denne påminninga, eller du har kome i hug det opphavlege passordet og ikkje lenger ynskjer å endra det, kan du sjå bort frå denne meldinga og halda fram med å nytta det gamle passordet ditt.",
        "passwordreset-emailtext-user": "Brukaren $1 på {{SITENAME}} bad om ei påminning for kontodetaljane dine for {{SITENAME}} ($4). {{PLURAL:$3|Den fylgjande brukarkontoen|Dei fylgjande brukarkontoane}} er assosierte med denne e-postadressa:\n\n$2\n\n{{PLURAL:$3|Dette mellombels passordet|Desse mellombels passorda}} vil verta ugilde om {{PLURAL:$5|éin dag|$5 dagar}}.\nDu bør logga inn og velja eit nytt passord no. Om nokon andre enn deg bad om denne påminninga, eller du har kome i hug det opphavlege passordet og ikkje lenger ynskjer å endra det, kan du sjå bort frå denne meldinga og halda fram med å nytta det gamle passordet ditt.",
        "passwordreset-emailelement": "↓Brukarnamn: \n$1\n\nMellombels passord: \n$2",
-       "passwordreset-emailsent": "Ein e-post for attendestilling av passord er vorten send",
+       "passwordreset-emailsentemail": "Ein e-post for attendestilling av passord er vorten send",
        "passwordreset-emailsent-capture": "Ein e-post om attendestilling av passord - vist under - er vorten send",
        "passwordreset-emailerror-capture": "Ein e-post om attendestilling av passord vart oppretta, og er vist nedanfor; men det lukkast ikkje å senda han til {{GENDER:$2|brukaren}}: $1",
        "changeemail": "↓Endre e-postadresse",
        "search-section": "(bolken $1)",
        "search-category": "(kategorien $1)",
        "search-suggest": "Meinte du: «$1»",
+       "search-rewritten": "Viser resultat for $1. Søk i staden etter $2.",
        "search-interwiki-caption": "Systerprosjekt",
        "search-interwiki-default": "Resultat frå $1:",
        "search-interwiki-more": "(meir)",
        "showingresults": "Nedanfor er opp til {{PLURAL:$1|'''eitt'''|'''$1'''}} resultat som byrjar med nummer '''$2''' vist{{PLURAL:$1||e}}.",
        "search-showingresults": "Resultat <strong>{{PLURAL:$4|$1|$1–$2}}</strong> av <strong>$3</strong>",
        "search-nonefound": "Ingen resultat svarte til førespurnaden.",
+       "search-nonefound-thiswiki": "Det var ingen resultat som passa til spørjinga på denne nettstaden.",
        "powersearch-legend": "Avansert søk",
        "powersearch-ns": "Søk i namnerom:",
        "powersearch-togglelabel": "Hak av:",
        "wlheader-showupdated": "Sider som har vorte endra sidan du sist såg på dei er '''utheva'''",
        "wlnote": "Nedanfor er {{PLURAL:$1|den siste endringa|dei siste '''$1''' endringane}} {{PLURAL:$2|den siste timen|dei siste '''$2''' timane}}, for $3, kl. $4.",
        "wlshowlast": "Vis siste $1 timane $2 dagane",
-       "watchlistall2": "alle",
+       "watchlistall2": "alt",
+       "watchlist-hide": "Gøym",
+       "wlshowtime": "Vis siste:",
+       "wlshowhideminor": "småplukk",
+       "wlshowhidebots": "robotar",
+       "wlshowhideliu": "registrerte brukarar",
+       "wlshowhideanons": "anonyme brukarar",
+       "wlshowhidepatr": "patruljerte endringar",
+       "wlshowhidemine": "mine endringar",
        "watchlist-options": "Alternativ for overvakingslista",
        "watching": "Overvakar...",
        "unwatching": "Fjernar frå overvakinglista...",
        "movenosubpage": "Denne sida har ingen undersider.",
        "movereason": "Årsak:",
        "revertmove": "flytt attende",
-       "delete_and_move": "Slett og flytt",
        "delete_and_move_text": "== Sletting påkravd ==\n\nMålsida «[[:$1]]» finst allereie. Vil du slette ho for å gje rom for flytting?",
        "delete_and_move_confirm": "Ja, slett sida",
        "delete_and_move_reason": "Sletta for å gje rom for flytting frå «[[$1]]»",
index fa7e2fe..4af83d6 100644 (file)
@@ -14,7 +14,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Xð"
                ]
        },
        "tog-underline": "Soslinhar los ligams :",
        "viewhelppage": "Vejatz la pagina d'ajuda",
        "categorypage": "Vejatz la pagina de las categorias",
        "viewtalkpage": "Pagina de discussion",
-       "otherlanguages": "Autras lengas",
+       "otherlanguages": "En autras lengas",
        "redirectedfrom": "(Redirigit dempuèi $1)",
        "redirectpagesub": "Pagina de redireccion",
        "redirectto": "Redirigir cap a :",
        "createaccountreason": "Motiu :",
        "createacct-reason": "Motiu",
        "createacct-reason-ph": "Perqué creatz un autre compte",
-       "createacct-captcha": "Contraròtle de seguretat",
-       "createacct-imgcaptcha-ph": "Entratz lo tèxte que vesètz çaisús",
        "createacct-submit": "Creatz vòstre compte",
        "createacct-another-submit": "Crear un autre compte",
        "createacct-benefit-heading": "{{SITENAME}} es escrich per de monde coma vos.",
        "wlheader-showupdated": "Las paginas que son estadas modificadas dempuèi vòstra darrièra visita son afichadas en '''gras'''.",
        "wlnote": "Çaijós {{PLURAL:$1|figura la darrièra modificacion efectuada|figuran las <strong>$1</strong> darrièras modificacions efectuadas}} pendent {{PLURAL:$2|la darrièra ora|las <strong>$2</strong> darrièras oras}}, dempuèi $3, $4.",
        "wlshowlast": "Far veire las darrièras $1 oras, los darrièrs $2 jorns",
+       "watchlistall2": "tot",
        "watchlist-options": "Opcions de la lista de seguiment",
        "watching": "Seguit...",
        "unwatching": "Fin del seguit...",
        "movenosubpage": "Aquesta pagina a pas cap de sospagina.",
        "movereason": "Motiu :",
        "revertmove": "anullar",
-       "delete_and_move": "Suprimir e tornar nomenar",
        "delete_and_move_text": "==Supression requerida==\nL’article de destinacion « [[:$1]] » existís ja.\nLo volètz suprimir per permetre lo cambiament de nom ?",
        "delete_and_move_confirm": "Òc, accèpti de suprimir la pagina de destinacion per permetre lo cambiament de nom.",
        "delete_and_move_reason": "Pagina suprimida per permetre lo cambiament de nom dempuèi « [[$1]] »",
index aae4321..8f760e4 100644 (file)
        "movenosubpage": "ଏହି ପୃଷ୍ଠାର ଉପପୃଷ୍ଠା ନାହିଁ ।",
        "movereason": "କାରଣ:",
        "revertmove": "ପଛକୁ ଫେରାଇବେ",
-       "delete_and_move": "ଲିଭାଇବେ ଓ ଘୁଞ୍ଚାଇବେ",
        "delete_and_move_text": "== ଲିଭାଇବା ଦରକାର ==\nମୁକାମ ପୃଷ୍ଠା \"[[:$1]]\" ଟି ଆଗରୁ ଅଛି ।\nଆପଣ ଏହାକୁ ଲିଭାଇ ଘୁଞ୍ଚାଇବାକୁ ବାଟ କଢ଼ାଇବାକୁ ଚାହାନ୍ତି କି?",
        "delete_and_move_confirm": "ହଁ, ଏହି ପୃଷ୍ଠାଟିକୁ ଲିଭାଇଦେବେ",
        "delete_and_move_reason": "\"[[$1]]\" ପାଇଁ ପଥ ସଳଖ କରିବା ନିମନ୍ତେ ଲିଭାଇଦିଆଗଲା",
index 61604b5..59f5979 100644 (file)
        "contributions": "Ambag da reng gagamit",
        "contributions-title": "Deng ambag da reng talagamit para king $1",
        "mycontris": "Deng kakung ambag",
+       "anoncontribs": "Deng ambag",
        "contribsub2": "Para $1 ($2)",
        "nocontribs": "Alang pamagbayung pareu/tutud kareng kundisiung deti.",
        "uctop": "(babo)",
        "movelogpagetext": "Makabili ya king lalam ing tala (list) da reng bulung a miyalis.",
        "movereason": "Sangkan:",
        "revertmove": "isubli",
-       "delete_and_move": "Buran at ialis",
        "delete_and_move_text": "==Kailangan ing pamamura==\nAtiu ne ing \"[[:$1]]\" a bulung a puntalan.\nBuri meng buran bang malaus ing pamanales?",
        "delete_and_move_confirm": "Wa, buran ya ing bulung",
        "delete_and_move_reason": "Mebura ya bang malaus ing pamanalis",
index 948914e..152a646 100644 (file)
@@ -95,7 +95,7 @@
        "tog-showtoolbar": "Pokaż pasek narzędzi",
        "tog-editondblclick": "Podwójne kliknięcie rozpoczyna edycję",
        "tog-editsectiononrightclick": "Kliknięcie prawym klawiszem myszy na tytule sekcji rozpoczyna jej edycję",
-       "tog-watchcreations": "Dodawaj do obserwowanych tworzone przeze mnie strony oraz wgrywane przeze mnie pliki",
+       "tog-watchcreations": "Dodawaj do obserwowanych tworzone przeze mnie strony oraz przesyłane przeze mnie pliki",
        "tog-watchdefault": "Dodawaj do obserwowanych strony i pliki, które edytuję",
        "tog-watchmoves": "Dodawaj do obserwowanych strony i pliki, które przenoszę",
        "tog-watchdeletion": "Dodawaj do obserwowanych strony i pliki, które usuwam",
        "tog-watchlisthidebots": "Ukryj edycje botów na liście obserwowanych",
        "tog-watchlisthideminor": "Ukryj drobne zmiany na liście obserwowanych",
        "tog-watchlisthideliu": "Ukryj edycje zalogowanych użytkowników na liście obserwowanych",
+       "tog-watchlistreloadautomatically": "Automatycznie odświeżaj listę obserwowanych, gdy zmieniany jest filtr (wymagany JavaScript)",
        "tog-watchlisthideanons": "Ukryj edycje anonimowych użytkowników na liście obserwowanych",
        "tog-watchlisthidepatrolled": "Ukryj sprawdzone edycje na liście obserwowanych",
        "tog-watchlisthidecategorization": "Ukryj kategoryzację stron",
        "morenotlisted": "Nie jest to kompletna lista.",
        "mypage": "Strona",
        "mytalk": "Dyskusja",
-       "anontalk": "Dyskusja tego IP",
+       "anontalk": "Dyskusja",
        "navigation": "Nawigacja",
        "and": "&#32;oraz",
        "qbfind": "Znajdź",
        "wrongpasswordempty": "Wprowadzone hasło jest puste. Spróbuj ponownie.",
        "passwordtooshort": "Hasło musi mieć co najmniej $1 {{PLURAL:$1|znak|znaki|znaków}}.",
        "passwordtoolong": "Hasło nie może być dłuższe niż  {{PLURAL:$1|1 znak|$1 znaków}}.",
+       "passwordtoopopular": "Często wybierane hasła nie mogą być stosowane. Proszę wybrać hasło bardziej unikalne.",
        "password-name-match": "Hasło musi być inne niż nazwa użytkownika.",
        "password-login-forbidden": "Wykorzystanie tej nazwy użytkownika lub hasła zostało zabronione.",
        "mailmypassword": "Zresetuj hasło",
        "passwordreset-emailtext-ip": "Ktoś (prawdopodobnie Ty, spod adresu IP $1) poprosił o zresetowanie twojego hasła w {{GRAMMAR:MS.lp{{SITENAME}}}} ($4). Z tym adresem e‐mailowym powiązane {{PLURAL:$3|jest konto użytkownika|są następujące konta użytkowników:}}\n\n$2\n\n{{PLURAL:$3|Tymczasowego hasła|Tymczasowych haseł}} można użyć w ciągu {{PLURAL:$5|jednego dnia|$5 dni}}.\nPowinieneś zalogować się i zmienić hasło na nowe. Jeśli to ktoś inny poprosił o wysłanie przypomnienia lub jeśli pamiętasz aktualne hasło i nie chcesz go zmieniać wystarczy, że zignorujesz tę wiadomość i będziesz nadal korzystać ze swojego starego hasła.",
        "passwordreset-emailtext-user": "Użytkownik $1 poprosił o zresetowanie twojego hasła w {{GRAMMAR:MS.lp{{SITENAME}}}} ($4). Z tym adresem e‐mailowym powiązane {{PLURAL:$3|jest konto użytkownika|są następujące konta użytkowników:}}\n\n$2\n\n{{PLURAL:$3|Tymczasowego hasła|Tymczasowych haseł}} można użyć w ciągu {{PLURAL:$5|jednego dnia|$5 dni}}.\nPowinieneś zalogować się i zmienić hasło na nowe. Jeśli to ktoś inny poprosił o wysłanie przypomnienia lub jeśli pamiętasz aktualne hasło i nie chcesz go zmieniać wystarczy, że zignorujesz tę wiadomość i będziesz nadal korzystać ze swojego starego hasła.",
        "passwordreset-emailelement": "Nazwa użytkownika: \n$1\n\nTymczasowe hasło: \n$2",
-       "passwordreset-emailsent": "Jeśli adres e‐mail przypisany do Twojego konta został zarejestrowany, zostanie wysłany e-mail do odzyskiwania hasła.",
+       "passwordreset-emailsentemail": "Jeśli adres e‐mail przypisany do Twojego konta został zarejestrowany, zostanie wysłany e-mail do odzyskiwania hasła.",
        "passwordreset-emailsent-capture": "Wyświetlony poniżej e‐mail pozwalający na zresetowanie hasła został wysłany.",
        "passwordreset-emailerror-capture": "Poniżej wyświetlony e‐mail pozwalający na zresetowanie hasła został wygenerowany, ale nie udało się wysłać go do {{GENDER:$2|użytkownika|użytkowniczki}}: $1",
        "changeemail": "Zmiana lub usunięcie adresu e‐mail",
        "userinvalidcssjstitle": "'''Uwaga:''' Brak skórki o nazwie „$1”.\nStrony użytkownika zawierające CSS i JavaScript powinny zaczynać się małą literą, np. {{ns:user}}:Foo/vector.css, w przeciwieństwie do nieprawidłowego {{ns:user}}:Foo/Vector.css.",
        "updated": "(Zmodyfikowano)",
        "note": "'''Uwaga:'''",
-       "previewnote": "'''To jest tylko podgląd'''\nZmiany nie zostały jeszcze zapisane!",
+       "previewnote": "<strong>To jest tylko podgląd.</strong>\nZmiany nie zostały jeszcze zapisane!",
        "continue-editing": "Przejdź do pola edycji",
        "previewconflict": "Podgląd odnosi się do tekstu z górnego pola edycji. Tak będzie wyglądać strona, jeśli zdecydujesz się ją zapisać.",
        "session_fail_preview": "'''Uwaga! Serwer nie może przetworzyć tej edycji z powodu utraty danych sesji.\nSpróbuj jeszcze raz.\nJeśli to nie pomoże – [[Special:UserLogout|wyloguj się]] i zaloguj ponownie.'''",
        "badsig": "Nieprawidłowy podpis, sprawdź znaczniki HTML.",
        "badsiglength": "Twój podpis jest zbyt długi.\nDopuszczalna długość to $1 {{PLURAL:$1|znak|znaki|znaków}}.",
        "yourgender": "Płeć:",
-       "gender-unknown": "Oprogramowanie, gdy będzie to możliwe, będzie korzystać z neutralnych słów",
-       "gender-male": "Jest zarejestrowany",
-       "gender-female": "Jest zarejestrowana",
+       "gender-unknown": "nie określono",
+       "gender-male": "mężczyzna",
+       "gender-female": "kobieta",
        "prefs-help-gender": "Podanie płci nie jest obowiązkowe. Jeśli zdecydujesz się ją określić, oprogramowanie dostosuje do niej interfejs. Informacja o Twojej płci będzie widoczna dla wszystkich.",
        "email": "E‐mail",
        "prefs-help-realname": "Imię i nazwisko jest opcjonalne.\nJeśli je podasz, to może być stosowane w celu przypisania Twojej pracy.",
        "right-viewmyprivateinfo": "Podgląd swoich prywatnych danych (np. adres e-mail, prawdziwe imię i nazwisko)",
        "right-editmyprivateinfo": "Edycja swoich prywatnych danych (np. adres e-mail, prawdziwe imię i nazwisko)",
        "right-editmyoptions": "Edycja swoich preferencji",
-       "right-rollback": "Szybkie wycofanie zmian wprowadzonych przez użytkownika, który jako ostatni edytował stronę",
+       "right-rollback": "Szybkie wycofywanie zmian wprowadzonych przez użytkownika, który jako ostatni edytował stronę",
        "right-markbotedits": "Oznaczanie rewertu jako edycji bota",
        "right-noratelimit": "Brak ograniczeń przepustowości",
        "right-import": "Importowanie stron z innych wiki",
        "recentchanges-legend-heading": "'''Legenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (zobacz też [[Special:NewPages|listę nowych stron]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Pokaż",
        "rcnotefrom": "Poniżej {{PLURAL:$5|pokazano zmianę|pokazano zmiany}} {{PLURAL:$5|wykonaną|wykonane}} po <strong>$3, $4</strong> (nie więcej niż '''$1''' pozycji).",
        "rclistfrom": "Pokaż nowe zmiany od $3 $2",
        "rcshowhideminor": "$1 drobne edycje",
        "mostrevisions": "Strony o największej liczbie wersji",
        "prefixindex": "Wszystkie strony o prefiksie",
        "prefixindex-namespace": "Wszystkie strony z prefiksem (przestrzeń nazw $1)",
+       "prefixindex-submit": "Pokaż",
        "prefixindex-strip": "Ukryj prefiks na liście wyników",
        "shortpages": "Najkrótsze strony",
        "longpages": "Najdłuższe strony",
        "protectedpages-performer": "Użytkownik zabezpieczający",
        "protectedpages-params": "Parametry zabezpieczenia",
        "protectedpages-reason": "Powód",
+       "protectedpages-submit": "Wyświetl strony",
        "protectedpages-unknown-timestamp": "Nieznane",
        "protectedpages-unknown-performer": "Użytkownik nieznany",
        "protectedtitles": "Zabezpieczone nazwy stron",
        "protectedtitles-summary": "Ta strona zawiera listę tytułów, których utworzenie jest obecnie zabronione. Aby zobaczyć listę istniejących stron, które są chronione, zobacz [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Dla tych ustawień dopuszczalne jest utworzenie stron o dowolnej nazwie.",
+       "protectedtitles-submit": "Wyświetl tytuły",
        "listusers": "Lista użytkowników",
        "listusers-editsonly": "Pokaż tylko użytkowników z edycjami",
        "listusers-creationsort": "Sortuj według daty utworzenia",
        "activeusers-hidebots": "Ukryj boty",
        "activeusers-hidesysops": "Ukryj administratorów",
        "activeusers-noresult": "Nie odnaleziono żadnego użytkownika.",
+       "activeusers-submit": "Wyświetl aktywnych użytkowników",
        "listgrouprights": "Uprawnienia grup użytkowników",
        "listgrouprights-summary": "Poniżej znajduje się spis zdefiniowanych na tej wiki grup użytkowników, z wyszczególnieniem przydzielonych im uprawnień.\nSprawdź stronę z [[{{MediaWiki:Listgrouprights-helppage}}|dodatkowymi informacjami]] o uprawnieniach.",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Przyznane uprawnienie</span>\n* <span class=\"listgrouprights-revoked\">Odebrane uprawnienie</span>",
        "wlshowlast": "Pokaż ostatnie $1 godzin, $2 dni",
        "watchlistall2": "wszystkie",
        "watchlist-hide": "Ukryj",
-       "wlshowtime": "Pokaż ostatnie:",
+       "watchlist-submit": "Pokaż",
+       "wlshowtime": "Okres czasu do wyświetlania:",
        "wlshowhideminor": "drobne edycje",
        "wlshowhidebots": "boty",
        "wlshowhideliu": "zarejestrowanych",
        "contributions": "Wkład {{GENDER:$1|użytkownika|użytkowniczki}}",
        "contributions-title": "Wkład {{GENDER:$1|użytkownika|użytkowniczki}} $1",
        "mycontris": "Edycje",
+       "anoncontribs": "Edycje",
        "contribsub2": "Dla {{GENDER:$3|użytkownika|użytkowniczki}} $1 ($2)",
        "contributions-userdoesnotexist": "Konto użytkownika „$1” nie jest zarejestrowane.",
        "nocontribs": "Brak zmian odpowiadających tym kryteriom.",
        "whatlinkshere-hidelinks": "$1 linki",
        "whatlinkshere-hideimages": "$1 linki z plików",
        "whatlinkshere-filters": "Filtry",
+       "whatlinkshere-submit": "Dalej",
        "autoblockid": "automatyczna blokada nr $1",
        "block": "Zablokuj użytkownika",
        "unblock": "Odblokuj użytkownika",
        "movenosubpage": "Ta strona nie posiada podstron.",
        "movereason": "Powód:",
        "revertmove": "cofnij",
-       "delete_and_move": "Usuń i przenieś",
        "delete_and_move_text": "== Przeniesienie wymaga usunięcia innej strony ==\nStrona docelowa „[[:$1]]” istnieje.\nCzy chcesz ją usunąć, by zrobić miejsce dla przenoszonej strony?",
        "delete_and_move_confirm": "Tak, usuń stronę",
        "delete_and_move_reason": "Usunięto, by zrobić miejsce dla przenoszonej strony „[[$1]]”",
        "tooltip-pt-preferences": "Moje preferencje",
        "tooltip-pt-watchlist": "Lista stron obserwowanych przez Ciebie",
        "tooltip-pt-mycontris": "Lista moich edycji",
+       "tooltip-pt-anoncontribs": "Lista edycji wykonanych z tego adresu IP",
        "tooltip-pt-login": "Zachęcamy do zalogowania się, choć nie jest to obowiązkowe.",
        "tooltip-pt-logout": "Wyloguj",
        "tooltip-pt-createaccount": "Zachęcamy do stworzenia konta i zalogowania, ale nie jest to konieczne.",
        "logentry-suppress-block": "$1 {{GENDER:$2|zablokował|zablokowała}} {{GENDER:$4|$3}}, czas blokady: $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia blokady dla {{GENDER:$4|$3}}, czas blokady: $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|zaimportował|zaimportowała}} $3 poprzez przesłanie pliku",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|zaimportował|zaimportowała|zaimportował(a)}} $3 poprzez przesłanie pliku ($4 {{PLURAL:$4|wersja|wersje|wersji}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|zaimportował|zaimportowała}} $3 z innej wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|zaimportował|zaimportowała|zaimportował(a)}} $3 z $5 ($4 {{PLURAL:$4|wersja|wersje|wersji}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|scalił|scaliła}} stronę $3 do $4 (wersje do $5)",
        "logentry-move-move": "$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 do $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4, bez pozostawienia przekierowania pod starym tytułem",
index 0ffb96a..09912bf 100644 (file)
@@ -40,6 +40,7 @@
        "tog-watchlisthidebots": "په کتنلړ کې د روباټ سمونې پټول",
        "tog-watchlisthideminor": "په کتنلړ کې وړې سمونې پټول",
        "tog-watchlisthideliu": "په کتنلړ کې د ثبت شويو کارنانو سمونې پټول",
+       "tog-watchlistreloadautomatically": "هرکله چې يو چاڼگر بدلېږي، کتنلړ دې هم په خپلکاره توگه بيابرسېره شي. (د جاواسکرېپټ اړتيا)",
        "tog-watchlisthideanons": "په کتنلړ کې د ورکنومو کارنانو سمونې پټول",
        "tog-watchlisthidepatrolled": "په کتنلړ کې څارل شوې سمونې پټول",
        "tog-watchlisthidecategorization": "په وېشنيزو کې د مخونو وېشنه پټول",
        "index-category": "ليکلړلرونکي مخونه",
        "noindex-category": "بې ليکلړه مخونه",
        "broken-file-category": "د دوتنو د ماتو تړنو مخونه",
+       "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "په اړه",
        "article": "مېنځپانگيز مخ",
        "newwindow": "(په نوې کړکۍ کې پرانيستل کېږي)",
        "morenotlisted": "دا لړليک بشپړ نه دی",
        "mypage": "زما مخ",
        "mytalk": "خبرې اترې",
-       "anontalk": "ددÛ\90 IP Ø®Ø¨Ø±Û\90 Ø§ØªØ±Û\90",
+       "anontalk": "خبرې اترې",
        "navigation": "گرځښت",
        "and": "&#32;او",
        "qbfind": "موندل",
        "newpage": "نوی مخ",
        "talkpage": "د دې مخ په اړه خبرې اترې کول",
        "talkpagelinktext": "خبرې اترې",
-       "specialpage": "Ú\81اÙ\86Ú¯Ú\93Û\90 Ù¾Ø§Ú¼Ù\87",
+       "specialpage": "Ú\81اÙ\86Ú¯Ú\93Û\8c Ù\85Ø®",
        "personaltools": "شخصي اوزار",
        "articlepage": "د مخ مېنځپانگه ښکاره کول",
        "talk": "خبرې اترې",
        "versionrequired": "د ميډياويکي $1 بڼې ته اړتيا ده",
        "versionrequiredtext": "د دې مخ په ليدلو کې د مېډياويکي $1 بڼې ته اړتيا ده. \n[[Special:Version|د بڼې مخ وگورۍ]].",
        "ok": "ښه",
+       "pagetitle": "$1 - {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "\"$1\" نه اخيستل شوی",
        "youhavenewmessages": "تاسې $1 لری  ($2).",
        "youhavenewmessagesfromusers": "تاسې د {{PLURAL:$3|يو بل کارن|$3 کارنانو}} لخوا $1 لرۍ ($2).",
        "user-mail-no-addy": "د يوې برېښليک پتې پرته د برېښليک لېږلو هڅه شوې.",
        "changepassword": "پټنوم بدلول",
        "resetpass_announce": "د ننوتلو د بشپړېدلو لپاره بايد تاسې يو نوی پټنوم وټاکئ.",
+       "resetpass_text": "<!-- متن مو دلته وليکئ -->",
        "resetpass_header": "د گڼون پټنوم بدلول",
        "oldpassword": "زوړ پټنوم:",
        "newpassword": "نوی پټنوم:",
        "passwordreset-email": "برېښليک پته:",
        "passwordreset-emailtitle": "د {{SITENAME}} د گڼون څرگندنې",
        "passwordreset-emailelement": "کارن-نوم: \n$1\n\nلنډمهاله پټنوم: \n$2",
-       "passwordreset-emailsent": "د پټنوم بيا پرځای کېدنې لپاره برېښليک درولېږل شو.",
+       "passwordreset-emailsentemail": "د پټنوم بيا پرځای کېدنې لپاره برېښليک درولېږل شو.",
        "passwordreset-emailsent-capture": "د پټنوم بياپرځای کېدنې لپار مو يو برېښليک درولېږه، برېښليک په لاندې توگه ښودل شوی.",
        "changeemail": "برېښليک پته بدلول يا ليرې کول",
        "changeemail-header": "د گڼون برېښليک پته بدلول",
        "headline_tip": "د ۲ کچې سرليک",
        "nowiki_sample": "دلته دې بې بڼې متن ځای پر ځای شي",
        "nowiki_tip": "د ويکي بڼه نيونه بابېزه گڼل",
+       "image_sample": "Example.jpg",
        "image_tip": "خښه شوې دوتنه",
+       "media_sample": "Example.ogg",
        "media_tip": "د دوتنې تړنه",
        "sig_tip": "ستاسې لاسليک د وخت د ټاپې سره",
        "hr_tip": "څنډيزه ليکه (ددې په کارولو کې سپما وکړۍ)",
        "anontalkpagetext": "----''دا د يوه ورکنومي کارن چې کارن-نوم نه لري او يا خپل کارن-نوم نه کاروي، د سکالو يوه پاڼه ده. نو د يوه کس د پېژندلو پخاطر موږ د هماغه کارن د انټرنېټ شمېره يا IP پته دلته ثبتوؤ. داسې يوه IP پته د ډېرو کارنانو لخوا هم کارېدلی شي. که تاسې يو ورکنومی کارن ياست او تاسې ته دا څرگندېږي چې تاسې ته نااړونده پېغامونه او تبصرې اشاره شوي، نو د نورو بې نومو کارنانو او ستاسې ترمېنځ د ټکنتوب د مخ نيونې لپاره لطفاً [[Special:UserLogin/signup|يو گڼون جوړ کړۍ]] او يا هم [[Special:UserLogin|غونډال ته ورننوځۍ]].''",
        "noarticletext": "دم مهال په دې مخ کې څه نشته.\nتاسې کولای شی چې په نورو مخونو کې [[Special:Search/{{PAGENAME}}|د دې مخ د سرليک پلټنه]] يا\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} د اړوندو يادښتونو پلټنه] وکړی.\nاو يا [{{fullurl:{{FULLPAGENAME}}|action=edit}} همدا مخ سم کړی]</span>.",
        "noarticletext-nopermission": "دم مهال په دې مخ کې متن نشته.\nتاسې کولای شی چې [[Special:Search/{{PAGENAME}}|همدا سرليک په نورو مخونو کې وپلټۍ]], يا هم <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} اړونده يادښتونه وپلټۍ]</span>، خو تاسې د دې مخ د جوړولو اجازه نه لرۍ.",
-       "userpage-userdoesnotexist": "د \"<nowiki>$1</nowiki>\" گڼون نه دی ثبت شوی.\nلطفاً ځان ډاډه کړۍ چې آيا تاسې په رښتيا همدا مخ جوړول که سمول غواړۍ.",
+       "userpage-userdoesnotexist": "د \"<nowiki>$1</nowiki>\" گڼون نه دی ثبت شوی.\nلطفاً ځان ډاډه کړئ چې آيا تاسې په رښتيا همدا مخ جوړول/سمول غواړئ.",
        "userpage-userdoesnotexist-view": "د \"$1\" گڼون نه دی ثبت شوی.",
        "blocked-notice-logextract": "دم مهال په دې کارن بنديز لگېدلی.\nد بنديز يادښت تازه مالومات په لاندې توگه دي:",
        "clearyourcache": "'''يادښت:''' د غوره توبونو د خوندي کولو وروسته، خپل د کتنمل (بروزر) ساتل شوې حافظه تازه کړی.\n* '''فايرفاکس/ سفري:''' په دې کتنمل کې د ''Reload'' د ټکوهلو په وخت د ''Shift'' تڼۍ نيولې وساتی، او يا هم ''Ctrl-F5'' يا ''Ctrl-R''تڼۍ کېښکاږۍ (په Apple Mac کمپيوټر باندې ''⌘-R'' کېښکاږۍ)\n* '''گووگل کروم:''' په دې کتنمل کې د ''Ctrl-Shift-R'' تڼۍ کېښکاږۍ (د مک لپاره ''⌘-Shift-R'')\n* '''انټرنټ اېکسپلورر:''' په دې کتنمل کې د ''Refresh'' د ټکوهلو په وخت کې د ''Ctrl'' تڼۍ کېښکاږلې ونيسۍ، او يا هم د ''Ctrl-F5'' تڼۍ کېښکاږۍ\n* '''اوپرا''': په دې کتنمل کې د خپل براوزر ساتل شوې حافظه پدې توگه سپينولی شی ''Tools→Preferences''",
        "template-protected": "(ژغورلی)",
        "template-semiprotected": "(نيم-ژغورلی)",
        "hiddencategories": "دا مخ د {{PLURAL:$1|1 پټې وېشنيزې|$1 پټو وېشنيزو}} يو غړی دی:",
+       "edittools-upload": "-",
        "nocreatetext": "{{SITENAME}} د نوو مخونو د جوړولو وړتيا محدوده کړې.\nتاسو بېرته پر شا تللای شی او په شته مخونو کې سمونې ترسره کولای شی، او يا هم [[Special:UserLogin|غونډال ته ننوتلای او يو گڼون جوړولای شی]].",
        "nocreate-loggedin": "تاسې د نوو مخونو د جوړولو پرېښله نلرۍ.",
        "sectioneditnotsupported-title": "د برخې د سمون ملاتړ نه کېږي",
        "content-model-text": "ساده متن",
        "content-model-javascript": "جاواسکرېپټ",
        "content-model-css": "CSS",
+       "content-model-json": "JSON",
        "content-json-empty-object": "تش څيز",
        "post-expand-template-inclusion-warning": "'''گواښنه:''' دا کينډۍ د خپل ټاکلي بريد نه ډېره لويه ده.\nځينې کينډۍ به په کې گډې نه شي.",
        "post-expand-template-inclusion-category": "هغه مخونه چې په کې د کارېدلو کينډيو شمېر له ټاکلې کچې ډېر دی",
        "mergehistory-comment": "[[:$1]] [[:$2]] کې اخږل شوی: $3",
        "mergehistory-same-destination": "د سرچينې او موخې مخونه بايد يو ډول نه وي",
        "mergehistory-reason": "سبب:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "د اخږلو يادښت",
        "revertmerge": "بېلول",
        "mergelogpagetext": "دلته لاندې د يو مخ د پېښليک تازه اخږنه بل مخ ته د يو لړليک په توگه راغلی.",
        "youremail": "برېښليک *",
        "username": "{{GENDER:$1|کارن نوم}}:",
        "prefs-memberingroups": "د {{PLURAL:$1|ډله|ډلې}} {{GENDER:$2|غړی}}:",
+       "prefs-memberingroups-type": "$1",
        "prefs-registration": "د نومليکنې وخت:",
+       "prefs-registration-date-time": "$1",
        "yourrealname": "اصلي نوم:",
        "yourlanguage": "ژبه:",
        "yourvariant": "د ژبگړدود مېنځپانگه:",
        "yournick": "نوی لاسليک:",
+       "prefs-help-signature": "د خبرو اترو مخونو د تبصرو پای بايد د \"<nowiki>~~~~</nowiki>\" په کوډ لاسليک شي، دا کوډ به بيا په خپلکاره توگه ستاسې په لاسليک او وخت ټاپې اړول کېږي.",
        "badsiglength": "ستاسو لاسليک ډېر اوږد دی.\nبايد چې لاسليک مو له $1 {{PLURAL:$1|توري|تورو}} نه لږ وي.",
        "yourgender": "څنگه غواړۍ ځان څرگند کړۍ؟",
        "gender-unknown": "ناڅرگنده",
        "saveusergroups": "کارن ډلې خوندي کول",
        "userrights-groupsmember": "غړی د:",
        "userrights-groupsmember-auto": "ضمني غړی د:",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "تاسې هغه ډلې چې همدا کارن يې غړی دی بدلولی شی:\n* يو په نښه شوی بکس د دې مانا لري چې کارن د هغې ډلې غړيتوب لري.\n* يو نانښه شوی بکس د دې مانا لري چې کارن د هغې ډلې غړيتوب نلري.\n* د * يوه نښه په دې مانا ده چې هر کله تاسې څوک په همدې ډلې کې غړی کړی بيا يې ترې نشی وېستلی او د دې برعکس هم.",
        "userrights-reason": "سبب:",
        "userrights-no-interwiki": "په همدې ويکي باندې تاسې د کارن رښتو د سمولو اجازه نه لرۍ.",
        "userrights-changeable-col": "هغه ډلې چې تاسې يې بدلولی شی",
        "userrights-unchangeable-col": "هغه ډلې چې تاسې يې نه شی بدلولی",
+       "userrights-irreversible-marker": "$1*",
        "group": "ډله:",
        "group-user": "کارنان",
        "group-autoconfirmed": "تاييد شوي کارنان",
        "recentchanges-label-plusminus": "د بايټونو د شمېر له مخې د مخ د بدلون کچه",
        "recentchanges-legend-heading": "'''لنډونونه:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|د نويو مخونو لړليک]] هم وگورئ)",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "rcnotefrom": "دلته لاندې د <strong>$2</strong> څخه راپدېخوا پېښ شوي بدلونونه راغلي (تر <strong>$1</strong> پورې ښکاري).",
        "rclistfrom": "نوي بدلونونه چې له $3، $2 څخه پيلېږي ښکاره کول",
        "rcshowhideminor": "وړې سمونې $1",
        "minoreditletter": "و",
        "newpageletter": "ن",
        "boteditletter": "ر",
+       "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1  {{PLURAL:$1|کتونکی کارن|کتونکي کارنان}}]",
        "rc_categories": "د وېشنيزو تر بريده (په \"|\" بېلول)",
        "rc_categories_any": "له ټاکل شويو هر يو",
+       "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|بايټ|بايټونه}} د بدلون وروسته",
        "newsectionsummary": "/* $1 */ نوې برخه",
        "rc-enhanced-expand": "تفصيل ښکاره کول",
        "upload-form-label-infoform-description": "څرگندونه",
        "upload-form-label-usage-title": "کارېدنې",
        "upload-form-label-usage-filename": "د دوتنې نوم",
+       "foreign-structured-upload-form-label-own-work": "دا زما خپل کار دی",
        "foreign-structured-upload-form-label-infoform-categories": "وېشنيزې",
        "foreign-structured-upload-form-label-infoform-date": "نېټه",
        "backend-fail-notexists": "د $1 په نوم دوتنه نشته.",
        "ntransclusions": "په $1 {{PLURAL:$1|مخ|مخونو}} کارېدلی",
        "specialpage-empty": "د دې راپور لپاره کومې پايلې نشته.",
        "lonelypages": "يتيم مخونه",
+       "lonelypagestext": "دا لانديني مخونه په {{SITENAME}} کې د هېڅ کوم بل مخ سره تړنې نه لري او په هېڅ کوم بل مخ کې نه دي رانغاړل شوي.",
        "uncategorizedpages": "ناوېشلي مخونه",
        "uncategorizedcategories": "ناوېشلې وېشنيزې",
        "uncategorizedimages": "ناوېشلي انځورنه",
        "wantedpages": "غوښتلي مخونه",
        "wantedpages-summary": "دا د هغو ناموجودو مخونو لړليک دی چې تر ټولو ډېرې تړنې لري، په دې لړليک کې د مخ گرځونو مخونه شامل نه دي. د هغو ناموجودو مخونو لپاره چې د مخ گرځونو مخونه په کې شامل دي، [[{{#special:BrokenRedirects}}|د ماتو مخ گرځونو لړليک]] کې کتلی شی.",
        "wantedfiles": "غوښتلې دوتنې",
+       "wantedfiletext-cat": "دا لاندې دوتنې دلته په نورو مخونو کې کارېدلي خو لا تر اوسه پورې نشته.. همداراز کېدای شي د باندنيو زېرمتونونو دوتنې د شتون سره سره دلته په لړليک کې راغلي وي. په دې ډول هرې ناسمې مثبته راوړنې باندې به <del>کرښه کښل</del> کېږي.\nد دې تر څنگ هغه مخونه چې ناموجوده دوتنې په ځان کې رانغاړي د لړليک په بڼه، [[:$1]] کې موندلی شئ.",
+       "wantedfiletext-nocat": "دا لاندې دوتنې دلته په نورو مخونو کې کارېدلي خو لا تر اوسه پورې نشته.. همداراز کېدای شي د باندنيو زېرمتونونو دوتنې د شتون سره سره دلته په لړليک کې راغلي وي. په دې ډول هرې ناسمې مثبته راوړنې باندې به <del>کرښه کښل</del> کېږي.",
+       "wantedfiletext-nocat-noforeign": "دا لاندينۍ دوتنې دلته کارېدلي خو لا تر اوسه نشته.",
        "wantedtemplates": "غوښتلې کينډۍ",
        "mostlinked": "د ډېرو تړنو مخونه",
        "mostlinkedcategories": "د گڼو تړنو وېشنيزې",
-       "mostlinkedtemplates": "د ډېرو تړنو کينډۍ",
+       "mostlinkedtemplates": "ډېر رانغاړل شوي مخونه",
        "mostcategories": "د گڼو وېشنيزو مخونه",
        "mostimages": "د ډېرو تړنو انځورونه",
        "mostinterwikis": "د ډېرو خپلمنځي تړنو مخونه",
        "mostrevisions": "ډېر کتلي مخونه",
        "prefixindex": "د مختاړيو ټول مخونه",
        "prefixindex-namespace": "د مختاړي ټول مخونه ($1 نومتشيال)",
+       "prefixindex-strip": "په لړليک کې مختاړی غورځول",
        "shortpages": "لنډ مخونه",
        "longpages": "اوږده مخونه",
        "deadendpages": "بې پايه مخونه",
        "protectedpages-page": "مخ",
        "protectedpages-expiry": "پای نېټه",
        "protectedpages-performer": "ژغورونکی کارن",
+       "protectedpages-params": "د ژغورنې پاراميټرونه",
        "protectedpages-reason": "سبب",
        "protectedpages-unknown-timestamp": "ناجوت",
        "protectedpages-unknown-performer": "ناڅرگنده کارن",
        "apihelp-no-such-module": "د \"$1\" ماډيول و نه موندل شو.",
        "booksources": "د کتاب سرچينې",
        "booksources-search-legend": "د کتابي سرچينو پلټنه",
+       "booksources-isbn": "ISBN:",
        "booksources-search": "پلټل",
        "booksources-text": "دا لاندې د هغه وېبځايونو د تړنو لړليک دی چېرته چې نوي او زاړه کتابونه پلورل کېږي، او يا هم کېدای شي چې د هغه کتاب په هکله مالومات ولري کوم چې تاسو ورپسې لټېږۍ:",
        "booksources-invalid-isbn": "دا ISBN چې تاسې ورکړی سم نه ښکاري؛ د تېروتنو لپاره د لمېسلو اصلي سرچينه وگورئ.",
        "listgrouprights-rights": "رښتې",
        "listgrouprights-helppage": "Help:د ډلې رښتې",
        "listgrouprights-members": "(د غړو لړليک)",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
+       "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 <code>($2)</code></span>",
        "listgrouprights-addgroup": "{{PLURAL:$2|ډله|ډلې}} ورگډول: $1",
        "listgrouprights-removegroup": "{{PLURAL:$2|ډله|ډلې}} ليري کول: $1",
        "listgrouprights-addgroup-all": "ټولې ډلې ورگډول",
        "listgrouprights-removegroup-self": "خپل گڼون نه د {{PLURAL:$2|ډله|ډلې}} ليري کول: $1",
        "listgrouprights-addgroup-self-all": "خپل گڼون کې ټولې ډلې ورگډول",
        "listgrouprights-removegroup-self-all": "خپل گڼون نه ټولې ډلې ليري کول",
+       "listgrouprights-namespaceprotection-header": "د نومتشيال محدوديتونه",
        "listgrouprights-namespaceprotection-namespace": "نوم-تشيال",
+       "listgrouprights-namespaceprotection-restrictedto": "د کارن سمون ترسره کولو رښته(رښتې)",
        "trackingcategories": "موندونکې وېشنيزې",
        "trackingcategories-msg": "وېشنيزه موندنه",
        "trackingcategories-name": "پيغام نوم",
        "deletereasonotherlist": "بل سبب",
        "deletereason-dropdown": "*د ړنگولو ټولگړی سبب\n** چټيات\n** د پوهې سره دښمني\n** د رښتو تېری\n** د ليکوال غوښتنه\n** ناسمه مخ گرځېدنه",
        "delete-edit-reasonlist": "د ړنگولو سببونه سمول",
+       "deleting-backlinks-warning": "گواښنه:''' دا مخ چې تاسې يې ړنگوی د [[Special:WhatLinksHere/{{FULLPAGENAME}}|نورو مخونو]] سره تړلی او يا هم په نورو مخونو کې نغاړل شوی دی.",
        "rollbacklink": "په شابېول",
        "rollbacklinkcount": "$1 {{PLURAL:$1|سمون|سمونونه}} پرشابېول",
        "editcomment": "د سمون لنډيز دا و: \"''$1''\".",
        "protect-fallback": "يوازې د \"$1\" اجازې لرونکي کارنان پرېښودل",
        "protect-level-autoconfirmed": "يوازې تاييد شوي کارنان",
        "protect-level-sysop": "يواځې پازوالان پرېښودل",
+       "protect-summary-desc": "[$1=$2] ($3)",
        "protect-summary-cascade": "ځوړاوبيز",
        "protect-expiring": "په $1 (UTC) پای ته رسېږي",
        "protect-expiring-local": "پای نېټه $1",
        "undelete-search-prefix": "هغه مخونه چې پيلېږي په:",
        "undelete-search-submit": "پلټل",
        "undelete-show-file-submit": "هو",
+       "undelete-revision-row": "$1 $2 ($3) $4 . . $5 $6 $7 $8 $9",
        "namespace": "نوم-تشيال:",
        "invert": "ټاکنې سرچپه کول",
        "tooltip-invert": "په ټاکلو نومتشيالونو کې (او اړونده نومتشيال کې که په نښه شوی وي) د مخونو بدلونونو د پټولو لپاره دا بکس په نښه کړئ",
        "contributions": "{{GENDER:$1|کارن}} ونډې",
        "contributions-title": "د $1 کارن ونډې",
        "mycontris": "ونډې",
+       "anoncontribs": "ونډې",
        "contribsub2": "د {{GENDER:$3|$1}} لپاره ($2)",
        "contributions-userdoesnotexist": "کارن گڼون \"$1\" نه دی ثبت شوی.",
        "nocontribs": "دې شرطونو سره سم بدلونونه و نه موندل شول.",
        "movenosubpage": "دا مخ کوم څېرمه مخونه نه لري.",
        "movereason": "سبب:",
        "revertmove": "په څټ گرځول",
-       "delete_and_move": "ړنگول او لېږدول",
        "delete_and_move_text": "== د ړنگولو اړتيا ==\nد \"[[:$1]]\" په نوم مخ له پخوا څخه شته.\nآيا د دې په ړنگولو سره لېږدولو ته لاره هوارول غواړۍ؟",
        "delete_and_move_confirm": "هو, دا مخ ړنگ کړه",
        "immobile-source-page": "دا مخ نه لېږدېدنونکی دی",
        "import-comment": "تبصره:",
        "import-revision-count": "$1 {{PLURAL:$1|بڼه|بڼې}}",
        "importnopages": "د رالېږدولو لپاره مخونه نشته.",
+       "imported-log-entries": "$1 {{PLURAL:$1|يادښتليک راوړل شوی|يادښتليکونه راوړل شوي}}.",
        "importcantopen": "واردونکې دوتنه و نه پرانيستل شوه.",
+       "importbadinterwiki": "ناسمه ويکيخپلمنځي تړنه",
        "import-upload": "د XML اومتوک پورته کول",
        "import-token-mismatch": "د اومتوک غونډېدنه له لاسه وتلې.\nلطفاً بيا يې وآزمايئ.",
        "importlogpage": "د واردولو يادښت",
        "tooltip-undo": "\"ناکړ\" همدا سمون پر شا گرځوي او د سمون کړکۍ د مخکتنې په بڼه پرانيزي.\nدا کړنه د لنډيز په برخه کې د سمونونو د سببونو د ورگډولو آسانتيا برابروي.",
        "tooltip-preferences-save": "غوره توبونه خوندي کول",
        "tooltip-summary": "يو لنډ لنډيز کښل",
+       "interlanguage-link-title": "$1 – $2",
+       "interlanguage-link-title-nonlang": "$1 – $2",
        "anonymous": "د {{SITENAME}} {{PLURAL:$1|ورکنومی کارن|ورکنومي کارنان}}",
        "siteuser": "د {{SITENAME}} کارن $1",
        "anonuser": "د {{SITENAME}} ورکنومی کارن $1",
        "pageinfo-watchers": "د مخ د کتونکو شمېر",
        "pageinfo-few-watchers": "له $1 څخه لږ {{PLURAL:$1|کتونکی|کتونکي}}",
        "pageinfo-redirects-name": "دې مخ ته د ورگرځونو شمېر",
+       "pageinfo-redirects-value": "$1",
        "pageinfo-subpages-name": "دې مخ ته څېرمه مخونه",
        "pageinfo-firstuser": "مخ جوړونکی",
        "pageinfo-firsttime": "د مخ جوړېدنې نېټه",
        "metadata-fields": "د انځور مېټاډاټا ډگرونه چې لړليک يې په همدې پيغام کې په لاندې توگه راغلی د انځور مخ په ښکارېدنه کې به هغه وخت ورگډ شي کله چې د مېټاډاټا لښتيال غځېږي.\nنور څه به په تلواليزه توگه پټ پاتې وي.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "سوروالی",
        "exif-imagelength": "لوړوالی",
+       "exif-photometricinterpretation": "پېکسل ترکيب",
        "exif-orientation": "لورموندنه",
+       "exif-planarconfiguration": "اومتوک ترتيب",
        "exif-xresolution": "څنډيز ژورليد",
        "exif-yresolution": "ولاړيز ژورليد",
        "exif-stripoffsets": "د انځور مالوماتځی",
        "exif-relatedsoundfile": "اړونده غږيزه دوتنه",
        "exif-datetimeoriginal": "د اومتوک د جوړېدنې وخت او نېټه",
        "exif-datetimedigitized": "د گڼياليز کېدنې وخت او نېټه",
+       "exif-exposuretime": "رڼاغورځونې وخت",
        "exif-exposuretime-format": "$1 ثانيه ($2)",
        "exif-fnumber": "F شمېره",
+       "exif-exposureprogram": "رڼاغورځونې پروگرام",
        "exif-spectralsensitivity": "طيفي حساسيت",
        "exif-isospeedratings": "د ISO چټکتيا ارزونه",
        "exif-shutterspeedvalue": "د APEX بندگر چټکتيا",
        "exif-brightnessvalue": "د APEX رڼښت",
+       "exif-meteringmode": "رڼامېچنې حالت",
        "exif-lightsource": "د رڼا سرچينه",
        "exif-flash": "فلش",
        "exif-focallength": "د عدسيې کانوني واټن",
        "exif-subjectarea": "د جسم سيمه",
        "exif-flashenergy": "د فلش انرژي",
        "exif-subjectlocation": "د جسم ځای",
+       "exif-sensingmethod": "د حس کولو چلندلار",
        "exif-filesource": "د دوتنې سرچينه",
+       "exif-scenetype": "د صحنې ډول",
+       "exif-customrendered": "دوديزه انځور بهير",
+       "exif-exposuremode": "د رڼا غورځولو حالت",
        "exif-whitebalance": "د سپين رنگ توازن",
+       "exif-digitalzoomratio": "د گڼياليز لويواله پرتلنه",
+       "exif-gaincontrol": "د صحنې تنظيم",
+       "exif-contrast": "رڼښت",
+       "exif-saturation": "رنگ گاټه توب",
+       "exif-gpslatitude": "لوړوالی",
+       "exif-gpslongituderef": "ختيځ يا لوېديځ اوږدالی",
+       "exif-gpslongitude": "اوږدوالی",
        "exif-gpsaltituderef": "د لوړوالي سرچينه",
        "exif-gpsaltitude": "لوړوالی",
+       "exif-gpstimestamp": "GPS وخت (اتومي گړۍ)",
+       "exif-gpssatellites": "د مېچنې لپاره کارېدلې سپوږمکۍ",
+       "exif-gpsstatus": "د اخيستگر دريځ",
+       "exif-gpsmeasuremode": "د مېچنې حالت",
+       "exif-gpsdop": "د مېچنې دقت",
        "exif-gpsspeedref": "د سرعت يوون",
+       "exif-gpsspeed": "د جي پي اس اخيستونکي چټکتيا",
+       "exif-gpstrack": "د خوځښت سمت",
        "exif-gpsimgdirection": "د انځور لوری",
        "exif-gpsareainformation": "د جي پي اس د سيمې نوم",
        "exif-gpsdatestamp": "د جي پي اس نېټه",
        "exif-orientation-1": "نورمال",
        "exif-componentsconfiguration-0": "نشته دی",
        "exif-exposureprogram-1": "لاسي",
-       "exif-exposureprogram-2": "Ù\86Ù\88رÙ\85اÙ\84Ù\87 Ù¾Ø±Ù\88Ú«رام",
+       "exif-exposureprogram-2": "Ù\86Ù\88رÙ\85اÙ\84Ù\87 Ù¾Ø±Ù\88Ú¯رام",
        "exif-subjectdistance-value": "$1 متره",
        "exif-meteringmode-0": "ناجوت",
        "exif-meteringmode-1": "منځالی",
        "exif-lightsource-11": "سيوری",
        "exif-lightsource-255": "د رڼا بله سرچينه",
        "exif-flash-fired-0": "فلش و نه ځلېده",
+       "exif-flash-mode-3": "خپلکاره حالت",
        "exif-focalplaneresolutionunit-2": "انچه",
        "exif-sensingmethod-1": "ناڅرگنده",
        "exif-filesource-3": "گڼياليزه ولاړه کامره",
        "exif-gaincontrol-0": "هېڅ",
        "exif-contrast-0": "نورمال",
        "exif-contrast-1": "پوست",
+       "exif-contrast-2": "کلک",
        "exif-saturation-0": "نورمال",
        "exif-sharpness-0": "نورمال",
        "exif-sharpness-1": "پوست",
+       "exif-sharpness-2": "کلک",
        "exif-subjectdistancerange-0": "ناجوت",
        "exif-subjectdistancerange-1": "ماکرو",
        "exif-subjectdistancerange-2": "نژدې ليدون",
        "exif-gpsdestdistance-k": "کيلومتر",
        "exif-gpsdestdistance-m": "مايلونه",
        "exif-gpsdestdistance-n": "سمندري مايلونه",
+       "exif-gpsdop-excellent": "عالي ($1)",
        "exif-gpsdop-good": "ښه ($1)",
        "exif-gpsdop-moderate": "منځوی ($1)",
        "exif-gpsdop-fair": "نه ښه نه بد ($1)",
        "exif-ycbcrpositioning-1": "منځنی",
        "exif-dc-contributor": "ونډه وال",
        "exif-dc-date": "نېټه (نېټې)",
-       "exif-dc-publisher": "خپرونکی",
+       "exif-dc-publisher": "خپرÙ\88Ù\88Ù\86Ú©Û\8c",
        "exif-dc-relation": "اړونده رسنۍ",
        "exif-dc-rights": "رښتې",
        "exif-dc-source": "د سرچينې رسنۍ",
        "autosumm-replace": "دا مخ د '$1' پرځای راوستل",
        "autoredircomment": "[[$1]] ته وروگرځېده",
        "autosumm-new": "د \"$1\" تورو مخ جوړ شو",
+       "autosumm-newblank": "تش مخ جوړ شو",
        "size-bytes": "$1 بايټ",
        "size-kilobytes": "$1 کيلوبايټ",
        "size-megabytes": "$1 مېگابايټ",
        "hebrew-calendar-m4": "تيفيت",
        "hebrew-calendar-m5": "شيفات",
        "hebrew-calendar-m6": "آدار",
+       "hebrew-calendar-m10-gen": "تموز",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|خبرې اترې]])",
        "duplicate-defaultsort": "'''گواښنه:'''د \"$2\" تلواليزه اوډون تڼۍ تر دې پخوا ټاکلې تلواليزه اوډون تڼۍ \"$1\" پر ځای چارنه کېږي.",
        "version": "بڼه",
        "fileduplicatesearch-result-1": "\"$1\" بله کټ مټ ورته غبرګونې دوتنه نلري.",
        "fileduplicatesearch-noresults": "د \"$1\" په نوم دوتنه و نه موندل شوه.",
        "specialpages": "ځانگړي مخونه",
+       "specialpages-note-top": "څرگندونې",
        "specialpages-note": "* نورماله ځانگړي مخونه.\n* <strong class=\"mw-specialpagerestricted\">محدوده ځانگړي مخونه.</strong>",
        "specialpages-group-maintenance": "د څارنې راپورونه",
        "specialpages-group-other": "نور ځانگړي مخونه",
        "specialpages-group-pagetools": "د مخ اوزارونه",
        "specialpages-group-wiki": "توکي او اوزارونه",
        "specialpages-group-redirects": "د ځانگړو مخونو مخ گرځونې",
+       "specialpages-group-developer": "د پرمختگگر اوزار",
        "blankpage": "تش مخ",
        "intentionallyblankpage": "همدا مخ په لوی لاس تش پرېښودل شوی دی",
        "external_image_whitelist": " #دا کرښه چې څنگه ده، همداسې پرېږدۍ<pre>\n#لاندې د منظمو اصطلاحگانو ټوټې (يوازې هغه برخه چې د // په مېنځ کې ليکلې) ځای پر ځای کړی\n#دا به د باندنيو انځورونو د يو آر اېل (hotlinked) سره مطابقه شي \n#هغه څه چې مطابقت لري هغه به د انځورونو په توگه ښکاره شي، کوم چې مطابقت نلري نو يوازې د انځور تړنه به ښکاره کېږي\n#هغه کرښې چې په # پيل کېږي د تبصرو په توگه په نظر کې نيول کېږي\n#دا کرښې د غټو تورو او وړو تورو سره حساسې نه دي\n\n#ټولې regex ټوټې د دغې کرښې نه پورته ځای پر ځای کړی. دا کرښه چې څنگه ده، همداسې يې پرېږدۍ</pre>",
+       "tags": "د کره بدلون نښلنونه",
        "tag-filter": "[[Special:Tags|نښلن]] چاڼگر:",
        "tag-filter-submit": "چاڼگر",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|نښلن|نښلنونه}}]]: $2)",
        "tags-create-already-exists": "د \"$1\" نښلن له پخوا څخه شته.",
        "tags-delete-title": "نښلن ړنگول",
        "tags-delete-reason": "سبب:",
+       "tags-activate-title": "نښلن فعالول",
+       "tags-activate-question": "تاسې د \"$1\" نښلن په فعالولو کې ياست.",
        "tags-activate-reason": "سبب:",
        "tags-activate-submit": "فعالول",
        "tags-deactivate-reason": "سبب:",
        "logentry-newusers-newusers": "د $1 کارن گڼون {{GENDER:$2|جوړ شو}}",
        "logentry-newusers-create": "د $1 کارن گڼون {{GENDER:$2|جوړ شو}}",
        "logentry-newusers-autocreate": "د $1 گڼون په اتوماتيک ډول {{GENDER:$2|جوړ شو}}",
+       "logentry-protect-unprotect": "$1 له $3 څخه ژغورنه {{GENDER:$2|ليرې کړه}}",
        "logentry-rights-rights": "$1 د $3 لپاره د غړيتوب ډله له $4 څخه $5 ته {{GENDER:$2|بدله کړه}}",
        "logentry-rights-rights-legacy": "$1 د $3 لپاره د غړيتوب ډله {{GENDER:$2|بدله کړه}}",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|ورپورته يې کړ}}",
        "log-name-tag": "نښلن يادښت",
        "rightsnone": "(هېڅ)",
        "revdelete-summary": "لنډيز سمول",
+       "feedback-back": "پر شا کېدل",
        "feedback-cancel": "ناگارل",
        "feedback-close": "ترسره شو",
        "feedback-external-bug-report-button": "د يوې تخنيکي دندې دوتنه جوړونه",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|ثانيه|ثانيې}}",
        "limitreport-walltime": "اصلي وخت کارېدنه",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|ثانيه|ثانيې}}",
+       "limitreport-ppvisitednodes-value": "$1/$2",
+       "limitreport-ppgeneratednodes-value": "$1/$2",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|بايټ|بايټونه}}",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بايټ|بايټونه}}",
+       "limitreport-expansiondepth-value": "$1/$2",
+       "limitreport-expensivefunctioncount-value": "$1/$2",
        "expandtemplates": "کينډۍ غځول",
        "expand_templates_input": "ځايونکی متن:",
        "expand_templates_output": "پايله",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ناچارن''')",
        "mediastatistics": "د رسنيو شمار",
        "mediastatistics-summary": "د پورته شويو دوتنو اړونده شمارنې. په دې ځای کې د يوې دوتنې يوازې تر ټولو تازه بڼې شاملې شوي. د دوتنو زړې يا ړنگې شوې بڼې په دې شمارنو کې نه دي شاملې شوي.",
+       "mediastatistics-nfiles": "$1 ($2%)",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 بايټ|$1 بايټونه}} ($2; $3%)",
        "mediastatistics-table-mimetype": "MIME بڼه",
        "mediastatistics-table-extensions": "ممکنه شاتاړي",
        "special-characters-group-thai": "تايلنډي",
        "special-characters-group-lao": "لاوي",
        "special-characters-group-khmer": "خمري",
+       "mw-widgets-dateinput-placeholder-day": "کککک-م م-و و",
+       "mw-widgets-dateinput-placeholder-month": "کککک-م م",
        "mw-widgets-titleinput-description-new-page": "تر اوسه پورې دا مخ نشته",
        "mw-widgets-titleinput-description-redirect": "$1 ته ورگرځېدنه"
 }
index f1da1cd..e1bc875 100644 (file)
        "movenosubpage": "Esta página não tem subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
-       "delete_and_move": "Eliminar e mover",
        "delete_and_move_text": "==Eliminação necessária==\nA página de destino (\"[[:$1]]\") já existe. Deseja eliminá-la de modo a poder mover?",
        "delete_and_move_confirm": "Sim, eliminar a página",
        "delete_and_move_reason": "Eliminada para mover \"[[$1]]\"",
index ec8ebcf..e0ef903 100644 (file)
@@ -72,6 +72,7 @@
        "tog-hideminor": "Esconder edições menores nas mudanças recentes",
        "tog-hidepatrolled": "Esconder edições patrulhadas nas mudanças recentes",
        "tog-newpageshidepatrolled": "Esconder páginas patrulhadas na lista de páginas novas",
+       "tog-hidecategorization": "Ocultar categorização de páginas",
        "tog-extendwatchlist": "Listagem expandida de todas as mudanças às páginas vigiadas, não apenas das mais recentes",
        "tog-usenewrc": "Agrupar alterações por página nas mudanças recentes e páginas vigiadas",
        "tog-numberheadings": "Auto-numerar cabeçalhos",
        "morenotlisted": "Esta lista não está completa.",
        "mypage": "Página",
        "mytalk": "Discussão",
-       "anontalk": "Discussão para este IP",
+       "anontalk": "Discussão",
        "navigation": "Navegação",
        "and": "&#32;e",
        "qbfind": "Procurar",
        "title-invalid-interwiki": "O título da página solicitada contém uma ligação interlíngua que não pode ser utilizada em títulos.",
        "title-invalid-talk-namespace": "O título da página solicitada refere-se a uma página de discussão que não existe.",
        "title-invalid-characters": "O título da página solicitada contém carateres inválidos: \"$1\".",
+       "title-invalid-magic-tilde": "O título da página solicitada possui uma sequência de tis inválida (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "O título da página solicitada é demasiado longo. Não deverá ser maior que $1 {{PLURAL:$1|byte|bytes}} na codificação UTF-8.",
        "title-invalid-leading-colon": "O título da página solicitada contém um erro de pontuação (:) no início.",
        "perfcached": "Os seguintes dados encontram-se armazenados na ''cache'' e podem não estar atualizados. No máximo {{PLURAL:$1|um resultado é disponível|$1 resultados são disponíveis}} na ''cache''.",
        "passwordreset-emailtext-ip": "Alguém (provavelmente você, a partir do endereço IP $1) pediu a recuperação da palavra-passe no projeto {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
        "passwordreset-emailtext-user": "O utilizador $1 do projeto {{SITENAME}} pediu a recuperação da sua palavra-passe no projeto {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este endereço de correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
        "passwordreset-emailelement": "{{GENDER:$1|Utilizador|Utilizadora}}: \n$1\n\nPalavra-passe temporária: \n$2",
-       "passwordreset-emailsent": "Se este é o endereço de correio eletrónico registado para a sua conta, então ser-lhe-à enviada uma palavra-passe de reposição.",
+       "passwordreset-emailsentemail": "Se este é o endereço de correio eletrónico registado para a sua conta, então ser-lhe-à enviada uma palavra-passe de reposição.",
        "passwordreset-emailsent-capture": "Foi enviado um correio eletrónico para recuperação da palavra-passe, que é mostrado abaixo.",
        "passwordreset-emailerror-capture": "Foi gerado um correio eletrónico para redefinição da palavra-passe, mostrado abaixo, mas o seu envio para {{GENDER:$2|o utilizador|a utilizadora}} falhou: $1",
        "changeemail": "Alterar ou remover o endereço de correio eletrónico",
        "permissionserrors": "Erro de permissão",
        "permissionserrorstext": "Não possui permissão para fazer isso, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
        "permissionserrorstext-withaction": "Não possui permissão para $2, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
+       "contentmodelediterror": "Não pode editar esta revisão pois seu modelo de conteúdo é <code>$1</code>, e o modelo actual do conteúdo da página é <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Aviso: Está a recriar uma página anteriormente eliminada.'''\n\nVerifique se é apropriado continuar a editar esta página.\nPara sua conveniência, é apresentado de seguida o registo de eliminação e de movimento da página:",
        "moveddeleted-notice": "Esta página foi eliminada.\nPara referência, é apresentado de seguida o registo de eliminações e de movimento da página.",
        "moveddeleted-notice-recent": "Desculpe, esta página foi eliminada recentemente (nas últimas 24 horas).\nA exclusão e registo de movimentação para a página são fornecidos abaixo para referência.",
        "showingresultsinrange": "Apresenta-se abaixo {{PLURAL:$1|<strong>1</strong> resultado|até <strong>$1</strong> resultados}} no intervalo #<strong>$2</strong> a #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Resultado <strong>$1</strong> de <strong>$3</strong>|Resultados <strong>$1 - $2</strong> de <strong>$3</strong>}}",
        "search-nonefound": "A pesquisa não produziu resultados.",
+       "search-nonefound-thiswiki": "Não existem resultados que correspondam à consulta neste sítio.",
        "powersearch-legend": "Pesquisa avançada",
        "powersearch-ns": "Pesquisar nos domínios:",
        "powersearch-togglelabel": "Marcar:",
        "rcshowhidemine": "$1 as minhas edições",
        "rcshowhidemine-show": "Mostrar",
        "rcshowhidemine-hide": "Ocultar",
+       "rcshowhidecategorization": "$1 categorização de páginas",
+       "rcshowhidecategorization-show": "Mostrar",
+       "rcshowhidecategorization-hide": "Ocultar",
        "rclinks": "Mostrar as últimas $1 mudanças nos últimos $2 dias<br />$3",
        "diff": "dif",
        "hist": "his",
        "recentchanges-page-added-to-category-bundled": "[[:$1]] e {{PLURAL:$2|uma outra página|$2 outras páginas}} foram adicionadas à categoria",
        "recentchanges-page-removed-from-category": "[[:$1]] foi removida da categoria",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] e {{PLURAL:$2|uma outra página|$2 outras páginas}} foram removidas da categoria",
+       "autochange-username": "Alteração automática do MediaWiki",
        "upload": "Carregar ficheiro",
        "uploadbtn": "Carregar ficheiro",
        "reuploaddesc": "Cancelar o envio e voltar ao formulário de carregamento",
        "wlnote": "A seguir {{PLURAL:$1|está a última alteração ocorrida|estão as últimas <strong>$1</strong> alterações ocorridas}} {{PLURAL:$2|na última hora|nas últimas <strong>$2</strong> horas}} até $3, $4.",
        "wlshowlast": "Ver últimas $1 horas $2 dias",
        "watchlistall2": "todas",
+       "watchlist-hide": "Ocultar",
+       "wlshowtime": "Mostrar mudanças desde há:",
        "wlshowhideminor": "edições menores",
        "wlshowhidebots": "robôs",
        "wlshowhideliu": "usuários registrados",
        "contributions": "Contribuições {{GENDER:$1|do utilizador|da utilizadora}}",
        "contributions-title": "Contribuições {{GENDER:$1|do utilizador|da utilizadora}} $1",
        "mycontris": "Contribuições",
+       "anoncontribs": "Contribuições",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "A conta de utilizador \"$1\" não está registada.",
        "nocontribs": "Não foram encontradas alterações com este critério.",
        "movenosubpage": "Esta página não tem subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
-       "delete_and_move": "Eliminar e mover",
        "delete_and_move_text": "==Eliminação necessária==\nA página de destino (\"[[:$1]]\") já existe. Deseja eliminá-la de modo a poder mover?",
        "delete_and_move_confirm": "Sim, eliminar a página",
        "delete_and_move_reason": "Eliminada para poder mover \"[[$1]]\" para este título",
index 4c1146e..061b248 100644 (file)
                        "TTO",
                        "J. 'mach' wust",
                        "Ciencia Al Poder",
-                       "Aursani"
+                       "Aursani",
+                       "Robin van der Vliet"
                ]
        },
        "sidebar": "{{notranslate}}",
        "tog-watchlisthidebots": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide bot edits from watchlist. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthideminor": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide minor edits from watchlist. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthideliu": "Option in tab 'Watchlist' of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
+       "tog-watchlistreloadautomatically": "[[Special:Preferences]], tab 'Watchlist'. Offers user to to automatically refresh the watchlist page, when a filter is changed.",
        "tog-watchlisthideanons": "Option in tab 'Watchlist' of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthidepatrolled": "Option in Watchlist tab of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthidecategorization": "Option in Watchlist tab of [[Special:Preferences]]. Offers user to hide/show categorization of pages. Appears next to checkboxes with labels such as {{msg-mw|tog-watchlisthideminor}}.",
        "morenotlisted": "An indication that more of a templates list is not shown.\n\nUsed as \"More...\" link for {{msg-mw|pageinfo-templates}} field.\n\nSimilar to {{msg-mw|moredotdotdot}}.",
        "mypage": "A text for the link to the user's user page in the links at the top of the page.\n{{Identical|Page}}",
        "mytalk": "In the personal URLs page section - right upper corner.\n\nUsed as link title in your personal toolbox.\n\nSee also:\n* {{msg-mw|Mytalk}}\n* {{msg-mw|Accesskey-pt-mytalk}}\n* {{msg-mw|Tooltip-pt-mytalk}}\n{{Identical|Talk}}",
-       "anontalk": "Link to the talk page appearing in [[mw:Help:Navigation#User_Links|user links]] for each anonymous users when [[mw:Manual:$wgShowIPinHeader|$wgShowIPinHeader]] is true.\n\nSee also:\n* {{msg-mw|Anontalk}}\n* {{msg-mw|Accesskey-pt-anontalk}}\n* {{msg-mw|Tooltip-pt-anontalk}}",
+       "anontalk": "Same as {{msg-mw|mytalk}} but used for non-logged-in users.\n{{Identical|Talk}}\n\nSee also:\n* {{msg-mw|Accesskey-pt-anontalk}}\n* {{msg-mw|Tooltip-pt-anontalk}}",
        "navigation": "This is shown as a section header in the sidebar of most skins.\n\n{{Identical|Navigation}}",
        "and": "The translation for \"and\" appears in the [[Special:Version]] page, between the last two items of a list. If a comma is needed, add it at the beginning without a gap between it and the \"&\". &amp;#32; is a blank space, one character long. Please leave it as it is.\n\nThis can also appear in the credits page if the credits feature is enabled,for example [{{canonicalurl:Support|action=credits}} the credits of the support page]. (To view any credits page type <nowiki>&action=credits</nowiki> at the end of any URL in the address bar.)\n{{Identical|And}}",
        "qbfind": "Alternative for \"search\" as used in Cologne Blue skin.\n{{Identical|Find}}",
        "databaseerror-query": "Identifies, in the list of technical details, the [[wikipedia:SQL|SQL]] statement that failed.\nParameters:\n* $1 - SQL statement (shown within a box)\n{{Identical|Query}}",
        "databaseerror-function": "Identifies, in the list of technical details, the function that tried to execute the database query.\nParameters:\n* $1 - Name of function\n{{Identical|Function}}",
        "databaseerror-error": "Identifies, in the list of technical details, the error message the database server returned.\nParameters:\n* $1 - Error message from the database server, probably in English\n{{Identical|Error}}",
+       "transaction-duration-limit-exceeded": "Plain text error shown when DB updates take too long. Parameters:\n* $1 - time spent in database updates\n* $2 - maximum time allowed in database updates",
        "laggedslavemode": "Used as warning when getting the timestamp of the latest version, if in LaggedSlaveMode.",
        "readonly": "Used as title of error message when database is locked.",
        "enterlockreason": "For developers when locking the database",
        "wrongpasswordempty": "Error message displayed when entering a blank password.\n{{Identical|Please try again}}",
        "passwordtooshort": "This message is shown in [[Special:Preferences]] and [[Special:CreateAccount]].\n\nParameters:\n* $1 - the minimum number of characters in the password",
        "passwordtoolong": "This message is shown in [[Special:Preferences]], [[Special:CreateAccount]], and [[Special:Userlogin]].\n\nParameters:\n* $1 - the maximum number of characters in the password",
+       "passwordtoopopular": "Shown if the user chooses a really popular password.",
        "password-name-match": "Used as error message when password validity check failed.",
        "password-login-forbidden": "Error message shown when the user has tried to log in using one of the special username/password combinations used for MediaWiki testing. (See [[mwr:75589]], [[mwr:75605]].)",
        "mailmypassword": "Used as label for Submit button in [[Special:PasswordReset]].\n{{Identical|Reset password}}",
        "passwordreset-emailtext-ip": "Be consistent with {{msg-mw|Passwordreset-emailtext-user}}.\n\nParameters:\n* $1 - an IP address\n* $2 - message {{msg-mw|Passwordreset-emailelement}} repeated $3 times\n* $3 - the number of repetitions in $2\n* $4 - base URL of the wiki\n* $5 - number of days",
        "passwordreset-emailtext-user": "Be consistent with {{msg-mw|Passwordreset-emailtext-ip}}.\n\nParameters:\n* $1 - a user name, no GENDER suport.\n* $2 - message {{msg-mw|Passwordreset-emailelement|notext=1}} repeated $3 times\n* $3 - the number of repetitions in $2\n* $4 - base URL of the wiki\n* $5 - number of days",
        "passwordreset-emailelement": "This is a body of a password reset email to allow them into the system with a new password. Parameters:\n* $1 - the user's login name. This parameter can be used for GENDER.\n* $2 - the temporary password given by the system",
-       "passwordreset-emailsent": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
-       "passwordreset-emailsent-capture": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
-       "passwordreset-emailerror-capture": "Error message displayed in [[Special:PasswordReset]] when sending an email fails. Parameters:\n* $1 - error message\n* $2 - username, used for GENDER\nSee also:\n* {{msg-mw|Passwordreset-emailsent}}\n* {{msg-mw|Passwordreset-emailsent-capture}}",
+       "passwordreset-emailsentemail": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
+       "passwordreset-emailsentusername": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
+       "passwordreset-emailsent-capture": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
+       "passwordreset-emailerror-capture": "Error message displayed in [[Special:PasswordReset]] when sending an email fails. Parameters:\n* $1 - error message\n* $2 - username, used for GENDER\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailsent-capture}}",
        "changeemail": "Title of [[Special:ChangeEmail|special page]]. This page also allows removing the user's email address.",
        "changeemail-summary": "{{ignored}}",
        "changeemail-header": "Text of [[Special:ChangeEmail]].",
        "page_last": "This is part of the navigation message on the top and bottom of Special pages which are lists of things in alphabetical order, e.g. the '[[Special:Categories|Categories]]' special page. It is followed by the message {{msg-mw|Viewprevnext}}.\n\n{{Identical|Last}}",
        "histlegend": "Text in history page.\n\nSee also:\n* {{msg-mw|Cur}}\n* {{msg-mw|Last}}\n* {{msg-mw|Minoreditletter}}",
        "history-fieldset-title": "Fieldset label in the edit history pages.",
+       "historyaction-submit": "Submit button on history pages",
        "history-show-deleted": "CheckBox to show only per [[mw:Manual:RevisionDelete|RevisonDelete]] deleted versions.\n\nUsed in History and [[Special:Contributions]].",
        "history_copyright": "{{notranslate}}",
        "histfirst": "This is part of the navigation message on the top and bottom of Page History pages which are lists of things in date order, e.g. [{{canonicalurl:Support|action=history}} Page History of Support].\n\nIt is followed by the message {{msg-mw|Viewprevnext}}.\n{{Identical|Oldest}}",
        "recentchanges-legend-bot": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-bot}}.",
        "recentchanges-legend-unpatrolled": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-unpatrolled}}.",
        "recentchanges-legend-plusminus": "{{optional}}\nA plus/minus sign with a number for the legend.",
+       "recentchanges-submit": "Label for submit button in [[Special:RecentChanges]]\n{{Identical|Show}}",
        "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}}.\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - (Optional) a date and time\n* $3 - a date\n* $4 - a time\n* $5 - Number of changes are displayed, for use with PLURAL",
        "rclistfrom": "Used on [[Special:RecentChanges]]. Parameters:\n* $1 - (Currently not use) date and time. The date and the time adds to the rclistfrom description.\n* $2 - time. The time adds to the rclistfrom link description (with split of date and time).\n* $3 - date. The date adds to the rclistfrom link description (with split of date and time).\n\nThe corresponding message is {{msg-mw|Rcnotefrom}}.",
        "rcshowhideminor": "Option text in [[Special:RecentChanges]]. Parameters:\n* $1 - the \"show/hide\" command, with the text taken from either {{msg-mw|rcshowhideminor-show}} or {{msg-mw|rcshowhideminor-hide}}\n{{Identical|Minor edit}}",
        "prefixindex": "{{doc-special|PrefixIndex}}\nWhen the user limits the list to a certain namespace, {{msg-mw|allinnamespace}} is used instead.",
        "prefixindex-namespace": "The page title of [[Special:PrefixIndex]] limited to a specific namespace. Similar to {{msg-mw|allinnamespace}}. $1 is the name of the namespace",
        "prefixindex-summary": "{{notranslate}}\n\nThe summary displayed at the top of [[Special:Prefixindex]]. [[mw:Manual:Interface/Special pages summary|MediaWiki manual]].",
+       "prefixindex-submit": "Label on submit button in [[Special:PrefixIndex]]\n{{Identical|Show}}",
        "prefixindex-strip": "Label for a checkbox. If the checkbox is checked, the prefix searched will be removed from the title displayed in the list. Used in [[Special:PrefixIndex]].\n\nSee the following search results:\n* [{{canonicalurl:Special:PrefixIndex|prefix=Doc&namespace=10}} Special:PrefixIndex?prefix=Doc&namespace=10] (prefix NOT stripped)\n* [{{canonicalurl:Special:PrefixIndex|prefix=Doc&namespace=10&stripprefix=1}} Special:PrefixIndex?prefix=Doc&namespace=10&stripprefix=1] (prefix stripped)",
        "shortpages": "{{doc-special|ShortPages}}",
        "shortpages-summary": "{{notranslate}}\nThe summary displayed at the top of [[Special:Shortpages]]. [[mw:Manual:Interface/Special pages summary|mw manual]].",
        "protectedpages-performer": "This is a column header in the table on the page [[Special:ProtectedPages]].",
        "protectedpages-params": "This is a column header in the table on the page [[Special:ProtectedPages]].\n\nProtection parameters are:\n* {{msg-mw|Restriction-level-autoconfirmed}}\n* {{msg-mw|Restriction-level-sysop}}",
        "protectedpages-reason": "This is a column header in the table on the page [[Special:ProtectedPages]].\n{{Identical|Reason}}",
+       "protectedpages-submit": "Label on search button in [[Special:ProtectedPages]]",
        "protectedpages-unknown-timestamp": "This is shown, when the date and time is unknown for a protection on the page [[Special:ProtectedPages]].\n{{Identical|Unknown}}",
        "protectedpages-unknown-performer": "This is shown, when the protecting user is unknown for a protection on the page [[Special:ProtectedPages]].",
        "protectedpages-unknown-reason": "{{ignored}}Comment used for extremely old protection log events (before there was a reason field).",
        "protectedtitles": "{{doc-special|ProtectedTitles}}",
        "protectedtitles-summary": "Summary of [[Special:ProtectedTitles]].\n\nSee also:\n* {{msg-mw|Protectedpages-summary}}",
        "protectedtitlesempty": "Used on [[Special:ProtectedTitles]]. This text appears if the list of protected titles is empty. See the [[mw:Project:Protected_titles|help page on MediaWiki]] for more information.",
+       "protectedtitles-submit": "Label on submit button in [[Special:ProtectedTitles]]",
        "listusers": "{{doc-special|ListUsers}}",
        "listusers-summary": "{{notranslate}}\nThe summary displayed at the top of [[Special:Listusers]]. [[mw:Manual:Interface/Special pages summary|mw manual]].",
        "listusers-editsonly": "Option in [[Special:ListUsers]].",
        "newpages": "{{doc-special|NewPages}}\n{{Identical|New page}}",
        "newpages-summary": "{{notranslate}}\nThe summary displayed at the top of [[Special:Newpages]]. [[mw:Manual:Interface/Special pages summary|mw manual]].",
        "newpages-username": "{{Identical|Username}}",
+       "newpages-submit": "Submit button on [[Special:Newpages]]",
        "ancientpages": "{{doc-special|AncientPages}}\nSee [[mw:Manual:Interface/Special pages title|manual]].",
        "ancientpages-summary": "{{doc-specialpagesummary|ancientpages}}",
        "move": "Name of Move tab. Should be in the imperative mood.\n\nSee also:\n* {{msg-mw|Move}}\n* {{msg-mw|Accesskey-ca-move}}\n* {{msg-mw|Tooltip-ca-move}}\n{{Identical|Move}}",
        "log": "{{doc-special|Log}}\n{{Identical|Log}}",
        "all-logs-page": "{{doc-logpage}}\nTitle of [[Special:Log]].",
        "alllogstext": "Header of [[Special:Log]]",
+       "logeventslist-submit": "Submit button on [[Special:Log]]",
        "logempty": "Used as warning when there are no items to show.",
        "log-title-wildcard": "* Appears in: [[Special:Log]]\n* Description: A check box to enable prefix search option",
        "showhideselectedlogentries": "Text of the button which brings up the [[mw:RevisionDelete|RevisionDelete]] menu on [[Special:Log]].",
        "cachedspecial-refresh-now": "Link text pointing to the most recent version of the page.",
        "categories": "The page name of [[Special:Categories]].\n{{Identical|Category}}",
        "categories-summary": "{{doc-specialpagesummary|categories}}",
+       "categories-submit": "Submit button on [[Special:Categories]]",
        "categoriespagetext": "{{doc-important|Do not translate or change links.}}\nText displayed in [[Special:Categories]].\n\nIn order to translate \"Unused categories\" and \"wanted categories\" see {{msg-mw|Unusedcategories}} and {{msg-mw|Wantedcategories}}.\n\nParameters:\n* $1 - number of categories",
        "categoriesfrom": "Used as label for the input box in [[Special:Categories]].\n\nThis message follows the fieldset label {{msg-mw|categories}}, and is followed by the input box.",
        "special-categories-sort-count": "Commented out at this time.\n\nThis message is used on [[Special:Categories]] to sort the list by the number of members in the categories.\n\nSee also:\n* {{msg-mw|Special-categories-sort-abc}}",
        "activeusers-hidebots": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}\n* {{msg-mw|activeusers-from|label for input box}}\n* {{msg-mw|activeusers-hidesysops|label for checkbox}}",
        "activeusers-hidesysops": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}\n* {{msg-mw|activeusers-from|label for input box}}\n* {{msg-mw|activeusers-hidebots|label for checkbox}}",
        "activeusers-noresult": "identical with {{msg-mw|listusers-noresult}}",
+       "activeusers-submit": "Used as label for button in the form on [[Special:ActiveUsers]]",
        "listgrouprights": "The name of the special page [[Special:ListGroupRights]].",
        "listgrouprights-summary": "The description used on [[Special:ListGroupRights]].\n\nRefers to {{msg-mw|Listgrouprights-helppage}}.",
        "listgrouprights-key": "Footer note for the [[Special:ListGroupRights]] page",
        "wlshowlast": "Appears on [[Special:Watchlist]]. Parameters:\n* $1 - a choice of different numbers of hours (\"1 | 2 | 6 | 12\")\n* $2 - a choice of different numbers of days (\"1 | 3 | 7\" and the maximum number of days available)\nClicking on your choice changes the list of changes you see (without changing the default in my preferences).",
        "watchlistall2": "Appears on [[Special:Watchlist]], after {{msg-mw|wlshowtime}}, as the option to display all available data regardless of age.\n{{Identical|All}}",
        "watchlist-hide": "Appears on [[Special:Watchlist]]. It is the first word on a new line with checkboxes to hide/unhide options\n{{Identical|Hide}}",
+       "watchlist-submit": "Label on the submit button in [[Special:Watchlist]]\n{{Identical|Show}}",
        "wlshowtime": "Appears on [[Special:Watchlist]]. Label of a drop-down list used to specify the period of time to display in the watchlist. This period can be {{msg-mw|days}}, {{msg-mw|hours}}, or {{msg-mw|watchlistall2}}.",
        "wlshowhideminor": "Option text in [[Special:Watchlist]]. Cf. {{msg-mw|rcshowhideminor}}.\n{{Identical|Minor edit}}",
        "wlshowhidebots": "Option text in [[Special:Watchlist]]. Cf. {{msg-mw|rcshowhidebots}}.\n{{Identical|Bot}}",
        "contributions-summary": "{{doc-specialpagesummary|contributions}}",
        "contributions-title": "{{Gender}}\nThe page title in your browser bar, but not the page title.\n\nParameters:\n* $1 - the username\nSee also:\n* {{msg-mw|Contributions}}",
        "mycontris": "In the personal urls page section - right upper corner.\n\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}\n{{Identical|Contribution}}",
+       "anoncontribs": "Same as {{msg-mw|mycontris}} but used for non-logged-in users.\n\nSee also:\n* {{msg-mw|Accesskey-pt-anoncontribs}}\n* {{msg-mw|Tooltip-pt-anoncontribs}}\n{{Identical|Contribution}}",
        "contribsub2": "Contributions for \"user\" (links). Parameters:\n* $1 is an IP address or a username, with a link which points to the user page (if registered user).\n* $2 is list of tool links. The list contains a link which has text {{msg-mw|Sp-contributions-talk}}.\n* $3 is a plain text username used for GENDER.\n{{Identical|For $1}}",
        "contributions-userdoesnotexist": "This message is used in [[Special:Contributions]]. It is used to tell the user that the name he searched for doesn't exists.\n\nParameters:\n* $1 - a username\n\n{{identical|userdoesnotexist}}",
        "nocontribs": "Used in [[Special:Contributions]] and [[Special:DeletedContributions]].\n\nSee examples: [[Special:Contributions/x]] and [[Special:DeletedContributions/x]].\n\nParameters:\n* $1 - (Unused) the user name",
        "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Link}}",
        "whatlinkshere-hideimages": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 - the {{msg-mw|Hide}} or {{msg-mw|Show}}\n\nSee also:\n*{{msg-mw|Isimage}}\n*{{msg-mw|Media tip}}",
        "whatlinkshere-filters": "{{Identical|Filter}}",
+       "whatlinkshere-submit": "Label for submit button in [[Special:WhatLinksHere]]\n{{Identical|Go}}",
        "autoblockid": "Used as name of autoblock, instead of autoblocked IPs. Parameters:\n* $1 - autoblock ID",
        "block": "{{doc-special|Block}}\n{{Identical|Block user}}",
        "unblock": "{{doc-special|Unblock}}",
        "accesskey-pt-preferences": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Mypreferences}}\n* {{msg-mw|Accesskey-pt-preferences}}\n* {{msg-mw|Tooltip-pt-preferences}}",
        "accesskey-pt-watchlist": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Mywatchlist}}\n* {{msg-mw|Accesskey-pt-watchlist}}\n* {{msg-mw|Tooltip-pt-watchlist}}",
        "accesskey-pt-mycontris": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}",
+       "accesskey-pt-anoncontribs": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Anoncontribs}}\n* {{msg-mw|Tooltip-pt-anoncontribs}}",
        "accesskey-pt-login": "{{doc-accesskey}}",
        "accesskey-pt-logout": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}",
        "accesskey-pt-createaccount": "{{doc-accesskey}}",
        "tooltip-pt-preferences": "Tooltip shown when hovering over the {{msg-mw|Mypreferences}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mypreferences}}\n* {{msg-mw|Accesskey-pt-preferences}}\n* {{msg-mw|Tooltip-pt-preferences}}\n{{Identical|Preferences}}",
        "tooltip-pt-watchlist": "Tooltip shown when hovering over the {{msg-mw|Mywatchlist}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mywatchlist}}\n* {{msg-mw|Accesskey-pt-watchlist}}\n* {{msg-mw|Tooltip-pt-watchlist}}",
        "tooltip-pt-mycontris": "Tooltip shown when hovering over the {{msg-mw|Mycontris}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}",
+       "tooltip-pt-anoncontribs": "Tooltip shown when hovering over the {{msg-mw|Anoncontribs}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Anoncontribs}}\n* {{msg-mw|Accesskey-pt-anoncontribs}}",
        "tooltip-pt-login": "Tooltip shown when hovering over the link 'Log in' in the upper right corner show on all pages while not logged in.",
        "tooltip-pt-logout": "Tooltip shown when hovering over the {{msg-mw|Logout}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}\n{{Identical|Log out}}",
        "tooltip-pt-createaccount": "Tooltip shown when hovering over the link 'Create account' in the upper right corner show on all pages while not logged in.",
        "exif-compression-34712": "{{optional}}",
        "exif-copyrighted-true": "The image is under copyright (including if its copyrighted but freely licensed)",
        "exif-copyrighted-false": "Copyright status is not set in the file.\n\nCompare: {{msg-mw|exif-copyrighted-true}}.",
-       "exif-photometricinterpretation-2": "{{optional}}",
-       "exif-photometricinterpretation-6": "{{optional}}",
+       "exif-photometricinterpretation-0": "Black and white image. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-1": "Black and white image. Commons for B&W tiffs. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-2": "{{optional}} RGB (red green blue) image. Common for colour tiffs. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-3": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-4": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-5": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-6": "{{optional}}\nYCbCr encoding. Common for jpeg images and tiffs with jpeg compressed data",
+       "exif-photometricinterpretation-8": "{{optional}}\nSee http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-9": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-10": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-32803": "Used mostly by DNG images. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
+       "exif-photometricinterpretation-34892": "Used mostly by DNG images. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
        "exif-unknowndate": "Used if the Exif date and time is \"<code>0000:00:00 00:00:00</code>\".\n\nRelated Exif attributes:\n* {{msg-mw|Exif-datetime}}\n* {{msg-mw|Exif-datetimeoriginal}}\n* {{msg-mw|Exif-datetimedigitized}}\n* {{msg-mw|Exif-datetimereleased}}\n* {{msg-mw|Exif-datetimeexpires}}\n* {{msg-mw|Exif-gpsdatestamp}}\n* {{msg-mw|Exif-dc-date}}\n* {{msg-mw|Exif-datetimemetadata}}",
        "exif-orientation-1": "0th row: top; 0th column: left\n{{Related|Exif-orientation}}\n{{Identical|Normal}}",
        "exif-orientation-2": "0th row: top; 0th column: right\n{{Related|Exif-orientation}}",
        "logentry-suppress-block": "{{Logentry}}\n* $4 - user name for gender or empty string for autoblocks\n* $5 - the block duration, localized and formatted with the english tooltip\n* $6 - block detail flags or empty string",
        "logentry-suppress-reblock": "{{Logentry}}\n* $4 - user name for gender or empty string for autoblocks\n* $5 - the block duration, localized and formatted with the english tooltip\n* $6 - block detail flags or empty string",
        "logentry-import-upload": "{{Logentry|[[Special:Log/import]]}}",
-       "logentry-import-upload-details": "{{Logentry|[[Special:Log/import]]}}\n* $4 - Number of imported revisions",
+       "logentry-import-upload-details": "{{Logentry|[[Special:Log/import]]}}\n* $4 - Number of imported revisions\n\nCf. {{msg-mw|logentry-import-upload}}",
        "logentry-import-interwiki": "{{Logentry|[[Special:Log/import]]}}",
-       "logentry-import-interwiki-details": "{{Logentry|[[Special:Log/import]]}}\n* $4 - Number of imported revisions\n* $5 - Interwiki title",
+       "logentry-import-interwiki-details": "{{Logentry|[[Special:Log/import]]}}\n* $4 - Number of imported revisions\n* $5 - Interwiki title\n\nCf. {{msg-mw|logentry-import-interwiki}}",
        "logentry-merge-merge": "{{Logentry|[[Special:Log/merge]]}}\n* $4 - the page into which the content is merged\n* $5 - a timestamp of limit\n\nThe log and its associated special page 'MergeHistory' is not enabled by default.\n\nPlease note that the parameters in a log entry will appear in the log only in the default language of the wiki. View [[Special:Log]] for examples on translatewiki.net with English default language.",
        "logentry-move-move": "{{Logentry|[[Special:Log/move]]}}\nParameter $4, the target page, is also not visible to parser functions.",
        "logentry-move-move-noredirect": "{{Logentry|[[Special:Log/move]]}}\nParameter $4, the target page, is also not visible to parser functions.",
index 519c19b..7b2aa28 100644 (file)
        "morenotlisted": "Această listă nu este completă.",
        "mypage": "Pagină",
        "mytalk": "Discuții",
-       "anontalk": "Discuția pentru această adresă IP",
+       "anontalk": "Discuții",
        "navigation": "Navigare",
        "and": "&#32;și",
        "qbfind": "Găsește",
        "passwordreset-emailtext-ip": "Cineva (probabil dumneavoastră, de la adresa IP $1) a solicitat resetarea parolei \npentru {{SITENAME}} ($4). {{PLURAL:$3|Următorul cont este asociat|Următoarele conturi sunt asociate}}\ncu această adresă de e-mail:\n\n$2\n\n{{PLURAL:$3|Această parolă temporară va|Aceste parole temporare vor}} expira {{PLURAL:$5|într-o zi|în $5 zile}}.\nAr trebui să vă autentificați și să schimbați parola acum. Dacă altcineva a făcut această cerere \nsau dacă v-ați reamintit parola inițială și nu mai doriți să o schimbați,\nputeți ignora acest mesaj, continuând să utilizați vechea parolă.",
        "passwordreset-emailtext-user": "Utilizatorul $1 de pe {{SITENAME}} a solicitat o resetare a parolei dumneavoastră pentru {{SITENAME}} ($4). Următorul utilizator are {{PLURAL:$3|contul asociat|conturile asociate}} cu această adresă de e-mail:\n\n$2\n\n{{PLURAL:$3|Această parolă temporară va|Aceste parole temporare vor}} expira {{PLURAL:$5|într-o zi|în $5 zile}}.\nAr trebui să vă autentificați și să alegeți acum o nouă parolă. Dacă altcineva a făcut această solicitare, ori dacă v-ați reamintit parola originală și nu mai doriți modificarea ei, puteți ignora acest mesaj, continuând cu vechea parolă.",
        "passwordreset-emailelement": "Nume de utilizator: \n$1\n\nParolă temporară: \n$2",
-       "passwordreset-emailsent": "Dacă aceasta este o adresă de e-mail înregistrată pentru contul dumneavoastră, atunci se va trimite un e-mail de resetare a parolei.",
+       "passwordreset-emailsentemail": "Dacă aceasta este o adresă de e-mail înregistrată pentru contul dumneavoastră, atunci se va trimite un e-mail de resetare a parolei.",
        "passwordreset-emailsent-capture": "Un mesaj de resetare a parolei a fost trimis, fiind afișat mai jos.",
        "passwordreset-emailerror-capture": "Un mesaj de resetare a parolei a fost generat (fiind afișat mai jos), dar trimiterea sa către {{GENDER:$2|utilizator}} a eșuat: $1",
        "changeemail": "Modificare sau înlăturare adresă de e-mail",
        "parser-unstrip-loop-warning": "Buclă nedetașabilă detectată",
        "parser-unstrip-recursion-limit": "Limita de recursivitate nedetașabilă depășită ($1)",
        "converter-manual-rule-error": "Eroare detectată în regula manuală de conversie a limbii",
-       "undo-success": "Modificarea poate fi anulată. Verificați diferența de dedesupt și apoi salvați pentru a termina anularea modificării.",
+       "undo-success": "Modificarea poate fi anulată. Verificați diferența de dedesubt și apoi salvați pentru a termina anularea modificării.",
        "undo-failure": "Modificarea nu poate fi reversibilă datorită conflictului de modificări intermediare.",
        "undo-norev": "Modificarea nu poate fi reversibilă pentru că nu există sau pentru că a fost ștearsă.",
        "undo-nochange": "Se pare că această modificare a fost deja anulată.",
        "wlnote": "Mai jos se află {{PLURAL:$1|ultima schimbare|ultimele <strong>$1</strong> schimbări|ultimele <strong>$1</strong> de schimbări}} din {{PLURAL:$2|ultima oră|ultimele <strong>$2</strong> ore|ultimele <strong>$2</strong> de ore}}, așa cum era situația la $3, $4.",
        "wlshowlast": "Arată ultimele $1 ore $2 zile",
        "watchlistall2": "toate",
+       "watchlist-hide": "Ascunde",
        "wlshowtime": "Arată ultimele:",
        "wlshowhideminor": "modificări minore",
        "wlshowhidebots": "roboți",
        "contributions": "Contribuții {{GENDER:$1|utilizator}}",
        "contributions-title": "Contribuțiile utilizatorului $1",
        "mycontris": "Contribuții",
+       "anoncontribs": "Contribuții",
        "contribsub2": "Pentru {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Contul de utilizator „$1” nu este înregistrat.",
        "nocontribs": "Nu a fost găsită nici o modificare care să satisfacă acest criteriu.",
        "movenosubpage": "Această pagină nu are subpagini.",
        "movereason": "Motiv:",
        "revertmove": "revenire",
-       "delete_and_move": "Șterge și redenumește",
        "delete_and_move_text": "==Ștergere necesară==\n\nPagina destinație „[[:$1]]” există deja. Doriți să o ștergeți pentru a face loc redenumirii?",
        "delete_and_move_confirm": "Da, șterge pagina.",
        "delete_and_move_reason": "Șters pentru a face loc redenumirii paginii „[[$1]]”",
        "tooltip-pt-preferences": "Preferințele dumneavoastră",
        "tooltip-pt-watchlist": "Lista paginilor pe care le monitorizați",
        "tooltip-pt-mycontris": "Listă de contribuții",
+       "tooltip-pt-anoncontribs": "O listă de modificări efectuate de la această adresă IP",
        "tooltip-pt-login": "Sunteți încurajat să vă autentificați, deși acest lucru nu este obligatoriu.",
        "tooltip-pt-logout": "Închide sesiunea de lucru",
        "tooltip-pt-createaccount": "Vă încurajăm să vă creați un cont și să vă autentificați; totuși, nu este obligatoriu",
        "size-bytes": "{{PLURAL:$1|un octet|$1 octeți|$1 de octeți}}",
        "size-pixel": "$1 {{PLURAL:$1|pixel|pixeli|de pixeli}}",
        "lag-warn-normal": "Modificările mai noi de $1 {{PLURAL:$1|secondă|seconde}} pot să nu apară în listă.",
-       "lag-warn-high": "Serverul bazei de date este suprasolicitat, astfel Ã®ncît modificÄ\83rile fÄ\83cute Ã®n ultimele $1 {{PLURAL:$1|secundÄ\83|secunde}} pot să nu apară în listă.",
+       "lag-warn-high": "Serverul bazei de date este suprasolicitat, astfel Ã®ncât modificÄ\83rile fÄ\83cute Ã®n ultimele $1 {{PLURAL:$1|secundÄ\83|secunde|de secunde}} ar putea să nu apară în listă.",
        "watchlistedit-normal-title": "Modificare listă pagini urmărite",
        "watchlistedit-normal-legend": "Ștergere titluri din lista de urmărire",
        "watchlistedit-normal-explain": "Lista de mai jos cuprinde paginile pe care le urmăriți.\nPentru a elimina un titlu, bifați-l și apăsați „{{int:Watchlistedit-normal-submit}}”.\nPuteți modifica și direct [[Special:EditWatchlist/raw|lista brută]].",
        "logentry-suppress-block": "$1 {{GENDER:$2|a blocat}} utilizatorul {{GENDER:$4|$3}} pe o perioadă de $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|a schimbat}} parametrii blocării pentru utilizatorul {{GENDER:$4|$3}} cu o perioadă de expirare de $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|a importat}} $3 prin încărcare de fișier",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|a importat}} $3 prin încărcare de fișier ($4 {{PLURAL:$4|versiune|versiuni|de versiuni}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|a importat}} $3 din alt wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|a importat}} $3 de la $5 ($4 {{PLURAL:$4|versiune|versiuni|de versiuni}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|a unificat}} $3 cu $4 (versiuni de până la $5)",
        "logentry-move-move": "$1 {{GENDER:$2|a redenumit}} pagina $3 în $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|a redenumit}} pagina $3 în $4 fără a lăsa o redirecționare în loc",
index 033221a..84f855a 100644 (file)
        "tog-watchlisthidebots": "Скрывать правки ботов из списка наблюдения",
        "tog-watchlisthideminor": "Скрывать малые правки из списка наблюдения",
        "tog-watchlisthideliu": "Скрывать правки представившихся участников из списка наблюдения",
+       "tog-watchlistreloadautomatically": "Перезагружать список наблюдения автоматически всякий раз, когда изменяется фильтр (требуется JavaScript)",
        "tog-watchlisthideanons": "Скрывать правки анонимных участников из списка наблюдения",
        "tog-watchlisthidepatrolled": "Скрывать отпатрулированные правки из списка наблюдения",
        "tog-watchlisthidecategorization": "Скрывать категоризацию страниц",
        "morenotlisted": "Этот список неполон.",
        "mypage": "Страница",
        "mytalk": "Обсуждение",
-       "anontalk": "Обсуждение для этого IP-адреса",
+       "anontalk": "Обсуждение",
        "navigation": "Навигация",
        "and": "&#32;и",
        "qbfind": "Поиск",
        "databaseerror-query": "Запрос: $1",
        "databaseerror-function": "Функция: $1",
        "databaseerror-error": "Ошибка: $1",
+       "transaction-duration-limit-exceeded": "Для того, чтобы избежать большого лага при репликации, эта транзакция была прервана, поскольку продолжительность записи ($1) превысила лимит в $2 сек.\nЕсли вы изменяете несколько элементов за один раз, постарайтесь вместо этого сделать несколько небольших операций.",
        "laggedslavemode": "Внимание: страница может не содержать последних обновлений.",
        "readonly": "Запись в базу данных заблокирована",
        "enterlockreason": "Укажите причину и намеченный срок блокировки.",
        "wrongpasswordempty": "Пожалуйста, введите непустой пароль.",
        "passwordtooshort": "Пароль должен состоять не менее чем из $1 {{PLURAL:$1|символа|символов}}.",
        "passwordtoolong": "Пароль не может превышать {{PLURAL:$1|1 символ|$1 символов|$1 символа}}.",
+       "passwordtoopopular": "Часто выбираемые пароли не могут быть использованы. Пожалуйста, выберите более уникальный пароль.",
        "password-name-match": "Введённый пароль должен отличаться от имени участника.",
        "password-login-forbidden": "Использование этого имени участника и пароля запрещено.",
        "mailmypassword": "Сбросить пароль",
        "passwordreset-emailtext-ip": "Кто-то (возможно, вы, с IP-адреса $1) запросил сброс пароля к вашей учётной записи в проекте {{SITENAME}} ($4).\nС этим адресом электронной почты {{PLURAL:$3|1=связана следующая учётная запись|связаны следующие учётные записи}}:\n\n$2\n\n{{PLURAL:$3|1=Этот временный пароль будет|Эти временные пароли будут}} действовать {{PLURAL:$5|$5 день|$5 дня|$5 дней|1=один день}}.\nВы должны представиться системе и выбрать новый пароль. \nЕсли вы не делали этого запроса, или вспомнили свой исходный пароль и не желаете его менять, \nто можете проигнорировать это сообщение и продолжить использовать свой старый пароль.",
        "passwordreset-emailtext-user": "Участник $1 из проекта {{SITENAME}} запросил сброс пароля для вашей учётной записи в проекте {{SITENAME}} ($4).\nС этим адресом электронной почты {{PLURAL:$3|1=связана следующая учётная запись|связаны следующие учётные записи}}:\n\n$2\n\n{{PLURAL:$3|1=Этот временный пароль будет|Эти временные пароли будут}} действовать {{PLURAL:$5|$5 день|$5 дней|$5 дня|1=один день}}.\nВы должны представиться системе и выбрать новый пароль.\nЕсли вы не делали этого запроса или вспомнили свой исходный пароль и не желаете его менять, \nто можете проигнорировать это сообщение и продолжить использовать свой старый пароль.",
        "passwordreset-emailelement": "Имя участника: \n$1\n\nВременный пароль: \n$2",
-       "passwordreset-emailsent": "Если это адрес электронной почты, на которую зарегистрирована ваша учётная запись, вам будет отправлено письмо для сброса пароля.",
+       "passwordreset-emailsentemail": "Если это адрес электронной почты, на которую зарегистрирована ваша учётная запись, вам будет отправлено письмо для сброса пароля.",
        "passwordreset-emailsent-capture": "Отправлено электронное письмо с информацией о сбросе пароля, текст которого можно увидеть ниже.",
        "passwordreset-emailerror-capture": "Было создано электронное письмо с информацией о сбросе пароля, текст которого можно увидеть ниже, однако его не удалось отправить {{GENDER:$2|участнику|участнице}} по следующей причине: $1",
        "changeemail": "Изменить или удалить адрес электронной почты",
        "wlshowlast": "Показать за последние $1 часов $2 дней",
        "watchlistall2": "все",
        "watchlist-hide": "Скрыть",
-       "wlshowtime": "Ð\9fоказаÑ\82Ñ\8c Ð¿Ð¾Ñ\81ледние:",
+       "wlshowtime": "Ð\9fеÑ\80иод Ð²Ñ\80емени Ð´Ð»Ñ\8f Ð¾Ñ\82обÑ\80ажениÑ\8f:",
        "wlshowhideminor": "малые правки",
        "wlshowhidebots": "ботов",
        "wlshowhideliu": "зарегистрированных участников",
        "contributions": "Вклад {{GENDER:$1|участника|участницы}}",
        "contributions-title": "Вклад {{GENDER:$1|участника|участницы}} $1",
        "mycontris": "Вклад",
+       "anoncontribs": "Вклад",
        "contribsub2": "Вклад {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Не зарегистрировано учётной записи «$1».",
        "nocontribs": "Изменений, соответствующих заданным условиям, найдено не было.",
        "movenosubpage": "У этой страницы нет подстраниц.",
        "movereason": "Причина:",
        "revertmove": "возврат",
-       "delete_and_move": "Удалить и переименовать",
        "delete_and_move_text": "== Требуется удаление ==\nСтраница с именем «[[:$1]]» уже существует. \nХотите удалить её, чтобы сделать возможным переименование?",
        "delete_and_move_confirm": "Да, удалить эту страницу",
        "delete_and_move_reason": "Удалено для возможности переименования «[[$1]]»",
        "tooltip-pt-preferences": "Ваши настройки",
        "tooltip-pt-watchlist": "Список страниц, изменения в которых вы отслеживаете",
        "tooltip-pt-mycontris": "Список ваших правок",
+       "tooltip-pt-anoncontribs": "Список правок, сделанных с этого IP-адреса",
        "tooltip-pt-login": "Здесь можно зарегистрироваться в системе, но это необязательно.",
        "tooltip-pt-logout": "Завершить сеанс работы",
        "tooltip-pt-createaccount": "Мы предлагаем вам создать учётную запись и войти в систему, хотя это и не обязательно.",
index b2c1111..3a9fdb7 100644 (file)
        "morenotlisted": "एषाऽऽवलिः अपूर्णा अस्ति ।",
        "mypage": "पृष्ठम्",
        "mytalk": "सम्भाषणम्",
-       "anontalk": "à¤\85सà¥\8dय à¤\85नà¥\8dतरà¥\8dà¤\9cालसà¤\82विदà¤\83 (I P address) à¤\95à¥\83तà¥\87 सम्भाषणम्",
+       "anontalk": "à¤\85नà¥\8dतरà¥\8dà¤\9cालसà¤\82वितà¥\8dसम्भाषणम्",
        "navigation": "सञ्चरणम्",
        "and": "&#32;तथा च",
        "qbfind": "अन्विष्यताम्",
        "passwordreset-emailtext-ip": "कोऽपि (कदाचित् भवान्/भवती, $1 अन्तर्जालसंविदः (from IP)) {{SITENAME}}($4) जालस्थानस्य  कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । निम्न{{PLURAL:$3|योजकः|योजकाः}} अनेन वि-पत्रेण सह सल्लग्नः अस्ति/सल्लग्नाः सन्ति ।\n\n$2\n\n{{PLURAL:$3|एषः अल्पकालीनकूटशब्दः|एते अल्पकालीनकूटशब्दाः}} {{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} निरस्तः भविष्यति/निरस्ताः भविष्यन्ति ।\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विनतिम् अकरोत् । \n२ पूरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छिति ।",
        "passwordreset-emailtext-user": "$1 सदस्यः {{SITENAME}}($4) जालस्थानस्य  कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । निम्न{{PLURAL:$3|सदस्यः|सदस्याः}} अनेन वि-पत्रेण सह सल्लग्नः अस्ति/सल्लग्नाः सन्ति ।\n\n$2\n\n{{PLURAL:$3|एषः अल्पकालीनकूटशब्दः|एते अल्पकालीनकूटशब्दाः}} {{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} निरस्तः भविष्यति/निरस्ताः भविष्यन्ति ।\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विज्ञप्तिम् अकरोत् । \n२ पूरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छिति ।",
        "passwordreset-emailelement": "सदस्यनाम : \n$1\n\nअल्पकालीनकूटशब्दः : \n$2",
-       "passwordreset-emailsent": "परिवर्तितकूटशब्दस्य वि-पत्रं प्रेषितम् अस्ति ।",
+       "passwordreset-emailsentemail": "परिवर्तितकूटशब्दस्य वि-पत्रं प्रेषितम् अस्ति ।",
        "passwordreset-emailsent-capture": "परिवर्तितकूटशब्दस्य वि-पत्रं प्रेषितम् अस्ति । तत् अधः द्रष्टुं शक्यते ।",
        "passwordreset-emailerror-capture": "परिवर्तितकूटशब्दस्य वि-पत्रं निर्मितम् अस्ति । तत् अधः द्रष्टुं शक्यते । परन्तु {{GENDER:$2|योजकाय}} प्रेषणकाले तत् निरस्तम् अभवत् : $1",
        "changeemail": "वि-पत्रसङ्केतः परिवर्त्यताम्",
        "movenosubpage": "अस्य पुटस्य उपपुटानि न सन्ति ।",
        "movereason": "कारणम् :",
        "revertmove": "प्रत्यावर्तनम्",
-       "delete_and_move": "अपमर्जनं चालनं च ।",
        "delete_and_move_text": "==अपमर्जनम् आवश्यकम्==\nलक्षितपुटं \"[[:$1]]\" पूर्वमेव अस्ति ।\nचालनपथं सृष्टुम् एतत् अपमर्जितुम् इच्छति वा ?",
        "delete_and_move_confirm": "आम्, पुटम् अपमर्जतु ।",
        "delete_and_move_reason": "\"[[$1]]\" तः स्थानान्तरणं कर्तुं पथनिर्माणार्थम् अपमर्जितम् ।",
index 614a877..2a53b49 100644 (file)
        "morenotlisted": "Бу тиһик толорута суох.",
        "mypage": "Сирэй",
        "mytalk": "Кэпсэтэр сирим",
-       "anontalk": "Ð\91Ñ\83 IP-га Ñ\8bрытыы",
+       "anontalk": "Ырытыы",
        "navigation": "Навигация",
        "and": "&#32;уонна",
        "qbfind": "Бул",
        "movenosubpage": "Бу сирэй алын сирэйэ суох.",
        "movereason": "Төрүөтэ:",
        "revertmove": "төннөрүү",
-       "delete_and_move": "Суох гын уонна аатын уларыт",
        "delete_and_move_text": "==Сотуохха наада==\n\nМаннык ааттаах сирэй [[:$1|«$1»]] бэлиэр баар. Эн ону суох гынан баран аатын уларытаары гынаҕын дуо?",
        "delete_and_move_confirm": "Сөп, бу сирэйи суох гын",
        "delete_and_move_reason": "Аатын уларытаары сотулунна \"[[$1]]\"",
index ae52802..9d1665a 100644 (file)
        "movenosubpage": "This page haes naw subpages.",
        "movereason": "Raison:",
        "revertmove": "revert",
-       "delete_and_move": "Delyte n muiv",
        "delete_and_move_text": "==Delytion caad fer==\n\nThe destination airticle \"[[:$1]]\" aareadies exists. Div ye want tae delyte it fer tae mak wey fer the muiv?",
        "delete_and_move_confirm": "Ai, delyte the page",
        "delete_and_move_reason": "Delytit fer tae mak wa fer muiv fae \"[[$1]]\"",
index 4a29b74..73400c5 100644 (file)
@@ -17,7 +17,7 @@
        "tog-numberheadings": "سُرخين کي خودڪاراً نمبر ڏيو",
        "tog-showtoolbar": "سنوار اوزار ڏيکاريو",
        "tog-editondblclick": "ٻٽي ڪلڪ تي صفحا سنواريو",
-       "tog-watchcreations": "منهنجا سرجيل صفحا ۽ منهنجا چاڙهيل فائيل منهنجي ٽيٽ فهرست تي رکو",
+       "tog-watchcreations": "منهنجا سرجيل صفحا ۽ منهنجا چاڙهيل فائيل منهنجي زيرِ نظر فهرست تي رکو",
        "tog-watchdefault": "منهنجا ترميميل صفحا منهنجي ٽيٽ فهرست تي رکو",
        "tog-watchmoves": "جيڪي صفحا ۽ فائيلس آئون چوريان، سي منهنجي ٽيٽ لسٽ ۾ شامل ڪريو.",
        "tog-watchdeletion": "آئون جيڪي صفحا ڊاهيان، سي منهنجي ٽيٽ فهرست تي رکو",
        "morenotlisted": "فهرست مڪمل ڪانهي.",
        "mypage": "منهنجو صفحو",
        "mytalk": "ڳالهہ ٻول",
-       "anontalk": "هن آءِ پِي پتي لاءِ مباحثي صفحو",
+       "anontalk": "ڳالھ ٻولھ",
        "navigation": "رهنمائي",
        "and": "&#32؛۽",
        "qbfind": "ڳوليو",
        "redirectedfrom": "($1 کان چوريل)",
        "redirectpagesub": "چوريل صفحو",
        "redirectto": "ڏانهن چوريو",
-       "lastmodifiedat": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ø¢Ø®Ø±Ù\8a Ø¯Ù\81عÙ\88 $2Ø\8c $1ع ØªÙ\8a ØªØ±Ù\85Ù\8aÙ\85يو ويو هو.",
+       "lastmodifiedat": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ø¢Ø®Ø±Ù\8a Ø¯Ù\81عÙ\88 $2Ø\8c $1ع ØªÙ\8a Ø³Ù\86Ù\88اريو ويو هو.",
        "viewcount": "هيءُ صفحو {{PLURAL:$1|دفعو|$1 دفعا}} ڏسجي چڪو آهي.",
        "protectedpage": "تحفظيل صفحو",
        "jumpto": "ڏانهن ٽپ ڏيو",
        "protectedpagetext": "هيءُ صفحو ترميمن کان تحفظيل آهي.",
        "viewsourcetext": "توهان هن صفحي جو ڪوڊ ڏسي ۽ نقل ڪري سگھو ٿا:",
        "namespaceprotected": "توهان کي نانءُ پولار '''$1''' جا صفحا سنوارڻ جا اختيار ناهن.",
-       "mycustomcssprotected": "توهان کي هيءُ CSS صفحو سنوارڻ جي اجازت ڪانهي.",
+       "mycustomcssprotected": "توهان کي هيءُ CSS صفحو سنوارڻ جي اجازت نہ آهي.",
        "mycustomjsprotected": "توهان کي هيءُ جاوا اسڪرپٽ صفحو سنوارڻ جي اجازت حاصل ڪانهي.",
-       "myprivateinfoprotected": "تÙ\88Ù\87اÙ\86 Ú©Ù\8a Ù¾Ù\86Ù\87Ù\86جÙ\8a Ø°Ø§ØªÙ\8a Ù\85عÙ\84Ù\88Ù\85ات Ø³Ù\86Ù\88ارڻ Ø¬Ù\8a Ø§Ø¬Ø§Ø²Øª Ø­Ø¢ØµÙ\84 ÚªØ§Ù\86هي.",
+       "myprivateinfoprotected": "تÙ\88Ù\87اÙ\86 Ú©Ù\8a Ù¾Ù\86Ù\87Ù\86جÙ\8a Ø°Ø§ØªÙ\8a Ù\85عÙ\84Ù\88Ù\85ات Ø³Ù\86Ù\88ارڻ Ø¬Ù\8a Ø§Ø¬Ø§Ø²Øª Ø­Ø§ØµÙ\84 Ù\86Û\81 Ø¢هي.",
        "mypreferencesprotected": "توهان جي پنهنجون ترجيحات سنوارڻ جي اجات حاصل ڪانهي.",
        "ns-specialprotected": "خاص صفحا سنواري نٿا سگھجن.",
        "titleprotected": "[[User:$1|$1]] اهڙي عنوان سان صفحو سرجڻ تي روڪ لڳائي ڇڏي آهي. سبب \"<em>$2</em>\" ڄاڻايو ويو آهي.",
        "createacct-yourpasswordagain-ph": "ٻيهر ڳجھو لفظ داخل ڪريو",
        "remembermypassword": "هن برائوزر تي منهنجي لاگ ان کي (وڌ ۾ وڌ $1 {{PLURAL:$1|ڏينهن}} لاءِ) ياد رکو",
        "userlogin-remembermypassword": "مون کي لاگ اِن رکو",
+       "userlogin-signwithsecure": "محفوظ ڳانڍاپو استعمال ڪريو",
        "yourdomainname": "توهان جو ميدان:",
        "password-change-forbidden": "هن وڪِي تي توهان ڳجھو لفظ بدلائي نہ ٿا سگھو.",
        "login": "لاگ اِن",
        "passwordtooshort": "ڳجھي لفظ گھٽ ۾ گھٽ  {{PLURAL:$1|1 اکر|$1 اکرَن}} تي ٻڌل هوڻ گھرجي.",
        "passwordtoolong": "ڳجھو لفظ {{PLURAL:$1|1 اکر|$1 اکرن}} کان وڏو نہ ٿو ٿي سگھي.",
        "password-name-match": "توهان جو ڳجھو لفظ توهان جي يوزرنانءُ کان مختلف هجڻ گھرجي.",
-       "mailmypassword": "نئون ڳجھو لفظ مقرر ڪريو",
+       "mailmypassword": "ڳجھو لفظ  نئين سِر مقرر ڪريو",
        "passwordremindertitle": "{{SITENAME}} لاءِ نئون عارضي ڳجھو لفظ",
        "passwordremindertext": "ڪنهن (شايد توهان آءِ پي پتي $1 تان) اسان کي {{SITENAME}} ($4) لاءِ نئون ڳجھو لفظ اماڻڻ جي گھُرَ ڪئي.\"$2\" يوزر لاءِ هڪ ڳجھُ لفظ تخليق ڪيو ويو آهي \"$3\" تي ترتيب ڏنو ويو هو. جيڪڏهن اهو توهان جي ارادو هيو، ته هاڻي توهان کي هينئر ئي لاگ اِن ٿي پنهنجو ڳجھو لفظ تبديل ڪرڻ گھرجي.\nتوهان جو عارضي ڳجھو لفظ {{PLURAL:$5|هڪ ڏينهُن|$5 ڏينهَن}} ۾ ختم ٿيندو.\n\nجيڪڏهن اها گھُرَ اوهان نه ڪئي هئي، يا هاڻي اوهان کي پنهنجو ڳجھو لفظ ياد اچي ويو آهي ۽ توهان ان کي تبديل ڪرڻ نه ٿا چاهيو، ته توهان هن نياپي کي نظر انداز ڪندي پنهنجو پراڻو ڳجھو لفظ ئي استعمال ڪري سگھو ٿا.",
        "noemail": "يُوزر \"$1\" جي ڪو بہ برق ٽپال پتو درج ٿيل ناهي.",
        "php-mail-error-unknown": "پي ايڇ پي جي  ڪاڄ اندر اڻڄاتل چُڪَ.",
        "user-mail-no-addy": "برق ٽپال پتو ڄاڻائڻ کان سواءِ برق ٽپال اماڻڻ جي ڪوشش ڪئي وئي.",
        "changepassword": "ڳجھو لفظ تبديل ڪريو",
-       "resetpass_announce": "لاگ اِن جو عمل پورو ڪرڻ لاءِ توهان کي نئون ڳجھو لفظ اختيار ڪرڻو پوندو.",
+       "resetpass_announce": "لاگ اِن جو عمل پورو ڪرڻ لاءِ، توهان کي نئون ڳجھو لفظ اختيار مقرر ڪرڻو پوندو.",
        "resetpass_header": "کاتي جو ڳجھو لفظ بدلايو",
        "oldpassword": "اڳوڻو ڳجھو لفظ:",
        "newpassword": "نئون ڳجھو لفظ:",
        "blockednoreason": "سبب اڻڄاڻايل",
        "whitelistedittext": "صفحا سنوارڻ لاءِ مهرباني ڪري $1.",
        "confirmedittext": "صفحا سنوارڻ کان اڳ توهان کي پنهنجي ايميل پتي جي تصديق ڪرڻي پوندي. مهرباني ڪري [[Special:Preferences|use preferences]] ذريعي پنهنجو ايميل پتو ڄاڻايو ۽ تصديقيو.",
-       "nosuchsectiontitle": "سÙ\8aڪشÙ\86 Ù\84Ú\80جÙ\8a Ù\86Û\81 Ø³Ú¯Ú¾Ù\8aÙ\88",
+       "nosuchsectiontitle": "سÙ\8aڪشÙ\86 Ù\86Ù¿Ù\88 Ù\84Ù\87Ù\8a Ø³Ú¯Ù\87Ù\8a",
        "loginreqtitle": "لاگ اِن گھربل آهي",
        "loginreqlink": "لاگ اِن",
        "loginreqpagetext": "ٻيا صفحا ڏسڻ لاءِ مهرباني ڪري $1",
        "userpage-userdoesnotexist-view": "يُوزر کاتو $1 درج ٿيل نہ آهي.",
        "blocked-notice-logextract": "هيءَ يُوزر في‌الحال بندشيل آهي. تازو بندش لاگ حوالي طور پيش ڪجي ٿو:",
        "previewnote": "<strong>'''هيءَ محظ پيش نگاهہ آهي.</strong> ترميمون اڃا سانڍجوين ناهن!'''",
+       "continue-editing": "ترميم گاھ ڏانهن وڃو",
        "editing": "زير ترميم $1",
        "creating": "$1 سرجيندي",
        "editingsection": "زير ترميم $1 (سيڪشن)",
        "content-model-javascript": "جاوا اسڪرپٽ",
        "content-json-empty-object": "خالي آبجيڪٽ",
        "content-json-empty-array": "خالي اري",
-       "duplicate-args-warning": "وارنڱ: [[:$2]] کي [[:$1]] ڪال ڪري رهيو آهي، جنهن منجھہ ’$3‘ نيم‌پيما لاءِ هڪ کان وڌيڪ قدر ڄاڻايل آهن. فقط آخري ڄاڻايل قدر استعمال ڪيو ويندو.",
+       "duplicate-args-warning": "چتاءُ: [[:$2]] کي [[:$1]] ڪال ڪري رهيو آهي، جنهن منجھہ ’$3‘ نيم‌پيما لاءِ هڪ کان وڌيڪ قدر ڄاڻايل آهن. فقط آخري ڄاڻايل قدر استعمال ڪيو ويندو.",
        "parser-template-loop-warning": "سانچو چڪر لڌو ويو: [[$1]]",
        "cantcreateaccounttitle": "کاتو کولي نہ ٿو سگھجي",
        "cantcreateaccount-text": "هن آءِ پي پتي تان کاتي جي تخليق تي يُوز (<strong>$1</strong>)  [[User:$3|$3]] روڪ لڳائي آهي.\n\n$3 جو ڄاڻايل سبب آهي <em>$2</em> آهي.",
-       "cantcreateaccount-range-text": "آءِ پي پتن جي حد '''$1''' ۾ [[User:$3|$3]] کاتو کولڻ تي روڪ لڳاي آهي، جنهن ۾ توهان جو آءِ پي پتو بہ ('''$4''')،  پڻ شامل آهي. \n\n$3 ان روڪَ جو سبب \"$2\" ڄاڻايو آهي.",
+       "cantcreateaccount-range-text": "آءِپي پتن جي حد '''$1''' ۾ [[User:$3|$3]] کاتو کولڻ تي روڪ لڳائي وئي آهي،$4 جنهن ۾ توهان جو آءِپي پتو بہ ('''$4''')،  پڻ شامل آهي. \n\n$3 ان روڪَ جو سبب \"$2\" ڄاڻايو آهي.",
        "viewpagelogs": "هن صفحي جا لاگس ڏسو",
        "nohistory": "هن صفحي جي ڪا بہ سوانح نہ آهي.",
        "currentrev": "هاڻوڪو مسودو",
        "history-feed-description": "وڪي جي هن صفحي جي ترميمي سوانح",
        "history-feed-item-nocomment": "$2 تي $1",
        "rev-deleted-user": "(يُوزرنانءُ ڊاٺو ويو)",
+       "rev-delundel": "نمائش تبديل ڪريو",
        "rev-showdeleted": "ڏيکاريو",
        "revisiondelete": "مسوادا ڊاهيو/اڻ‌ڊاهيو",
        "revdelete-no-file": "ڄاڻايل فائيل وجود نہ ٿو رکي.",
        "revdelete-show-file-submit": "ها",
+       "revdelete-legend": "نمائش جون پابنديون ترتيب ڪريو",
        "revdelete-hide-image": "فائيل جو مواد لڪايو",
        "revdelete-hide-comment": "ترميم جو تتُ",
+       "revdelete-hide-user": "ايڊيٽر جو يوزرنانءُ / آء پي پتو",
        "revdelete-radio-same": "(نہ بدلايو)",
        "revdelete-radio-set": "لڪل",
        "revdelete-radio-unset": "ظاهر",
        "revdelete-log": "سبب:",
+       "revdel-restore": "نمائش تبديل ڪريو",
        "pagehist": "صفحي جي سوانح",
        "deletedhist": "ڊاٺل سوانح",
        "revdelete-otherreason": "ٻيا/اضافي ڪارڻ:",
        "mergehistory-list": "ضمائتي ترميم سوانح",
        "mergehistory-submit": "ڀيرن کي ضم ڪريو",
        "mergehistory-empty": "ڪي بہ ڀيرا ضم ڪري نہ ٿا سگھجن.",
-       "mergehistory-no-source": "مصدر صفحو $1 وجود نٿو رکي!",
+       "mergehistory-no-source": "ذريعاتي صفحو $1 وجود نٿو رکي.",
        "mergehistory-no-destination": "مقصود صفحو $1 وجود نہ ٿو رکي.",
-       "mergehistory-invalid-source": "مصدر صفحي جو عنوان قابل‌ڪار هجڻ گھرجي.",
+       "mergehistory-invalid-source": "ذريعاتي صفحي جو عنوان قابلِ قبول هجڻ لازمي آهي.",
        "mergehistory-invalid-destination": "مقصود صفحي جو عنوان قابل‌ڪار هجڻ گھرجي.",
        "mergehistory-autocomment": "[[:$1]] کي [[:$2]] ۾ ضم ڪيو ويو",
        "mergehistory-comment": "[[:$1]]، [[:$2]] ۾ ضم ٿي ويو: $3",
-       "mergehistory-same-destination": "مصدر ۽ مقصود صفحو ساڳيو نہ ٿو ٿي سگھي.",
+       "mergehistory-same-destination": "ذريعاتي ۽ مقصود صفحا ساڳيا نٿا ٿي سگھن",
        "mergehistory-reason": "سبب:",
        "mergelog": "ضم لاگ",
        "revertmerge": "اڻ ضم",
        "history-title": "\"$1\" جي ترميمي سوانح",
        "difference-title": "\"$1\" جي مسودن ۾ تفاوت",
-       "difference-title-multipage": "صفحن \"$1\" ۽ \"$1\" ۾ تفاوت",
+       "difference-title-multipage": "صفحن \"$1\" ۽ \"$2\" ۾ تفاوت",
        "difference-multipage": "(صفحن درميان تفاوت)",
        "lineno": "سِٽَ $1:",
        "compareselectedversions": "چونڊيل پرت ڀيٽيو",
        "diff-empty": "(ڪو بہ تفاوت ڪونهي)",
        "searchresults": "ڳولا نتيجا",
        "searchresults-title": "”$1“ لاءِ ڳولا نتيجا",
+       "titlematches": "صفحي جو عنوان مشابهت رکي ٿو",
+       "textmatches": "صفحي جو متن مشابهت رکي ٿو",
+       "notextmatches": "ڪنهن به صفحي جو متن مشابهت نٿو رکي",
        "prevn": "پويان {{PLURAL:$1|$1}}",
        "nextn": "اڳيان {{PLURAL:$1|$1}}",
        "prev-page": "اڳوڻو صفحو",
        "search-category": "(ذمرو $1)",
        "search-suggest": "ڇا توهان جو مطلب $1 آهي؟",
        "search-interwiki-caption": "برادر رٿائون",
+       "search-interwiki-default": "$1 مان نتيجا",
        "search-interwiki-more": "(وڌيڪ)",
        "search-relatedarticle": "لاڳاپيل",
        "searchrelated": "لاڳاپيل",
        "searchall": "سڀ",
        "search-nonefound": "توهان جي ڳولا جي نتيجي ۾ ڪجھہ بہ ڪو نہ لڌو.",
+       "powersearch-legend": "اعليٰ ڳولا",
        "powersearch-togglelabel": "چڪاسيو:",
        "powersearch-toggleall": "سڀ",
        "powersearch-togglenone": "ڪو بہ نہ",
        "prefs-watchlist-days-max": "وڌ ۾ وڌ $1 {{PLURAL:$1|ڏينهن}}",
        "prefs-watchlist-edits-max": "وڌ ۾ وڌ تعداد: 1000",
        "prefs-watchlist-token": "ٽيٽ لسٽ جو ٽوڪن:",
+       "prefs-misc": "متفرق",
        "prefs-resetpass": "ڳجھو لفظ بدلايو",
        "prefs-changeemail": "برق ٽپال پتو مِٽايو يا بدلايو",
        "prefs-setemail": "ڪو برق ٽپال پتو ڄاڻايو",
        "prefs-email": "برق ٽپال چارا",
        "prefs-rendering": "حليو",
        "saveprefs": "سانڍيو",
+       "prefs-editing": "سنوارڻ",
        "rows": "قطارون:",
+       "columns": "ڪالمَ:",
        "searchresultshead": "ڳولا",
        "stub-threshold-sample-link": "نمونو",
        "stub-threshold-disabled": "غيرفعال",
+       "recentchangesdays": "تازين تبديلين ۾ ڏيکارڻ جي لاءِ ڏينهن:",
        "recentchangesdays-max": "وڌ ۾ وڌ $1 {{PLURAL:$1|ڏينهن}}",
+       "recentchangescount": "عدم پيروي جي صورت ۾ ڏيکارڻ جي لاءِ ترميمون:",
        "prefs-help-recentchangescount": "ان ۾ تازيون تبديليون، صفحن جي سوانح، ۽ لاگ شامل آهن.",
        "savedprefs": "توهان جون ترجيحات سانڍجي چڪيون آهن.",
        "savedrights": "{{GENDER:$1|$1}} نالي يوزر جا حق سانڇجي چڪا آهن.",
        "timezonelegend": "اوقاتي زون:",
        "localtime": "مقامي وقت:",
+       "timezoneuseserverdefault": "وڪي عدم پيروي استعمال ڪريو ($1)",
        "servertime": "سَروَر پٽاندر وقت:",
        "guesstimezone": "جھانگُوءَ مان ڀريو",
        "timezoneregion-africa": "آفريڪا",
        "allowemail": "ٻين يُوزرس کان ايندڙ برق ٽپال بحال ڪريو",
        "prefs-searchoptions": "ڳولا",
        "prefs-namespaces": "نانءُپولار",
+       "default": "ڏنل",
        "prefs-files": "فائيلس",
        "prefs-emailconfirm-label": "برق ٽپال جي خاطري:",
        "youremail": "برق ٽپال:",
        "prefs-info": "بنيادي ڄاڻ",
        "prefs-i18n": "بين‌الاقوامڪاري",
        "prefs-signature": "صحيح",
+       "prefs-dateformat": "تاريخ جو طرز",
        "prefs-advancedediting": "عمومي چارا",
        "prefs-editor": "ايڊيٽر",
        "prefs-preview": "پيش نگاهہ",
        "prefs-help-prefershttps": "هيءَ ترجيح توهان جي ايندڙ لاگ اِن تي عمل ۾ ايندي.",
        "email-address-validity-valid": "برق ٽپال پتو قابل ڪار ڏسجي ٿو.",
        "email-address-validity-invalid": "قابل ڪار برق ٽپال پتو ڄاڻايو",
-       "userrights": "يُوزر حقن جو بندوبست",
+       "userrights": "يُوزر حقن جو انتظام",
+       "userrights-lookup-user": "يوزر گروپَ سنڀاليو",
        "userrights-user-editname": "يُوزرنانءُ ڄاڻايو:",
+       "editusergroup": "يوزر گروپَ سنواريو",
+       "userrights-editusergroup": "يوزر گروپَ سنواريو",
+       "saveusergroups": "يوزر گروپَ سنڀاليو",
        "userrights-groupsmember": "برڪن:",
        "userrights-groupsmember-auto": "رڪن واجبي:",
        "userrights-reason": "سبب:",
        "userrights-no-interwiki": "توهان کي ٻين وڪيز تي يُوزر حقن ۾ ترميم ڪرڻ جو حق حاصل نہ آهي.",
        "userrights-nodatabase": "اعداخانو $1 يا تہ وجود نہ ٿو رکي يا تہ اهو مقامي اعدادخانو نہ آهي.",
+       "userrights-notallowed": "توهان کي يوزر جا حق شامل يا هٽائڻ جي اجازت نه آهي.",
+       "userrights-changeable-col": "گروپَ جيڪي توهان تبديل ڪري سگھو ٿا",
+       "userrights-unchangeable-col": "گروپَ جيڪي توهان تبديل نٿا ڪري سگھو",
        "group": "گروپ:",
        "group-user": "يوزرس",
+       "group-autoconfirmed": "خودبخود پڪ ڪيل يوزرس",
+       "group-bot": "بوٽس",
+       "group-sysop": "منتظم",
+       "group-bureaucrat": "ڪامورا",
        "group-all": "(سڀ)",
        "group-user-member": "{{GENDER:$1|يُوزر}}",
        "group-sysop-member": "{{GENDER:$1|منتظم}}",
        "right-move-subpages": "ذيلي صفحن سميت صفحا چوريو",
        "right-movefile": "فائيل چوريو",
        "right-upload": "فائيل چاڙهيو",
-       "right-upload_by_url": "ڪنهن يُو آر ايل تان فائيل چاڙهيو",
+       "right-upload_by_url": "ڪنهن يُوآرايل تان فائيل چاڙهيو",
+       "right-writeapi": "اي پر آءِ لکڻ جو استعمال",
        "right-delete": "صفحا ڊاهيو",
        "right-bigdelete": "ڊگھيون سوانح رکندڙ صفحا ڊاهيو",
        "right-browsearchive": "ڊاٺل صفحا ڳوليو",
        "right-undelete": "ڪو صفحو اڻڊاهيو",
+       "right-unblockself": "ڪنهن تان بندش ختم ڪريو",
        "right-editinterface": "يُوزر باهمرُو کي سنواريو",
        "right-viewmywatchlist": "پنهنجي ٽيٽ لسٽ ڏسو",
        "right-editmyoptions": "پنهنجون ترجيحات سنواريو",
        "right-import": "ٻين وڪيز کان صفحا درآمديو",
        "right-mergehistory": "صفحن جي سوانح سنواريو",
+       "right-userrights": "سڀ يوزر حق ترميم ڪريو",
+       "right-userrights-interwiki": "هن وڪي جي يوزرس جا حق ترميم ڪريو",
+       "right-sendemail": "ٻين يوزرس ڏانهن ايميل موڪليو",
        "newuserlogpage": "يوزر کاتن جو لاگ",
        "rightslog": "يُوزر حق لاگ",
+       "action-read": "هي صفحو پڙهو",
+       "action-edit": "هن صفحي کي سسنواريو",
+       "action-createpage": "صفحا تخليق ڪريو",
+       "action-createtalk": "مباحثي صفحا تخليق ڪريو",
+       "action-createaccount": "هي يوزر کاتو تخليق ڪريو",
+       "action-history": "هن صفحي جي سوانح ڏسو",
+       "action-minoredit": "هن ترميم کي معمولي طور نشان لڳايو",
        "action-move": "هيءَُ صفحو چوريو",
        "action-move-subpages": "هيءُ صفحو، ۽ ان جا ذيلي صفحا چوريو",
        "action-move-categorypages": "زمرن جا صفحا چوريو",
        "action-import": "ٻي ڪنهن وڪي کان صفحا درآمد ڪريو",
        "action-importupload": "ڪو فائيل چاڙهي صفحا درآمديو",
        "action-mergehistory": "هن صفحي جي سوانح ضم ڪريو",
+       "action-userrights": "سڀ يوزر حق ترميم ڪريو",
+       "action-userrights-interwiki": "ٻين وڪيز جي يوزرس جا حق ترميم ڪريو",
        "action-siteadmin": "اعدادخاني کي بند ڪريو يا کوليو",
        "action-sendemail": "برق ٽپال اماڻيو",
        "action-editmywatchlist": "پنهنجي ٽيٽ فهرست سنواريو",
        "action-viewmywatchlist": "پنهنجي ٽيٽ فهرست ڏسو",
+       "action-viewmyprivateinfo": "پنهنجي ذاتي معلومات ڏسو",
+       "action-editmyprivateinfo": "پنهنجي ذاتي معلومات سنواريو",
        "nchanges": "$1 {{PLURAL:$1|تبديلي|تبديليون}}",
        "enhancedrc-history": "سوانح",
        "recentchanges": "تازيون تبديليون",
        "recentchanges-label-plusminus": "هن صفحي جي ماپ ۾ هيترين ٻاٺڻين جو ڦير آيو آهي",
        "recentchanges-legend-heading": "\"ڪنجي.\"",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (پڻ ڏسو [[Special:NewPages|نون صفحن جي فهرست]])",
+       "recentchanges-submit": "ڏيکاريو",
        "rcnotefrom": "هيٺ {{PLURAL:$5|تبديلي آهي|تبديليون آهن}} کان <strong>$3, $4</strong> (تائين <strong>$1</strong> ) ڏيکاريل آهن.",
        "rclistfrom": "$3 $2 کان شروع ٿيندڙ نيون تبديليون",
        "rcshowhideminor": "$1 معمولي ترميمون",
        "filename": "فائيل نانءُ",
        "filedesc": "خلاصو",
        "fileuploadsummary": "خلاصو:",
+       "filereuploadsummary": "فائيل تبديليون:",
+       "filesource": "ذريعو:",
        "filename-tooshort": "فائيل نانءَُ هيڪاندو ننڍو آهي.",
+       "uploadwarning": "چاڙھ جو چتاءُ",
        "savefile": "فائيل سانڍيو",
+       "uploaddisabled": "چاڙھ ناقابلِ ڪار بڻيل.",
        "upload-scripted-pi-callback": "ن فائيل کي اپلوڊ نه ٿو ڪري سگهي جنهن ۾ ايڪس ايم ايل اسٽائيل شيٽ جون پراسيسنگ هدايتون شامل هجن.",
        "uploaded-script-svg": "اسڪرپٽ جوڳو ايليمينٽ ”$1” مليو آهي، اپلوڊ ٿيل ايس وي جي فائيل ۾.",
        "uploaded-hostile-svg": "اپلوڊ ٿيل ايس وي جي فائيل جو غير محفوظ سي ايس ايس ۾ اسٽائيل ايلمينٽ مليو",
        "uploaded-remote-url-svg": "ايس وي جي جيڪا سيٽ ڪري ٿي ڪنهن اسٽائيل وصف  رموٽ يو آر ايل سان  بلاڪ ٿيل آهي.\n <code>$1=\"$2\"</code> اپلوڊ ٿيل ايس وي جي فائيل ۾ مليو",
        "uploaded-image-filter-svg": "هن يو آر ايل سان <code>&lt;$1 $2=\"$3\"&gt;</code> اميج فلٽر مليو آهي، اپلوڊ ٿيل ايس وي جي فائيل ۾،",
        "uploadvirus": "هن فائيل ۾ وائرس آهي! \nتفصيل: $1",
+       "upload-source": "ذريعي جو فائيل",
+       "sourcefilename": "ذريعي جي فائيل جو نالو:",
        "upload-description": "فائيل جي تشريح",
+       "upload-options": "چاڙھ جا چارا",
        "watchthisupload": "هيءُ فائيل ٽيٽيو",
        "upload-success-subj": "چاڙهہ ڪامياب",
+       "upload-failure-subj": "چاڙھ جو مسئلو",
+       "upload-warning-subj": "چاڙھ جو چتاءُ",
        "upload-file-error": "اندروني چُڪَ",
        "upload-dialog-title": "فائيل چاڙهيو",
        "upload-dialog-button-cancel": "رد",
+       "upload-dialog-button-done": "ٿي ويو",
        "upload-dialog-button-save": "سانڍيو",
        "upload-dialog-button-upload": "چاڙهيو",
        "upload-form-label-select-file": "فائيل چونڊيو",
        "foreign-structured-upload-form-label-own-work": "هيءُ منهنجو پنهنجو ڪم آهي.",
        "foreign-structured-upload-form-label-infoform-categories": "زمرا",
        "foreign-structured-upload-form-label-infoform-date": "تاريخ",
+       "backend-fail-notexists": "فائيل ''$1'' وجود نٿو رکي.",
+       "backend-fail-delete": "\"$1\" فائيل ڊهي نہ سگھيو.",
+       "backend-fail-alreadyexists": "\"$1\" فائيل اڳ ئي وجود رکي ٿو.",
+       "backend-fail-copy": "فائيل \"$1\" کي \"$2\" ڏانهن نقل نه ڪري سگھيو.",
+       "backend-fail-move": "فائيل \"$1\" کي \"$2\" ڏانهن چوري نه سگھيو.",
+       "backend-fail-opentemp": "عارضي فائيئ کولي نه سگھيو.",
+       "backend-fail-read": "فائيل \"$1\" کي پڙهي نه سگھيو.",
        "license-header": "لائيسنسڪاري",
        "listfiles-delete": "ڊاهيو",
        "imgfile": "فائيل",
        "listfiles": "فائيل فهرست",
+       "listfiles_date": "تاريخ",
        "listfiles_name": "نالو",
        "listfiles_user": "يُوزر",
        "listfiles_size": "ماپَ",
        "listfiles_description": "تشريح",
+       "listfiles_count": "ورزن",
+       "listfiles-latestversion": "هاڻوڪو ورزن",
        "listfiles-latestversion-yes": "ها",
        "listfiles-latestversion-no": "نہ",
        "file-anchor-link": "فائيل",
        "filehist": "فائيل جي سوانح",
-       "filehist-help": "ÚªÙ\86Ù\87Ù\86 Ø¨Û\81 ØªØ§Ø±Ù\8aØ®/Ù\88Ù\82ت ØªÙ\8a ÚªÙ\84Úª ÚªØ±Ù\8a Ú\8fسÙ\86دا ØªÛ\81 ØªÚ\8fÚ»Ù\8a اهو فائيل ڪيئن هو.",
+       "filehist-help": "ÚªÙ\86Ù\87Ù\86 Ø¨Û\81 ØªØ§Ø±Ù\8aØ®/Ù\88Ù\82ت ØªÙ\8a ÚªÙ\84Úª ÚªØ±Ù\8a Ú\8fسÙ\86دا ØªÛ\81 Ø§Ù\86 Ù\88Ù\82ت اهو فائيل ڪيئن هو.",
        "filehist-deleteall": "سڀ ڊاهيو",
        "filehist-deleteone": "ڊاهيو",
        "filehist-revert": "واپس ورايو",
        "filehist-current": "حاليہ",
        "filehist-datetime": "تاريخ/وقت",
        "filehist-thumb": "آڱوٺي ننهن",
+       "filehist-thumbtext": "$1 جي نظرثاني لاءِ تصويري نشان",
        "filehist-user": "يُوزر",
        "filehist-dimensions": "ماپَ",
        "filehist-filesize": "فائيل سائيز",
        "filehist-comment": "تاثرات",
        "imagelinks": "فائيل جو استعمال",
        "linkstoimage": "هن فائيل سان {{PLURAL:$1|هيٺيون صفحو ڳنڍيل آهي |$1 هيٺيان صفحا ڳنڍيل آهن}}:",
-       "nolinkstoimage": "Ù\87Ù\86 Ù\81ائÙ\8aÙ\84 Ø³Ø§Ù\86 ÚªÙ\88 Ø¨Û\81 ØµÙ\81Ø­Ù\88 Ú³Ù\86Ú\8dÙ\8aÙ\84 Ù\86اÙ\87Ù\8a.",
+       "nolinkstoimage": "Ù\87Ù\86 Ù\81ائÙ\8aÙ\84 Ø³Ø§Ù\86 ÚªÙ\8a Ø¨Û\81 ØµÙ\81حا Ú³Ù\86Ú\8dÙ\8aÙ\84 Ù\86اÙ\87Ù\86.",
        "sharedupload": "هيءَ فائيل $1 کان آهي ۽ ان کي ٻيون رٿائون به استعمال ڪري سگھن ٿيون.",
+       "sharedupload-desc-here": "هي فائيل $1 مان آهي ۽ ٻين رٿائن پاران پڻ استعمال ٿي سگهي ٿو. تشريح انجي [[$2 جو تشريحي صفحو]] هيٺان ڏنل آهي.",
        "uploadnewversion-linktext": "هن فائيل جو نئون پرت چاڙهيو",
        "shared-repo-from": "$1 کان",
        "upload-disallowed-here": "توهان هن فائيل مٿان لکي نہ ٿا سگھو.",
        "mostrevisions": "وڌانوڌ ترميميل صفحا",
        "prefixindex": "هيءَ اڳياڙي رکندڙ سمورا صفحا",
        "prefixindex-namespace": "سمورا صفحا جن کي هيءَ اڳياڙي آهي ($1 نانءُپولار)",
+       "prefixindex-submit": "ڏيکاريو",
        "shortpages": "مختصر صفحا",
        "longpages": "طويل صفحا",
        "deadendpages": "اڻ ڳنڍيندڙ صفحا",
        "protectedpages-noredirect": "چورڻا لڪايو",
        "protectedpages-page": "صفحو",
        "protectedpages-reason": "سبب",
+       "protectedpages-submit": "صفحا ڏيکاريو",
        "protectedpages-unknown-timestamp": "اڻڄاتل",
        "protectedpages-unknown-performer": "نامعلوم يُوزر",
        "protectedtitles": "تحفظيل عنوان",
+       "protectedtitles-submit": "عنوان ڏيکاريو",
        "listusers": "يُوزر فهرست",
        "newpages": "نوان صفحا",
        "newpages-username": "يُوزرنانءُ:",
        "listusers-noresult": "ڪو بہ يُوزر نہ لڌو",
        "listusers-blocked": "(بندشيل)",
        "activeusers": "سرگرم يُوزرس جي فهرست",
+       "activeusers-hidebots": "بوٽس لڪايو",
        "activeusers-hidesysops": "منتظمن کي لڪايو",
        "activeusers-noresult": "ڪي بہ يُوزرس نہ لڌا.",
+       "activeusers-submit": "سرگرم يُوزرس ڏيکاريو",
+       "listgrouprights": "يوزر گروپ جا حق",
        "listgrouprights-group": "گروهہ:",
        "listgrouprights-rights": "حق",
        "listgrouprights-members": "(رڪنن جي لسٽ)",
+       "listgrouprights-addgroup-all": "سڀ گروپَ شامل ڪريو",
+       "listgrouprights-removegroup-all": "سڀ گروپ هٽايو",
        "listgrouprights-namespaceprotection-namespace": "نانءُ پولار:",
+       "trackingcategories-name": "پيغام جو نالو",
+       "trackingcategories-nodesc": "ڪا به تشريح موجود نه آهي.",
+       "trackingcategories-disabled": "زمرو ناقابلِ ڪار بڻايل آهي.",
        "emailuser": "هن يوزر کي برق ٽپال اماڻيو",
        "emailuser-title-notarget": "يُوزر ڏانهن برق ٽپال اماڻيو",
+       "usermaildisabled": "يوزر ايميل ناقابلِ ڪار بڻيل",
+       "usermaildisabledtext": "توهان هن وڪي تي ٻين يوزرس ڏانهن ايميل نٿا موڪلي سگھو",
        "noemailtitle": "برق ٽپال پتو نامعلوم",
        "noemailtext": "هن يُوزر ڪو بہ قابل ڪار برق ٽپال پتو نہ ڄاڻايو آهي.",
        "emailusername": "يُوزرنانءُ:",
        "watchlist-details": "{{PLURAL:$1|$1 صفحو|$1 صفحا}} توهان جي ٽيٽ فهرست، ڳالھ ٻولھ جا صفحا الڳ شمار نٿا ٿين.",
        "wlshowlast": "گذريل $1 ڪلاڪ $2 ڏينهن ڏيکاريو",
        "watchlistall2": "سڀ",
-       "wlshowtime": "آخري ڏيکاريو",
+       "watchlist-hide": "لڪايو",
+       "watchlist-submit": "ڏيکاريو",
+       "wlshowtime": "ڏيکارڻ جي لاءِ وقت جو دورانيو:",
        "wlshowhideminor": "معمولي ترميم",
+       "wlshowhidebots": "بوٽس",
        "wlshowhideliu": "کاتيدار يُوزرس",
        "wlshowhideanons": "گمنام يُوزرس",
        "wlshowhidemine": "منهنجون ترميمون",
+       "watchlist-options": "زيرِ نظر فهرست جا چارا",
        "watching": "ٽيٽيندي...",
        "unwatching": "اڻ ٽيٽيندي...",
+       "enotif_reset": "سڀ گھميل صفحن تي نشان لڳايو",
        "enotif_impersonal_salutation": "{{SITENAME}} يُوزر",
+       "enotif_lastdiff": "هي تبديلي ڏسڻ لاءِ $1 ڏسو",
        "enotif_anon_editor": "گمنام يُوزر $1",
        "created": "ٺهي چڪو",
        "changed": "تبديل ٿي ويو",
        "historywarning": "<strong>خبردار:</strong> جيڪو صفحو توهان ڊاهڻ وڃي رهيا آهيو ان ساڻ هڪ تاريخ آهي $1 {{PLURAL:$1|revision|revisions}}:",
        "confirmdeletetext": "توهان هڪ صفحي کي ان جي سموري سوانح سميت ڊاهڻ وارا آهيو. مهرباني ڪري پڪ ڪندا ته توهان اهو ئي ڪرڻ گھرو ٿا، ۽ اهو ته توهان ان جي نتيجن کان واقف آهيو، ۽ اهو پڻ ته توهان اهو ڪم [[{{MediaWiki:Policy-url}}|پاليسي]]ءَ مطابق ڪري رهيا آهيو.",
        "actioncomplete": "ڪم پُورو",
+       "actionfailed": "عمل ناڪام",
        "deletedtext": "\"$1\" ڊهي چڪو آهي.\nتازو ڊاٺل صفحن جي فهرست لاءِ $2 ڏسندا.",
        "dellogpage": "ڊاٺ لاگ",
        "deletionlog": "ڊاٺ لاگ",
        "rollbacklinkcount": "اڻ ڪريو $1 {{PLURAL:$1|ترميم|ترميمون}}",
        "changecontentmodel-title-label": "صفحي جو عنوان",
        "changecontentmodel-reason-label": "سبب:",
+       "logentry-contentmodel-change-revertlink": "واپس ورايو",
+       "logentry-contentmodel-change-revert": "واپس ورايو",
        "protectlogpage": "تحفظ لاگ",
+       "protectedarticle": "محفوظ ٿيل \"[[$1]]\"",
        "prot_1movedto2": "[[$1]] کي چوري [[$2]] تي رکيو ويو",
        "protect-legend": "تحفظڻ جي پڪ ڪريو",
        "protectcomment": "سبب:",
        "protect-level-autoconfirmed": "خودڪار نموني پڪ ڪيل يوزرس کي اجازت ڏيو",
        "protect-level-sysop": "صرف منتظمين کي اجازت ڏيو",
        "protect-summary-cascade": "تحفظ در تحفظ",
+       "protect-expiry-indefinite": "لامحدود",
        "protect-cascade": "هن صفحي ۾ شامل صفحن کي تحفظيو (تحفظ در تحفظ)",
        "protect-cantedit": "توهان هن صفحي جي تحفظاتي سطح نٿا بدلائي سگھو، ڇاڪاڻ ته توهان ان کي سنوارڻ جي اجازت نٿا رکو.",
+       "protect-othertime": "ٻيو وقت:",
+       "protect-othertime-op": "ٻيو وقت",
+       "protect-existing-expiry": "موجوده پڄاڻي جو وقت: $3, $2",
+       "protect-existing-expiry-infinity": "موجوده پڄاڻي جو وقت: لامحدود",
        "protect-otherreason-op": "ٻيو سبب",
        "protect-expiry-options": "1 ڪلاڪ:1 hour,1 ڏينهن:1 day,1 هفتو:1 week,2 هفتو:2 weeks,1 مهينا:1 month,3 مهينا:3 months,6 مهينا:6 months,1 سال:1 year,اڻ کٽ:infinite",
        "restriction-type": "اجازتنامو:",
        "undeletebtn": "بحاليو",
        "undeleteviewlink": "ڏسو",
        "undeletecomment": "سبب:",
+       "undelete-search-title": "ڊاٺل صفحا ڳوليو",
+       "undelete-search-box": "ڊاٺل صفحا ڳوليو",
+       "undelete-search-prefix": "سان شروع ٿيندڙ صفحا ڏيکاريو:",
        "undelete-search-submit": "ڳوليو",
        "undelete-error-short": "هيءُ فائيل اڻڊاهيندي چُڪَ ٿي آهي: $1",
        "undelete-show-file-submit": "ها",
        "namespace": "نانءُ پولار:",
        "invert": "چونڊ ابتيو",
+       "tooltip-invert": "هن دٻي تي نشان لڳايو صحفن ۾ تبديليون لڪائڻ لاءِ چونڊيل نيم اسپيس مان (۽ لاڳاپيل نيم اسپيس جيڪڏهن نشان لڳل)",
        "namespace_association": "منسلڪ نانءُپولار",
        "blanknamespace": "(مُک)",
        "contributions": "{{GENDER:$1|يوزر}} جون ڀاڱيداريون",
        "contributions-title": "يُوزر ڀاڱيداريون براءِ $1",
        "mycontris": "ڀاڱيداريون",
+       "anoncontribs": "ڀاڱيداريون",
        "contribsub2": "{{GENDER:$3|$1}} ($2) لاءِ",
+       "contributions-userdoesnotexist": "يُوزر کاتو \"$1\" درج ٿيل نہ آهي.",
        "uctop": "(هاڻوڪو)",
        "month": "مهينو (۽ اڳوڻيون):",
        "year": "سال (۽ اڳوڻيون):",
+       "sp-contributions-newbies": "صرف نون کاتن جون ڀاڱيداريون ڏيکاريو",
        "sp-contributions-newbies-sub": "نون کاتن لاءِ",
+       "sp-contributions-newbies-title": "نون کاتن جي لاءِ يوزر جون ڀاڱيداريون",
        "sp-contributions-blocklog": "بنسش لاگ",
+       "sp-contributions-deleted": "يُوزر جون ڊاٺل ڀاڱيداريون",
+       "sp-contributions-uploads": "چاڙھَ",
+       "sp-contributions-logs": "لاگس",
        "sp-contributions-talk": "ڳالھہ",
+       "sp-contributions-userrights": "يُوزر حقن جي سنڀال",
+       "sp-contributions-search": "ڀاڱيدارين لاءِ ڳولا ڪريو",
+       "sp-contributions-username": "آءِپي پتو يا يوزرنانءُ:",
        "sp-contributions-submit": "ڳوليو",
        "whatlinkshere": "هتان ڇا ڳنڍيل آهي",
        "whatlinkshere-title": "$1 سان ڳنڍيل صفحا",
        "whatlinkshere-hideredirs": "$1 چورجي ٿو",
        "whatlinkshere-hidelinks": "$1 ڳنڍڻا",
        "whatlinkshere-filters": "ڇاڻيون",
+       "whatlinkshere-submit": "هلو",
        "block": "يُوزر کي بندشيو",
        "unblock": "يُوزر کي اڻبندشيو",
        "blockip": "{{GENDER:$1|يوزر}} تي بندش وجھو",
        "blockip-legend": "يُوزر کي بندشيو",
        "ipbexpiry": "اختتام:",
        "ipbreason": "سبب:",
+       "ipbother": "ٻيو وقت:",
        "ipboptions": "2 ڪلاڪ:2 hours,1 ڏينهن:1 day,3 days:3 days,1 هفتو:1 week,2 weeks:2 weeks,1 مهينا:1 month,3 مهينا:3 months,6 مهينا:6 months,1 سال:1 year,اڻ کٽ:infinite",
        "ipb-confirm": "بندش جي پڪ ڪريو",
        "badipaddress": "ناقابلڪار آءِ پي پتو",
        "unblocked-range": "$1 تان بندش هٽي چڪي آهي.",
        "unblocked-id": "بندش $1 هٽي چڪي آهي.",
        "blocklist": "بندشيل يُوزرس",
-       "ipblocklist": "بندشيل يوزرس",
+       "ipblocklist": "بندش وڌل يوزرس",
        "blocklist-timestamp": "اوقاتي مهر",
        "blocklist-target": "هدف",
+       "blocklist-expiry": "اختتام:",
        "blocklist-reason": "سبب",
        "ipblocklist-submit": "ڳوليو",
        "ipblocklist-localblock": "مقامي بندش",
        "infiniteblock": "لامحدود",
        "anononlyblock": "فقط گمنام",
-       "noautoblockblock": "خودڪار بندش غير فعال",
+       "noautoblockblock": "خودڪار بندش ناقابلِ ڪار بڻيل",
        "createaccountblock": "کاتو کولڻ جي روڪَ ٿيل",
        "emailblock": "برق ٽپال غير فعال",
        "blocklink": "بندشيو",
        "movelogpage": "چورڻ لاگ",
        "movereason": "سبب:",
        "revertmove": "ورايو",
-       "delete_and_move": "ڊاهيو ۽ چوريو",
        "delete_and_move_confirm": "جي ها، صفحو ڊاهيو",
        "delete_and_move_reason": "\"[[$1]]\" کان چورڻ جو عمل ممڪن بڻائڻ لاءِ ڊاٺو ويو",
        "export": "صفحا برآمديو",
        "tooltip-ca-edit": "هيءُ صفحو سنواريو",
        "tooltip-ca-addsection": "نئون سيڪشن شروع ڪريو",
        "tooltip-ca-viewsource": "هيءُ صفحو تحفظيل آهي. توهان ان جو ڪوڊ ڏسي سگھو ٿا.",
-       "tooltip-ca-history": "هن صفحي جٰ گذريل ڀيرا",
+       "tooltip-ca-history": "هن صفحي جا گذريل ڀيرا",
        "tooltip-ca-protect": "هيءُ صفحو تحفظيو",
        "tooltip-ca-delete": "هيءُ صفحو ڊاهيو",
        "tooltip-ca-move": "هيءُ صفحو چوريو",
        "tooltip-ca-watch": "هيءُ صفحو پنهنجي ٽيٽ فهرست ۾ شامل ڪريو",
-       "tooltip-ca-unwatch": "هيءُ صفحو پنهنجي ٽيٽ فهرست تان هٽايو",
+       "tooltip-ca-unwatch": "هيءُ صفحو پنهنجي زيرِ نظر فهرست تان هٽايو",
        "tooltip-search": "{{SITENAME}} ۾ ڳوليو",
        "tooltip-search-go": "تز ان ئي نالي سان ڪو صفحو موجود آهي تہ کوليو",
        "tooltip-search-fulltext": "هن متن لاءِ صفحا ڳوليو",
        "watchlisttools-edit": "ٽيٽ فهرست ڏسو ۽ سنواريو",
        "watchlisttools-raw": "ڪچي ٽيٽ فهرست سنواريو",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ڳالهہ]])",
-       "version": "ڀيرو",
+       "version": "ورزن",
        "version-extensions": "تنصيب شده توسيعات",
-       "version-skins": "تنصيب شده چَمُون",
+       "version-skins": "تنصيب شده چَمڙيون",
        "version-specialpages": "خاص صفحا",
        "version-variables": "ڦِرڻا",
        "version-other": "ٻيو",
        "version-ext-license": "لائيسنس",
        "version-ext-colheader-name": "توسيع",
        "version-skin-colheader-name": "چَمَ",
-       "version-ext-colheader-version": "ڀيرو",
+       "version-ext-colheader-version": "ورزن",
        "version-ext-colheader-license": "لائيسنس",
        "version-ext-colheader-description": "تشريح",
        "version-ext-colheader-credits": "ليکڪ",
        "version-poweredby-translators": "translatewiki.net جا ترجميڪار",
        "version-software": "تنصيب شده منطقگري",
        "version-software-product": "پراڊڪٽ",
-       "version-software-version": "ڀيرو",
+       "version-software-version": "ورزن",
        "version-libraries-library": "لائبريري",
-       "version-libraries-version": "ڀيرو",
+       "version-libraries-version": "ورزن",
        "version-libraries-license": "لائيسنس",
        "version-libraries-description": "تشريح",
        "version-libraries-authors": "ليکڪ",
        "tags-delete-title": "ٽيگ ڊاهيو",
        "tags-delete-reason": "سبب:",
        "tags-activate-reason": "سبب:",
-       "tags-activate-submit": "فعاليو",
-       "tags-deactivate-title": "Ù½Ù\8aÚ¯ Ú©Ù\8a Ø§Ú»Ù\81عاÙ\84يو.",
+       "tags-activate-submit": "فعال بڻايو",
+       "tags-deactivate-title": "Ù½Ù\8aÚ¯ Ú©Ù\8a ØºÙ\8aر Ù\81عاÙ\84 Ù\86ڻايو.",
        "tags-deactivate-reason": "سبب:",
        "tags-edit-existing-tags-none": "\"ڪو بہ نہ\"",
        "tags-edit-new-tags": "نوان ٽيگس:",
index f7ec7e5..2730515 100644 (file)
        "rc-enhanced-expand": "Ruodītė smolkmenas",
        "rc-enhanced-hide": "Kavuotė smolkmenas",
        "rc-old-title": "pradiuo padėrbta kāp \"$1\"",
-       "recentchangeslinked": "Sosėjėn pakeitėmā",
-       "recentchangeslinked-feed": "Sosėjėn pakeitėmā",
-       "recentchangeslinked-toolbox": "Sosėjėn pakeitėmā",
+       "recentchangeslinked": "Sosėjė̄ pakeitėmā",
+       "recentchangeslinked-feed": "Sosėjė̄ pakeitėmā",
+       "recentchangeslinked-toolbox": "Sosėjė̄ pakeitėmā",
        "recentchangeslinked-title": "So $1 sosėjē pakeitėmā",
        "recentchangeslinked-summary": "Tamė specēliam poslapi sogol vielībė̄jė pakeitėmā poslapiūs, i katrūs īr nuruodoma. Poslapē ėš Tamstas [[Special:Watchlist|keravuojamu sāroša]] ėšruod '''stuorā'''.",
        "recentchangeslinked-page": "Poslapė pavadėnėms:",
        "movelogpagetext": "Sārašos parvadintu poslapiu.",
        "movereason": "Dingstės:",
        "revertmove": "atmestė",
-       "delete_and_move": "Ėštrintė ė parkeltė",
        "delete_and_move_text": "==Rēkalings ėštrīnims==\nPaskėrties straipsnis „[[:$1]]“ jau īr. A nuorėt ana ėštrintė, kū galietomiet parvadintė?",
        "delete_and_move_confirm": "Tēp, trintė poslapi",
        "delete_and_move_reason": "Ėštrinta, ka $1 galietom būtė parvadints",
index 96ee497..a673d6e 100644 (file)
        "movenosubpage": "Ova stranica nema podstranica.",
        "movereason": "Razlog:",
        "revertmove": "vrati - врати",
-       "delete_and_move": "Brisanje i premještanje",
        "delete_and_move_text": "==Brisanje neophodno==\nOdredišna stranica \"[[:$1]]\" već postoji.\nDa li je želite obrisati kako bi ste mogli izvršiti premještanje?",
        "delete_and_move_confirm": "Da, izbriši stranicu - Да, избриши страницу",
        "delete_and_move_reason": "Obrisano da se oslobodi mjesto za premještanje iz „[[$1]]“",
index 14dfb7f..69a4a59 100644 (file)
        "morenotlisted": "Tento zoznam nie je úplný.",
        "mypage": "Stránka",
        "mytalk": "Diskusia",
-       "anontalk": "Diskusia k tejto IP adrese",
+       "anontalk": "Diskusia",
        "navigation": "Navigácia",
        "and": "&#32;a",
        "qbfind": "Hľadať",
        "createacct-reason": "Dôvod",
        "createacct-reason-ph": "Prečo si vytvárate ďalší účet",
        "createacct-submit": "Vytvoriť účet",
-       "createacct-another-submit": "Vytvoriť ďalší účet",
+       "createacct-another-submit": "Vytvoriť účet",
        "createacct-benefit-heading": "{{GRAMMAR:akuzatív|{{SITENAME}}}} tvoria ľudia ako vy.",
        "createacct-benefit-body1": "{{PLURAL:$1|úprava|úpravy|úprav}}",
        "createacct-benefit-body2": "{{PLURAL:$1|stránka|stránky|stránok}}",
        "passwordreset-emailtext-ip": "Niekto (pravdepodobne vy z IP adresy $1) požiadal o obnovenie vášho hesla na {{GRAMMAR:genitív|{{SITENAME}}}} ($4). {{PLURAL:$3|Nasledujúci používateľský účet je spojený|Nasledujúce používateľské účty sú spojené}}\ns touto emailovou adresou:\n\n$2\n\n{{PLURAL:$3|Platnosť tohto dočasného hesla vyprší|Platnosť týchto dočasných hesiel vyprší}} o {{PLURAL:$5|jeden deň|$5 dni|$5 dní}}.\nMali by ste sa prihlásiť teraz a zvoliť nové heslo. Ak túto žiadosť podal niekto iný alebo\nak ste si spomenuli svoje pôvodné heslo a už ho chcete zmeniť, môžete túto správu\nignorovať a ďalej používať vaše staré heslo.",
        "passwordreset-emailtext-user": "Používateľ $1 na {{GRAMMAR:genitív|{{SITENAME}}}} požiadal o obnovenie vášho hesla na na {{GRAMMAR:genitív|{{SITENAME}}}} ($4). {{PLURAL:$3|Nasledujúci používateľský účet je spojený|Nasledujúce používateľské účty sú spojené}}\ns touto emailovou adresou:\n\n$2\n\n{{PLURAL:$3|Platnosť tohto dočasného hesla vyprší|Platnosť týchto dočasných hesiel vyprší}} o {{PLURAL:$5|jeden deň|$5 dni|$5 dní}}.\nMali by ste sa prihlásiť teraz a zvoliť nové heslo. Ak túto žiadosť podal niekto iný alebo\nak ste si spomenuli svoje pôvodné heslo a už ho chcete zmeniť, môžete túto správu\nignorovať a ďalej používať vaše staré heslo.",
        "passwordreset-emailelement": "Používateľské meno: \n$1\n\nDočasné heslo:\n$2",
-       "passwordreset-emailsent": "Email s novým heslom bol odoslaný.",
+       "passwordreset-emailsentemail": "Email s novým heslom bol odoslaný.",
        "passwordreset-emailsent-capture": "Bol odoslaný email s novým heslom, ktorý je zobrazený nižšie.",
        "passwordreset-emailerror-capture": "Bol odoslaný email s novým heslom, ktorý je zobrazený nižšie, ale nepodarilo sa ho odoslať {{GENDER:$2|používateľovi}}: $1",
-       "changeemail": "Zmeniť emailovú adresu",
+       "changeemail": "Zmeniť alebo odstrániť e-mailovú adresu",
        "changeemail-header": "Zmena e-mailovej adresy pre účet",
        "changeemail-passwordrequired": "Pre potvrdenie tejto zmeny budete musieť zadať svoje heslo.",
        "changeemail-no-info": "Na prístup k tejto stránke musíte byť prihlásený.",
        "movenosubpage": "Táto stránka nemá podstránky.",
        "movereason": "Dôvod:",
        "revertmove": "obnoviť",
-       "delete_and_move": "Vymazať a presunúť",
        "delete_and_move_text": "==Je potrebné zmazať stránku==\n\nCieľová stránka „[[:$1]]“ už existuje. Chcete ho vymazať a vytvoriť tak priestor pre presun?",
        "delete_and_move_confirm": "Áno, zmaž stránku",
        "delete_and_move_reason": "Vymazané, aby sa umožnil presun z „[[$1]]“",
        "spam_reverting": "Vraciam poslednú verziu, ktorá neobsahuje odkazy na $1",
        "spam_blanking": "Všetky revízie obsahovali odkaz na $1, odstraňujem obsah",
        "spam_deleting": "Všetky revízie obsahovali odkaz na $1, odstraňuje sa",
-       "simpleantispam-label": "Antispamová kontrola.\n'''NEVYPĹŇAJTE''' nasledovné!",
+       "simpleantispam-label": "Antispamová kontrola.\n<strong>Nevypĺňajte</strong> nasledovné!",
        "pageinfo-title": "Informácie o „$1“",
        "pageinfo-not-current": "Ospravedlňujeme sa, túto informáciu nie je možné poskytnúť pre staré revízie.",
        "pageinfo-header-basic": "Základné údaje",
index d15128d..9d0322c 100644 (file)
@@ -46,6 +46,7 @@
        "tog-watchlisthidebots": "Na spisku nadzorov skrij urejanja botov",
        "tog-watchlisthideminor": "Na spisku nadzorov skrij manjša urejanja",
        "tog-watchlisthideliu": "Na spisku nadzorov skrij urejanja prijavljenih uporabnikov",
+       "tog-watchlistreloadautomatically": "Samodejno ponovno naloži spisek nadzorov ob spremembi filtra (zahteva JavaScript)",
        "tog-watchlisthideanons": "Na spisku nadzorov skrij urejanja anonimnih uporabnikov",
        "tog-watchlisthidepatrolled": "Na spisku nadzorov skrij pregledana urejanja",
        "tog-watchlisthidecategorization": "Skrij kategorizacijo strani",
        "morenotlisted": "Seznam ni popoln.",
        "mypage": "Stran",
        "mytalk": "Pogovor",
-       "anontalk": "Pogovorna stran IP-naslova",
+       "anontalk": "Pogovorna stran",
        "navigation": "Navigacija",
        "and": "&#32;in",
        "qbfind": "Poišči",
        "databaseerror-query": "Poizvedba: $1",
        "databaseerror-function": "Funkcija: $1",
        "databaseerror-error": "Napaka: $1",
+       "transaction-duration-limit-exceeded": "V izogib ustvarjanju visokega zamika replikacije smo transakcijo prekinili, saj je trajanje zapisovanja ($1) preseglo omejitev $2 sekund.\nČe naenkrat spreminjate več predmetov, poskusite izvesti več manjših operacij.",
        "laggedslavemode": "'''Opozorilo:''' Stran morda ne vsebuje najnovejših posodobitev.",
        "readonly": "Zbirka podatkov je zaklenjena",
        "enterlockreason": "Vnesite razlog za zaklenitev in oceno, kdaj bo urejanje spet mogoče",
        "wrongpasswordempty": "Vpisali ste prazno geslo. Prosimo, poskusite znova.",
        "passwordtooshort": "Geslo mora imeti najmanj $1 {{PLURAL:$1|znak|znaka|znake|znakov|znakov}}.",
        "passwordtoolong": "Gesla ne morejo biti daljša od {{PLURAL:$1|1 znaka|$1 znakov}}.",
+       "passwordtoopopular": "Pogosto izbrana gesla ne morete uporabiti. Prosimo, izberite bolj edinstveno geslo.",
        "password-name-match": "Vaše geslo se mora razlikovati od vašega uporabniškega imena.",
        "password-login-forbidden": "Uporaba tega uporabniškega imena in gesla je prepovedana.",
        "mailmypassword": "Ponastavitev gesla",
        "passwordreset-emailtext-ip": "Nekdo (verjetno vi, z IP-naslova $1) je zahteval ponastavitev vašega\ngesla na {{SITENAME}} ($4). S tem e-poštnim naslovom\n{{PLURAL:$3|je povezan naslednji uporabniški račun|sta povezana naslednja uporabniška računa|so povezani naslednji uporabniški računi}}:\n\n$2\n\n{{PLURAL:$3|Začasno geslo bo poteklo|Začasni gesli bosta potekli|Začasna gesla bodo potekla}} v {{PLURAL:$5|enem dnevu|$5 dneh}}.\nPrijavite se in izberite novo geslo. Če je zahtevo podal\nnekdo drug ali pa ste se spomnili svojega prvotnega gesla in ga več\nne želite spremeniti, lahko to sporočilo prezrete in nadaljujete z uporabo\nsvojega starega gesla.",
        "passwordreset-emailtext-user": "Uporabnik $1 na strani {{SITENAME}} je zahteval ponastavitev vašega gesla na {{SITENAME}}\n($4). S tem e-poštnim naslovom {{PLURAL:$3|je povezan naslednji uporabniški račun|sta povezana naslednja uporabniška računa|so povezani naslednji uporabniški računi}}:\n\n$2\n\n{{PLURAL:$3|Začasno geslo bo poteklo|Začasni gesli bosta potekli|Začasna gesla bodo potekla}} v {{PLURAL:$5|enem dnevu|$5 dneh}}.\nPrijavite se in izberite novo geslo sedaj. Če je zahtevo podal\nnekdo drug ali pa ste se spomnili svojega prvotnega gesla in ga več\nne želite spremeniti, lahko to sporočilo prezrete in nadaljujete z uporabo\nsvojega starega gesla.",
        "passwordreset-emailelement": "Uporabniško ime: \n$1\n\nZačasno geslo: \n$2",
-       "passwordreset-emailsent": "Če je to registriran e-poštni naslov za vaš račun, vam bomo poslali e-pošto za postavitev gesla.",
+       "passwordreset-emailsentemail": "Če je to registriran e-poštni naslov za vaš račun, vam bomo poslali e-pošto za postavitev gesla.",
+       "passwordreset-emailsentusername": "Če obstaja pripadajoč registriran e-poštni naslov, vam bomo poslali e-pošto za postavitev gesla.",
        "passwordreset-emailsent-capture": "Poslali smo e-pošto za ponastavitev gesla, ki je prikazana spodaj.",
        "passwordreset-emailerror-capture": "Ustvarili smo e-pošto za ponastavitev gesla, ki je prikazana spodaj, vendar pa pošiljanje {{GENDER:$2|uporabniku|uporabnici}} ni uspelo: $1",
        "changeemail": "Sprememba ali odstranitev e-poštnega naslova",
        "recentchanges-label-plusminus": "uporabnik je velikost strani spremenil za tolikšno število bajtov",
        "recentchanges-legend-heading": "'''Legenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (glej tudi [[Special:NewPages|seznam novih strani]])",
+       "recentchanges-submit": "Prikaži",
        "rcnotefrom": "{{PLURAL:$5|Navedena je sprememba|Navedeni sta spremembi|Navedene so spremembe}} od <strong>$3 $4</strong> dalje (prikazujem jih do <strong>$1</strong>).",
        "rclistfrom": "Prikaži spremembe od $3 $2 naprej",
        "rcshowhideminor": "$1 manjša urejanja",
        "mostrevisions": "Največkrat urejane strani",
        "prefixindex": "Vse strani s predpono",
        "prefixindex-namespace": "Vse strani s predpono (imenski prostor $1)",
+       "prefixindex-submit": "Prikaži",
        "prefixindex-strip": "Na seznamu odreži predpono",
        "shortpages": "Kratke strani",
        "longpages": "Dolge strani",
        "protectedpages-performer": "Zaščitni uporabnik",
        "protectedpages-params": "Parametri zaščite",
        "protectedpages-reason": "Razlog",
+       "protectedpages-submit": "Prikaži strani",
        "protectedpages-unknown-timestamp": "Neznano",
        "protectedpages-unknown-performer": "Neznani uporabnik",
        "protectedtitles": "Zaščiteni naslovi",
        "protectedtitles-summary": "Stran navaja obstoječe strani, ki so trenutno zaščitene pred ustvarjanjem. Za seznam obstoječih strani, ki so zaščitene, glej [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Noben naslov ni trenutno zaščiten s temi parametri.",
+       "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Seznam uporabnikov",
        "listusers-editsonly": "Pokaži samo uporabnike z urejanji",
        "listusers-creationsort": "Razvrsti po datumu ustvaritve",
        "activeusers-hidebots": "Skrij bote",
        "activeusers-hidesysops": "Skrij administratorje",
        "activeusers-noresult": "Noben uporabnik ni bil najden.",
+       "activeusers-submit": "Prikaži dejavne uporabnike",
        "listgrouprights": "Pravice uporabniških skupin",
        "listgrouprights-summary": "Tu je na razpolago seznam uporabniških skupin na tem wikiju z navedbo dodeljenih pravic dostopa.\nMorda so na razpolago tudi [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]] o posameznih skupinah.",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Dodeljena pravica</span>\n* <span class=\"listgrouprights-revoked\">Odvzeta pravica</span>",
        "wlshowlast": "Prikaži zadnjih $1 ur; $2 dni",
        "watchlistall2": "vse",
        "watchlist-hide": "Skrij",
-       "wlshowtime": "Prikaži zadnje:",
+       "watchlist-submit": "Prikaži",
+       "wlshowtime": "Časovno obdobje za prikaz:",
        "wlshowhideminor": "manjša urejanja",
        "wlshowhidebots": "boti",
        "wlshowhideliu": "registrirani uporabniki",
        "contributions": "{{GENDER:$1|Uporabnikovi|Uporabničini}} prispevki",
        "contributions-title": "Prispevki uporabnika $1",
        "mycontris": "Prispevki",
+       "anoncontribs": "Prispevki",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Uporabniški račun »$1« ni registriran.",
        "nocontribs": "Ne najdem nobene merilom ustrezajoče spremembe.",
        "whatlinkshere-hidelinks": "$1 povezave",
        "whatlinkshere-hideimages": "$1 povezave datotek",
        "whatlinkshere-filters": "Filtri",
+       "whatlinkshere-submit": "Pojdi",
        "autoblockid": "Samodejna blokada št. $1",
        "block": "Blokiraj uporabnika",
        "unblock": "Odblokiraj uporabnika",
        "movenosubpage": "Ta stran nima podstrani.",
        "movereason": "Razlog:",
        "revertmove": "vrni",
-       "delete_and_move": "Briši in prestavi",
        "delete_and_move_text": "==Treba bi bilo brisati==\n\nCiljna stran »[[:$1]]« že obstaja. Ali jo želite, da bi pripravili prostor za prestavitev, izbrisati?",
        "delete_and_move_confirm": "Da, izbriši stran",
        "delete_and_move_reason": "Izbrisano z namenom pripraviti prostor za »[[$1]]«",
        "tooltip-pt-preferences": "Vaše nastavitve",
        "tooltip-pt-watchlist": "Seznam strani, katerih spremembe spremljate",
        "tooltip-pt-mycontris": "Seznam vaših prispevkov",
+       "tooltip-pt-anoncontribs": "Seznam urejanj s tega IP-naslova",
        "tooltip-pt-login": "Prijava ni obvezna, vendar je zaželena",
        "tooltip-pt-logout": "Odjavite se",
        "tooltip-pt-createaccount": "Predlagamo vam, da ustvarite račun in se prijavite, vendar pa to ni obvezno.",
index 24d4db5..33ddb6c 100644 (file)
        "movenosubpage": "Kjo faqe nuk ka nën-faqe.",
        "movereason": "Arsyeja:",
        "revertmove": "ktheje",
-       "delete_and_move": "Grise dhe zhvendose",
        "delete_and_move_text": "==Nevojitet grisje==\n\nFaqja \"[[:$1]]\" ekziston, dëshironi ta grisni për të mundësuar zhvendosjen?",
        "delete_and_move_confirm": "Po, fshi këtë faqe",
        "delete_and_move_reason": "U gris për të liruar vendin për përcjellim të \"[[$1]]\"",
index 1e26246..48d7695 100644 (file)
        "morenotlisted": "Ова листа није комплетна.",
        "mypage": "Страница",
        "mytalk": "Разговор",
-       "anontalk": "Разговор за ову ИП адресу",
+       "anontalk": "Разговор",
        "navigation": "Навигација",
        "and": "&#32;и",
        "qbfind": "Пронађи",
        "confirmable-no": "Не",
        "thisisdeleted": "Погледати или вратити $1?",
        "viewdeleted": "Погледати $1?",
-       "restorelink": "{{PLURAL:$1|обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
+       "restorelink": "{{PLURAL:$1|1=обрисану измену|$1 обрисане измене|$1 обрисаних измена}}",
        "feedlinks": "Довод:",
        "feed-invalid": "Неисправна врста довода.",
        "feed-unavailable": "Доводи нису доступни",
        "passwordreset-emailtext-ip": "Неко (вероватно Ви, са ИП адресе $1) је затражио нову лозинку на викију {{SITENAME}} ($4).\nСледећи {{PLURAL:$3|кориснички налог је повезан|кориснички налози су повезани}} с овом имејл адресом:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nПријавите се и изаберите нову лозинку. Ако је неко други захтевао ову радњу или сте се сетили лозинке и не желите да је мењате, занемарите ову поруку и наставите користити стару лозинку.",
        "passwordreset-emailtext-user": "{{GENDER:$1|Корисник је затражио|Корисница је затражила}} подсетник о подацима за пријаву на викију {{SITENAME}} ($4).\nСледећи {{PLURAL:$3|кориснички налог је повезан|кориснички налози су повезани}} с овом имејл адресом:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nПријавите се и изаберите нову лозинку. Ако је неко други захтевао ову радњу или сте се сетили лозинке и не желите да је мењате, занемарите ову поруку.",
        "passwordreset-emailelement": "Корисничко име: \n$1\n\nПривремена лозинка: \n$2",
-       "passwordreset-emailsent": "Ако је ово имејл адреса регистована на Вашем налогу, подсетник о лозинци ће бити послат на имејл.",
+       "passwordreset-emailsentemail": "Ако је ово имејл адреса регистована на Вашем налогу, подсетник о лозинци ће бити послат на имејл.",
        "passwordreset-emailsent-capture": "Послат је подсетник преко имејла, који је приказан доле.",
        "passwordreset-emailerror-capture": "Имејл за ресетовање лозинке, приказан испод је послат, али слање {{GENDER:$2|кориснику|корисници}} није успело: $1",
        "changeemail": "Промени или уклони имејл адресу",
        "contributions": "{{GENDER:$1|Кориснички}} доприноси",
        "contributions-title": "Доприноси {{GENDER:$1|корисника|кориснице}} $1",
        "mycontris": "Доприноси",
+       "anoncontribs": "Доприноси",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Кориснички налог „$1“ није регистрован.",
        "nocontribs": "Нема измена које одговарају наведеним критеријумима.",
        "movenosubpage": "Ова страница нема подстрана.",
        "movereason": "Разлог:",
        "revertmove": "врати",
-       "delete_and_move": "Обриши и премести",
        "delete_and_move_text": "== Потребно брисање ==\n\nОдредишна страница „[[:$1]]“ већ постоји. \nЖелите ли да је обришете да бисте ослободили место за премештање?",
        "delete_and_move_confirm": "Да, обриши страницу",
        "delete_and_move_reason": "Обрисано да се ослободи место за премештање из „[[$1]]“",
        "tooltip-pt-preferences": "Ваша подешавања",
        "tooltip-pt-watchlist": "Списак страница које надгледате",
        "tooltip-pt-mycontris": "Списак ваших доприноса",
+       "tooltip-pt-anoncontribs": "Списак измена направљених са ове IP адресе",
        "tooltip-pt-login": "Препоручујемо вам да се пријавите, иако то није обавезно.",
        "tooltip-pt-logout": "Одјавите се",
        "tooltip-pt-createaccount": "Охрабрујемо вас да отворите налог и пријавите се али то није обавезно",
        "tags-deactivate-not-allowed": "Није могуће деактивирати ознаку „$1“.",
        "tags-deactivate-submit": "Декативирај",
        "tags-edit-title": "Уреди ознаке",
+       "tags-edit-manage-link": "Управљај ознакама",
        "tags-edit-existing-tags": "Постојеће ознаке:",
        "tags-edit-new-tags": "Нове ознаке:",
        "tags-edit-reason": "Разлог:",
        "htmlform-cloner-create": "Додај још",
        "htmlform-cloner-delete": "Уклони",
        "htmlform-cloner-required": "Бар једна вредност је потребна.",
+       "htmlform-title-badnamespace": "[[:$1]] није у именском простору „{{ns:$2}}“.",
        "htmlform-title-not-exists": "$1 не постоји.",
        "htmlform-user-not-exists": "<strong>$1</strong> не постоји.",
        "htmlform-user-not-valid": "<strong>$1</strong> није исправно корисничко име.",
        "special-characters-group-thai": "тајландски",
        "special-characters-group-lao": "лаоски",
        "special-characters-group-khmer": "кмерски",
+       "mw-widgets-dateinput-no-date": "Датум није изабран",
        "mw-widgets-dateinput-placeholder-day": "ГГГГ-ММ-ДД",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
index 96aa7b3..be91d97 100644 (file)
        "morenotlisted": "Ova lista nije kompletna.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
-       "anontalk": "Razgovor za ovu IP adresu",
+       "anontalk": "Razgovor",
        "navigation": "Navigacija",
        "and": "&#32;i",
        "qbfind": "Pronađi",
        "confirmable-no": "Ne",
        "thisisdeleted": "Pogledati ili vratiti $1?",
        "viewdeleted": "Pogledati $1?",
-       "restorelink": "{{PLURAL:$1|obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
+       "restorelink": "{{PLURAL:$1|1=obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
        "feedlinks": "Dovod:",
        "feed-invalid": "Neispravna vrsta dovoda.",
        "feed-unavailable": "Dovodi nisu dostupni",
        "passwordreset-emailtext-ip": "Neko, verovatno Vi, sa IP adrese $1 je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom e-adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku i nastavite koristiti staru lozinku.",
        "passwordreset-emailtext-user": "{{GENDER:$1|Korisnik je zatražio|Korisnica je zatražila}} podsetnik o podacima za prijavu na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom e-adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena lozinka: \n$2",
-       "passwordreset-emailsent": "Podsetnik o lozinci je poslat na vašu adresu.",
+       "passwordreset-emailsentemail": "Podsetnik o lozinci je poslat na vašu adresu.",
        "passwordreset-emailsent-capture": "Poslat je podsetnik preko e-pošte (prikazan dole).",
        "passwordreset-emailerror-capture": "E-poruka za resetovanje lozinke, prikazana ispod je poslata, ali slanje {{GENDER:$2|korisniku|korisnici}} nije uspelo: $1",
        "changeemail": "Promeni ili ukloni e-adresu",
        "movenosubpage": "Ova stranica nema podstrana.",
        "movereason": "Razlog:",
        "revertmove": "vrati",
-       "delete_and_move": "Obriši i premesti",
        "delete_and_move_text": "== Potrebno brisanje ==\n\nOdredišna stranica „[[:$1]]“ već postoji. \nŽelite li da je obrišete da biste oslobodili mesto za premeštanje?",
        "delete_and_move_confirm": "Da, obriši stranicu",
        "delete_and_move_reason": "Obrisano da se oslobodi mesto za premeštanje iz „[[$1]]“",
index 2951941..2328bd4 100644 (file)
@@ -67,7 +67,8 @@
                        "Macofe",
                        "Aaoo",
                        "Josve05a",
-                       "Pipetricker"
+                       "Pipetricker",
+                       "Dammråtta"
                ]
        },
        "tog-underline": "Stryk under länkar:",
        "tog-watchlisthidebots": "Visa inte robotredigeringar i bevakningslistan",
        "tog-watchlisthideminor": "Dölj mindre ändringar i bevakningslistan",
        "tog-watchlisthideliu": "Visa inte redigeringar av inloggade användare i bevakningslistan",
+       "tog-watchlistreloadautomatically": "Uppdatera bevakningslistan automatiskt när ett filter ändras (JavaScript krävs)",
        "tog-watchlisthideanons": "Dölj redigeringar av anonyma användare i bevakningslistan",
        "tog-watchlisthidepatrolled": "Dölj patrullerade redigeringar i bevakningslistan",
        "tog-watchlisthidecategorization": "Dölj kategorisering av sidor",
        "december-gen": "december",
        "jan": "jan",
        "feb": "feb",
-       "mar": "mar",
+       "mar": "mars",
        "apr": "apr",
        "may": "maj",
-       "jun": "jun",
-       "jul": "jul",
+       "jun": "juni",
+       "jul": "juli",
        "aug": "aug",
-       "sep": "sep",
+       "sep": "sept",
        "oct": "okt",
        "nov": "nov",
        "dec": "dec",
        "morenotlisted": "Denna lista är inte fullständig.",
        "mypage": "Sida",
        "mytalk": "Diskussion",
-       "anontalk": "Diskussionssida för denna IP-adress",
+       "anontalk": "Diskussion",
        "navigation": "Navigering",
        "and": "&#32;och",
        "qbfind": "Hitta",
        "wrongpasswordempty": "Lösenordet som angavs var blankt. Var god försök igen.",
        "passwordtooshort": "Lösenord måste innehålla minst {{PLURAL:$1|$1 tecken}}.",
        "passwordtoolong": "Lösenord kan inte vara längre än {{PLURAL:$1|1 tecken|$1 tecken}}.",
+       "passwordtoopopular": "Vanliga lösenord kan inte användas. Välj ett mer unikt lösenord.",
        "password-name-match": "Ditt lösenord måste vara olikt ditt användarnamn.",
        "password-login-forbidden": "Användningen av dessa användarnamn och lösenord har förbjudits.",
        "mailmypassword": "Återställ lösenord",
        "passwordreset-emailtext-ip": "Någon (förmodligen du, från IP-adressen $1) begärde en återställning av ditt lösenord för {{SITENAME}} ($4). Följande användar{{PLURAL:$3|konto är förknippad|konton är förknippade}} med denna e-postadress:\n\n$2\n\n{{PLURAL:$3|Detta|Dessa}} tillfälliga lösenord kommer att gå ut om {{PLURAL:$5|en dag|$5 dagar}}.\nDu bör logga in och välja ett nytt lösenord nu. Om någon annan gjorde denna begäran, eller om du kommer ihåg ditt ursprungliga lösenord, och inte längre önskar ändra det, kan du ignorera detta meddelande och fortsätta använda ditt gamla lösenord.",
        "passwordreset-emailtext-user": "Användaren $1 på {{SITENAME}} begärde en återställning av ditt lösenord för {{SITENAME}} ($4). Följande användar{{PLURAL:$3|konto är förknippad|konton är förknippade}} med denna e-postadress:\n\n$2\n\n{{PLURAL:$3|Detta|Dessa}} tillfälliga lösenord kommer att gå ut om {{PLURAL:$5|en dag|$5 dagar}}.\nDu bör logga in och välja ett nytt lösenord nu. Om någon annan gjorde denna begäran, eller om du kommer ihåg ditt ursprungliga lösenord, och inte längre önskar ändra det, kan du ignorera detta meddelande och fortsätta använda ditt gamla lösenord.",
        "passwordreset-emailelement": "Användarnamn: \n$1\n\nTillfälligt lösenord: \n$2",
-       "passwordreset-emailsent": "Om detta är en registrerad e-postadress för ditt konto kommer en lösenordsåterställning via e-post skickas.",
+       "passwordreset-emailsentemail": "Om detta är en registrerad e-postadress för ditt konto kommer en lösenordsåterställning skickas via e-post.",
+       "passwordreset-emailsentusername": "Om det finns en motsvarande e-postadress för ditt konto kommer en lösenordsåterställning skickas via e-post.",
        "passwordreset-emailsent-capture": "En lösenordsåterställning via e-post har skickats, som visas nedan.",
        "passwordreset-emailerror-capture": "En lösenordsåterställning via e-post har skapats, som visas nedan, men det gick inte att skicka den till {{GENDER:$2|användaren}}: $1",
        "changeemail": "Ändra eller ta bort e-postadress",
        "history-feed-description": "Versionshistorik för denna sida på wikin",
        "history-feed-item-nocomment": "$1 den $2",
        "history-feed-empty": "Den begärda sidan finns inte.\nDen kan ha tagits bort från wikin eller bytt namn.\nProva att [[Special:Search|söka på wikin]] för relevanta nya sidor.",
-       "history-edit-tags": "Redigera märken för valda sidversioner",
+       "history-edit-tags": "Redigera taggar för valda sidversioner",
        "rev-deleted-comment": "(redigeringssammanfattning togs bort)",
        "rev-deleted-user": "(användarnamn borttaget)",
        "rev-deleted-event": "(loggdetaljer borttagna)",
        "recentchanges-legend-heading": "'''Teckenförklaring:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se även [[Special:NewPages|listan över nya sidor]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Visa",
        "rcnotefrom": "Nedan visas {{PLURAL:$5|ändringen|ändringar}} sedan <strong>$3, $4</strong> (upp till <strong>$1</strong> ändringar visas).",
        "rclistfrom": "Visa ändringar från och med $3 $2",
        "rcshowhideminor": "$1 mindre ändringar",
        "mostrevisions": "Sidor med flest ändringar",
        "prefixindex": "Alla sidor med prefix",
        "prefixindex-namespace": "Alla sidor med prefix ($1 namnrymder)",
+       "prefixindex-submit": "Visa",
        "prefixindex-strip": "Avlägsna prefix i lista",
        "shortpages": "Korta sidor",
        "longpages": "Långa sidor",
        "protectedpages-performer": "Skyddande användare",
        "protectedpages-params": "Skyddsparametrar",
        "protectedpages-reason": "Anledning",
+       "protectedpages-submit": "Visa sidor",
        "protectedpages-unknown-timestamp": "Okänd",
        "protectedpages-unknown-performer": "Okänd användare",
        "protectedtitles": "Skyddade titlar",
        "protectedtitles-summary": "Denna sida listar de titlar som skyddas från att skapas. För en lista över befintliga sidor som är skyddade, se [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Just nu finns inga skyddade sidtitlar med de parametrarna.",
+       "protectedtitles-submit": "Visa titlar",
        "listusers": "Användarlista",
        "listusers-editsonly": "Visa endast användare som redigerat",
        "listusers-creationsort": "Sortera efter datum skapat",
        "activeusers-hidebots": "Dölj botar",
        "activeusers-hidesysops": "Dölj administratörer",
        "activeusers-noresult": "Inga användare funna.",
+       "activeusers-submit": "Visa aktiva användare",
        "listgrouprights": "Behörigheter för användargrupper",
        "listgrouprights-summary": "Följande lista visar vilka användargrupper som är definierade på den här wikin och vilka behörigheter grupperna har.\nDet kan finnas [[{{MediaWiki:Listgrouprights-helppage}}|ytterligare information]] om de olika behörigheterna.",
        "listgrouprights-key": "Teckenförklaring:\n* <span class=\"listgrouprights-granted\">Beviljad rättighet</span>\n* <span class=\"listgrouprights-revoked\">Tillbakatagen rättighet</span>",
        "wlshowlast": "Visa senaste $1 timmarna $2 dygnen",
        "watchlistall2": "alla",
        "watchlist-hide": "Dölj",
-       "wlshowtime": "Visa senaste:",
+       "watchlist-submit": "Visa",
+       "wlshowtime": "Tidsperiod att visa:",
        "wlshowhideminor": "mindre redigering",
        "wlshowhidebots": "robotar",
        "wlshowhideliu": "registrerade användare",
        "contributions": "{{GENDER:$1|Användarbidrag}}",
        "contributions-title": "Bidrag av $1",
        "mycontris": "Bidrag",
+       "anoncontribs": "Bidrag",
        "contribsub2": "För {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Användarkontot \"$1\" är inte registrerat.",
        "nocontribs": "Inga ändringar som motsvarar dessa kriterier hittades.",
        "whatlinkshere-hidelinks": "$1 länkar",
        "whatlinkshere-hideimages": "$1 fillänkar",
        "whatlinkshere-filters": "Filter",
+       "whatlinkshere-submit": "Gå",
        "autoblockid": "Autoblockera #$1",
        "block": "Blockera användare",
        "unblock": "Upphäv blockering av användare",
        "movenosubpage": "Denna sida har inga undersidor.",
        "movereason": "Anledning:",
        "revertmove": "återställ",
-       "delete_and_move": "Radera och flytta",
        "delete_and_move_text": "==Radering krävs==\nDen titel du vill flytta sidan till, \"[[:$1]]\", finns redan. Vill du radera den för att möjliggöra flytt av denna sida dit?",
        "delete_and_move_confirm": "Ja, radera sidan",
        "delete_and_move_reason": "Raderad för att göra plats till flyttning av \"[[$1]]\"",
        "tooltip-pt-preferences": "Dina inställningar",
        "tooltip-pt-watchlist": "Listan över sidor du bevakar för ändringar",
        "tooltip-pt-mycontris": "Lista över dina bidrag",
+       "tooltip-pt-anoncontribs": "En lista över redigeringar från denna IP-adress",
        "tooltip-pt-login": "Du uppmuntras att logga in, men det är inget krav",
        "tooltip-pt-logout": "Logga ut",
        "tooltip-pt-createaccount": "Du uppmuntras att skapa ett konto och logga in, men det är inte obligatoriskt",
        "tooltip-ca-watch": "Lägg till sidan på din bevakningslista",
        "tooltip-ca-unwatch": "Ta bort denna sida från din bevakningslista",
        "tooltip-search": "Sök på {{SITENAME}}",
-       "tooltip-search-go": "Gå till sidan med detta namn om den finns",
+       "tooltip-search-go": "Gå till sidan med exakt detta namn om den finns",
        "tooltip-search-fulltext": "Sök efter sidor som innehåller denna text",
        "tooltip-p-logo": "Besök huvudsidan",
        "tooltip-n-mainpage": "Besök huvudsidan",
        "filedelete-archive-read-only": "Webbservern kan inte skriva till arkivkatalogen \"$1\".",
        "previousdiff": "← Äldre redigering",
        "nextdiff": "Nyare redigering →",
-       "mediawarning": "'''Varning''': Den här filen kan innehålla elak kod.\nOm du kör den kan din dator skadas.",
+       "mediawarning": "'''Varning''': Den här filen kan innehålla skadlig kod.\nOm du kör den kan din dator skadas.",
        "imagemaxsize": "Begränsa bilders storlek:<br />''(för filbeskrivningssidor)''",
        "thumbsize": "Storlek på minibild:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|sida|sidor}}",
index c227d45..e5ddf98 100644 (file)
        "sig_tip": "ลายเซ็นของคุณพร้อมตราเวลา",
        "hr_tip": "เส้นนอน (ใช้อย่างจำกัด)",
        "summary": "คำอธิบายอย่างย่อ:",
-       "subject": "เรื่อง/พาดหัว:",
+       "subject": "เรื่อง:",
        "minoredit": "เป็นการแก้ไขเล็กน้อย",
        "watchthis": "เฝ้าดูหน้านี้",
        "savearticle": "บันทึกหน้า",
        "missingsummary": "<strong>อย่าลืม:</strong> คุณยังไม่ได้ให้คำอธิบายการแก้ไข \nถ้าคุณคลิก \"{{int:savearticle}}\" อีก จะบันทึกการแก้ไขของคุณโดยไม่มีคำอธิบายการแก้ไข",
        "selfredirect": "<strong>คำเตือน:</strong> คุณกำลังสร้างการเปลี่ยนทางไปบทความเดียวกัน\nคุณอาจระบุเป้าหมายของการเปลี่ยนทางผิด หรือคถณอาจแก้ไขหน้าผิด \nหากคุณคลิก \"{{int:savearticle}}\" อีกครั้ง จะสร้างการเปลี่ยนทาง",
        "missingcommenttext": "กรุณากรอกความเห็นด้านล่าง",
-       "missingcommentheader": "<strong>อยà¹\88าลืม:</strong> à¸\84ุà¸\93ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¹\83สà¹\88หัวà¸\82à¹\89อ/à¸\9eาà¸\94หัวสำหรัà¸\9aà¸\84วามà¹\80หà¹\87à¸\99à¸\99ีà¹\89 \nà¸\96à¹\89าà¸\84ุà¸\93à¸\84ลิà¸\81 \"{{int:savearticle}}\" à¸­à¸µà¸\81 à¸\88ะà¸\9aัà¸\99à¸\97ึà¸\81à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93à¹\82à¸\94ยà¹\84มà¹\88มีหัวà¸\82à¹\89อ/à¸\9eาà¸\94หัว",
+       "missingcommentheader": "<strong>อยà¹\88าลืม:</strong> à¸\84ุà¸\93ยัà¸\87à¹\84มà¹\88à¹\84à¸\94à¹\89à¹\83สà¹\88à¹\80รืà¹\88อà¸\87สำหรัà¸\9aà¸\84วามà¹\80หà¹\87à¸\99à¸\99ีà¹\89 \nà¸\96à¹\89าà¸\84ุà¸\93à¸\84ลิà¸\81 \"{{int:savearticle}}\" à¸­à¸µà¸\81 à¸\88ะà¸\9aัà¸\99à¸\97ึà¸\81à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\84ุà¸\93à¹\82à¸\94ยà¹\84มà¹\88ระà¸\9aุà¹\80รืà¹\88อà¸\87",
        "summary-preview": "ตัวอย่างคำอธิบาย:",
-       "subject-preview": "ตัวอย่างเรื่อง/พาดหัว:",
+       "subject-preview": "ตัวอย่างเรื่อง:",
        "previewerrortext": "เกิดข้อผิดพลาดขณะกำลังพยายามดูตัวอย่างการเปลี่ยนแปลงของคุณ",
        "blockedtitle": "ผู้ใช้ถูกบล็อก",
        "blockedtext": "<strong>ชื่อผู้ใช้หรือเลขที่อยู่ไอพีของคุณถูกบล็อก</strong>\n\nการบล็อกนี้ดำเนินการโดย $1\nซึ่งให้เหตุผลว่า ''$2''\n\n* เริ่มการบล็อก: $8\n* หมดเขตการบล็อก: $6\n* ผู้ถูกบล็อกที่เจตนา: $7\n\nคุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่ออภิปรายการบล็อกนี้ได้\nคุณไม่สามารถใช้คุณลักษณะ \"ส่งอีเมลหาผู้ใช้รายนี้ได้\" จนกว่าจะระบุที่อยู่อีเมลให้ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกห้ามใช้ความสามารถนี้\nเลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 \nโปรดแสดงรายละเอียดข้างต้นทั้งหมดในการสอบถามใด ๆ",
        "prefs-help-recentchangescount": "นี่รวมถึงการปรับปรุงล่าสุด ประวิติหน้า และปูม",
        "prefs-help-watchlist-token2": "นี่คือแป้นลับสำหรับเข้าการป้อนเว็บรายการเฝ้าดูของคุณ\nใครก็ตามที่ทราบจะสามารถอ่านรายการเฝ้าดูของคุณได้ ฉะนั้นอย่าบอกผู้อื่น\n[[Special:ResetTokens|คลิกที่นี่หากคุณต้องการตั้งใหม่]]",
        "savedprefs": "บันทึกการตั้งค่าของคุณแล้ว",
+       "savedrights": "บันทึกสิทธิผู้ใช้ของ {{GENDER:$1|$1}} แล้ว",
        "timezonelegend": "เขตเวลา:",
        "localtime": "เวลาท้องถิ่น:",
        "timezoneuseserverdefault": "ใช้ค่าโดยปริยายของวิกิ ($1)",
        "emailccsubject": "คัดลอกสารของคุณไป $1: $2",
        "emailsent": "ส่งอีเมลแล้ว",
        "emailsenttext": "ส่งสารอีเมลของคุณแล้ว",
-       "emailuserfooter": "$1 à¸ªà¹\88à¸\87อีà¹\80มลà¸\96ึà¸\87 $2 à¸\94à¹\89วยà¸\9fัà¸\87à¸\81à¹\8cà¸\8aัà¸\99 \"อีà¹\80มลà¸\9cูà¹\89à¹\83à¸\8aà¹\89รายà¸\99ีà¹\89\" ที่ {{SITENAME}}",
+       "emailuserfooter": "$1 à¸ªà¹\88à¸\87อีà¹\80มลà¸\99ีà¹\89à¸\96ึà¸\87 $2 à¹\82à¸\94ยà¸\9fัà¸\87à¸\81à¹\8cà¸\8aัà¸\99 \"{{int:emailuser}}\" ที่ {{SITENAME}}",
        "usermessage-summary": "ฝากสารระบบ",
        "usermessage-editor": "ตัวส่งสารของระบบ",
        "watchlist": "รายการเฝ้าดู",
        "wlnote": "ด้านล่างเป็น{{PLURAL:$1|การเปลี่ยนแปลงหลังสุด| <strong>$1</strong> การเปลี่ยนแปลงหลังสุด}} ใน{{PLURAL:$2|ชั่วโมง| <strong>$2</strong> ชั่วโมง}}ที่หลังสุด จนถึง $3, $4",
        "wlshowlast": "แสดง $1 ชั่วโมง $2 วันล่าสุด",
        "watchlistall2": "ทั้งหมด",
+       "watchlist-hide": "ซ่อน",
+       "wlshowtime": "แสดงล่าสุด:",
+       "wlshowhideminor": "การแก้ไขเล็กน้อย",
+       "wlshowhidebots": "บอต",
+       "wlshowhideliu": "ผู้ใช้ลงทะเบียน",
+       "wlshowhideanons": "ผู้ใช้นิรนาม",
+       "wlshowhidepatr": "การแก้ไขที่ตรวจสอบแล้ว",
+       "wlshowhidemine": "การแก้ไขของฉัน",
        "watchlist-options": "ตัวเลือกรายการเฝ้าดู",
        "watching": "กำลังเฝ้าดู...",
        "unwatching": "กำลังเลิกเฝ้าดู...",
        "deletepage": "ลบหน้า",
        "confirm": "ยืนยัน",
        "excontent": "เนื้อหาเดิม: \"$1\"",
-       "excontentauthor": "เนื้อหาเดิม: \"$1\" (และมีผู้เขียนคนเดียวคือ \"[[Special:Contributions/$2|$2]]\")",
+       "excontentauthor": "เนื้อหาเดิม: \"$1\" และมีผู้เขียนคนเดียวคือ \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|พูดคุย]])",
        "exbeforeblank": "เนื้อหาก่อนถูกทำว่างคือ: \"$1\"",
        "delete-confirm": "ลบ \"$1\"",
        "delete-legend": "ลบ",
        "undeletepagetext": "{{PLURAL:$1||$1 }}หน้าต่อไปนี้ถูกลบแล้ว แต่เนื้อหายังคงอยู่ในหน่วยเก็บถาวรและสามารถกู้คืนได้ \nหน่วยเก็บถาวรอาจถูกลบเป็นระยะ",
        "undelete-fieldset-title": "กู้คืนรุ่นปรับปรุง",
        "undeleteextrahelp": "ในการกู้ประวัติของหน้าคืนทั้งหมด ให้เว้นทุกกล่องและคลิก <strong><em>{{int:undeletebtn}}</em></strong>\nถ้าต้องการกู้ประวัติคืนเฉพาะบางส่วน ให้เลือกกล่องที่มีประวัติส่วนที่ต้องการและคลิก <strong><em>{{int:undeletebtn}}</em></strong>",
-       "undeleterevisions": "$1 à¸£à¸¸à¹\88à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\96ูà¸\81à¹\80à¸\81à¹\87à¸\9aà¸\96าวร",
+       "undeleterevisions": "$1 à¸£à¸¸à¹\88à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\96ูà¸\81ลà¸\9a",
        "undeletehistory": "เมื่อคุณกู้หน้าคืน รุ่นทั้งหมดจะถูกกู้คืนไปยังประวัติ \nหากมีการสร้างหน้าใหม่ชื่อเดียวกันหลังการลบ รุ่นที่กู้คืนนั้นจะปรากฏในประวัติก่อนหน้า",
        "undeleterevdel": "จะไม่ดำเนินการกู้คืนหากส่งผลให้รุ่นบนสุดของหน้าหรือไฟล์ถูกลบบางส่วน\nในกรณีเช่นนั้น คุณต้องไม่เลือกหรือแสดงรุ่นที่ถูกลบใหม่สุด",
        "undeletehistorynoadmin": "หน้านี้ถูกลบแล้ว\nสาเหตุการลบแสดงในความย่อด้านล่าง ร่วมกับรายละเอียดผู้ใช้ที่เคยแก้ไขหน้านี้ก่อนลบ\nเฉพาะผู้ดูแลระบบที่ดูข้อความแท้จริงของรุ่นที่ถูกลบเหล่านี้ได้",
        "movenosubpage": "หน้านี้ไม่มีหน้าย่อย",
        "movereason": "เหตุผล:",
        "revertmove": "ย้อน",
-       "delete_and_move": "ลบและย้าย",
        "delete_and_move_text": "== ต้องการลบ ==\nมีหน้าปลายทาง \"[[:$1]]\" แล้ว \nคุณต้องการลบหน้าดังกล่าวเพื่อสร้างหนทางสำหรับการย้ายหรือไม่",
        "delete_and_move_confirm": "ใช่ ลบหน้านั้น",
        "delete_and_move_reason": "ถูกลบเพื่อสร้างหนทางสำหรับการย้ายจาก \"[[$1]]\"",
index 31f9d7b..9a2bdb3 100644 (file)
        "wrongpassword": "Mali ang ipinasok na password.\nPakisubok muli.",
        "wrongpasswordempty": "Walang laman ang ipinasok na password.\nPakisubok muli.",
        "passwordtooshort": "Ang mga password ay dapat mayroong {{PLURAL:$1|1 panitik|$1 panitik}} (karakter).",
+       "passwordtoopopular": "Hindi maaaring gamitin ang mga hudyat (''password'') na pangkaraniwang pinipili. Mangyaring pumili ng higit na natatanging hudyat.",
        "password-name-match": "Dapat magkaiba ang password mo sa bansag o username mo.",
        "password-login-forbidden": "Ipinagbabawal ang paggamit ng ganitong pangalan ng tagagamit at password.",
        "mailmypassword": "Baguhin ang password",
        "passwordreset-emailtext-ip": "Isang tao (marahil ay ikaw, mula sa IP address na $1) ang humiling ng isang paalala sa iyong mga detalye ng account para sa {{SITENAME}} ($4). Ang sumusunod na {{PLURAL:$3|account ng tagagamit ay|mga account ng tagagamit ay}} may kaugnayan sa email address na ito:\n\n$2\n\n{{PLURAL:$3|Ang pansamantalang password na ito|Ang mga pansamantalang password na ito}} ay mawawalan ng bisa sa loob ng {{PLURAL:$5|isang araw|$5 araw}}.\nDapat kang mag-login at pumili ng isang bagong password ngayon. Kung ibang tao ang gumawa ng kahilingang ito, o kung naalala mo na ang orihinal mong password, at hindi mo na nais palitan ito, maaari mong huwag nang pansinin ang mensaheng ito at magpatuloy sa paggamit ng luma mong password.",
        "passwordreset-emailtext-user": "Ang tagagamit na si $1 sa {{SITENAME}} ay humiling ng isang paalala ng iyong mga akawnt ng detalye para sa {{SITENAME}}\n($4). Ang sumusunod na pangtagagamit na {{PLURAL:$3|akawnt ay|mga akawnt ay}} may kaugnayan sa tirahang ito ng e-liham:\n\n$2\n\n{{PLURAL:$3|Ang pansamantalang hudyat na ito|Ang pansamantalang mga hudyat na ito}} mawawalan ng bias sa loob ng {{PLURAL:$5|isang araw|$5 mga araw}}.\nDapat kang lumagda at pumili ng isang hudyat ngayon. Kung ibang tao ang gumawa ng kahilingang ito, o kung naalala mo na ang iyong orihinal na hudyat, at hindi mo na nais palitan pa ito, maaari mong huwag nang pansinin ang mensaheng ito at magpatuloy sa paggamit ng iyong lumang hudyat.",
        "passwordreset-emailelement": "Pangalan ng tagagamit: \n$1\n\nPansamantalang password: \n$2",
-       "passwordreset-emailsent": "Naipadala na ang isang e-liham na pampaalala.",
+       "passwordreset-emailsentemail": "Naipadala na ang isang e-liham na pampaalala.",
        "passwordreset-emailsent-capture": "Naipadala na ang isang e-liham na paalala, na ipinapakita sa ibaba.",
        "passwordreset-emailerror-capture": "Nalikha na ang isang e-liham na paalala, na ipinapakita sa ibaba, subalit nabigo ang pagpapadala sa tagagamit: $1",
        "changeemail": "Baguhin ang direksiyong e-liham",
        "wlshowlast": "Ipakita ang huling $1 mga oras $2 mga araw",
        "watchlistall2": "lahat",
        "watchlist-hide": "Itago",
+       "wlshowhideminor": "mga maliliit na edit",
+       "wlshowhidebots": "mga bot",
        "wlshowhideliu": "mga nakarehistrong tagagamit",
+       "wlshowhideanons": "Mga di-nagpakilalang tagagamit",
+       "wlshowhidepatr": "mga binabantayang edit",
+       "wlshowhidemine": "mga edit ko",
        "watchlist-options": "Mga pagpipilian para sa talaan ng mga binabantayan",
        "watching": "Isinasama sa mga binabantayan...",
        "unwatching": "Tinatanggal mula sa mga binabantayan...",
        "movenosubpage": "Ang pahinang ito ay walang kabahaging mga pahina.",
        "movereason": "Dahilan:",
        "revertmove": "ibalik",
-       "delete_and_move": "Burahin at ilipat",
        "delete_and_move_text": "==Kinakailangan ang pagbura==\n\nMayroon na ang pupuntahang artikulo na \"[[$1]]\". Nais mo bang burahin ito para magbigay daan para sa paglipat?",
        "delete_and_move_confirm": "Oo, burahin ang pahina",
        "delete_and_move_reason": "Binura upang makapagbigay ng daan para sa paglipat mula sa \"[[$1]]\"",
index 7e30471..b1cb62f 100644 (file)
        "tog-watchlisthidebots": "İzleme listemde bot değişikliklerini gizle",
        "tog-watchlisthideminor": "İzleme listemde küçük değişiklikleri gizle",
        "tog-watchlisthideliu": "İzleme listemde, kayıtlı kullanıcılar tarafından yapılan değişiklikleri gizle",
+       "tog-watchlistreloadautomatically": "Filtre değiştiğinde otomatik izleme (JavaScript gerekir)yeniden",
        "tog-watchlisthideanons": "İzleme listemde, anonim kullanıcılar tarafından yapılan değişiklikleri gizle",
        "tog-watchlisthidepatrolled": "İzleme listesinde, devriye görmüş değişiklikleri gizle",
        "tog-watchlisthidecategorization": "Sayfa kategorilendirmesni gizle",
        "morenotlisted": "Bu liste tam değildir.",
        "mypage": "Sayfa",
        "mytalk": "Mesaj",
-       "anontalk": "Bu IP'nin iletileri",
+       "anontalk": "Mesaj",
        "navigation": "Gezinti",
        "and": "&#32;ve",
        "qbfind": "Bul",
        "wrongpasswordempty": "Boş parola girdiniz. Lütfen tekrar deneyiniz.",
        "passwordtooshort": "Parolalar en az {{PLURAL:$1|1 karakter|$1 karakter}} uzunluğunda olmalı.",
        "passwordtoolong": "Parolalar en az {{PLURAL:$1|1 karakter|$1 karakter}} uzunluğunda olmalı.",
+       "passwordtoopopular": "Sıklıkla seçilen parolalar kullanılamaz. Lütfen daha özgün bir parola belirleyin.",
        "password-name-match": "Şifreniz kullanıcı adınızdan farklı olmalıdır.",
        "password-login-forbidden": "Bu kullanıcı adı ve şifre kullanımı yasaklanmıştır",
        "mailmypassword": "Parolayı sıfırla",
        "passwordreset-emailtext-ip": "Birisi, (muhtemelen siz, $1 IP adresinden) {{SITENAME}} ($4) için hesap bilgilerinizin \nhatırlatılmasını istedi. Aşağıdaki kullanıcı {{PLURAL:$3|hesabı|hesapları}} bu e-posta adresiyle ilişkili:\n\n$2\n\n{{PLURAL:$3|Bu geçici şifre|Bu geçici şifreler}} {{PLURAL:$5|bir gün|$5  gün}} geçerlidir.\nBu geçici parola ile giriş yapın ve yeni bir şifre seçin. Şifre değişimini siz istemediyseniz veya şifrenizi hatırladıysanız ve artık şifrenizi değiştirmek istemiyorsanız; bu iletiyi önemsemeyerek eski şifrenizi kullanmaya devam edebilirsiniz.",
        "passwordreset-emailtext-user": "$1 adlı kullanıcı, {{SITENAME}} ($4) için hesap bilgilerinizin hatırlatılmasını istedi. Aşağıdaki kullanıcı {{PLURAL:$3|hesabı|hesapları}} bu e-posta adresiyle ilişkili:\n\n$2\n\n{{PLURAL:$3|Bu geçici şifre|Bu geçici şifreler}} {{PLURAL:$5|bir gün|$5  gün}} geçerlidir.\nBu geçici parola ile giriş yapın ve yeni bir şifre seçin. Bu talep bir başkasına aitse veya şifrenizi hatırladıysanız ve artık şifrenizi değiştirmek istemiyorsanız; bu iletiyi önemsemeyerek eski şifrenizi kullanmaya devam edebilirsiniz.",
        "passwordreset-emailelement": "Kullanıcı adı: \n$1\n\nGeçici şifre: \n$2",
-       "passwordreset-emailsent": "Eğer bu hesabınız için kayıtlı bir e-posta adresi ise, bir parola sıfırlama e-postası gönderilecektir.",
+       "passwordreset-emailsentemail": "Eğer bu hesabınız için kayıtlı bir e-posta adresi ise, bir parola sıfırlama e-postası gönderilecektir.",
        "passwordreset-emailsent-capture": "Aşağıda gözüktüğü gibi bir parola sıfırlama e-postası gönderildi.",
        "passwordreset-emailerror-capture": "Aşağıda gözüktüğü gibi bir parola sıfırlama e-postası oluşturuldu ancak {{GENDER:$2|kullanıcıya}} gönderme işlemi başarısız oldu: $1",
        "changeemail": "E-posta adresini değiştir veya çıkar",
        "wlshowlast": "Son $1 saati $2 günü göster",
        "watchlistall2": "Hepsini göster",
        "watchlist-hide": "Gizle",
+       "wlshowhideminor": "küçük değişiklikler",
        "wlshowhidebots": "botlar",
        "wlshowhideliu": "kayıtlı kullanıcılar",
        "wlshowhideanons": "anonim kullanıcılar",
        "contributions": "{{GENDER:$1|Kullanıcı}} katkıları",
        "contributions-title": "$1 için kullanıcı katkıları",
        "mycontris": "Katkılar",
+       "anoncontribs": "Katkılar",
        "contribsub2": "{{GENDER:$3|$1}} ($2) tarafından",
        "contributions-userdoesnotexist": "\"$1\" kullanıcı hesabı kayıtlı değil.",
        "nocontribs": "Bu kriterlere uyan değişiklik bulunamadı",
        "movenosubpage": "Bu sayfanın altsayfası yoktur.",
        "movereason": "Neden:",
        "revertmove": "geri al",
-       "delete_and_move": "Sil ve taşı",
        "delete_and_move_text": "==Silinmesi gerekiyor==\n\n\"[[:$1]]\" isimli bir sayfa zaten mevcut. O sayfayı silerek, isim değişikliğini gerçekleştirmeye devam etmek istiyor musunuz?",
        "delete_and_move_confirm": "Evet, sayfayı sil",
        "delete_and_move_reason": "[[$1]] sayfasının isim değişikliğinin gerçekleşmesi için silindi.",
        "tooltip-pt-preferences": "Tercihleriniz (ayarlarınız)",
        "tooltip-pt-watchlist": "Değişiklikler için izlemeye aldığınız sayfaların listesi",
        "tooltip-pt-mycontris": "Katkılarınızın listesi",
+       "tooltip-pt-anoncontribs": "Bu IP adresinden yapılmış değişiklikler listesi",
        "tooltip-pt-login": "Oturum açmanız tavsiye edilmektedir; ancak bu zorunda değildir",
        "tooltip-pt-logout": "Sistemden çık",
        "tooltip-pt-createaccount": "Bir hesap oluşturup oturum açmanız tavsiye edilmektedir ancak bu zorunlu değildir",
index ff64e31..c0eaef3 100644 (file)
        "morenotlisted": "Исемлек тулы түгел.",
        "mypage": "Бит",
        "mytalk": "Бәхәс бите",
-       "anontalk": "Бу IP адресы өчен бәхәс бите",
+       "anontalk": "Бәхәс",
        "navigation": "Навигация",
        "and": "&#32;һәм",
        "qbfind": "Эзләү",
        "sort-descending": "Кимү буенча урнаштыру",
        "sort-ascending": "Арту буенча урнаштыру",
        "nstab-main": "Бит",
-       "nstab-user": "Кулланучы бите",
+       "nstab-user": "Кулланучы",
        "nstab-media": "Мультимедиа",
        "nstab-special": "Махсус бит",
        "nstab-project": "Проект бите",
        "createacct-emailrequired": "Электрон почта юлламагыз",
        "createacct-emailoptional": "Электрон почта юлламагыз (мәҗбүри түгел)",
        "createacct-email-ph": "Электрон почта юлламагызны языгыз",
+       "createacct-another-email-ph": "Электрон почта юлламагызны кертегез",
        "createaccountmail": "электрон почта аша",
+       "createacct-realname": "Чын исем (мәҗбүри түгел)",
        "createaccountreason": "Сәбәп:",
+       "createacct-reason": "Сәбәп",
+       "createacct-reason-ph": "Нигә сез яңа зисап язмасы төзисез",
        "createacct-submit": "Хисап язмасы төзү",
+       "createacct-another-submit": "Хисап язмасын төзү",
        "createacct-benefit-heading": "{{SITENAME}} — сезнең шикелле кешеләрнең хезмәте.",
        "createacct-benefit-body1": "{{PLURAL:$1|төзәтмә}}",
        "createacct-benefit-body2": "{{PLURAL:$1|мәкалә}}",
        "passwordreset-emailtext-ip": "Кемдер (бәлки, сездер, $1 IP-адресыннан) {{SITENAME}} ($4) проектында сезнең серсүзне искә төшерүне сорады.\n{{PLURAL:$3|1=Түбәндәге хисап язмасы|Түбәндәге хисап язмалары}} бу электрон әрҗә адресы белән бәйле:\n\n$2\n\n{{PLURAL:$3|1=Бу вакытлы серсүз|Бу вакытлы серсүзләр}} {{PLURAL:$5|$5 көн}} дәвамында эшлиячәкләр.\nСез системага керергә һәм яңа серсүз сайларга тиешсез.\nӘгәр сез серсүз сорамаган булсагыз яки элеккеге серсүзегезне искә төшерсәгез \nһәм аны үзгәртергә теләмәсәгез, бу хатка җавап бирмәгез\nһәм элеккеге серсүзегезне кулланыгыз.",
        "passwordreset-emailtext-user": "{{SITENAME}} проектыннан $1 кулланучысы {{SITENAME}} ($4) проектында сезнең серсүзне искә төшерүне сорады.\n{{PLURAL:$3|1=Түбәндәге хисап язмасы|Түбәндәге хисап язмалары}} бу электрон әрҗә адресы белән бәйле:\n\n$2\n\n{{PLURAL:$3|1=Бу вакытлы серсүз|Бу вакытлы серсүзләр}} {{PLURAL:$5|$5 көн}} дәвамында эшлиячәкләр.\nСез системага керергә һәм яңа серсүз сайларга тиешсез.\nӘгәр сез серсүз сорамаган булсагыз яки элеккеге серсүзегезне искә төшерсәгез \nһәм аны үзгәртергә теләмәсәгез, бу хатка җавап бирмәгез\nһәм элеккеге серсүзегезне кулланыгыз.",
        "passwordreset-emailelement": "Кулланучы исеме: \n$1\n\nВакытлыча серсүз: \n$2",
-       "passwordreset-emailsent": "Электрон әрҗәгә искәртү җибәрелгән иде",
+       "passwordreset-emailsentemail": "Электрон әрҗәгә искәртү җибәрелгән иде",
        "passwordreset-emailsent-capture": "Җибәрелгән хат-искәртү түбәндә китерелә",
        "passwordreset-emailerror-capture": "Түбәндә язылган хат-искәртү китерелгән, аны җибәрмәүнең сәбәбе:$1",
-       "changeemail": "Электрон әрҗә адресын үзгәртү",
+       "changeemail": "Электрон әрҗә адресын үзгәртү яисә бетерү",
        "changeemail-header": "Электрон әрҗә адресын үзгәртү",
        "changeemail-no-info": "Бу сәхифәгә турыдан-туры мөрәҗәгать итәр өчен, сез системага керергә тиешсез",
        "changeemail-oldemail": "Хәзерге электрон әрҗә адресы:",
        "edit-already-exists": "Яңа бит төзеп булмый.\nУл инде бар.",
        "editwarning-warning": "Башка биткә күчү вакытында бу мәкаләгә керткән үзгәрешләр югалырга мөмкин.\nӘгәрдә сез теркәлгән булсагыз, бу искәрмәне сез «Көйләнмәләрем» өлешендә үзгәртә аласыз.",
        "duplicate-args-category": "Калыпны чакыруда кабатлап торган аргументларны кулланган битләр",
-       "expensive-parserfunction-warning": "'''Игътибар:''' бу биттә хәтерне еш кулланучы функцияләр артык күп.\n\nЧикләү: $2 {{PLURAL:$2|1=куллану}}, бу очракта {{PLURAL:$1|$1 тапкыр}} башкарырга рөхсәт ителә.",
+       "expensive-parserfunction-warning": "<strong>Игътибар:</strong>  бу биттә хәтерне еш кулланучы функцияләр артык күп.\n\nБиттә {{PLURAL:$2|$2 эш куллану}} рөхсәт ителгән очракта, монда $1 {{PLURAL:$1|эш башкарыла}}.",
        "expensive-parserfunction-category": "Хәтерне еш кулланучы функцияләр күп булган битләр",
        "post-expand-template-inclusion-warning": "'''Игътибар:''' Кулланылучы үрнәкләр артык зур.\nКайберләре кабызылмаячак.",
        "post-expand-template-inclusion-category": "Рөхсәт ителгән күләмнән артык булган үрнәкле битләр",
        "rcshowhideminor-show": "күрсәт",
        "rcshowhideminor-hide": "яшер",
        "rcshowhidebots": "ботларны $1",
-       "rcshowhidebots-show": "күрсәт",
+       "rcshowhidebots-show": "Ð\9aүрсәт",
        "rcshowhidebots-hide": "яшер",
        "rcshowhideliu": "теркәлгән кулланучыларны $1",
        "rcshowhideliu-show": "күрсәт",
        "nolicense": "Юк",
        "license-nopreview": "(Алдан карау мөмкин түгел)",
        "upload_source_file": "(сезнең санакта сайланган файл)",
+       "listfiles-summary": "Әлеге махсус бит Сез йөкләгән бөтен файлларны күрсәтә.",
        "imgfile": "файл",
        "listfiles": "Сүрәтләр исемлеге",
        "listfiles_thumb": "Миниатюра",
        "contributions": "{{GENDER:$1|Кулланучының}} кертеме",
        "contributions-title": "$1 исемле кулланучының кертеме",
        "mycontris": "Кертем",
+       "anoncontribs": "Кертем",
        "contribsub2": "Кертем {{GENDER:$3|$1}} ($2)",
        "uctop": "(хәзерге)",
        "month": "Айдан башлап (һәм элегрәк):",
        "movelogpage": "Күчерү көндәлеге",
        "movereason": "Сәбәп:",
        "revertmove": "кире кайту",
-       "delete_and_move": "Бетерү һәм исемен алмаштыру",
        "delete_and_move_reason": "Күчерүне мөмкин итәр өчен бетерелде «[[$1]]»",
        "move-leave-redirect": "Юнәлтү калдырылсын",
        "export": "Битләрне чыгаруы",
        "newimages-legend": "Фильтр",
        "ilsubmit": "Эзләү",
        "hours": "{{PLURAL:$1|$1 cәгать|$1 cәгать}}",
+       "ago": "$1 элек",
        "hours-ago": "$1 cәгать элек",
        "minutes-ago": "$1 минут элек",
        "bad_image_list": "Киләчәк рәвеш кирәк:\n\nИсемлек кисәкләре генә (* символыннан башланучы юллар) саналырлар.\nЮлның беренче сылтамасы куйма өчен тыелган рәсемгә сылтама булырга тиеш.\nШул ук юлның киләчәк сылтамалары чыгармалар, рәсемгә тыелмаган битләре, саналырлар.",
        "api-error-unknownerror": "Билгесез хата: \"$1\".",
        "api-error-uploaddisabled": "Бу викидә файллар йөкләү мөмкинлеге сүндерелгән.",
        "api-error-verification-error": "Бәлки, бу файл бозылгандыр яки дөрес түгел киңәйтелмәгә ия.",
+       "duration-minutes": "$1 {{PLURAL:$1|минут}}",
+       "duration-hours": "$1 {{PLURAL:$1|сәгать}}",
+       "duration-days": "$1 {{PLURAL:$1|көн}}",
        "expandtemplates": "Үрнәкләрне ачу",
        "expand_templates_ok": "OK",
        "special-characters-group-latin": "Латин",
index dfa7a1f..05fd3b7 100644 (file)
        "movelogpage": "Küçerü köndälege",
        "movereason": "Säbäp:",
        "revertmove": "kire qaytu",
-       "delete_and_move": "Beterü häm isemen almaştıru",
        "delete_and_move_reason": "Küçerüne mömkin itär öçen beterelde",
        "move-leave-redirect": "Yünältü qaldırılsın",
        "export": "Bitlärne çığaruı",
index 4c0b29d..745a727 100644 (file)
@@ -98,6 +98,7 @@
        "tog-watchlisthidebots": "Приховати редагування ботів у списку спостереження",
        "tog-watchlisthideminor": "Приховати незначні редагування у списку спостереження",
        "tog-watchlisthideliu": "Приховати редагування зареєстрованих дописувачів у списку спостереження",
+       "tog-watchlistreloadautomatically": "Перезавантажувати список спостереження автоматично кожного разу, коли зміниться фільтр (вимагається JavaScript)",
        "tog-watchlisthideanons": "Приховати редагування анонімних користувачів у списку спостереження",
        "tog-watchlisthidepatrolled": "Приховати відпатрульовані редагування у списку спостереження",
        "tog-watchlisthidecategorization": "Приховати категоризацію сторінок",
        "morenotlisted": "Цей список неповний.",
        "mypage": "Сторінка",
        "mytalk": "Обговорення",
-       "anontalk": "Обговорення для цієї IP-адреси",
+       "anontalk": "Обговорення",
        "navigation": "Навігація",
        "and": "&#32;і",
        "qbfind": "Знайти",
        "databaseerror-query": "Запит: $1",
        "databaseerror-function": "Функція: $1",
        "databaseerror-error": "Помилка: $1",
+       "transaction-duration-limit-exceeded": "Для того, щоб уникнути лагу при реплікації, ця транзакція була перервана, оскільки тривалість запису ($1) перевищила лімів в $2 сек.\nЯкщо ви змінюєте декілька елементів за один раз, постарайтесь замість цього зробити декілька невеликих операцій.",
        "laggedslavemode": "Увага: сторінка може не містити останніх редагувань.",
        "readonly": "Запис до бази даних заблокований",
        "enterlockreason": "Зазначте причину і приблизний термін блокування",
        "wrongpasswordempty": "Ви не ввели пароль. Будь ласка, спробуйте ще раз.",
        "passwordtooshort": "Ваш пароль закороткий, він має містити принаймні $1 {{PLURAL:$1|символ|символи|символів}}.",
        "passwordtoolong": "Пароль не може бути довшим ніж {{PLURAL:$1|1 символ|$1 символи|$1 символів}}.",
+       "passwordtoopopular": "Паролі, що часто обираються, не можуть бути використані. Будь ласка, оберіть більш унікальний пароль.",
        "password-name-match": "Ваш пароль має відрізнятися від імені користувача.",
        "password-login-forbidden": "Використання цього імені користувача і пароля заборонено.",
        "mailmypassword": "Перевстановити пароль",
        "passwordreset-emailtext-ip": "Хтось (імовірно ви, з IP-адреси $1) попросив нагадати деталі вашого облікового запису для {{SITENAME}} ($4). З вашою електронною скринькою пов'язан{{PLURAL:$3|1=ий такий запис|і такі записи}}:\n\n$2\n\n{{PLURAL:$3|1=Цей тимчасовий пароль стане недійсним|Ці тимчасові паролі стануть недійсними}} через $5 {{PLURAL:$5|день|дні|днів}}.\nВи маєте ввійти в систему і вибрати новий пароль. Якщо ж цей запит зробив хтось інший або ви згадали свій старий пароль і не бажаєте його змінювати, можете ігнорувати це повідомлення та продовжувати використовувати старий пароль.",
        "passwordreset-emailtext-user": "Користувач $1 з {{SITENAME}} попросив нагадати деталі вашого облікового запису для {{SITENAME}} ($4). З вашою електронною скринькою пов'язан{{PLURAL:$3|1=ий такий запис|і такі записи}}:\n\n$2\n\n{{PLURAL:$3|1=Цей тимчасовий пароль|Ці тимчасові паролі}} стануть нечинні через {{PLURAL:$5|день|$5 дні|$5 днів}}.\nВи маєте ввійти в систему і вибрати новий пароль. Якщо ж цей запит зробив хтось інший, або ви згадали свій старий пароль і не бажаєте його змінювати, можете просто ігнорувати це повідомлення та продовжувати використовувати старий пароль.",
        "passwordreset-emailelement": "Ім'я користувача: \n$1\n\nТимчасовий пароль: \n$2",
-       "passwordreset-emailsent": "Якщо це зареєстрована адреса електронної пошти для вашого облікового запису, то буде надісланий лист для відновлення пароля.",
+       "passwordreset-emailsentemail": "Якщо це зареєстрована адреса електронної пошти для вашого облікового запису, то буде надісланий лист для відновлення пароля.",
        "passwordreset-emailsent-capture": "Електронний лист скидання пароля було надіслано, як показано нижче.",
        "passwordreset-emailerror-capture": "Електронний лист для відновлення пароля мав бути надісланий, як показано нижче, але його надсилання {{GENDER:$2|користувачеві|користувачці}} $1 не вдалося.",
        "changeemail": "Змінити або вилучити адресу електронної пошти",
        "booksources-text": "На цій сторінці наведено список посилань на сайти, де ви, можливо, знайдете додаткову інформацію про книгу. Це інтернет-магазини й системи пошуку в бібліотечних каталогах.",
        "booksources-invalid-isbn": "Вказаний номер ISBN, судячи з усього, містить помилку. Будь ласка, перевірте, що при перенесенні номера з першоджерела не виникло спотворень.",
        "specialloguserlabel": "Виконавець:",
-       "speciallogtitlelabel": "Ціль (назва або {{ns:user}}:ім'я для користувача):",
+       "speciallogtitlelabel": "Ціль (назва сторінки або {{ns:user}}:ім'я користувача):",
        "log": "Журнали",
        "all-logs-page": "Усі публічні журнали",
        "alllogstext": "Комбінований показ журналів {{grammar:genitive|{{SITENAME}}}}.\nВи можете відфільтрувати результати за типом журналу, іменем користувача (враховується регістр) або зазначеною сторінкою (також враховується регістр).",
        "wlshowlast": "Показати зміни за останні $1 годин $2 днів",
        "watchlistall2": "всі",
        "watchlist-hide": "Приховати",
-       "wlshowtime": "Ð\9fоказаÑ\82и Ð¾Ñ\81Ñ\82аннÑ\96:",
+       "wlshowtime": "Ð\9fеÑ\80Ñ\96од Ñ\87аÑ\81Ñ\83 Ð´Ð»Ñ\8f Ð²Ñ\96добÑ\80аженнÑ\8f:",
        "wlshowhideminor": "незначні редагування",
        "wlshowhidebots": "ботів",
        "wlshowhideliu": "зареєстрованих користувачів",
        "contributions": "Внесок {{GENDER:$1|користувача|користувачки}}",
        "contributions-title": "Внесок користувача $1",
        "mycontris": "Внесок",
+       "anoncontribs": "Внесок",
        "contribsub2": "Для {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Обліковий запис користувача  «$1» не зареєстровано.",
        "nocontribs": "Редагувань, що задовольняють заданим умовам не знайдено.",
        "movenosubpage": "Ця сторінка не має підсторінок.",
        "movereason": "Причина:",
        "revertmove": "відкинути",
-       "delete_and_move": "Вилучити і перейменувати",
        "delete_and_move_text": "== Потрібне вилучення ==\nСторінка з назвою [[:$1|«$1»]] вже існує.\nБажаєте вилучити її для можливості перейменування?",
        "delete_and_move_confirm": "Так, вилучити для перейменування",
        "delete_and_move_reason": "Вилучена для можливості перейменування сторінки «[[$1]]»",
        "tooltip-pt-preferences": "Ваші налаштування",
        "tooltip-pt-watchlist": "Список сторінок, за змінами в яких Ви спостерігаєте",
        "tooltip-pt-mycontris": "Ваш внесок",
+       "tooltip-pt-anoncontribs": "Список редагувань, зроблених з цієї IP-адреси",
        "tooltip-pt-login": "Тут можна зареєструватися в системі, але це не обов'язково.",
        "tooltip-pt-logout": "Вихід із системи",
        "tooltip-pt-createaccount": "Пропонуємо створити обліковий запис і увійти в систему; однак, це не обов'язково",
        "logentry-suppress-block": "$1 {{GENDER:$2|заблокував}} {{GENDER:$4|$3}} строком на $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|змінив}} блокування для {{GENDER:$4|$3}} на період $5 $6",
        "logentry-import-upload": "$1 імпортува{{GENDER:$2|в|ла}} $3 через завантаження файлів",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|імпортував|імпортувала}} $3 за допомогою файлового завантаження ($4 {{PLURAL:$4|версія|версій|версії}})",
        "logentry-import-interwiki": "$1 імпортува{{GENDER:$2|в|ла}} $3 з іншої вікі",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|імпортував|імпортувала}} $3 з $5 ($4 {{PLURAL:$4|версія|версій|версії}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|приєднав|приєднала}} $3 до $4 (версії до $5)",
        "logentry-move-move": "$1 {{GENDER:$2|перейменував|перейменувала}} сторінку з $3 на $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|перейменував|перейменувала}} сторінку з $3 на $4 без створення перенаправлення",
index 312fae9..7ad6b90 100644 (file)
@@ -23,7 +23,8 @@
                        "عرفان ارشد",
                        "Obaid Raza",
                        "عثمان خان شاہ",
-                       "Syedalinaqinaqvi"
+                       "Syedalinaqinaqvi",
+                       "محمد افضل"
                ]
        },
        "tog-underline": "ربط کی خط کشیدگی:",
        "disclaimerpage": "Project:عام اعلان",
        "edithelp": "معاونت براۓ ترمیم",
        "helppage-top-gethelp": "مدد",
-       "mainpage": "صÙ\81Ø­Û\82 Ø§Ù\88Ù\84",
-       "mainpage-description": "صفحہ اول",
+       "mainpage": "سرÙ\88رÙ\82",
+       "mainpage-description": "صفحہ اول/سرورق",
        "policy-url": "Project:حکمتِ عملی",
        "portal": "دیوان عام",
        "portal-url": "Project:دیوان عام",
        "userloginnocreate": "داخلِ نوشتہ ہوجائیے",
        "logout": "اخراج",
        "userlogout": "خارج ہوجائیں",
-       "notloggedin": "داخلہ نہیں ہوا",
+       "notloggedin": "داخل نہیں",
        "userlogin-noaccount": "کیا آپ نے کھاتہ نہیں بنایا ہوا؟",
        "userlogin-joinproject": "منسلک ہو {{SITENAME}} سے",
        "nologin": "کیا آپ نے کھاتہ نہیں بنایا ہوا؟ '''$1'''۔",
        "changeemail-newemail": "نیا برقی ڈاک پتہ:",
        "changeemail-none": "(کوئی نہیں)",
        "changeemail-submit": "برقی ڈاک تبدیل کریں",
+       "resettokens-tokens": "ٹوکن:",
+       "resettokens-token-label": "$1 (موجودہ قدر: $2)",
        "bold_sample": "دبیز متن",
        "bold_tip": "دبیز متن",
        "italic_sample": "ترچھا متن",
        "search-result-category-size": "{{PLURAL:$1|1 رُکن|$1 اراکین}} ({{PLURAL:$2|1 ذیلی زمرہ|$2 ذیلی زمرہ جات}}, {{PLURAL:$3|1 ملف|$3 ملفات}})",
        "search-redirect": "(رجوع مکرر $1)",
        "search-section": "(حصہ $1)",
+       "search-category": "(زمرہ $1)",
        "search-suggest": "کیا آپ کا مطلب تھا: $1",
        "search-interwiki-caption": "ساتھی منصوبے",
        "search-interwiki-default": "$1 نتائج:",
        "prefs-advancedrendering": "اعلی اختیارات",
        "prefs-advancedsearchoptions": "اعلی اختیارات",
        "prefs-advancedwatchlist": "اعلی اختیارات",
+       "prefs-tokenwatchlist": "ٹوکن",
        "prefs-diffs": "فروق",
        "userrights": "حقوقِ صارف کی نظامت",
        "userrights-lookup-user": "گروہائے صارف کا انتظام",
        "recentchangeslinked-title": "\"$1\" سے متعلقہ تبدیلیاں",
        "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات متجل (bold) نظر آئیں گےـ",
        "recentchangeslinked-page": "صفحۂ منصوبہ دیکھئے",
-       "upload": "فائل اثقال",
+       "upload": "فائل اثقال/اپلوڈ فائل",
        "uploadbtn": "زبراثقال ملف (اپ لوڈ فائل)",
        "reuploaddesc": "زبراثقال ورقہ (فارم) کیجانب واپس۔",
        "uploadnologin": "آپ داخل شدہ حالت میں نہیں",
        "contributions": "{{GENDER:$1|صارف}} شراکتیں",
        "contributions-title": "مساہماتِ صارف برائے $1",
        "mycontris": "شراکت",
+       "anoncontribs": "شراکتیں",
        "contribsub2": "براۓ $1 ($2)",
        "uctop": " (اوپر)",
        "month": "مہینہ (اور اُس سے قبل):",
        "movelogpage": "نوشتۂ منتقلی",
        "movereason": "وجہ:",
        "revertmove": "رجوع",
-       "delete_and_move": "حذف اور منتقل",
        "delete_and_move_text": "==حذف شدگی لازم==\n\nمنتقلی کے سلسلے میں انتخاب کردہ مضمون \"[[:$1]]\" پہلے ہی موجود ہے۔ کیا آپ اسے حذف کرکے منتقلی کیلیۓ راستہ بنانا چاہتے ہیں؟",
        "delete_and_move_confirm": "ہاں، صفحہ حذف کر دیا جائے",
        "delete_and_move_reason": "[[$1]] سے منتقلی کے سلسلے میں حذف",
        "tooltip-pt-logout": "خارجِ نوشتہ ہوجائیں",
        "tooltip-pt-createaccount": "آپ کو مدعو کیا جاتا ہے کہ کھاتہ بنائیں۔تاہم کھاتہ بنانا لازم نہیں۔",
        "tooltip-ca-talk": "مضمون بارے تبادلۂ خیال",
-       "tooltip-ca-edit": "آپ Ø§Ø³ ØµÙ\81Ø­Û\81 Ù\85Û\8cÚº ØªØ±Ù\85Û\8cÙ\85 Ú©Ø±Ø³Ú©ØªÛ\92 Û\81Û\8cÚº.\nبرائÛ\92 Ù\85Û\81رباÙ\86Û\8c! Ø§Ù¾Ù\86Û\8c ØªØ±Ù\85Û\8cÙ\85ات Ù\85Ø­Ù\81Ù\88ظ Ú©Ø±Ù\86Û\92 Ø³Û\92 Ù¾Û\81Ù\84Û\92 Ù\86Ù\85ائش Ú©Ø§ Ø¨Ù¹Ù\86 Ø§Ø³ØªØ¹Ù\85اÙ\84 Ú©Û\8cجئÛ\92",
+       "tooltip-ca-edit": "اس ØµÙ\81Ø­Û\92 Ù¾Ø± ØªØ±Ù\85Û\8cÙ\85 Ú©Ø±Û\8cÚº",
        "tooltip-ca-addsection": "نیا قطعہ شروع کیجئے",
        "tooltip-ca-viewsource": "یہ ایک محفوظ شدہ صفحہ ہے.\nآپ اِس کا مآخذ دیکھ سکتے ہیں",
        "tooltip-ca-history": "صفحۂ ہٰذا کی سابقہ نظرثانی",
index 278c375..0d8c1b9 100644 (file)
        "protectedpagetext": "Bu sahifa tahrirlash va boshqa oʻzgarishlar kiritishdan himoyalangan.",
        "viewsourcetext": "Siz bu sahifaning manbasini koʻrishingiz va uni nusxasini olishingiz mumkin:",
        "protectedinterface": "Ushbu sahifada dasturiy taʼminot interfeysi xabari mavjud. Bezoriliklardan saqlash uchun uni oʻzgartirish taʼqiqlangan.\nUshbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
-       "editinginterface": "<strong>Eʼtibor bering:</strong> Siz interfeys matnini aks ettiruvchi sahifani tahrirlamoqdasiz.\nUning oʻzgartirilishi barcha ushbu vikidan foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.",
+       "editinginterface": "<strong>Eʼtibor bering:</strong> Siz interfeys matnini aks ettiruvchi sahifani tahrirlamoqdasiz.\nUning oʻzgartirilishi boshqa foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.",
        "translateinterface": "Ushbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
        "namespaceprotected": "Sizda '''$1''' nomfazosi sahifalarini tahrirlash huquqi yoʻq",
        "customcssprotected": "Sizda uchbu CSS sahifani tahrirlash huquqi yoʻq, chunki bu yerda boshqa foydalanuvchining shaxsiy moslamalari saqlanadi.",
        "post-expand-template-inclusion-category": "Qo'llaniladigan andozalarning mumkin bo'lgan miqdoridan oshgan sahifalar",
        "post-expand-template-argument-category": "Andozalarning to'ldirilmagan o'zgaruvchilariga ega sahifalar",
        "undo-success": "Tahrirni bekor qilish imkoniyati bor. Iltimos, solishtirish oynasini koʻrib chiqib, aynan shu oʻzgarishlarni bekor qilmoqchiligingizga ishonch hosil qiling va undan keyin «Saqla» tugmasini bosing.",
+       "undo-failure": "Keyingi tahrirlar bilan chalkashib ketgani sababli, ushbu tahrirni alohida oʻzini bekor qilishni iloji yoʻq.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|mun.]]) tomonidan qilingan $1-sonli tahrir qaytarildi",
        "cantcreateaccounttitle": "Ro‘yxatdan o‘tib bo‘lmadi",
        "cantcreateaccount-text": "[[User:$3|$3]] ushbu IP manzil (<strong>$1</strong>) orqali ro‘yxatdan o‘tishni bloklab qo‘ygan.\n\n$3 <em>$2</em>ni sabab qilib ko‘rsatdi",
        "brokenredirects-edit": "tahrirlash",
        "nbytes": "$1 {{PLURAL:$1|bayt}}",
        "ncategories": "$1 {{PLURAL:$1|turkum|turkumlar}}",
-       "nmembers": "$1 {{PLURAL:$1|ta a'zo}}",
+       "nmembers": "$1 {{PLURAL:$1|ta sahifa}}",
        "lonelypages": "Yetim sahifalar",
        "uncategorizedpages": "Turkumlashtirilmagan sahifalar",
        "uncategorizedcategories": "Turkumlashtirilmagan turkumlar",
        "movepage-moved": "'''Sahifa nomi «$1»dan «$2»ga koʻchirildi'''",
        "movepage-moved-redirect": "Qayta yo‘naltirish yaratildi.",
        "movetalk": "Mos munozara sahifasini qayta nomlash",
-       "move-subpages": "Ostsahifalarni ham qayta nomlash ($1 gacha)",
-       "move-talk-subpages": "Munozara sahifasining ostsahifalarini ham qayta nomlash ($1 gacha)",
+       "move-subpages": "Ostsahifalarni ham qayta nomlash ($1 tadan kam)",
+       "move-talk-subpages": "Munozara sahifasining ostsahifalarini ham qayta nomlash ($1 tadan kam)",
        "movepage-page-moved": "Sahifa nomi «$1»dan «$2»ga koʻchirilgan edi.",
        "movelogpage": "Koʻchirish qaydlari",
        "movesubpage": "{{PLURAL:$1|Ostsahifa|Ostsahifalar}}",
        "movenosubpage": "Bu sahifa ostsahifalarga ega emas.",
        "movereason": "Sabab:",
        "revertmove": "qaytarish",
-       "delete_and_move": "O‘chirish va qayta nomlash",
        "delete_and_move_confirm": "Ha, ushbu sahifa o‘chirilsin",
        "fix-double-redirects": "Oldingi nomga yoʻnaltirishlarni toʻgʻrilash",
        "move-leave-redirect": "Qayta yoʻnaltirish qoldirish",
index 3ecc5fd..01629cb 100644 (file)
        "movenosubpage": "Sta pagina no la gà nissuna sotopagina.",
        "movereason": "Motivo:",
        "revertmove": "ripristina",
-       "delete_and_move": "Scanceła e sposta",
        "delete_and_move_text": "==Scancełassion richiesta==\n\nLa voxe specificà come destinassion \"[[:$1]]\" l'esiste xà. Vóto scancełarla par proseguir con ło spostamento?",
        "delete_and_move_confirm": "Sì, scancèla la pagina",
        "delete_and_move_reason": "Scanselà par rendar posibiłe el spostamento da \"[[$1]]\"",
index c48232f..d1d8bb0 100644 (file)
        "permalink": "Kaikenaigaine kosketuz",
        "print": "Painda",
        "view": "Nähta",
+       "view-foreign": "Kacta $1-saital",
        "edit": "Redaktiruida",
        "create": "Säta",
        "editthispage": "Redaktiruida nece lehtpol'",
        "nstab-template": "Šablon",
        "nstab-help": "Abun lehtpol'",
        "nstab-category": "Kategorii",
+       "mainpage-nstab": "Pälehtpol'",
        "nosuchaction": "Mugošt tegendad ei ole",
        "nosuchactiontext": "URLas ozutadud tegend om petuzline.\nTö olet tehnu petusen URLan kirjutades vai männu värad kosketustme.\nNece voib mugažo ozutada viga {{SITENAME}}-projektan programmištos.",
        "nosuchspecialpage": "Mugošt speciališt lehtpol't ei ole",
        "createaccountreason": "Sü:",
        "createacct-reason": "Sü",
        "createacct-reason-ph": "Mikš sädad kävutajanprofilid?",
-       "createacct-captcha": "Varuitomuden kodvind",
-       "createacct-imgcaptcha-ph": "Kirjutagat tekst pälpäi",
        "createacct-submit": "Säta kävutajanprofil'",
        "createacct-another-submit": "Säta toine kävutajanprofil'",
        "createacct-benefit-heading": "{{SITENAME}}-saitad tehtas teiden pojavad ristitud.",
        "login-throttled": "Tö olet tehnu äjahkon naprindoid kirjutadas sistemha.\nOlgat hüväd, varastagat $1 aigad edel ut naprindad.",
        "login-abort-generic": "Teiden naprind tulda sistemha om satusetoi - Azotadud",
        "loginlanguagelabel": "Kel’: $1",
+       "pt-login": "Kirjutagatoiš sistemha",
+       "pt-createaccount": "Sada registracii",
        "php-mail-error-unknown": "Tundmatoi petuz PHP:n mail()-funkcijas",
        "user-mail-no-addy": "Tö ladit oigeta kirjeine e-počtan adresata.",
        "changepassword": "Peitsanan toižetuz",
        "passwordreset-capture": "Ozutada-k loptud kirjeine?",
        "passwordreset-email": "E-počtan adres:",
        "passwordreset-emailelement": "Kävutajannimi: \n$1\n\nAigaline peitsana: \n$2",
-       "passwordreset-emailsent": "Muštatai kirjeine uden peitsananke oigetihe e-počtadme.",
+       "passwordreset-emailsentemail": "Muštatai kirjeine uden peitsananke oigetihe e-počtadme.",
        "changeemail": "Toižetada e-počtan adres",
        "changeemail-no-info": "Miše kirjutada necil lehtpolel, teile pidab kirjutadas sistemha.",
        "changeemail-oldemail": "Nügüdläine e-počtan adres:",
        "preview": "Ezikacund",
        "showpreview": "Ozutada ezikacund",
        "showdiff": "Ozutada toižetused",
-       "anoneditwarning": "'''Homaikat:''' Tö et olgoi kirjutanus sistemha.\nTeiden IP-adres om kirjutadud necen lehtpolen redaktiruindan istorijaha.",
+       "anoneditwarning": "<strong>Homaikat:<strong> Tö et olgoi kirjutanus sistemha. Teiden IP-adres kirjutadas necen lehtpolen redaktiruindan istorijaha, ku toižetaškandet sidä. Ku tö <strong>[$1 kirjutatoiš sistemha]</strong> vai <strong>[$2 sat registracijan]</strong>, ka teiden redakcijad sidotas teiden kävutajannimehe. Siloi teil linneb toižid-ki ližavoimuzid.",
        "missingsummary": "'''Muštatez:''' Tö et olgoi andnuded toižetusiden lühüdad ümbrikacundad.\nKu tö valičet völ kerdan \"Kirjutada lehtpol'\", ka teiden toižetused kirjutase ningoižeta ümbrikacundata.",
        "missingcommenttext": "Olgat hüväd, pangat teiden tedotuz alahaks.",
        "missingcommentheader": "'''Muštatez:''' Tö et olgoi andnuded toižetusiden ümbrikacundoiden pälkirjutest.\nKu tö valičet völ kerdan ”{{int:savearticle}}” \"Kirjutada lehtpol'\", ka teiden toižetusiden ümbrikacund kirjutase ningoižeta pälkirjuteseta.",
        "shown-title": "Ozutada $1 {{PLURAL:$1|rezul'tat|rezul'tatad}} lehtpoleks",
        "viewprevnext": "Kacta ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Neciš Wikiš om jo lehtpol' ningoižen nimenke: \"[[:$1]]\"'''",
-       "searchmenu-new": "'''Säta lehtpol' \"[[:$1]]\" neciš Wikiš!'''",
+       "searchmenu-new": "<strong>Säta lehtpol' \"[[:$1]]\" neciš Wikiš!<strong> {{PLURAL:$2|0=|Kackat mugažo löutud lehtpol'he.|Kackat mugažo ecindan rezul'tatoihe.}}",
        "searchprofile-articles": "Südäimištlehtpoled",
        "searchprofile-images": "Mul'timedii",
        "searchprofile-everything": "Kaikjal",
        "rcnotefrom": "Alemba oma anttud toižetused '''$2'''-späi ( '''$1'''-hesai).",
        "rclistfrom": "Ozutada uded toižetused dataspäi $3 $2 augotaden",
        "rcshowhideminor": "$1 pened redakcijad",
+       "rcshowhideminor-hide": "Peitta",
        "rcshowhidebots": "$1 botad",
+       "rcshowhidebots-show": "Ozutada",
        "rcshowhideliu": "$1 sistemha kirjutadud kävutajad",
+       "rcshowhideliu-hide": "Peitta",
        "rcshowhideanons": "$1 anonimišt kävutajad",
+       "rcshowhideanons-hide": "Peitta",
        "rcshowhidepatr": "$1 kodvdud toižetust",
        "rcshowhidemine": "$1 ičein redakcijad",
+       "rcshowhidemine-hide": "Peitta",
        "rclinks": "Ozutada jäl'gmäižed $1 toižetust $2 päiväs<br />$3",
        "diff": "erod",
        "hist": "istorii",
        "watchlist-details": "Teiden kaclendnimikirjuteses om {{PLURAL:$1|$1 lehtpol'|$1 lehtpol't}}. Lodulehtpoled ei olgoi neciš lugus.",
        "wlheader-enotif": "Tedotand e-počtadme om kävutamas.",
        "wlshowlast": "Ozutada jäl'gmäižiš $1 časuiš da $2 päiviš",
+       "watchlistall2": "kaik",
        "watchlist-options": "Kaclendnimikirjutesen järgendused",
        "watching": "Ližaduz kaclendnimikirjuteshe...",
        "unwatching": "Heitmine kaclendnimikirjutesespäi...",
        "movenosubpage": "Necil lehtpolel ei ole alalehtpolid.",
        "movereason": "Sü:",
        "revertmove": "heitta pätand",
-       "delete_and_move": "Čuta poiš da udesnimitada",
        "delete_and_move_confirm": "Ka, čuta lehtpol' poiš",
        "delete_and_move_reason": "Čutud poiš \"[[$1]]\"n udesnimitamižen voimusen täht.",
        "immobile-source-namespace": "Ei voi udesnimitada lehtpolid \"$1\"-nimiavaruses",
        "tooltip-pt-mycontris": "Minun redakcijoiden nimikirjutez",
        "tooltip-pt-login": "Naku sab kirjutadas sistemha, no necidä ei tarbiž radon täht",
        "tooltip-pt-logout": "Lähtta sistemaspäi",
+       "tooltip-pt-createaccount": "Mö taričem teile sada registracii i kirjutadas sistemha, no mö em tarbhaikoi necidä.",
        "tooltip-ca-talk": "Diskussii neciš lehtpoles",
-       "tooltip-ca-edit": "Sab redaktiruida necidä lehtpol't.\nOlgat hüväd, kävutagat ezikacund.",
+       "tooltip-ca-edit": "Sab redaktiruida necidä lehtpol't.",
        "tooltip-ca-addsection": "Augotada uz' jaguz",
        "tooltip-ca-viewsource": "Nece lehtpol' om kaitud.\nSab lugeda sen augotižkod da kopiruida se.",
        "tooltip-ca-history": "Necen lehtpolen enččed versijad",
        "tooltip-ca-nstab-main": "Südäimištlehtpol'",
        "tooltip-ca-nstab-user": "Kacta kävutajan lehtpol'he",
        "tooltip-ca-nstab-media": "Mediafail",
-       "tooltip-ca-nstab-special": "Nece om specialine lehtpol', tö et voigoi toižetada sidä",
+       "tooltip-ca-nstab-special": "Nece om specialine lehtpol', sidä ei sa toižetada",
        "tooltip-ca-nstab-project": "Kacta projektan lehtpol'he",
        "tooltip-ca-nstab-image": "Kacta failan lehtpol'he",
        "tooltip-ca-nstab-mediawiki": "Lugeda sisteman tedotuz",
        "spamprotectiontext": "Lehtpolen, kudamban tö tahtoit kirjutada muštho, om blokiruidud spamanfil'tral.\nVoib olda, necil lehtpolel om kosketuz irdsaitale, kudamb om mustas nimikirjuteses.",
        "spamprotectionmatch": "Meiden spamanfil'tr tedoti necil statjal mugošt: $1",
        "spambot_username": "MediaWikid puhtastadas spamaspäi",
+       "simpleantispam-label": "Spamanvastaine kodv.\n<strong>Algat</strong> täutkoi necidä!",
        "pageinfo-header-edits": "Redakcijoiden istorii",
        "pageinfo-article-id": "Lehtpolen ID",
        "pageinfo-watchers": "Lehtpolen kaclijoiden lugu",
        "pageinfo-edits": "Redakcijoiden lugumär",
        "pageinfo-authors": "Erazvuiččiden avtoroiden lugu",
+       "pageinfo-toolboxlink": "Lehtpolen informacii",
        "pageinfo-contentpage-yes": "Ka",
        "pageinfo-protect-cascading-yes": "Ka",
        "pageinfo-category-pages": "Lehtpoliden lugumär",
        "tags": "Aktualižed toižetusiden vestatesed",
        "tag-filter": "[[Special:Tags|Vestatesiden]] fil'tr:",
        "tag-filter-submit": "Fil'tr",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Virg|Virgad}}]]: $2)",
        "tags-title": "Virgad",
        "tags-intro": "Necil lehtpolel om virgoiden nimikirj i neniden virgoiden znamoičendad. Programmad znamoitas virgoil toižetusid.",
        "tags-tag": "Tegan (virgan) nimi",
        "sqlite-no-fts": " $1 täuz'tekstaižen ecindan tügedamižeta",
        "revdelete-restricted": "kaidendused administratoriden täht",
        "revdelete-unrestricted": "kaidendused heittud administratoriden täht",
+       "logentry-newusers-create": "{{GENDER:$2|tegihe}} $1-kävutajaks",
        "rightsnone": "(ei ole)",
        "revdelete-summary": "kaik toižetused",
        "feedback-cancel": "Heitta pätand",
index 21714c0..c1a700f 100644 (file)
        "movenosubpage": "Trang này không có trang con.",
        "movereason": "Lý do:",
        "revertmove": "lùi lại",
-       "delete_and_move": "Xóa và đổi tên",
        "delete_and_move_text": "==Cần xóa==\n\nTrang với tên “[[:$1]]” đã tồn tại. Bạn có muốn xóa nó để dọn chỗ di chuyển tới tên này không?",
        "delete_and_move_confirm": "Xóa trang để đổi tên",
        "delete_and_move_reason": "Xóa để có chỗ đổi tên “[[$1]]”",
index 4c3f099..3e055ed 100644 (file)
@@ -6,7 +6,8 @@
                        "Matma Rex",
                        "Midnight Gambler",
                        "Silvicola",
-                       "아라"
+                       "아라",
+                       "Zombie45764"
                ]
        },
        "tog-underline": "Linggs undârschdrajchn:",
        "nstab-template": "Foorlaach",
        "nstab-help": "Hilfs-sajdn",
        "nstab-category": "Ghadegorii",
+       "mainpage-nstab": "Haubdsajdn",
        "nosuchaction": "Des schded ned dsur auswaal",
        "nosuchactiontext": "Di agdsjoon, dii in dr URL schdäd, ged ned.\nFilajchd is di URL falsch gschriiwn, odr duu bisch âm falschn lingg nôôch.\nS'ghend aa â brogramiirfäälâr in dr sofdwäâr sâj, dii baj {{SITENAME}} lefd.",
        "nosuchspecialpage": "Dii sôndâr-sajdn gajd's ned",
        "viewpagelogs": "Logbicher fär dii sajdn dsajchn",
        "currentrev-asof": "Jedsiche wärsjoon, am $2 um $3 gmachd",
        "revisionasof": "Wärsjoon fom $2 um $3 Uur",
-       "revision-info": "Version vom $1 Uhr von $2",
+       "revision-info": "Version vom $1 Uhr von {{GENDER:$6|$2}}$7",
        "previousrevision": "← wärsjoon dâfoor",
        "nextrevision": "Nägsdnajâre wärsjoon →",
        "currentrevisionlink": "Geechnwärdiche wärsjoon",
        "unwatch": "Nimmä beoobachdn",
        "watchlist-details": "Duu häldsch {{PLURAL:$1|1 sajdn|$1 sajdn}} undâr beoobachdung.",
        "wlshowlast": "Dsajch dii ändrunga fo di ledsdn $1 schdundn, $2 dooch odär",
+       "watchlistall2": "ale",
        "watchlist-options": "Was un wii alles af Dajnâr beobachdungslisdn dsajchd wärn sol",
        "watching": "Ghumd undâr beoobachdung ...",
        "unwatching": "Beobachdn ajschränggn",
        "delete-toobig": "Dii sajdn had iiwâr $1 {{PLURAL:$1|Wersjoon|Wersjoon'n}}, des is fiil. Solche sajdn däf mr nima miir nigs diir nigs leschn, damid dii seewâr ned in d'gnii geen.",
        "delete-warning-toobig": "Dii sajdn had mäa wii $1 {{PLURAL:$1|wärsjoon|wärsjoon'n}}, des is fiil. Wem ma solchene leschd, ghan dr seerwâr fiir {{SITENAME}} ins scholbârn ghomn.",
        "rollback": "D'ändrungn riggängich machn",
-       "rollback_short": "riggängich machn",
        "rollbacklink": "Dsrigsedsn",
        "rollbackfailed": "Riggängich machn is ned gangn.",
        "protectlogpage": "Sajdnschbär-Logbuch",
        "namespace": "Nôômâraum:",
        "invert": "Auswaal umdreâ",
        "blanknamespace": "(Sajdn)",
-       "contributions": "Eichne Beidrääch",
+       "contributions": "{{GENDER:$1|Beidrääch}}",
        "contributions-title": "Bajdrääch fo „$1“",
        "mycontris": "Bajdreech",
        "contribsub2": "Von {{GENDER:$3|$1}} ($2)",
        "block-log-flags-nocreate": "Naj ôôdsmeldn is gschbärd.",
        "movepagetext": "Mid dem fôrmulaar hiir wärd â sajdn umdaafd, midsamd alle foorichâ wärsjoona. Dii sajdn mi'm aldn nôômâ blajbd, fârwajsd danôôch awâr bloos noch af dii naje.\nWajdârlajdunga af den aldn sajdn-nôômâ ghansd audomaadisch ghôrigiirn lasn. Wenns´d des ned magsd,  gug ob's ned dsu [[Special:DoubleRedirects|dobldâ]] odär [[Special:BrokenRedirects|ghabude wajdârlajdunga]] fiird. Du musd dâfiir sorgn, das dii aldn fârwajse aa ghinfdich wajdâr fungdsjoniirn!\n\nWen's scho â sajdn mid dem naja nôômâ gibd, wärd dii sajdn ned umdaafd wärn, es saj den, dii sajdn mi'm naja nôômâ wäär läär odär bloos â wajdârladung oone äldâre wärsjoon.\n\nDesdaweechn ghansd â beschdeende sajdn nii aus fârseen iwârschrajwn, und wen'D doch an feelâr gmachd hasd mi'm umdaafn, ghansd des dan aa oone wajdârs widâr righgengich machn.\n\n'''Achdung'''\nWen'D des mid'râr  beliibdn sajdn duusd, ghan soo a umdaaf-agdsion â hefdiche sach saj, neemlich mid folchng, di fär andâre rächd iwârraschnd sin. Magg's also bloos, wenn´sd genau waasd, was´d ôôrichsd.",
        "movepagetalktext": "Dii droôhängnde  disghusjoonssajdn wärd mid umdaafd, '''ausâr wen:'''\n*es scho undârm naja nôômâ â disghusjoonssajdn geem dääd\n*duu sechsd undn, das'd es hald ned wilsd.\nDan musd hald was drinschded fon hand riiwârschafn odr dsamschdudârn, wen de des dôô hôôm wilsd.\nSchrajb bide den '''naja'' nôômâ fo dâr sajdn undârals '''Dsiil'' nâj un '''nen dâ grund''' fir des umgedaaf drundâr.",
-       "movearticle": "Sajdn fârschiibm:",
        "newtitle": "Dôôhi:",
        "move-watch": "Alde un naje sajdn beoobachdn.",
        "movepagebtn": "Sajdn fârschiibm",
        "tooltip-pt-login": "S'is gän gseen, das mä´ si ôômäld, mâ däf awâr aa soo raj",
        "tooltip-pt-logout": "Abmeldn",
        "tooltip-ca-talk": "Disghusjoon dsur sajdn hiir",
-       "tooltip-ca-edit": "Dii sajdn ghansd beärbâdn.\nBidde gug's mi´m foorschau-gnobf ôô fôrm schbajchan",
+       "tooltip-ca-edit": "Dii sajdn ändârn",
        "tooltip-ca-addsection": "An naja abschnid ôôfanga",
        "tooltip-ca-viewsource": "Dii sajdn is gecha ändrunga gschbärd. Mär ghôô awâr den gwäl-dhägsd ôôschaua.",
        "tooltip-ca-history": "Friâre Fassunga fo där sajdn",
index a9f92e8..be3f0e5 100644 (file)
@@ -59,7 +59,7 @@
        "tog-watchlisthideanons": "關注表裏囥脫隱姓埋名用戶所編",
        "tog-watchlisthidepatrolled": "關注表裏囥脫巡脫編",
        "tog-watchlisthidecategorization": "囥脱对页面个分类",
-       "tog-ccmeonemails": "æ\88\91ç\99¼ç\95\80å\90\84許ç\94¨æ\88¶ç®\87é\9b»å­\90ä¿¡ä¹\9fç\99¼ä»½ç\95\80æ\88\91",
+       "tog-ccmeonemails": "æ\8b¿æ\88\91å\8f\91ç\95\80å\85¶ä»\96ç\94¨æ\88·ä¸ªç\94µå­\90é\82®ä»¶ä¹\9få\8f\91å\8fªå\89¯æ\9c¬ç\95\80æ\88\91è\87ªå®¶",
        "tog-diffonly": "比較兩版弗樣到弗顯示頁內容",
        "tog-showhiddencats": "顯示囥脫分類",
        "tog-norollbackdiff": "执行退回之后弗显示两样",
        "noindex-category": "朆索引个页",
        "broken-file-category": "有无用文件链接个页",
        "about": "有关",
-       "article": "å\85§å®¹é \81",
+       "article": "å\86\85容页é\9d¢",
        "newwindow": "(用新窗口开)",
        "cancel": "取消",
        "moredotdotdot": "還多...",
        "morenotlisted": "箇張表還朆完成。",
        "mypage": "我个页面",
        "mytalk": "我个讨论",
-       "anontalk": "箇IP地址個話",
+       "anontalk": "讲张",
        "navigation": "导航",
        "and": "&#32;搭",
        "qbfind": "尋",
        "create-local": "添加本地说明",
        "editthispage": "編箇頁",
        "create-this-page": "建箇頁",
-       "delete": "å\88ª",
+       "delete": "å\88 é\99¤",
        "deletethispage": "刪箇頁",
        "undeletethispage": "弗删箇页",
        "undelete_short": "復原消脫個$1個編寫",
        "protect": "保",
        "protect_change": "改",
        "protectthispage": "保箇頁",
-       "unprotect": "變更保態",
-       "unprotectthispage": "變更箇頁保態",
+       "unprotect": "更改保护",
+       "unprotectthispage": "更改此页个保护",
        "newpage": "新页",
        "talkpage": "探討箇頁",
        "talkpagelinktext": "讨论",
        "specialpage": "特別頁",
        "personaltools": "私人家伙",
-       "articlepage": "æ\9c\9bå\85§å®¹é \81",
+       "articlepage": "æ\9c\9bå\86\85容页",
        "talk": "讨论",
        "views": "望",
        "toolbox": "家生",
        "helppage-top-gethelp": "帮忙",
        "mainpage": "封面",
        "mainpage-description": "封面",
-       "policy-url": "Project:策略",
+       "policy-url": "Project:政策",
        "portal": "社区门堂",
        "portal-url": "Project:社区门堂",
        "privacy": "隐私政策",
        "createacct-benefit-body1": "{{PLURAL:$1|编写}}",
        "createacct-benefit-body2": "{{PLURAL:$1|页}}",
        "createacct-benefit-body3": "此垡 {{PLURAL:$1|出力个人}}",
-       "badretype": "倷输入个密码搭倪个档案弗配。",
+       "badretype": "侬输入个密码弗匹配。",
        "usernameinprogress": "迭个用户名个账户创建已经勒了进行。请侬等一等。",
-       "userexists": "用戶名有人用哉。相勞爾揀別樣名字。",
+       "userexists": "输入个用户名有人用哉。请再选个两样个名字。",
        "loginerror": "登录错误",
        "createacct-error": "建账号出错",
        "createaccounterror": "无法建立账户:$1",
        "blockedtext": "侬个用户名或IP地址已经拨$1查封。\n\n箇趟查封是由$1所封个。原因是''$2''。\n\n* 箇趟查封开始个辰光是:$8\n* 箇趟查封到期个辰光是:$6\n* 对于畀查封者:$7\n\n侬可以联络$1或者其他个 [[{{MediaWiki:Grouppage-sysop}}|管理员]],讨论箇趟查封。\n除非侬已经垃侬个 [[Special:Preferences|个人设置]]里向设置仔一只有效个电子邮件地址,弗然侬弗好使用「e-mail箇位用户」功能。当设置了一只有效个电子邮件地址之后,箇只功能是弗会畀封锁个。\n\n侬个IP地址是$3,而该查封ID是 #$5。 请垃拉侬个查询里向注明以上所有资料。",
        "autoblockedtext": "侬个IP地址已经自动查封,由于之前另一位 搭侬用一样IP个用户畀$1所查封。\n而查封个原因是:\n\n:''$2''\n\n* 箇趟查封个开始辰光是:$8\n* 箇趟查封个到期辰光是:$6\n* 对于畀查封者:$7\n\n侬可以联络$1或者其他个 [[{{MediaWiki:Grouppage-sysop}}|管理员]],讨论箇趟查封。\n除非侬已经垃侬个 [[Special:Preferences|个人设置]]里向设置仔一只有效个电子邮件地址,弗然侬弗好使用「e-mail箇位用户」功能。当设置了一只有效个电子邮件地址之后,箇只功能是弗会畀封锁个。\n\n侬个IP地址是$3,而该查封ID是 #$5。 请垃拉侬个查询里向注明以上所有资料。",
        "blockednoreason": "朆畀出原因",
-       "whitelistedittext": "侬必须$1才能编辑。",
+       "whitelistedittext": "请$1编辑。",
        "confirmedittext": "垃拉编辑此页之前侬必须确认侬个邮箱地址。请通过[[Special:Preferences|个人设置]]设置并验证侬个邮箱地址。",
        "nosuchsectiontitle": "寻弗着箇只段落",
        "nosuchsectiontext": "侬尝试编辑个章节弗存在。\n作兴是垃拉侬查看页面个辰光已经移动或者畀删除。",
        "token_suffix_mismatch": "'''由于侬用户端里向个编辑令牌毁损仔一些标点符号字元,为防止编辑个文字损坏,侬个编辑已经畀回头。'''\n箇种情况通常出现垃拉使用含有交关bug、以网络为主个匿名代理服务个辰光。",
        "editing": "来里编$1",
        "creating": "创建“$1”",
-       "editingsection": "徕里编写$1(段)",
+       "editingsection": "来里编辑$1(段落)",
        "editingcomment": "垃许编辑 $1 (新段落)",
        "editconflict": "编辑冲突: $1",
        "explainconflict": "有人垃拉侬开始编辑之后更改仔页面。\n上头个文字框内显示个是箇歇本页个内容。\n侬个修改显示垃拉下底只文字框里向。\n侬应当拿侬个修改加入到现有个内容里向。\n<b>只有</b>上头文字框里向个内容会得垃侬点击\"保存页面\"之后畀保存。",
        "undo-norev": "由于其版本弗存在或已删除,此编辑弗好撤销。",
        "undo-nochange": "箇届编辑看出来已经畀撤销。",
        "undo-summary": "撤销由[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])作出个版本$1",
-       "cantcreateaccounttitle": "å\91\92å¤\84建ç«\8bå¸\90户",
+       "cantcreateaccounttitle": "å¼\97好å¼\80户",
        "cantcreateaccount-text": "从箇只IP地址 (<b>$1</b>) 创建账户已经畀[[User:$3|$3]]禁止。\n\n$3封禁个原因是''$2''",
        "viewpagelogs": "望箇页日志",
        "nohistory": "该只页面呒拨编辑历史。",
        "right-editmyoptions": "编辑侬个个人设置",
        "right-sendemail": "發郵件畀各許人",
        "newuserlogpage": "用户创建日志",
+       "newuserlogpagetext": "箇是用户创建个记录。",
        "rightslog": "用户权限日志",
        "action-read": "讀箇頁",
        "action-edit": "编箇页",
        "statistics-users-active": "活跃用户",
        "pageswithprop-submit": "去",
        "brokenredirects": "坏脱个重定向",
-       "brokenredirectstext": "ä¸\8bå\90\91å\80\8bè½\89æ\88³é\8f\88æ\8e¥å\88°æ\9c\86è¦\8bå\80\8bé \81面:",
+       "brokenredirectstext": "ä¸\8båº\95个é\87\8då®\9aå\90\91é\93¾å\88°å¼\97å­\98å\9c¨ä¸ªé¡µ面:",
        "brokenredirects-edit": "编辑",
        "brokenredirects-delete": "删除",
        "withoutinterwiki": "嘸語言鏈接個頁面",
        "specialloguserlabel": "用戶:",
        "speciallogtitlelabel": "目標(標題要弗用戶):",
        "log": "记录",
+       "alllogstext": "所有{{SITENAME}}公开日志个联合展示。侬可以选择日志类型、用户名(区分大小写)或者相关页面(区分大小写)来缩小查询范围。",
        "allpages": "全部页面",
        "nextpage": "下页 ($1)",
        "prevpage": "上一页($1)",
        "allinnamespace": "所有页面 ($1 名字空间)",
        "allpagessubmit": "提交",
        "allpagesprefix": "显示个页面有下底个前缀:",
-       "allpages-bad-ns": "{{SITENAME}}没有叫做\"$1\"个名字空间.",
+       "allpagesbadtitle": "畀定个页面标题是非法个,或者具有一个内部语言或内部 wiki 个前缀。渠作兴包括一个或更多个弗好用于标题个字符。",
+       "allpages-bad-ns": "{{SITENAME}}呒不叫\"$1\"个名字空间。",
        "categories": "页面分类",
+       "deletedcontributions": "删脱个用户贡献",
        "linksearch": "外部链接搜寻",
        "linksearch-ns": "名字空間:",
        "linksearch-ok": "搜尋",
        "unwatchthispage": "停止监控",
        "notanarticle": "弗是內容頁",
        "watchlist-details": "弗包括讨论页,有 $1 页徕你侬关注表里向。",
+       "wlheader-showupdated": "勒侬上趟查看之后畀修改个页面<strong>加粗</strong>显示。",
        "wlnote": "下底是{{PLURAL:$2|过去<strong>$2</strong>个钟头}}个{{PLURAL:$1|最后<strong>$1</strong>届更改}},截至$3 $4。",
        "wlshowlast": "显示上$1个钟头$2日天",
        "watchlistall2": "全部",
        "actioncomplete": "操作完成哉",
        "deletedtext": "\"$1\"已经删除。最近删除记录请参见$2。",
        "dellogpage": "删除记录",
+       "dellogpagetext": "下底是最近个删除个列表。",
        "deletionlog": "删除记录",
        "deletecomment": "理由:",
        "deleteotherreason": "其它/附加理由:",
        "rollbacklink": "回退",
        "rollbacklinkcount": "回退$1届编辑",
        "rollbackfailed": "恢复失败",
+       "cantrollback": "弗好恢复编辑;阿末个贡献人是本页唯一个作者。",
+       "alreadyrolled": "恢复弗落[[User:$2|$2]]([[User talk:$2|讲张]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])对[[:$1]]个编辑,其他人已经编辑歇或恢复过该个页面。\n\n最后编辑者是[[User:$3|$3]]([[User talk:$3|讲张]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])。",
        "revertpage": "恢复[[Special:Contributions/$2|$2]] ([[User talk:$2|讲张]])个改动;恢复到[[User:$1|$1]]个上一版本",
        "protectlogpage": "保护日志",
        "protectedarticle": "保护“[[$1]]”",
        "whatlinkshere-hidelinks": "$1链接",
        "whatlinkshere-filters": "过滤器",
        "blockip": "查封{{GENDER:$1|用户}}",
+       "blockiptext": "用下头个表单来禁止来自某一特定IP地址或用户名个修改权限。只有勒勒为仔防止破坏,及符合[[{{MediaWiki:Policy-url}}|政策]]个情况下底再好采取此行动。请勒勒下底输入一个具体个理由(譬如引述一只畀破坏个页面)。",
        "ipaddressorusername": "IP地址或用户名:",
        "ipbreason": "理由:",
        "ipbsubmit": "封杀该个用户",
        "ipbother": "其它时间:",
        "ipboptions": "2个钟头:2 hours,1天:1 day,3天:3 days,1个礼拜:1 week,2个礼拜:2 weeks,1个号头:1 month,3个号头:3 months,6个号头:6 months,1年:1 year,老世:infinite",
        "badipaddress": "无效 IP 地址",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]]已经畀查封。<br />\n参看[[Special:BlockList|查封列表]]来复审查封。",
        "ipblocklist": "封脱个用户",
        "infiniteblock": "永远",
        "blocklink": "封禁",
        "unblocklink": "解封",
        "change-blocklink": "改变封禁",
        "contribslink": "贡献",
+       "autoblocker": "因为侬搭“[[User:$1|$1]]”共享一个IP地址了畀自动查封。$1畀查封个理由是“$2”",
        "blocklogpage": "封禁日志",
-       "blocklogentry": "“[[$1]]”查封徕里,$2 $3到期",
-       "blocklogtext": "箇是用戶封搭解封操作個記錄。自動封個IP地址弗排。到[[Special:BlockList|IP 封表]]裏望目前生效個封表。",
+       "blocklogentry": "查封[[$1]],终止辰光为$2$3",
+       "blocklogtext": "该个是用户查封搭著解封操作个记录。自动查封个IP地址弗会列勒该𡍲。到[[Special:BlockList|封禁列表]]去看当前生效个查封。",
        "unblocklogentry": "$1已经拨解封",
        "block-log-flags-nocreate": "建账号禁用哉",
        "lockdb": "鎖數據庫",
        "movelogpagetext": "下底是拨拉捅荡个页面列表。",
        "movereason": "理由:",
        "revertmove": "恢复",
-       "delete_and_move": "删脱搭仔捅荡",
        "delete_and_move_confirm": "对哉,删脱该只页面",
        "export": "页导出",
        "allmessages": "系统讯息",
        "tooltip-preview": "望望相你侬个修改,保存之前用!",
        "tooltip-diff": "显示你侬对文本个修改",
        "tooltip-compareselectedversions": "查看本页面两只选定个修订版个差异。",
-       "tooltip-watch": "畀箇页加到你侬个关注表里",
+       "tooltip-watch": "拿箇页加到侬个关注表里",
        "tooltip-rollback": "揿一记“回转”就回退到上一位贡献者个编辑状态",
        "tooltip-undo": "“撤销”可以恢复该编辑并且垃拉预览模式下头打开编辑表单。渠允许垃拉摘要里向说明原因。",
        "tooltip-summary": "打进短摘要",
        "confirmemail_body": "用IP地址$1嗰人(呒数是你侬),徕translatewiki.net里一个账号“$2”建起,用你侬个电子信箱地址。\n\n确认记箇账号是弗是你侬嘅,激活translatewiki.net里嗰电子信功能。用浏览器打开下向嗰链接:\n\n$3\n\n假使你侬*朆*注册过箇账号,揿下向嗰链接取消电子信确认:\n\n$5\n\n确认码会到$4过期。",
        "confirmemail_body_changed": "用IP地址$1嗰人,(呒数是你侬)徕{{SITENAME}}里一个账号“$2”建起,用你侬个电子信箱地址。\n\n确认记箇账号是弗是你侬嘅,激活{{SITENAME}}里嗰电子信功能。用浏览器打开下向嗰链接:\n\n$3\n\n假使你侬*朆*注册过箇账号,揿下向嗰链接取消电子信确认:\n\n$5\n\n确认码会到$4过期。",
        "scarytranscludetoolong": "[URL忒长]",
+       "deletedwhileediting": "<strong>警告:</strong>此页拉侬开始编辑之后已经畀删脱!",
        "confirmrecreate": "用户[[User:$1|$1]] ([[User talk:$1|讲张]])勒拉倷开始编辑该页面之后拿俚删脱,理由是: : ''$2'' 请拿定章程,倷阿是真个要重建该页面。",
        "confirm_purge_button": "确定",
        "comma-separator": "、",
index 36ebd26..a0b517d 100644 (file)
        "morenotlisted": "די ליסטע איז נישט פֿולשטענדיק.",
        "mypage": "מיין בלאַט",
        "mytalk": "שמועס",
-       "anontalk": "×\93×\90ס ×¨×¢×\93×\9f ×¤×\95×\9f ×\93×¢×\9d IP",
+       "anontalk": "ש×\9e×\95עס",
        "navigation": "נאַוויגאַציע",
        "and": "&#32;און",
        "qbfind": "טרעף",
        "passwordreset-emailtext-ip": "עמעצער (מסתמא איר, פון IP אדרעס $1) האט געבעטן צוריקצושטעלן אייער פאסווארט פאר {{SITENAME}} ($4). די פאלגנדע באניצער {{PLURAL:$3|קאנטע איז|קאנטעס זענען}}\nפארבונדן מיט דעם ע־פאסט אדרעס:\n\n$2\n\n{{PLURAL:$3|דאס פראוויזארישע פאסווארט|די פראוויזארישע פאסווערטער}} וועלן אויסגיין נאך {{PLURAL:$5|איין טאג|$5 טעג}}.\nאיר זאלט אריינלאגירן און קלויבן א נייע פאסווארט אצינד. טאמער א צווייטער האט געשיקט די בקשה,\nאדער ווען איר געדענקט יא אייער פריעריקע פאסווארט, און וויל עס נישט ענדערן,\n קענט איר איגנארירן דעם אנזאג און ניצן ווייטער דאס אלטע פאסווארט.",
        "passwordreset-emailtext-user": "באניצער $1 אויף  {{SITENAME}} האט געבעטן צוריקצושטעלן אייער פאסווארט פאר {{SITENAME}} ($4).\nדי פאלגנדע באניצער {{PLURAL:$3|קאנטע איז|קאנטעס זענען}} פארבונדן מיט דעם ע־פאסט אדרעס:\n\n$2\n\n{{PLURAL:$3|דאס פראוויזארישע פאסווארט|די פראוויזארישע פאסווערטער}} וועלן אויסגיין נאך {{PLURAL:$5|איין טאג|$5 טעג}}.\nאיר זאלט אריינלאגירן און קלויבן א נייע פאסווארט אצינד. טאמער א צווייטער האט געשיקט די בקשה,\nאדער ווען איר געדענקט יא אייער פריעריקע פאסווארט, און וויל עס נישט ענדערן,\n קענט איר איגנארירן דעם אנזאג און ניצן ווייטער דאס אלטע פאסווארט.",
        "passwordreset-emailelement": "באַניצער נאָמען: \n$1\n\nפראוויזארישער פּאַראָל: \n$2",
-       "passwordreset-emailsent": "טאמער איז דאס אן איינגעשריבענער ע־פאסט אדרעס פאר אייער קאנטע, וועט מען שיקן א פאסווארט צוריקשטעלן ע-פּאָסט.",
+       "passwordreset-emailsentemail": "טאמער איז דאס אן איינגעשריבענער ע־פאסט אדרעס פאר אייער קאנטע, וועט מען שיקן א פאסווארט צוריקשטעלן ע-פּאָסט.",
        "passwordreset-emailsent-capture": "מען האט געשיקט א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן.",
        "passwordreset-emailerror-capture": "מען האט געשאפן א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן, אבער שיקן צום {{GENDER:$2|באניצער}}איז דורכגעפאלן: $1",
        "changeemail": "ענדערן אדער אראפנעמען ע-פּאָסט אַדרעס",
        "wlnote": "אונטן {{PLURAL:$1|איז די לעצטע ענדערונג|זענען די לעצטע <strong>$1</strong> ענדערונגען}} אין {{PLURAL:$2|דער לעצטער שעה|די לעצטע <strong>$2</strong> שעה'ן}} ביז $3, $4.",
        "wlshowlast": "ווײַזן די לעצטע $1 שעה'ן  $2 טעג",
        "watchlistall2": "אַלע",
+       "watchlist-hide": "באַהאַלטן",
+       "wlshowtime": "ווײַזן לעצטע:",
+       "wlshowhideminor": "מינערדיקער רעדאקטירונגען",
        "watchlist-options": "אויפֿפאַסן ליסטע ברירות",
        "watching": "אויפפאסענדונג…",
        "unwatching": "נעמט אראפ פון אויפפאסונג ליסטע…",
        "contributions": "{{GENDER:$1|באניצער}} בײַשטײַערונגען",
        "contributions-title": "בײַשטײַערונגען פֿון באַניצער $1",
        "mycontris": "בײַשטײַערונגען",
+       "anoncontribs": "בײַשטײַערונגען",
        "contribsub2": "פֿאַר {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "באניצער קאנטע \"$1\" איז נישט איינגעשריבן.",
        "nocontribs": "נישט געטראפן קיין ענדערונגען צוזאמעגעפאסט מיט די קריטעריעס.",
        "movenosubpage": "דער דאָזיגער בלאַט האט נישט קיין אונטערבלעטער.",
        "movereason": "אורזאַך:",
        "revertmove": "צוריקדרייען",
-       "delete_and_move": "אויסמעקן און באוועגן",
        "delete_and_move_text": "== אויסמעקן פארלאנגט ==\nדער ציל בלאַט \"[[:$1]]\" עקזיסטירט שוין.\nצי ווילט איר אים אויסמעקן כדי צו ערמעגליכן די באוועגונג?",
        "delete_and_move_confirm": "יא, מעק אויס דעם בלאט",
        "delete_and_move_reason": "אויסגעמעקט כדי צו קענען באוועגן פֿון \"[[$1]]\"",
index 5ee69d8..c3bfd9f 100644 (file)
        "passwordreset-emailtext-ip": "有人(可能係閣下自己,來自IP地址$1)請求更改閣下喺{{SITENAME}}($4)嘅密碼。同爾個電子郵件有關聯嘅用戶包括:\n\n$2\n\n{{PLURAL:$3|爾個|爾啲}}臨時密碼會喺{{$5}}日之後失效。\n\n如果係閣下自己請求改密碼嘅,請馬上登錄{{SITENAME}}並且更改密碼。如果閣下諗返起自己個密碼,或者根本無申請過改密碼嘅話,請忽略爾條訊息,繼續用返舊密碼。",
        "passwordreset-emailtext-user": "{{SITENAME}}用戶$1請求更改閣下喺{{SITENAME}}道嘅密碼$4。同爾個電子郵件有關聯嘅用戶包括:\n\n$2\n\n{{PLURAL:$3|爾個|爾啲}}臨時密碼會喺{{$5}}日之後失效。\n\n如果係閣下自己請求改密碼嘅,請馬上登錄{{SITENAME}}並且更改密碼。如果閣下諗返起自己個密碼,或者根本無申請過改密碼嘅話,請忽略爾條訊息,繼續用返舊密碼。",
        "passwordreset-emailelement": "用戶名:\n$1\n\n臨時密碼:\n$2",
-       "passwordreset-emailsent": "若果你個戶口有登記電郵,密碼重設電郵經已送出。",
+       "passwordreset-emailsentemail": "若果你個戶口有登記電郵,密碼重設電郵經已送出。",
        "passwordreset-emailsent-capture": "密碼重設電郵經已送出,下面有顯示。",
        "passwordreset-emailerror-capture": "密碼重設電郵經已送出,下面有顯示,但送畀{{GENDER:$2|user}}時失敗: $1",
        "changeemail": "改或者剷走電郵地址",
        "recentchanges-label-plusminus": "頁面位元組大細變化",
        "recentchanges-legend-heading": "'''標記:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新開版]])",
+       "recentchanges-submit": "顯示",
        "rcnotefrom": "下面嘅{{PLURAL:$5|改動}}由 <strong>$3 $4</strong> 開始(顯示到'''$1''')。",
        "rclistfrom": "顯示由$3 $2嘅新更改",
        "rcshowhideminor": "$1小編輯",
        "mostinterwikis": "有最多跨維基連結嘅頁面",
        "mostrevisions": "有最多修改嘅頁面",
        "prefixindex": "全部頁嘅前綴",
+       "prefixindex-submit": "顯示",
        "shortpages": "短頁",
        "longpages": "長頁",
        "deadendpages": "掘頭頁",
        "protectedpages-performer": "保護用戶",
        "protectedpages-params": "保護參數",
        "protectedpages-reason": "原因",
+       "protectedpages-submit": "顯示頁面",
        "protectedpages-unknown-timestamp": "唔知",
        "protectedpages-unknown-performer": "未知嘅用戶",
        "protectedtitles": "保護咗嘅標題",
        "protectedtitlesempty": "響呢啲參數之下並無標題保護住。",
+       "protectedtitles-submit": "顯示標題",
        "listusers": "用戶一覽",
        "listusers-editsonly": "只顯示有編輯嘅用戶",
        "listusers-creationsort": "按建立日期排序",
        "activeusers-hidebots": "隱藏機械人",
        "activeusers-hidesysops": "隱藏管理員",
        "activeusers-noresult": "搵唔到用戶。",
+       "activeusers-submit": "顯示活躍用戶",
        "listgrouprights": "用戶組權限",
        "listgrouprights-summary": "下面係一個響呢個wiki定義咗嘅用戶權限一覽,同埋佢哋嘅存取權。\n更多有關個別權限嘅[[{{MediaWiki:Listgrouprights-helppage}}|更多細節]]可以響嗰度搵到。",
        "listgrouprights-key": "說明:\n* <span class=\"listgrouprights-granted\">畀咗嘅權限</span>\n* <span class=\"listgrouprights-revoked\">拎咗嘅權限</span>",
        "wlshowlast": "顯示最近 $1 個鐘 $2 日",
        "watchlistall2": "全部",
        "watchlist-hide": "收埋",
+       "watchlist-submit": "顯示",
        "wlshowtime": "顯示最後:",
        "wlshowhideminor": "細編輯",
        "wlshowhidebots": "機械人",
        "contributions": "{{GENDER:$1|用戶}}貢獻",
        "contributions-title": "$1嘅用戶貢獻",
        "mycontris": "個人貢獻",
+       "anoncontribs": "貢獻",
        "contribsub2": "{{GENDER:$3|$1}}嘅貢獻 ($2)",
        "contributions-userdoesnotexist": "用戶「$1」未有註冊。",
        "nocontribs": "搵唔到符合呢啲條件嘅修改。",
        "whatlinkshere-hidelinks": "$1連結",
        "whatlinkshere-hideimages": "$1檔案連結",
        "whatlinkshere-filters": "過濾器",
+       "whatlinkshere-submit": "去",
        "autoblockid": "自動封鎖 #$1",
        "block": "封鎖用戶",
        "unblock": "解封用戶",
        "movenosubpage": "呢版無細頁。",
        "movereason": "原因",
        "revertmove": "恢復",
-       "delete_and_move": "刪除並移動",
        "delete_and_move_text": "==需要刪除==\n\n目標頁「[[:$1]]」已經存在。你要唔要刪咗佢空個位出嚟畀個搬文動作?",
        "delete_and_move_confirm": "好,刪咗嗰個頁面",
        "delete_and_move_reason": "已經刪咗「[[$1]]」嚟畀位畀個搬文動作",
index 2d2bb8a..e0b7c49 100644 (file)
        "tog-watchlisthidebots": "隐藏监视列表中的机器人编辑",
        "tog-watchlisthideminor": "隐藏监视列表中的小编辑",
        "tog-watchlisthideliu": "隐藏监视列表中的登录用户的编辑",
+       "tog-watchlistreloadautomatically": "当一条过滤器规则被更改时,自动重新加载监视列表(需要JavaScript)",
        "tog-watchlisthideanons": "隐藏监视列表中的匿名用户的编辑",
        "tog-watchlisthidepatrolled": "隐藏监视列表中的已巡查编辑",
        "tog-watchlisthidecategorization": "隐藏对页面的分类",
        "morenotlisted": "本列表不完整。",
        "mypage": "页面",
        "mytalk": "讨论",
-       "anontalk": "该IPå\9c°å\9d\80ç\9a\84讨论",
+       "anontalk": "讨论",
        "navigation": "导航",
        "and": "和",
        "qbfind": "查找",
        "databaseerror-query": "查询:$1",
        "databaseerror-function": "函数:$1",
        "databaseerror-error": "错误:$1",
+       "transaction-duration-limit-exceeded": "因为写入时间($1)超过了$2秒的限制,为防止创建大量复制延迟,此次处理已被中止。如果您正在同时更改很多项目,请尝试进行多次小规模操作。",
        "laggedslavemode": "'''警告:'''页面中可能没有包含最近的更新。",
        "readonly": "数据库被锁定",
        "enterlockreason": "请输入锁定的原因,这包括预计解除锁定的时间",
        "wrongpasswordempty": "密码输入为空。请重试。",
        "passwordtooshort": "您的密码至少需要$1个字符。",
        "passwordtoolong": "密码不能超过{{PLURAL:$1|$1个字符}}。",
+       "passwordtoopopular": "不能使用普遍选择的密码。请选择一个更独一无二的密码。",
        "password-name-match": "您的密码必须和您的用户名不相同。",
        "password-login-forbidden": "这个用户名称及密码的使用是被禁止的。",
        "mailmypassword": "重置密码",
        "passwordreset-emailtext-ip": "有人(可能是您,来自IP地址$1)请求重设{{SITENAME}}($4)上相关账户的密码。以下$3个账户与该电子邮件地址关联:\n\n$2\n\n这个临时密码将会在{{PLURAL:$5|一天|$5天}}后过期。请立即登录并设置新的密码。如果请求是其他人发出的,或者您已回忆起您的旧密码并不再需要更改,您可以忽略本条消息并继续使用原密码。",
        "passwordreset-emailtext-user": "用户$1请求重设{{SITENAME}}($4)上您的账户的密码。{{PLURAL:$3|以下账户|此账户}}与该电子邮件地址关联:\n\n$2\n\n这个临时密码将会在{{PLURAL:$5|一天|$5天}}后过期。请立即登录并设置新的密码。如果请求是其他人发出的,或者您已回忆起您的旧密码并不再需要更改,您可以忽略本条消息并继续使用原密码。",
        "passwordreset-emailelement": "用户名:\n$1\n\n临时密码:\n$2",
-       "passwordreset-emailsent": "如果您的账户有一个已注册的电子邮件地址的话,将发送一封密码重置邮件。",
+       "passwordreset-emailsentemail": "如果您的账户有一个已注册的电子邮件地址的话,将发送一封密码重置邮件。",
+       "passwordreset-emailsentusername": "如果有对应注册的电子邮件地址的话,将发送一封密码重置邮件。",
        "passwordreset-emailsent-capture": "密码重设电子邮件已发送,并在下面显示。",
        "passwordreset-emailerror-capture": "重置密码邮件已生成,但是无法向{{GENDER:$2|下列用户}} 发送:$1",
        "changeemail": "更改或移除电子邮件地址",
        "recentchanges-legend-heading": "'''说明:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}(见[[Special:NewPages|新页面列表]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
+       "recentchanges-submit": "显示",
        "rcnotefrom": "下面{{PLURAL:$5|是}}<strong>$3 $4</strong>之后的更改(最多显示<strong>$1</strong>个)。",
        "rclistfrom": "显示$3 $2之后的新更改",
        "rcshowhideminor": "$1小编辑",
        "mostrevisions": "有最多版本的页面",
        "prefixindex": "所有有前缀的页面",
        "prefixindex-namespace": "所有有前缀的页面($1名字空间)",
+       "prefixindex-submit": "显示",
        "prefixindex-strip": "在列表中除去前缀",
        "shortpages": "短页面",
        "longpages": "长页面",
        "protectedpages-performer": "保护用户",
        "protectedpages-params": "保护参数",
        "protectedpages-reason": "原因",
+       "protectedpages-submit": "显示页面",
        "protectedpages-unknown-timestamp": "未知",
        "protectedpages-unknown-performer": "未知用户",
        "protectedtitles": "受保护标题",
        "protectedtitles-summary": "本页面列出当前限制创建的标题。要浏览受限制页面的列表,请参见[[{{#special:ProtectedPages}}|{{int:protectedpages}}]]。",
        "protectedtitlesempty": "在这些参数之下并无标题正在保护。",
+       "protectedtitles-submit": "显示标题",
        "listusers": "用户列表",
        "listusers-editsonly": "只显示有编辑的用户",
        "listusers-creationsort": "按创建日期排序",
        "activeusers-hidebots": "隐藏机器人",
        "activeusers-hidesysops": "隐藏管理员",
        "activeusers-noresult": "找不到用户。",
+       "activeusers-submit": "显示活跃用户",
        "listgrouprights": "用户组权限",
        "listgrouprights-summary": "以下是在本wiki定义的用户组及它们的相关访问权限的列表。可能有关于单个权限的[[{{MediaWiki:Listgrouprights-helppage}}|附加信息]]。",
        "listgrouprights-key": "说明:\n* <span class=\"listgrouprights-granted\">被授予的权限</span>\n* <span class=\"listgrouprights-revoked\">被取消的权限</span>",
        "wlshowlast": "显示过去$1小时$2天",
        "watchlistall2": "所有",
        "watchlist-hide": "隐藏",
-       "wlshowtime": "显示最近:",
+       "watchlist-submit": "显示",
+       "wlshowtime": "显示时段:",
        "wlshowhideminor": "小编辑",
        "wlshowhidebots": "机器人",
        "wlshowhideliu": "注册用户",
        "contributions": "{{GENDER:$1|用户}}贡献",
        "contributions-title": "$1的用户贡献",
        "mycontris": "贡献",
+       "anoncontribs": "贡献",
        "contribsub2": "{{GENDER:$3|$1}}的贡献($2)",
        "contributions-userdoesnotexist": "用户“$1”尚未注册。",
        "nocontribs": "没有找到匹配这些规则的更改。",
        "whatlinkshere-hidelinks": "$1链接",
        "whatlinkshere-hideimages": "$1文件链接",
        "whatlinkshere-filters": "过滤器",
+       "whatlinkshere-submit": "提交",
        "autoblockid": "自动封禁#$1",
        "block": "封禁用户",
        "unblock": "解封用户",
        "movenosubpage": "这个页面没有子页面。",
        "movereason": "原因:",
        "revertmove": "恢复",
-       "delete_and_move": "删除并移动",
        "delete_and_move_text": "== 需要删除 ==\n\n目标页面“[[:$1]]”已存在。是否确认删除该页面以便进行移动?",
        "delete_and_move_confirm": "是,删除该页面",
        "delete_and_move_reason": "删除以便移动[[$1]]",
        "tooltip-pt-preferences": "你的设置",
        "tooltip-pt-watchlist": "你正在监视更改的页面的列表",
        "tooltip-pt-mycontris": "你的贡献的列表",
+       "tooltip-pt-anoncontribs": "来自此IP地址的编辑列表",
        "tooltip-pt-login": "我们鼓励您登录;然而,这不是强制性的",
        "tooltip-pt-logout": "退出登录",
        "tooltip-pt-createaccount": "建议您创建一个账户并登录,但这不是强制的",
        "autosumm-newblank": "创建空白页面",
        "size-bytes": "$1字节",
        "lag-warn-normal": "过去$1秒内的更改未必会在这个列表中显示。",
-       "lag-warn-high": "由于数据库的过度延迟,过去$1秒的更改未必会在这个列表中显示。",
+       "lag-warn-high": "由于数据库的过度延迟,$1秒内的更改未必会在这个列表中显示。",
        "watchlistedit-normal-title": "编辑监视列表",
        "watchlistedit-normal-legend": "从监视列表移除标题",
        "watchlistedit-normal-explain": "您的监视列表中的标题显示在下方。要移除标题,请勾选它旁边的复选框,然后点击“{{int:Watchlistedit-normal-submit}}”。您也可以[[Special:EditWatchlist/raw|编辑原始列表]]。",
index d23590d..b5b3d59 100644 (file)
                ]
        },
        "tog-underline": "底線標示連結:",
-       "tog-hideminor": "隱藏最近更改中的小修訂",
-       "tog-hidepatrolled": "隱藏最近更改中巡查過的編輯",
+       "tog-hideminor": "隱藏最近變更中的小修訂",
+       "tog-hidepatrolled": "隱藏最近變更中巡查過的編輯",
        "tog-newpageshidepatrolled": "隱藏新頁面清單中巡查過的頁面",
        "tog-hidecategorization": "隱藏頁面分類",
        "tog-extendwatchlist": "展開監視清單顯示包含最近以外的所有變更",
-       "tog-usenewrc": "依最近更改與監視清單的頁面分類顯示更改",
+       "tog-usenewrc": "依最近變更與監視清單的頁面分類顯示變更",
        "tog-numberheadings": "標題自動編號",
        "tog-showtoolbar": "顯示編輯工具列",
        "tog-editondblclick": "開啟滑鼠雙擊編輯頁面",
        "morenotlisted": "此清單尚未讀取完畢。",
        "mypage": "頁面",
        "mytalk": "對話",
-       "anontalk": "此 IP 位址的對話頁面",
+       "anontalk": "對話",
        "navigation": "導覽",
        "and": "&#32;和&#32;",
        "qbfind": "尋找",
        "site-atom-feed": "$1 的 Atom 摘要",
        "page-rss-feed": "\"$1\" 的 RSS 摘要",
        "page-atom-feed": "\"$1\" 的 Atom 摘要",
-       "red-link-title": "$1 (頁面不存在)",
+       "red-link-title": "$1(頁面不存在)",
        "sort-descending": "降冪排序",
        "sort-ascending": "昇冪排序",
        "nstab-main": "頁面",
        "viewsourcetext": "您可以檢視並複製此頁面的原始碼。",
        "viewyourtext": "您可以檢視並複製此頁面中<strong>您編輯</strong>的原始碼。",
        "protectedinterface": "本頁用來提供此 Wiki 軟體介面上的文字,並且已被設為保護以防止惡意修改。\n如欲增加或修改 Wiki 的翻譯,請至 [//translatewiki.net/ translatewiki.net] 上的 MediaWiki 在地化專案。",
-       "editinginterface": "<strong>警告:</strong>您正在編輯的頁面文字是用來作為軟體介面使用。\n更改此頁面將會影響其他使用者在此 Wiki 上看到的使用者介面。",
+       "editinginterface": "<strong>警告:</strong>您正在編輯的頁面文字是用來作為軟體介面使用。\n變更此頁面將會影響其他使用者在此 Wiki 上看到的使用者介面。",
        "translateinterface": "如欲修改 Wiki 的翻譯,請至 [//translatewiki.net/ translatewiki.net] 上的 MediaWiki 在地化專案。",
        "cascadeprotected": "此頁面被保護無法編輯,因為此頁面被以下開啟 \"連鎖保護\" 選項的{{PLURAL:$1|一頁|數頁}}保護頁面引用:\n$2",
        "namespaceprotected": "您沒有權限編輯 <strong>$1</strong> 命名空間的頁面。",
        "noemailprefs": "在您的偏好設定中設定電子郵件地址,讓您可以使用這些功能。",
        "emailconfirmlink": "確認您的電子郵件地址",
        "invalidemailaddress": "無法接受格式不正確的電子郵件地址,請輸入正確的電子郵件地址格式或略過填寫該欄位。",
-       "cannotchangeemail": "此 Wiki 不允許更改帳號的電子郵件地址。",
+       "cannotchangeemail": "此 Wiki 禁止變更帳號的電子郵件地址。",
        "emaildisabled": "此網站不能傳送電子郵件。",
        "accountcreated": "已建立帳號",
        "accountcreatedtext": "使用者帳號 [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|對話]]) 已建立。",
        "resetpass-no-info": "您必須直接登入存取這個頁面。",
        "resetpass-submit-loggedin": "變更密碼",
        "resetpass-submit-cancel": "取消",
-       "resetpass-wrong-oldpass": "無效的臨時或現有密碼。\n您可能早已成功地更改了您的密碼,或者已經請求一個新的臨時密碼。",
+       "resetpass-wrong-oldpass": "無效的臨時或現有密碼。\n您可能早已成功地變更了密碼,或者已經請求一個新的臨時密碼。",
        "resetpass-recycled": "請重設您的密碼為一個與目前不同的密碼。",
        "resetpass-temp-emailed": "您使用臨時電子郵件傳送的代碼登入。\n要完成登入,您必須在這裡設定一個新密碼:",
        "resetpass-temp-password": "臨時密碼:",
        "passwordreset-emailtext-ip": "不明人士 (可能是您自己,來自 IP 位址 $1) 要求重設在 {{SITENAME}} ($4) 的密碼,下列是與此電子郵件地址有關的使用者{{PLURAL:$3|帳號}}:\n\n$2\n\n{{PLURAL:$3|這個臨時密碼|這些臨時密碼}}將會在{{PLURAL:$5|一天|$5 天}}內到期,\n您應立即登入並更改新的密碼。如果不是您要求重設密碼,或您已想起密碼,並不準備修改,\n您可以忽略本訊息並且繼續使用您原本的密碼。",
        "passwordreset-emailtext-user": "使用者 $1 要求重設在 {{SITENAME}} ($4) 的密碼,下列是與此電子郵件位址有關的使用者{{PLURAL:$3|帳號}}:\n\n$2\n\n{{PLURAL:$3|這個臨時密碼|這些臨時密碼}}將會在{{PLURAL:$5|一天|$5 天}}內到期,\n您應立即登入並更改新的密碼。如果不是您要求重設密碼,或您已想起密碼,並不準備修改,\n您可以忽略此訊息並且繼續使用您原本的密碼。",
        "passwordreset-emailelement": "使用者名稱:\n$1\n\n臨時密碼:\n$2",
-       "passwordreset-emailsent": "若此確實為您帳號所登記的電子郵件地址,將會寄出重設密碼的信件給您。",
+       "passwordreset-emailsentemail": "若此確實為您帳號所登記的電子郵件地址,將會寄出重設密碼的信件給您。",
        "passwordreset-emailsent-capture": "已寄出重設密碼的電子郵件,並於下方顯示。",
        "passwordreset-emailerror-capture": "下列為重設密碼的電子郵件內容,傳送給{{GENDER:$2|使用者}}失敗:$1",
        "changeemail": "變更或移除電子郵件地址",
        "revdelete-failure": "無法更新修訂的顯示設定:\n$1",
        "logdelete-success": "已成功更新日誌的顯示設定。",
        "logdelete-failure": "無法更新日誌的顯示設定:\n$1",
-       "revdel-restore": "更改顯示設定",
+       "revdel-restore": "變更能見度",
        "pagehist": "頁面歷史",
        "deletedhist": "已刪除歷史",
        "revdelete-hide-current": "隱藏於 $1 $2 的項目錯誤:此為目前的修訂,不可隱藏。",
        "sessionfailure-title": "連線階段失敗",
        "sessionfailure": "您的登入連線階段似乎有問題,\n為了預防連線階段受到劫持攻擊,此動作已經被取消。\n請返回上一頁,重新讀取該頁面再試一次。",
        "changecontentmodel": "更改頁面的內容模型",
-       "changecontentmodel-legend": "更改內容模型",
+       "changecontentmodel-legend": "變更內容模型",
        "changecontentmodel-title-label": "頁面標題",
        "changecontentmodel-model-label": "新內容模型",
        "changecontentmodel-reason-label": "原因:",
        "contributions": "{{GENDER:$1|使用者}}貢獻",
        "contributions-title": "$1 的使用者貢獻",
        "mycontris": "貢獻",
+       "anoncontribs": "貢獻",
        "contribsub2": "{{GENDER:$3|$1}} 的貢獻 ($2)",
        "contributions-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。",
        "nocontribs": "沒有找到符合條件的變更。",
        "movenosubpage": "此頁面沒有任何子頁面。",
        "movereason": "原因",
        "revertmove": "還原",
-       "delete_and_move": "刪除並移動",
        "delete_and_move_text": "== 需要刪除 ==\n目標頁面 \"[[:$1]]\" 已存在。\n您是否要刪除該頁面以完成移動?",
        "delete_and_move_confirm": "是的,刪除該頁面",
        "delete_and_move_reason": "已刪除讓來自 [[$1]] 頁面可移動",
index 4e6f12b..ec20601 100644 (file)
@@ -360,6 +360,7 @@ $magicWords = array(
        'numberingroup'           => array( 1, 'NUMBERINGROUP', 'NUMINGROUP' ),
        'staticredirect'          => array( 1, '__STATICREDIRECT__' ),
        'protectionlevel'         => array( 1, 'PROTECTIONLEVEL' ),
+       'protectionexpiry'        => array( 1, 'PROTECTIONEXPIRY' ),
        'cascadingsources'        => array( 1, 'CASCADINGSOURCES' ),
        'formatdate'              => array( 0, 'formatdate', 'dateformat' ),
        'url_path'                => array( 0, 'PATH' ),
index 38265ae..0da2291 100644 (file)
@@ -20,7 +20,6 @@
  * @author Gjue
  * @author Ha98574
  * @author Hoo
- * @author Hym411
  * @author IRTC1015
  * @author ITurtle
  * @author Idh0854
@@ -128,7 +127,7 @@ $specialPageAliases = array(
        'Mostlinkedcategories'      => array( '많이쓰는분류' ),
        'Mostlinkedtemplates'       => array( '많이쓰는틀' ),
        'Mostrevisions'             => array( '역사긴문서' ),
-       'Movepage'                  => array( 'ì\98®ê¸°ê¸°', '문ì\84\9cì\98®ê¸°ê¸°', 'ì\9d´ë\8f\99', '문ì\84\9cì\9d´ë\8f\99' ),
+       'Movepage'                  => array( 'ì\9d´ë\8f\99', '문ì\84\9cì\9d´ë\8f\99', 'ì\98®ê¸°ê¸°', '문ì\84\9cì\98®ê¸°ê¸°' ),
        'Mycontributions'           => array( '내기여', '내기여목록' ),
        'MyLanguage'                => array( '내언어' ),
        'Mypage'                    => array( '내사용자문서' ),
index 30bb6ad..8d0b1c4 100644 (file)
@@ -90,9 +90,6 @@ installations.
        runJobs.php
        Immediately complete all jobs in the job queue
 
-       showCacheStats.php
-       Show all statistics stored in the cache
-
        undelete.php
        Undelete all revisions of a page
 
index 42c1eb7..9eca73c 100644 (file)
@@ -63,7 +63,7 @@ class BenchmarkPurge extends Benchmarker {
        private function benchSquid( $urls, $trials = 1 ) {
                $start = microtime( true );
                for ( $i = 0; $i < $trials; $i++ ) {
-                       SquidUpdate::purge( $urls );
+                       CdnCacheUpdate::purge( $urls );
                }
                $delta = microtime( true ) - $start;
                $pertrial = $delta / $trials;
index 915a2c0..1bd0217 100644 (file)
@@ -2,10 +2,6 @@
 /**
  * Clean up broken, unparseable upload filenames.
  *
- * Usage: php cleanupImages.php [--fix]
- * Options:
- *   --fix  Actually clean up titles; otherwise just checks for them
- *
  * Copyright © 2005-2006 Brion Vibber <brion@pobox.com>
  * https://www.mediawiki.org/
  *
index ae05930..68f57a3 100644 (file)
@@ -58,20 +58,6 @@ class CleanupRemovedModules extends Maintenance {
                        wfWaitForSlaves();
                } while ( $numRows > 0 );
                $this->output( "done\n" );
-
-               $this->output( "Cleaning up msg_resource table...\n" );
-               $i = 1;
-
-               $mrRes = $dbw->tableName( 'msg_resource' );
-               do {
-                       $where = $moduleList ? "mr_resource NOT IN ($moduleList)" : '1=1';
-                       $dbw->query( "DELETE FROM $mrRes WHERE $where LIMIT $limit", __METHOD__ );
-                       $numRows = $dbw->affectedRows();
-                       $this->output( "Batch $i: $numRows rows\n" );
-                       $i++;
-                       wfWaitForSlaves();
-               } while ( $numRows > 0 );
-               $this->output( "done\n" );
        }
 }
 
index 84e3aee..8368c84 100644 (file)
@@ -173,9 +173,3 @@ class TableCleanup extends Maintenance {
        }
 }
 
-class TableCleanupTest extends TableCleanup {
-       function processRow( $row ) {
-               $this->progress( mt_rand( 0, 1 ) );
-       }
-}
-
index 0df9e7f..1eba303 100644 (file)
@@ -2,10 +2,6 @@
 /**
  * Clean up broken, unparseable titles.
  *
- * Usage: php cleanupTitles.php [--fix]
- * Options:
- *   --fix  Actually clean up titles; otherwise just checks for them
- *
  * Copyright © 2005 Brion Vibber <brion@pobox.com>
  * https://www.mediawiki.org/
  *
diff --git a/maintenance/clearCacheStats.php b/maintenance/clearCacheStats.php
deleted file mode 100644 (file)
index 6a96612..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * Removes all statistics tracking from the cache.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/Maintenance.php';
-
-/**
- * Maintenance script to remove all statistics tracking from the cache.
- *
- * @ingroup Maintenance
- */
-class ClearCacheStats extends Maintenance {
-
-       public function __construct() {
-               parent::__construct();
-               $this->mDescription = "Remove all statistics tracking from the cache";
-       }
-
-       public function execute() {
-               global $wgLocalDatabases, $wgMemc;
-               foreach ( $wgLocalDatabases as $db ) {
-                       $wgMemc->delete( "$db:stats:request_with_session" );
-                       $wgMemc->delete( "$db:stats:request_without_session" );
-                       $wgMemc->delete( "$db:stats:pcache_hit" );
-                       $wgMemc->delete( "$db:stats:pcache_miss_expired" );
-                       $wgMemc->delete( "$db:stats:pcache_miss_absent" );
-                       $wgMemc->delete( "$db:stats:pcache_miss_stub" );
-                       $wgMemc->delete( "$db:stats:image_cache_hit" );
-                       $wgMemc->delete( "$db:stats:image_cache_miss" );
-                       $wgMemc->delete( "$db:stats:image_cache_update" );
-                       $wgMemc->delete( "$db:stats:diff_cache_hit" );
-                       $wgMemc->delete( "$db:stats:diff_cache_miss" );
-                       $wgMemc->delete( "$db:stats:diff_uncacheable" );
-                       $wgMemc->delete( "$db:stats:job-insert" );
-                       $wgMemc->delete( "$db:stats:job-pop" );
-               }
-       }
-}
-
-$maintClass = "ClearCacheStats";
-require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/createCommonPasswordCdb.php b/maintenance/createCommonPasswordCdb.php
new file mode 100644 (file)
index 0000000..c678712
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Create serialized/commonpasswords.cdb
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script to create common password cdb database.
+ *
+ * Meant to take a file like
+ * https://github.com/danielmiessler/SecLists/blob/master/Passwords/rockyou.txt?raw=true
+ * as input.
+ * @see serialized/commonpasswords.cdb and PasswordPolicyChecks::checkPopularPasswordBlacklist
+ * @since 1.27
+ * @ingroup Maintenance
+ */
+class GenerateCommonPassword extends Maintenance {
+       public function __construct() {
+               global $IP;
+               parent::__construct();
+               $this->mDescription = "Generate CDB file of common passwords";
+               $this->addOption( 'limit', "Max number of passwords to write", false, true, 'l' );
+               $this->addArg( 'inputfile', 'List of passwords (one per line) to use or - for stdin', true );
+               $this->addArg(
+                       'output',
+                       "Location to write CDB file to (Try $IP/serialized/commonpasswords.cdb)",
+                       true
+               );
+       }
+
+       public function execute() {
+               $limit = (int)$this->getOption( 'limit', PHP_INT_MAX );
+               $langEn = Language::factory( 'en' );
+
+               $infile = $this->getArg( 0 );
+               if ( $infile === '-' ) {
+                       $infile = 'php://stdin';
+               }
+               $outfile = $this->getArg( 1 );
+
+               if ( !is_readable( $infile ) && $infile !== 'php://stdin' ) {
+                       $this->error( "Cannot open input file $infile for reading", 1 );
+               }
+
+               $file = fopen( $infile, 'r' );
+               if ( $file === false ) {
+                       $this->error( "Cannot read input file $infile", 1 );
+               }
+
+               try {
+                       $db = \Cdb\Writer::open( $outfile );
+
+                       $alreadyWritten = array();
+                       $skipped = 0;
+                       for ( $i = 0; ( $i - $skipped ) < $limit; $i++ ) {
+                               if ( feof( $file ) ) {
+                                       break;
+                               }
+                               $rawLine = fgets( $file );
+
+                               if ( $rawLine === false ) {
+                                       $this->error( "Error reading input file" );
+                                       break;
+                               }
+                               if ( substr( $rawLine, -1 ) !== "\n" && !feof( $file ) ) {
+                                       // We're assuming that this just won't happen.
+                                       $this->error( "fgets did not return whole line at $i??" );
+                               }
+                               $line = $langEn->lc( trim( $rawLine ) );
+                               if ( $line === '' ) {
+                                       $this->error( "Line number " . ( $i + 1 ) . " is blank?" );
+                                       $skipped++;
+                                       continue;
+                               }
+                               if ( isset( $alreadyWritten[$line] ) ) {
+                                       $this->output( "Password '$line' already written (line " . ( $i + 1 ) .")\n" );
+                                       $skipped++;
+                                       continue;
+                               }
+                               $alreadyWritten[$line] = true;
+                               $db->set( $line, $i + 1 - $skipped );
+                       }
+                       // All caps, so cannot conflict with potential password
+                       $db->set( '_TOTALENTRIES', $i - $skipped );
+                       $db->close();
+
+                       $this->output( "Successfully wrote " . ( $i - $skipped ) .
+                               " (out of $i) passwords to $outfile\n"
+                       );
+               } catch ( \Cdb\Exception $e ) {
+                       $this->error( "Error writing cdb file: " . $e->getMessage(), 2 );
+               }
+
+       }
+}
+
+$maintClass = "GenerateCommonPassword";
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/makeTestEdits.php b/maintenance/makeTestEdits.php
new file mode 100644 (file)
index 0000000..c6569a0
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Make test edits for a user to populate a test wiki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Make test edits for a user to populate a test wiki
+ *
+ * @ingroup Maintenance
+ */
+class MakeTestEdits extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Make test edits for a user";
+               $this->addOption( 'user', 'User name', true, true );
+               $this->addOption( 'count', 'Number of edits', true, true );
+               $this->addOption( 'namespace', 'Namespace number', false, true );
+               $this->setBatchSize( 100 );
+       }
+
+       public function execute() {
+               $user = User::newFromName( $this->getOption( 'user' ) );
+               if ( !$user->getId() ) {
+                       $this->error( "No such user exists.", 1 );
+               }
+
+               $count = $this->getOption( 'count' );
+               $namespace = (int)$this->getOption( 'namespace', 0 );
+
+               for ( $i = 0; $i < $count; ++$i ) {
+                       $title = Title::makeTitleSafe( $namespace, "Page " . wfRandomString( 2 ) );
+                       $page = WikiPage::factory( $title );
+                       $content = ContentHandler::makeContent( wfRandomString(), $title );
+                       $summary = "Change " . wfRandomString( 6 );
+
+                       $page->doEditContent( $content, $summary, 0, false, $user );
+
+                       $this->output( "Edited $title\n" );
+                       if ( $i && ( $i % $this->mBatchSize ) == 0 ) {
+                               wfWaitForSlaves();
+                       }
+               }
+
+               $this->output( "Done\n" );
+       }
+}
+
+$maintClass = "MakeTestEdits";
+require_once RUN_MAINTENANCE_IF_MAIN;
index 12f6518..a332c41 100644 (file)
@@ -87,7 +87,7 @@ CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_name
 
 -- Create a dummy page to satisfy fk contraints especially with revisions
 INSERT INTO &mw_prefix.page
-  VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, NULL, 0, 0, NULL, NULL);
+  VALUES (0, 0, ' ', NULL, 0, 0, 0, current_timestamp, NULL, 0, 0, NULL, NULL);
 
 /*$mw$*/
 CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page
index 56e22c4..31500c9 100644 (file)
@@ -135,7 +135,7 @@ class PurgeChangedPages extends Maintenance {
                        }
 
                        // Send batch of purge requests out to squids
-                       $squid = new SquidUpdate( $urls, count( $urls ) );
+                       $squid = new CdnCacheUpdate( $urls, count( $urls ) );
                        $squid->doUpdate();
 
                        if ( $this->hasOption( 'sleep-per-batch' ) ) {
index 2e19630..31ea5d0 100644 (file)
@@ -129,7 +129,7 @@ class PurgeList extends Maintenance {
                                if ( $this->hasOption( 'verbose' ) ) {
                                        $this->output( $url . "\n" );
                                }
-                               $u = new SquidUpdate( array( $url ) );
+                               $u = new CdnCacheUpdate( array( $url ) );
                                $u->doUpdate();
                                usleep( $delay * 1e6 );
                        }
@@ -137,7 +137,7 @@ class PurgeList extends Maintenance {
                        if ( $this->hasOption( 'verbose' ) ) {
                                $this->output( implode( "\n", $urls ) . "\n" );
                        }
-                       $u = new SquidUpdate( $urls );
+                       $u = new CdnCacheUpdate( $urls );
                        $u->doUpdate();
                }
        }
diff --git a/maintenance/showCacheStats.php b/maintenance/showCacheStats.php
deleted file mode 100644 (file)
index 3d16af1..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-/**
- * Show statistics from the cache.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/Maintenance.php';
-
-/**
- * Maintenance script that shows statistics from the cache.
- *
- * @ingroup Maintenance
- */
-class ShowCacheStats extends Maintenance {
-
-       public function __construct() {
-               $this->mDescription = "Show statistics from the cache";
-               parent::__construct();
-       }
-
-       public function getDbType() {
-               return Maintenance::DB_NONE;
-       }
-
-       public function execute() {
-               global $wgMemc;
-
-               // Can't do stats if
-               if ( get_class( $wgMemc ) == 'EmptyBagOStuff' ) {
-                       $this->error( "You are running EmptyBagOStuff, I can not provide any statistics.", true );
-               }
-
-               $this->output( "\nParser cache\n" );
-               $hits = intval( $wgMemc->get( wfMemcKey( 'stats', 'pcache_hit' ) ) );
-               $expired = intval( $wgMemc->get( wfMemcKey( 'stats', 'pcache_miss_expired' ) ) );
-               $absent = intval( $wgMemc->get( wfMemcKey( 'stats', 'pcache_miss_absent' ) ) );
-               $stub = intval( $wgMemc->get( wfMemcKey( 'stats', 'pcache_miss_stub' ) ) );
-               $total = $hits + $expired + $absent + $stub;
-               if ( $total ) {
-                       $this->output( sprintf( "hits:              %-10d %6.2f%%\n", $hits, $hits / $total * 100 ) );
-                       $this->output( sprintf(
-                               "expired:           %-10d %6.2f%%\n",
-                               $expired,
-                               $expired / $total * 100
-                       ) );
-                       $this->output( sprintf(
-                               "absent:            %-10d %6.2f%%\n",
-                               $absent,
-                               $absent / $total * 100
-                       ) );
-                       $this->output( sprintf( "stub threshold:    %-10d %6.2f%%\n", $stub, $stub / $total * 100 ) );
-                       $this->output( sprintf( "total:             %-10d %6.2f%%\n", $total, 100 ) );
-               } else {
-                       $this->output( "no statistics available\n" );
-               }
-
-               $this->output( "\nImage cache\n" );
-               $hits = intval( $wgMemc->get( wfMemcKey( 'stats', 'image_cache_hit' ) ) );
-               $misses = intval( $wgMemc->get( wfMemcKey( 'stats', 'image_cache_miss' ) ) );
-               $updates = intval( $wgMemc->get( wfMemcKey( 'stats', 'image_cache_update' ) ) );
-               $total = $hits + $misses;
-               if ( $total ) {
-                       $this->output( sprintf( "hits:              %-10d %6.2f%%\n", $hits, $hits / $total * 100 ) );
-                       $this->output( sprintf(
-                               "misses:            %-10d %6.2f%%\n",
-                               $misses,
-                               $misses / $total * 100
-                       ) );
-                       $this->output( sprintf( "updates:           %-10d\n", $updates ) );
-               } else {
-                       $this->output( "no statistics available\n" );
-               }
-
-               $this->output( "\nDiff cache\n" );
-               $hits = intval( $wgMemc->get( wfMemcKey( 'stats', 'diff_cache_hit' ) ) );
-               $misses = intval( $wgMemc->get( wfMemcKey( 'stats', 'diff_cache_miss' ) ) );
-               $uncacheable = intval( $wgMemc->get( wfMemcKey( 'stats', 'diff_uncacheable' ) ) );
-               $total = $hits + $misses + $uncacheable;
-               if ( $total ) {
-                       $this->output( sprintf( "hits:              %-10d %6.2f%%\n", $hits, $hits / $total * 100 ) );
-                       $this->output( sprintf(
-                               "misses:            %-10d %6.2f%%\n",
-                               $misses,
-                               $misses / $total * 100
-                       ) );
-                       $this->output( sprintf(
-                               "uncacheable:       %-10d %6.2f%%\n",
-                               $uncacheable,
-                               $uncacheable / $total * 100
-                       ) );
-               } else {
-                       $this->output( "no statistics available\n" );
-               }
-       }
-}
-
-$maintClass = "ShowCacheStats";
-require_once RUN_MAINTENANCE_IF_MAIN;
index 209d325..08646d6 100644 (file)
@@ -12,7 +12,7 @@
     "grunt-contrib-copy": "0.8.1",
     "grunt-contrib-jshint": "0.11.3",
     "grunt-contrib-watch": "0.6.1",
-    "grunt-jscs": "2.1.0",
+    "grunt-jscs": "2.5.0",
     "grunt-jsonlint": "1.0.5",
     "grunt-karma": "0.12.1",
     "karma": "0.13.10",
index 0eb5118..d7320f5 100644 (file)
@@ -1065,6 +1065,7 @@ return array(
                'dependencies' => array(
                        'oojs',
                        'mediawiki.api',
+                       'mediawiki.ForeignApi',
                ),
                'targets' => array( 'desktop', 'mobile' ),
        ),
@@ -1270,6 +1271,12 @@ return array(
        ),
        'mediawiki.toc' => array(
                'scripts' => 'resources/src/mediawiki/mediawiki.toc.js',
+               'styles' => array(
+                       'resources/src/mediawiki/mediawiki.toc.css'
+                               => array( 'media' => 'screen' ),
+                       'resources/src/mediawiki/mediawiki.toc.print.css'
+                               => array( 'media' => 'print' ),
+               ),
                'dependencies' => 'mediawiki.cookie',
                'messages' => array( 'showtoc', 'hidetoc' ),
                'targets' => array( 'desktop', 'mobile' ),
@@ -1834,6 +1841,9 @@ return array(
                        'mediawiki.util',
                ),
        ),
+       'mediawiki.special.watchlist' => array(
+               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.watchlist.js',
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
index caf6dab..d3b74f2 100644 (file)
@@ -36,6 +36,7 @@ return call_user_func( function () {
        $modules['oojs-ui'] = array(
                'scripts' => array(
                        'resources/lib/oojs-ui/oojs-ui.js',
+                       'resources/src/oojs-ui-local.js',
                ),
                'skinScripts' => array_combine(
                        array_keys( $themes ),
@@ -51,6 +52,7 @@ return call_user_func( function () {
                        'oojs-ui.styles.icons',
                        'oojs-ui.styles.indicators',
                        'oojs-ui.styles.textures',
+                       'mediawiki.language',
                ),
                'messages' => array(
                        'ooui-dialog-message-accept',
index 02d57e0..c46ea01 100644 (file)
@@ -25,7 +25,7 @@
        "ooui-dialog-process-retry": "আবার চেষ্টা করুন",
        "ooui-dialog-process-continue": "অগ্রসর হোন",
        "ooui-selectfile-button-select": "একটি ফাইল নির্বাচন করুন",
-       "ooui-selectfile-not-supported": "à¦\9aিতà§\8dর à¦¨à¦¿à¦°à§\8dবাà¦\9aন à¦¸à¦®à¦°à§\8dথন à¦\95রà¦\9bà§\87 à¦¨à¦¾à¥¤",
-       "ooui-selectfile-placeholder": " কোন চিত্র নির্বাচিত হয়নি।",
+       "ooui-selectfile-not-supported": "à¦\9aিতà§\8dর à¦¨à¦¿à¦°à§\8dবাà¦\9aন à¦¸à¦®à¦°à§\8dথিত à¦¨à¦¯à¦¼",
+       "ooui-selectfile-placeholder": "কোন চিত্র নির্বাচিত হয়নি",
        "ooui-selectfile-dragdrop-placeholder": "এখানে ফাইল ছাড়ুন"
 }
diff --git a/resources/lib/oojs-ui/i18n/lki.json b/resources/lib/oojs-ui/i18n/lki.json
new file mode 100644 (file)
index 0000000..ec17c9b
--- /dev/null
@@ -0,0 +1,23 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Hosseinblue"
+               ]
+       },
+       "ooui-outline-control-move-down": "جاوواز کردن ئإ هووار",
+       "ooui-outline-control-move-up": "جاوواز کردن ئإ بِلِنگ",
+       "ooui-outline-control-remove": "حذف مورد",
+       "ooui-toolbar-more": "ویشتر/فرۀتر",
+       "ooui-toolgroup-expand": "ویشتر/فرۀتر",
+       "ooui-toolgroup-collapse": "کۀمتر",
+       "ooui-dialog-message-accept": "خوو/ باشد",
+       "ooui-dialog-message-reject": "ئآهووسانن-لغو",
+       "ooui-dialog-process-error": "مشکلی هۀس",
+       "ooui-dialog-process-dismiss": "رد کردن",
+       "ooui-dialog-process-retry": "دووآرۀ تلاش کۀ",
+       "ooui-dialog-process-continue": "ادامه-دؤم گرتن",
+       "ooui-selectfile-button-select": "فایلئ انتخاب کۀ",
+       "ooui-selectfile-not-supported": "انتخاب پرونده پشتیبانی نمی‌شود",
+       "ooui-selectfile-placeholder": "هیچ پرونده‌ای انتخاب نشده است",
+       "ooui-selectfile-dragdrop-placeholder": "فایل را اینجا رها کنید"
+}
index 8d9071a..d3d265c 100644 (file)
@@ -26,6 +26,7 @@
        "ooui-dialog-process-dismiss": "Ignorar",
        "ooui-dialog-process-retry": "Tentar novamente",
        "ooui-dialog-process-continue": "Continuar",
+       "ooui-selectfile-button-select": "Selecionar ficheiro",
        "ooui-selectfile-not-supported": "A seleção de ficheiros não é suportada",
        "ooui-selectfile-placeholder": "Nenhum ficheiro selecionado",
        "ooui-selectfile-dragdrop-placeholder": "Soltar ficheiro aqui"
diff --git a/resources/lib/oojs-ui/i18n/sd.json b/resources/lib/oojs-ui/i18n/sd.json
new file mode 100644 (file)
index 0000000..12c77e0
--- /dev/null
@@ -0,0 +1,22 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Mehtab ahmed"
+               ]
+       },
+       "ooui-outline-control-move-down": "شيءِ کي هيٺ چوريو",
+       "ooui-outline-control-move-up": "شيءِ کي مٿي چوريو",
+       "ooui-outline-control-remove": "شيءِ هٽايو",
+       "ooui-toolbar-more": "وڌيڪ",
+       "ooui-toolgroup-expand": "وڌيڪ",
+       "ooui-toolgroup-collapse": "گھٽ تر",
+       "ooui-dialog-message-accept": "ٺيڪ",
+       "ooui-dialog-message-reject": "رد",
+       "ooui-dialog-process-error": "ڪا غلطي ٿي",
+       "ooui-dialog-process-dismiss": "برخاست ڪريو",
+       "ooui-dialog-process-retry": "ٻيهر ڪوشش ڪريو",
+       "ooui-dialog-process-continue": "جاري رکو",
+       "ooui-selectfile-button-select": "ڪو فائيل چونڊِو",
+       "ooui-selectfile-placeholder": "ڪوبه فائيل چونڊيو نه ويو آهي",
+       "ooui-selectfile-dragdrop-placeholder": "فائيل کي هتي ڪيرايو"
+}
index d19bdc0..5e1caa8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.14.0
+ * OOjs UI v0.14.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-11-25T01:06:55Z
+ * Date: 2015-12-08T21:43:53Z
  */
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
        from {
 .oo-ui-horizontalLayout > .oo-ui-layout {
        display: inline-block;
 }
+.oo-ui-horizontalLayout > .oo-ui-layout,
 .oo-ui-horizontalLayout > .oo-ui-widget {
        margin-right: 0.5em;
 }
+.oo-ui-horizontalLayout > .oo-ui-layout:last-child,
 .oo-ui-horizontalLayout > .oo-ui-widget:last-child {
        margin-right: 0;
 }
+.oo-ui-horizontalLayout > .oo-ui-layout {
+       margin-bottom: 0;
+}
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
        z-index: 4;
        display: inline-block;
        position: relative;
 }
+.oo-ui-capsuleMultiSelectWidget-content {
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
+       display: none;
+}
 .oo-ui-capsuleMultiSelectWidget-group {
        display: inline;
 }
        cursor: text;
        min-height: 2.4em;
        margin-right: 0.5em;
-       padding: 0.25em 0;
+       padding: 0.15em 0.25em;
        border: 1px solid rgba(0, 0, 0, 0.1);
        border-radius: 0.25em;
        -webkit-box-sizing: border-box;
 .oo-ui-capsuleMultiSelectWidget-handle:last-child {
        margin-right: 0;
 }
-.oo-ui-capsuleMultiSelectWidget-handle .oo-ui-capsuleMultiSelectWidget-group {
-       margin: 0 0.2em;
-}
 .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
 .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
        position: absolute;
        background-position: center center;
        background-repeat: no-repeat;
 }
-.oo-ui-capsuleMultiSelectWidget-handle > input {
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
        border: none;
-       min-width: 1em;
-       max-width: 100%;
        line-height: 1.675em;
        margin: 0;
+       margin-left: 0.2em;
        padding: 0;
        font-size: inherit;
        font-family: inherit;
        color: black;
        vertical-align: middle;
 }
-.oo-ui-capsuleMultiSelectWidget-handle > input:focus {
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
        outline: none;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-right: 0.9375em;
+       padding-right: 2.4875em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
        right: 0;
        margin: 0.775em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-left: 1.875em;
+       padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
        left: 0;
                box-sizing: border-box;
        vertical-align: middle;
        padding: 0 0.4em;
-       margin: 0 0.1em;
+       margin: 0.1em;
        height: 1.7em;
        line-height: 1.7em;
        background: #eeeeee;
 .oo-ui-messageDialog-message {
        display: block;
        text-align: center;
+}
+.oo-ui-messageDialog-title.oo-ui-labelElement,
+.oo-ui-messageDialog-message.oo-ui-labelElement {
        padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
index 7dcadb9..7db559c 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.14.0
+ * OOjs UI v0.14.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-11-25T01:06:47Z
+ * Date: 2015-12-08T21:43:47Z
  */
 /**
  * @class
index 9fef769..a3ebbae 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.14.0
+ * OOjs UI v0.14.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-11-25T01:06:55Z
+ * Date: 2015-12-08T21:43:53Z
  */
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
        from {
 .oo-ui-horizontalLayout > .oo-ui-widget:last-child {
        margin-right: 0;
 }
-.oo-ui-horizontalLayout .oo-ui-fieldLayout {
+.oo-ui-horizontalLayout > .oo-ui-layout {
        margin-bottom: 0;
 }
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
        border-bottom: none;
        border-top-left-radius: 2px;
        border-top-right-radius: 2px;
-       color: #666666;
+       color: #555555;
        font-weight: bold;
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
        display: inline-block;
        position: relative;
 }
+.oo-ui-capsuleMultiSelectWidget-content {
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
+       display: none;
+}
 .oo-ui-capsuleMultiSelectWidget-group {
        display: inline;
 }
        cursor: text;
        min-height: 2.4em;
        margin-right: 0.5em;
-       padding: 0.25em 0;
+       padding: 0.15em 0.25em;
        border: 1px solid #cccccc;
        border-radius: 0.1em;
        -webkit-box-sizing: border-box;
 .oo-ui-capsuleMultiSelectWidget-handle:last-child {
        margin-right: 0;
 }
-.oo-ui-capsuleMultiSelectWidget-handle .oo-ui-capsuleMultiSelectWidget-group {
-       margin: 0 0.2em;
-}
 .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
 .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
        position: absolute;
        background-position: center center;
        background-repeat: no-repeat;
 }
-.oo-ui-capsuleMultiSelectWidget-handle > input {
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
        border: none;
-       min-width: 1em;
-       max-width: 100%;
        line-height: 1.675em;
        margin: 0;
+       margin-left: 0.2em;
        padding: 0;
        font-size: inherit;
        font-family: inherit;
        color: black;
        vertical-align: middle;
 }
-.oo-ui-capsuleMultiSelectWidget-handle > input:focus {
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
        outline: none;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-right: 0.9375em;
+       padding-right: 2.4875em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
        right: 0;
        margin: 0.775em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-left: 1.875em;
+       padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
        left: 0;
                box-sizing: border-box;
        vertical-align: middle;
        padding: 0 0.4em;
-       margin: 0 0.1em;
+       margin: 0.1em;
        height: 1.7em;
        line-height: 1.7em;
        background-color: #eeeeee;
 .oo-ui-messageDialog-message {
        display: block;
        text-align: center;
+}
+.oo-ui-messageDialog-title.oo-ui-labelElement,
+.oo-ui-messageDialog-message.oo-ui-labelElement {
        padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
 .oo-ui-messageDialog-message {
        font-size: 0.9em;
        line-height: 1.25em;
-       color: #666666;
+       color: #555555;
 }
 .oo-ui-messageDialog-message-verbose {
        font-size: 1.1em;
index ab2b505..677ab5b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.14.0
+ * OOjs UI v0.14.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-11-25T01:06:47Z
+ * Date: 2015-12-08T21:43:47Z
  */
 /**
  * @class
index f36814e..c77bfd7 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.14.0
+ * OOjs UI v0.14.1
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-11-25T01:06:47Z
+ * Date: 2015-12-08T21:43:47Z
  */
 ( function ( OO ) {
 
@@ -369,67 +369,150 @@ OO.ui.infuse = function ( idOrNode ) {
                }
                return message;
        };
+} )();
 
-       /**
-        * Package a message and arguments for deferred resolution.
-        *
-        * Use this when you are statically specifying a message and the message may not yet be present.
-        *
-        * @param {string} key Message key
-        * @param {Mixed...} [params] Message parameters
-        * @return {Function} Function that returns the resolved message when executed
-        */
-       OO.ui.deferMsg = function () {
-               var args = arguments;
-               return function () {
-                       return OO.ui.msg.apply( OO.ui, args );
-               };
+/**
+ * Package a message and arguments for deferred resolution.
+ *
+ * Use this when you are statically specifying a message and the message may not yet be present.
+ *
+ * @param {string} key Message key
+ * @param {Mixed...} [params] Message parameters
+ * @return {Function} Function that returns the resolved message when executed
+ */
+OO.ui.deferMsg = function () {
+       var args = arguments;
+       return function () {
+               return OO.ui.msg.apply( OO.ui, args );
        };
+};
 
-       /**
       * Resolve a message.
       *
       * If the message is a function it will be executed, otherwise it will pass through directly.
       *
       * @param {Function|string} msg Deferred message, or message text
       * @return {string} Resolved message
       */
-       OO.ui.resolveMsg = function ( msg ) {
-               if ( $.isFunction( msg ) ) {
-                       return msg();
-               }
-               return msg;
-       };
+/**
+ * Resolve a message.
+ *
+ * If the message is a function it will be executed, otherwise it will pass through directly.
+ *
+ * @param {Function|string} msg Deferred message, or message text
+ * @return {string} Resolved message
+ */
+OO.ui.resolveMsg = function ( msg ) {
+       if ( $.isFunction( msg ) ) {
+               return msg();
+       }
+       return msg;
+};
 
-       /**
       * @param {string} url
       * @return {boolean}
       */
-       OO.ui.isSafeUrl = function ( url ) {
-               var protocol,
-                       // Keep in sync with php/Tag.php
-                       whitelist = [
-                               'bitcoin:', 'ftp:', 'ftps:', 'geo:', 'git:', 'gopher:', 'http:', 'https:', 'irc:', 'ircs:',
-                               'magnet:', 'mailto:', 'mms:', 'news:', 'nntp:', 'redis:', 'sftp:', 'sip:', 'sips:', 'sms:', 'ssh:',
-                               'svn:', 'tel:', 'telnet:', 'urn:', 'worldwind:', 'xmpp:'
-                       ];
-
-               if ( url.indexOf( ':' ) === -1 ) {
-                       // No protocol, safe
-                       return true;
-               }
+/**
+ * @param {string} url
+ * @return {boolean}
+ */
+OO.ui.isSafeUrl = function ( url ) {
+       var protocol,
+               // Keep in sync with php/Tag.php
+               whitelist = [
+                       'bitcoin:', 'ftp:', 'ftps:', 'geo:', 'git:', 'gopher:', 'http:', 'https:', 'irc:', 'ircs:',
+                       'magnet:', 'mailto:', 'mms:', 'news:', 'nntp:', 'redis:', 'sftp:', 'sip:', 'sips:', 'sms:', 'ssh:',
+                       'svn:', 'tel:', 'telnet:', 'urn:', 'worldwind:', 'xmpp:'
+               ];
+
+       if ( url.indexOf( ':' ) === -1 ) {
+               // No protocol, safe
+               return true;
+       }
 
-               protocol = url.split( ':', 1 )[ 0 ] + ':';
-               if ( !protocol.match( /^([A-za-z0-9\+\.\-])+:/ ) ) {
-                       // Not a valid protocol, safe
-                       return true;
-               }
+       protocol = url.split( ':', 1 )[ 0 ] + ':';
+       if ( !protocol.match( /^([A-za-z0-9\+\.\-])+:/ ) ) {
+               // Not a valid protocol, safe
+               return true;
+       }
 
-               // Safe if in the whitelist
-               return whitelist.indexOf( protocol ) !== -1;
-       };
+       // Safe if in the whitelist
+       return whitelist.indexOf( protocol ) !== -1;
+};
 
-} )();
+/**
+ * Lazy-initialize and return a global OO.ui.WindowManager instance, used by OO.ui.alert and
+ * OO.ui.confirm.
+ *
+ * @private
+ * @return {OO.ui.WindowManager}
+ */
+OO.ui.getWindowManager = function () {
+       if ( !OO.ui.windowManager ) {
+               OO.ui.windowManager = new OO.ui.WindowManager();
+               $( 'body' ).append( OO.ui.windowManager.$element );
+               OO.ui.windowManager.addWindows( {
+                       messageDialog: new OO.ui.MessageDialog()
+               } );
+       }
+       return OO.ui.windowManager;
+};
+
+/**
+ * Display a quick modal alert dialog, using a OO.ui.MessageDialog. While the dialog is open, the
+ * rest of the page will be dimmed out and the user won't be able to interact with it. The dialog
+ * has only one action button, labelled "OK", clicking it will simply close the dialog.
+ *
+ * A window manager is created automatically when this function is called for the first time.
+ *
+ *     @example
+ *     OO.ui.alert( 'Something happened!' ).done( function () {
+ *         console.log( 'User closed the dialog.' );
+ *     } );
+ *
+ * @param {jQuery|string} text Message text to display
+ * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
+ * @return {jQuery.Promise} Promise resolved when the user closes the dialog
+ */
+OO.ui.alert = function ( text, options ) {
+       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
+               message: text,
+               verbose: true,
+               actions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]
+       }, options ) ).then( function ( opened ) {
+               return opened.then( function ( closing ) {
+                       return closing.then( function () {
+                               return $.Deferred().resolve();
+                       } );
+               } );
+       } );
+};
+
+/**
+ * Display a quick modal confirmation dialog, using a OO.ui.MessageDialog. While the dialog is open,
+ * the rest of the page will be dimmed out and the user won't be able to interact with it. The
+ * dialog has two action buttons, one to confirm an operation (labelled "OK") and one to cancel it
+ * (labelled "Cancel").
+ *
+ * A window manager is created automatically when this function is called for the first time.
+ *
+ *     @example
+ *     OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {
+ *         if ( confirmed ) {
+ *             console.log( 'User clicked "OK"!' );
+ *         } else {
+ *             console.log( 'User clicked "Cancel" or closed the dialog.' );
+ *         }
+ *     } );
+ *
+ * @param {jQuery|string} text Message text to display
+ * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
+ * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to
+ *  confirm, the promise will resolve to boolean `true`; otherwise, it will resolve to boolean
+ *  `false`.
+ */
+OO.ui.confirm = function ( text, options ) {
+       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
+               message: text,
+               verbose: true
+       }, options ) ).then( function ( opened ) {
+               return opened.then( function ( closing ) {
+                       return closing.then( function ( data ) {
+                               return $.Deferred().resolve( !!( data && data.action === 'accept' ) );
+                       } );
+               } );
+       } );
+};
 
 /*!
  * Mixin namespace.
@@ -4071,10 +4154,10 @@ OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
 /**
  * Get tools from the factory
  *
- * @param {Array} include Included tools
- * @param {Array} exclude Excluded tools
- * @param {Array} promote Promoted tools
- * @param {Array} demote Demoted tools
+ * @param {Array|string} [include] Included tools, see #extract for format
+ * @param {Array|string} [exclude] Excluded tools, see #extract for format
+ * @param {Array|string} [promote] Promoted tools, see #extract for format
+ * @param {Array|string} [demote] Demoted tools, see #extract for format
  * @return {string[]} List of tools
  */
 OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
@@ -4102,17 +4185,24 @@ OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, dem
 /**
  * Get a flat list of names from a list of names or groups.
  *
- * Tools can be specified in the following ways:
+ * Normally, `collection` is an array of tool specifications. Tools can be specified in the
+ * following ways:
  *
- * - A specific tool: `{ name: 'tool-name' }` or `'tool-name'`
- * - All tools in a group: `{ group: 'group-name' }`
- * - All tools: `'*'`
+ * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.
+ * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the
+ *   tool to a group, use OO.ui.Tool.static.group.)
+ *
+ * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the
+ * catch-all selector `'*'`.
+ *
+ * If `used` is passed, tool names that appear as properties in this object will be considered
+ * already assigned, and will not be returned even if specified otherwise. The tool names extracted
+ * by this function call will be added as new properties in the object.
  *
  * @private
- * @param {Array|string} collection List of tools
- * @param {Object} [used] Object with names that should be skipped as properties; extracted
- *  names will be added as properties
- * @return {string[]} List of extracted names
+ * @param {Array|string} collection List of tools, see above
+ * @param {Object} [used] Object containing information about used tools, see above
+ * @return {string[]} List of extracted tool names
  */
 OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
        var i, len, item, name, tool,
@@ -7224,6 +7314,11 @@ OO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {
  * out when the tool is selected. Tools must also be registered with a {@link OO.ui.ToolFactory tool factory},
  * which creates the tools on demand.
  *
+ * Every Tool subclass must implement two methods:
+ *
+ * - {@link #onUpdateState}
+ * - {@link #onSelect}
+ *
  * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},
  * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which determine how
  * the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an example.
@@ -7412,7 +7507,11 @@ OO.ui.Tool.static.isCompatibleWith = function () {
 /* Methods */
 
 /**
- * Handle the toolbar state being updated.
+ * Handle the toolbar state being updated. This method is called when the
+ * {@link OO.ui.Toolbar#event-updateState 'updateState' event} is emitted on the
+ * {@link OO.ui.Toolbar Toolbar} that uses this tool, and should set the state of this tool
+ * depending on application state (usually by calling #setDisabled to enable or disable the tool,
+ * or #setActive to mark is as currently in-use or not).
  *
  * This is an abstract method that must be overridden in a concrete subclass.
  *
@@ -7423,7 +7522,8 @@ OO.ui.Tool.static.isCompatibleWith = function () {
 OO.ui.Tool.prototype.onUpdateState = null;
 
 /**
- * Handle the tool being selected.
+ * Handle the tool being selected. This method is called when the user triggers this tool,
+ * usually by clicking on its label/icon.
  *
  * This is an abstract method that must be overridden in a concrete subclass.
  *
@@ -7542,6 +7642,13 @@ OO.ui.Tool.prototype.destroy = function () {
  * The arrangement and order of the toolgroups is customized when the toolbar is set up. Tools can be presented in
  * any order, but each can only appear once in the toolbar.
  *
+ * The toolbar can be synchronized with the state of the external "application", like a text
+ * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as
+ * active when the text cursor was inside bolded text) or enabled/disabled (e.g. a table caption
+ * tool would be disabled while the user is not editing a table). A state change is signalled by
+ * emitting the {@link #event-updateState 'updateState' event}, which calls Tools'
+ * {@link OO.ui.Tool#onUpdateState onUpdateState method}.
+ *
  * The following is an example of a basic toolbar.
  *
  *     @example
@@ -7557,23 +7664,24 @@ OO.ui.Tool.prototype.destroy = function () {
  *     // Define the tools that we're going to place in our toolbar
  *
  *     // Create a class inheriting from OO.ui.Tool
- *     function ImageTool() {
- *         ImageTool.parent.apply( this, arguments );
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
  *     }
- *     OO.inheritClass( ImageTool, OO.ui.Tool );
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
  *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
  *     // of 'icon' and 'title' (displayed icon and text).
- *     ImageTool.static.name = 'image';
- *     ImageTool.static.icon = 'image';
- *     ImageTool.static.title = 'Insert image';
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
  *     // Defines the action that will happen when this tool is selected (clicked).
- *     ImageTool.prototype.onSelect = function () {
- *         $area.text( 'Image tool clicked!' );
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
  *         // Never display this tool as "active" (selected).
  *         this.setActive( false );
  *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
  *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( ImageTool );
+ *     toolFactory.register( SearchTool );
  *
  *     // Register two more tools, nothing interesting here
  *     function SettingsTool() {
@@ -7587,6 +7695,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         $area.text( 'Settings tool clicked!' );
  *         this.setActive( false );
  *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( SettingsTool );
  *
  *     // Register two more tools, nothing interesting here
@@ -7601,6 +7710,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         $area.text( 'More stuff tool clicked!' );
  *         this.setActive( false );
  *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( StuffTool );
  *
  *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
@@ -7625,7 +7735,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         {
  *             // 'bar' tool groups display tools' icons only, side-by-side.
  *             type: 'bar',
- *             include: [ 'image', 'help' ]
+ *             include: [ 'search', 'help' ]
  *         },
  *         {
  *             // 'list' tool groups display both the titles and icons, in a dropdown list.
@@ -7657,9 +7767,10 @@ OO.ui.Tool.prototype.destroy = function () {
  *     // Here is where the toolbar is actually built. This must be done after inserting it into the
  *     // document.
  *     toolbar.initialize();
+ *     toolbar.emit( 'updateState' );
  *
  * The following example extends the previous one to illustrate 'menu' toolgroups and the usage of
- * 'updateState' event.
+ * {@link #event-updateState 'updateState' event}.
  *
  *     @example
  *     // Create the toolbar
@@ -7673,28 +7784,24 @@ OO.ui.Tool.prototype.destroy = function () {
  *     // Define the tools that we're going to place in our toolbar
  *
  *     // Create a class inheriting from OO.ui.Tool
- *     function ImageTool() {
- *         ImageTool.parent.apply( this, arguments );
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
  *     }
- *     OO.inheritClass( ImageTool, OO.ui.Tool );
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
  *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
  *     // of 'icon' and 'title' (displayed icon and text).
- *     ImageTool.static.name = 'image';
- *     ImageTool.static.icon = 'image';
- *     ImageTool.static.title = 'Insert image';
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
  *     // Defines the action that will happen when this tool is selected (clicked).
- *     ImageTool.prototype.onSelect = function () {
- *         $area.text( 'Image tool clicked!' );
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
  *         // Never display this tool as "active" (selected).
  *         this.setActive( false );
  *     };
- *     // The toolbar can be synchronized with the state of some external stuff, like a text
- *     // editor's editing area, highlighting the tools (e.g. a 'bold' tool would be shown as active
- *     // when the text cursor was inside bolded text). Here we simply disable this feature.
- *     ImageTool.prototype.onUpdateState = function () {
- *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
  *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( ImageTool );
+ *     toolFactory.register( SearchTool );
  *
  *     // Register two more tools, nothing interesting here
  *     function SettingsTool() {
@@ -7713,8 +7820,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         // To update the menu label
  *         this.toolbar.emit( 'updateState' );
  *     };
- *     SettingsTool.prototype.onUpdateState = function () {
- *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( SettingsTool );
  *
  *     // Register two more tools, nothing interesting here
@@ -7734,8 +7840,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         // To update the menu label
  *         this.toolbar.emit( 'updateState' );
  *     };
- *     StuffTool.prototype.onUpdateState = function () {
- *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( StuffTool );
  *
  *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
@@ -7760,7 +7865,7 @@ OO.ui.Tool.prototype.destroy = function () {
  *         {
  *             // 'bar' tool groups display tools' icons only, side-by-side.
  *             type: 'bar',
- *             include: [ 'image', 'help' ]
+ *             include: [ 'search', 'help' ]
  *         },
  *         {
  *             // 'menu' tool groups display both the titles and icons, in a dropdown menu.
@@ -7858,6 +7963,18 @@ OO.inheritClass( OO.ui.Toolbar, OO.ui.Element );
 OO.mixinClass( OO.ui.Toolbar, OO.EventEmitter );
 OO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );
 
+/* Events */
+
+/**
+ * @event updateState
+ *
+ * An 'updateState' event must be emitted on the Toolbar (by calling `toolbar.emit( 'updateState' )`)
+ * every time the state of the application using the toolbar changes, and an update to the state of
+ * tools is required.
+ *
+ * @param {Mixed...} data Application-defined parameters
+ */
+
 /* Methods */
 
 /**
@@ -8037,19 +8154,9 @@ OO.ui.Toolbar.prototype.getToolAccelerator = function () {
  * to which a tool belongs determines how the tool is arranged and displayed in the toolbar. Toolgroups
  * themselves are created on demand with a {@link OO.ui.ToolGroupFactory toolgroup factory}.
  *
- * Toolgroups can contain individual tools, groups of tools, or all available tools:
- *
- * To include an individual tool (or array of individual tools), specify tools by symbolic name:
- *
- *      include: [ 'tool-name' ] or [ { name: 'tool-name' }]
- *
- * To include a group of tools, specify the group name. (The tool's static ‘group’ config is used to assign the tool to a group.)
- *
- *      include: [ { group: 'group-name' } ]
- *
- *  To include all tools that are not yet assigned to a toolgroup, use the catch-all selector, an asterisk (*):
- *
- *      include: '*'
+ * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified
+ * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.
+ * The options `exclude`, `promote`, and `demote` support the same formats.
  *
  * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in general,
  * please see the [OOjs UI documentation on MediaWiki][1].
@@ -8064,10 +8171,10 @@ OO.ui.Toolbar.prototype.getToolAccelerator = function () {
  * @constructor
  * @param {OO.ui.Toolbar} toolbar
  * @param {Object} [config] Configuration options
- * @cfg {Array|string} [include=[]] List of tools to include in the toolgroup.
- * @cfg {Array|string} [exclude=[]] List of tools to exclude from the toolgroup.
- * @cfg {Array|string} [promote=[]] List of tools to promote to the beginning of the toolgroup.
- * @cfg {Array|string} [demote=[]] List of tools to demote to the end of the toolgroup.
+ * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.
+ * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.
+ * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup, see above.
+ * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.
  *  This setting is particularly useful when tools have been added to the toolgroup
  *  en masse (e.g., via the catch-all selector).
  */
@@ -8487,6 +8594,7 @@ OO.ui.MessageDialog.static.title = null;
  */
 OO.ui.MessageDialog.static.message = null;
 
+// Note that OO.ui.alert() and OO.ui.confirm() rely on these.
 OO.ui.MessageDialog.static.actions = [
        { action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' },
        { action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' }
@@ -11485,23 +11593,24 @@ OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );
  *     // Define the tools that we're going to place in our toolbar
  *
  *     // Create a class inheriting from OO.ui.Tool
- *     function ImageTool() {
- *         ImageTool.parent.apply( this, arguments );
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
  *     }
- *     OO.inheritClass( ImageTool, OO.ui.Tool );
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
  *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
  *     // of 'icon' and 'title' (displayed icon and text).
- *     ImageTool.static.name = 'image';
- *     ImageTool.static.icon = 'image';
- *     ImageTool.static.title = 'Insert image';
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
  *     // Defines the action that will happen when this tool is selected (clicked).
- *     ImageTool.prototype.onSelect = function () {
- *         $area.text( 'Image tool clicked!' );
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
  *         // Never display this tool as "active" (selected).
  *         this.setActive( false );
  *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
  *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( ImageTool );
+ *     toolFactory.register( SearchTool );
  *
  *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
  *     // little popup window (a PopupWidget).
@@ -11525,7 +11634,7 @@ OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );
  *         {
  *             // 'bar' tool groups display tools by icon only
  *             type: 'bar',
- *             include: [ 'image', 'help' ]
+ *             include: [ 'search', 'help' ]
  *         }
  *     ] );
  *
@@ -11827,6 +11936,7 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  *     SettingsTool.prototype.onSelect = function () {
  *         this.setActive( false );
  *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( SettingsTool );
  *     // Register two more tools, nothing interesting here
  *     function StuffTool() {
@@ -11834,11 +11944,12 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  *     }
  *     OO.inheritClass( StuffTool, OO.ui.Tool );
  *     StuffTool.static.name = 'stuff';
- *     StuffTool.static.icon = 'ellipsis';
+ *     StuffTool.static.icon = 'search';
  *     StuffTool.static.title = 'Change the world';
  *     StuffTool.prototype.onSelect = function () {
  *         this.setActive( false );
  *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( StuffTool );
  *     toolbar.setup( [
  *         {
@@ -11846,7 +11957,7 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  *             type: 'list',
  *             label: 'ListToolGroup',
  *             indicator: 'down',
- *             icon: 'image',
+ *             icon: 'ellipsis',
  *             title: 'This is the title, displayed when user moves the mouse over the list toolgroup',
  *             header: 'This is the header',
  *             include: [ 'settings', 'stuff' ],
@@ -12012,8 +12123,7 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
  * the menu label is empty. The menu can be configured with an indicator, icon, title, and/or header.
  *
  * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar
- * is set up. Note that all tools must define an {@link OO.ui.Tool#onUpdateState onUpdateState} method if
- * a MenuToolGroup is used.
+ * is set up.
  *
  *     @example
  *     // Example of a MenuToolGroup
@@ -12042,8 +12152,7 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
  *         // To update the menu label
  *         this.toolbar.emit( 'updateState' );
  *     };
- *     SettingsTool.prototype.onUpdateState = function () {
- *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( SettingsTool );
  *
  *     function StuffTool() {
@@ -12062,8 +12171,7 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
  *         // To update the menu label
  *         this.toolbar.emit( 'updateState' );
  *     };
- *     StuffTool.prototype.onUpdateState = function () {
- *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
  *     toolFactory.register( StuffTool );
  *
  *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
@@ -13400,6 +13508,7 @@ OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config )
        OO.ui.mixin.IconElement.call( this, config );
 
        // Properties
+       this.$content = $( '<div>' );
        this.allowArbitrary = !!config.allowArbitrary;
        this.$overlay = config.$overlay || this.$element;
        this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
@@ -13431,7 +13540,8 @@ OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config )
                this.$input.on( {
                        focus: this.onInputFocus.bind( this ),
                        blur: this.onInputBlur.bind( this ),
-                       'propertychange change click mouseup keydown keyup input cut paste select': this.onInputChange.bind( this ),
+                       'propertychange change click mouseup keydown keyup input cut paste select focus':
+                               OO.ui.debounce( this.updateInputSize.bind( this ) ),
                        keydown: this.onKeyDown.bind( this ),
                        keypress: this.onKeyPress.bind( this )
                } );
@@ -13442,7 +13552,7 @@ OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config )
                remove: 'onMenuItemsChange'
        } );
        this.$handle.on( {
-               click: this.onClick.bind( this )
+               mousedown: this.onMouseDown.bind( this )
        } );
 
        // Initialization
@@ -13452,21 +13562,23 @@ OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config )
                        role: 'combobox',
                        'aria-autocomplete': 'list'
                } );
-               this.$input.width( '1em' );
+               this.updateInputSize();
        }
        if ( config.data ) {
                this.setItemsFromData( config.data );
        }
+       this.$content.addClass( 'oo-ui-capsuleMultiSelectWidget-content' )
+               .append( this.$group );
        this.$group.addClass( 'oo-ui-capsuleMultiSelectWidget-group' );
        this.$handle.addClass( 'oo-ui-capsuleMultiSelectWidget-handle' )
-               .append( this.$indicator, this.$icon, this.$group );
+               .append( this.$indicator, this.$icon, this.$content );
        this.$element.addClass( 'oo-ui-capsuleMultiSelectWidget' )
                .append( this.$handle );
        if ( this.popup ) {
-               this.$handle.append( $tabFocus );
+               this.$content.append( $tabFocus );
                this.$overlay.append( this.popup.$element );
        } else {
-               this.$handle.append( this.$input );
+               this.$content.append( this.$input );
                this.$overlay.append( this.menu.$element );
        }
        this.onMenuItemsChange();
@@ -13631,6 +13743,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.addItems = function ( items ) {
        }
        if ( !same ) {
                this.emit( 'change', this.getItemsData() );
+               this.menu.position();
        }
 
        return this;
@@ -13655,6 +13768,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.removeItems = function ( items ) {
        }
        if ( !same ) {
                this.emit( 'change', this.getItemsData() );
+               this.menu.position();
        }
 
        return this;
@@ -13667,6 +13781,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.clearItems = function () {
        if ( this.items.length ) {
                OO.ui.mixin.GroupElement.prototype.clearItems.call( this );
                this.emit( 'change', this.getItemsData() );
+               this.menu.position();
        }
        return this;
 };
@@ -13742,15 +13857,17 @@ OO.ui.CapsuleMultiSelectWidget.prototype.onPopupFocusOut = function () {
 };
 
 /**
- * Handle mouse click events.
+ * Handle mouse down events.
  *
  * @private
- * @param {jQuery.Event} e Mouse click event
+ * @param {jQuery.Event} e Mouse down event
  */
-OO.ui.CapsuleMultiSelectWidget.prototype.onClick = function ( e ) {
+OO.ui.CapsuleMultiSelectWidget.prototype.onMouseDown = function ( e ) {
        if ( e.which === 1 ) {
                this.focus();
                return false;
+       } else {
+               this.updateInputSize();
        }
 };
 
@@ -13784,7 +13901,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.onKeyPress = function ( e ) {
                        }
 
                        // Make sure the input gets resized.
-                       setTimeout( this.onInputChange.bind( this ), 0 );
+                       setTimeout( this.updateInputSize.bind( this ), 0 );
                }
        }
 };
@@ -13808,14 +13925,42 @@ OO.ui.CapsuleMultiSelectWidget.prototype.onKeyDown = function ( e ) {
 };
 
 /**
- * Handle input change events.
+ * Update the dimensions of the text input field to encompass all available area.
  *
  * @private
  * @param {jQuery.Event} e Event of some sort
  */
-OO.ui.CapsuleMultiSelectWidget.prototype.onInputChange = function () {
+OO.ui.CapsuleMultiSelectWidget.prototype.updateInputSize = function () {
+       var $lastItem, direction, contentWidth, currentWidth, bestWidth;
        if ( !this.isDisabled() ) {
-               this.$input.width( this.$input.val().length + 'em' );
+               this.$input.css( 'width', '1em' );
+               $lastItem = this.$group.children().last();
+               direction = OO.ui.Element.static.getDir( this.$handle );
+               contentWidth = this.$input[ 0 ].scrollWidth;
+               currentWidth = this.$input.width();
+
+               if ( contentWidth < currentWidth ) {
+                       // All is fine, don't perform expensive calculations
+                       return;
+               }
+
+               if ( !$lastItem.length ) {
+                       bestWidth = this.$content.innerWidth();
+               } else {
+                       bestWidth = direction === 'ltr' ?
+                               this.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :
+                               $lastItem.position().left;
+               }
+               // Some safety margin for sanity, because I *really* don't feel like finding out where the few
+               // pixels this is off by are coming from.
+               bestWidth -= 10;
+               if ( contentWidth > bestWidth ) {
+                       // This will result in the input getting shifted to the next line
+                       bestWidth = this.$content.innerWidth() - 10;
+               }
+               this.$input.width( Math.floor( bestWidth ) );
+
+               this.menu.position();
        }
 };
 
@@ -13849,7 +13994,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.onMenuItemsChange = function () {
 OO.ui.CapsuleMultiSelectWidget.prototype.clearInput = function () {
        if ( this.$input ) {
                this.$input.val( '' );
-               this.$input.width( '1em' );
+               this.updateInputSize();
        }
        if ( this.popup ) {
                this.popup.toggle( false );
@@ -13902,6 +14047,7 @@ OO.ui.CapsuleMultiSelectWidget.prototype.focus = function () {
                                .first()
                                .focus();
                } else {
+                       this.updateInputSize();
                        this.menu.toggle( true );
                        this.$input.focus();
                }
index d6e3e8e..de70cd6 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/search.png and b/resources/lib/oojs-ui/themes/apex/images/icons/search.png differ
index 137150b..c2a4b27 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
     <g id="search">
-        <path id="search" d="M16.02 15.96l-2.373-2.375-.17-.1c.404-.565.644-1.26.644-2.008C14.12 9.557 12.567 8 10.648 8 8.727 8 7.17 9.557 7.17 11.478c0 1.92 1.556 3.477 3.477 3.477.75 0 1.442-.24 2.01-.643l.098.17 2.375 2.373c.19.19.542.143.79-.104s.292-.6.103-.79zm-5.376-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.996-2.213 2.217-2.213 1.222 0 2.213.992 2.213 2.213 0 1.222-.993 2.213-2.214 2.213z"/>
+        <path id="magnifying-glass" d="M18.87 18.375l-3.987-3.99-.286-.17c.68-.948 1.082-2.116 1.082-3.372C15.67 7.616 13.06 5 9.84 5 6.616 5 4 7.616 4 10.844c0 3.226 2.614 5.842 5.842 5.842 1.26 0 2.423-.403 3.377-1.08l.16.286 3.99 3.987c.32.31.91.24 1.33-.18.41-.42.49-1.01.17-1.33zM9.837 14.56c-2.05 0-3.718-1.663-3.718-3.717 0-2.05 1.67-3.72 3.72-3.72s3.72 1.668 3.72 3.72c0 2.053-1.67 3.718-3.72 3.718z"/>
     </g>
 </svg>
index 9b3c199..11b232c 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
     <g id="search">
-        <path id="path3051" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
+        <path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
     </g>
 </svg>
index 3201301..0679fa2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
     <g id="search">
-        <path id="path3051" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
+        <path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
     </g>
 </svg>
index cf4de68..0b7af8e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
     <g id="search">
-        <path id="path3051" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
+        <path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
     </g>
 </svg>
index 9b3c199..11b232c 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
     <g id="search">
-        <path id="path3051" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
+        <path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1c.404-.566.644-1.26.644-2.01-.002-1.92-1.56-3.476-3.478-3.476-1.92 0-3.478 1.557-3.478 3.478 0 1.92 1.557 3.477 3.478 3.477.75 0 1.442-.24 2.01-.647l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27c-1.22 0-2.213-.99-2.213-2.213 0-1.22.99-2.21 2.212-2.21 1.22 0 2.21.99 2.21 2.214s-.99 2.213-2.21 2.213z"/>
     </g>
 </svg>
index 41fe9bd..9b6ac9a 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
     <g id="search">
-        <path id="path3051" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
+        <path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
     </g>
 </svg>
index 3201301..0679fa2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
     <g id="search">
-        <path id="path3051" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
+        <path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1c-.404-.566-.644-1.26-.644-2.01.002-1.92 1.56-3.476 3.478-3.476 1.92 0 3.478 1.557 3.478 3.478 0 1.92-1.557 3.477-3.478 3.477-.75 0-1.442-.24-2.01-.647l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27c1.22 0 2.213-.99 2.213-2.213 0-1.22-.99-2.21-2.21-2.21S4.8 3.77 4.8 4.995 5.79 7.207 7.01 7.207z"/>
     </g>
 </svg>
index df6fff3..719eacb 100644 (file)
@@ -19,6 +19,7 @@
  * @class jQuery.plugin.suggestions
  */
 
+ // jscs:disable checkParamNames
 /**
  * @method suggestions
  * @chainable
@@ -93,6 +94,7 @@
  * @param {boolean} [options.highlightInput=false] Whether to highlight matched portions of the
  *  input or not.
  */
+ // jscs:enable checkParamNames
 
 ( function ( $ ) {
 
index 5cd4a7e..6de537a 100644 (file)
                                        diffHtml = query.pages[ query.pageids[ 0 ] ]
                                                .revisions[ 0 ].diff[ '*' ];
                                        $wikiDiff.find( 'table.diff tbody' ).html( diffHtml );
+                                       mw.hook( 'wikipage.diff' ).fire( $wikiDiff.find( 'table.diff' ) );
                                } catch ( e ) {
                                        // "result.blah is undefined" error, ignore
                                        mw.log.warn( e );
index ce565e0..453d928 100644 (file)
@@ -18,8 +18,6 @@ div.top,
 div#column-one,
 .mw-editsection,
 .mw-editsection-like,
-.toctoggle,
-#toc.tochidden,
 div#f-poweredbyico,
 div#f-copyrightico,
 li#about,
index 66161ed..77391d7 100644 (file)
@@ -212,11 +212,6 @@ table.toc td {
        margin: 0 0 0 2em;
 }
 
-#toc .toctoggle,
-.toc .toctoggle {
-       font-size: 94%;
-}
-
 .error {
        color: red;
        font-size: larger;
index 75a091c..daebac1 100644 (file)
@@ -872,8 +872,6 @@ table.floatleft {
 }
 
 .mw-editsection,
-.toctoggle,
-.tochidden,
 #jump-to-nav {
        -moz-user-select: none;
        -webkit-user-select: none;
index ad01865..862454d 100644 (file)
@@ -8,9 +8,10 @@
         *
         * @constructor
         * @param {mw.Title} title Wikitext page in a talk namespace, to post to
+        * @param {mw.Api} api mw.Api object to use
         */
-       function WikitextMessagePoster( title ) {
-               this.api = new mw.Api();
+       function WikitextMessagePoster( title, api ) {
+               this.api = api;
                this.title = title;
        }
 
index 4d0231f..b6dc2b4 100644 (file)
@@ -8,7 +8,6 @@
         * @singleton
         */
        function MwMessagePosterFactory() {
-               this.api = new mw.Api();
                this.contentModelToClass = {};
        }
 
@@ -50,6 +49,7 @@
         * API and ResourceLoader requests in the background.
         *
         * @param {mw.Title} title Title that will be posted to
+        * @param {string} [apiUrl] api.php URL if the title is on another wiki
         * @return {jQuery.Promise} Promise resolving to a mw.messagePoster.MessagePoster.
         *   For failure, rejected with up to three arguments:
         *
         *   - error Error explanation
         *   - details Further error details
         */
-       MwMessagePosterFactory.prototype.create = function ( title ) {
-               var pageId, page, contentModel, moduleName,
+       MwMessagePosterFactory.prototype.create = function ( title, apiUrl ) {
+               var pageId, page, contentModel, moduleName, api,
                        factory = this;
 
-               return this.api.get( {
+               if ( apiUrl ) {
+                       api = new mw.ForeignApi( apiUrl );
+               } else {
+                       api = mw.Api();
+               }
+
+               return api.get( {
                        action: 'query',
                        prop: 'info',
                        indexpageids: true,
@@ -76,7 +82,8 @@
                                return mw.loader.using( moduleName ).then( function () {
                                        return factory.createForContentModel(
                                                contentModel,
-                                               title
+                                               title,
+                                               api
                                        );
                                }, function () {
                                        return $.Deferred().reject( 'failed-to-load-module', 'Failed to load the \'' + moduleName + '\' module' );
         *
         * @param {string} contentModel Content model of title
         * @param {mw.Title} title Title being posted to
+        * @param {mw.Api} api mw.Api instance that the instance should use
         * @return {mw.messagePoster.MessagePoster}
         *
         */
-       MwMessagePosterFactory.prototype.createForContentModel = function ( contentModel, title ) {
-               return new this.contentModelToClass[ contentModel ]( title );
+       MwMessagePosterFactory.prototype.createForContentModel = function ( contentModel, title, api ) {
+               return new this.contentModelToClass[ contentModel ]( title, api );
        };
 
        mw.messagePoster = {
index 4399f3e..b069e50 100644 (file)
@@ -82,11 +82,6 @@ table.toc td {
        margin: 0 0 0 2em;
 }
 
-#toc .toctoggle,
-.toc .toctoggle {
-       font-size: 94%;
-}
-
 /* Separate columns for tocnumber and toctext */
 /* Ignored by IE7 and lower */
 .tocnumber,
diff --git a/resources/src/mediawiki.special/mediawiki.special.watchlist.js b/resources/src/mediawiki.special/mediawiki.special.watchlist.js
new file mode 100644 (file)
index 0000000..a35f4d1
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+ * JavaScript for Special:Watchlist
+ *
+ * This script is only loaded, if the user opt-in a setting in Special:Preferences,
+ * that the watchlist should be automatically reloaded, when a filter option is
+ * changed in the header form.
+ */
+jQuery( function ( $ ) {
+       // add a listener on all form elements in the header form
+       $( '#mw-watchlist-form input, #mw-watchlist-form select' ).on( 'change', function () {
+               // submit the form, when one of the input fields was changed
+               $( '#mw-watchlist-form' ).submit();
+       } );
+
+} );
index c26dd6a..10e0c56 100644 (file)
                 */
                badToken: function ( type ) {
                        var promiseGroup = promises[ this.defaults.ajax.url ];
+
+                       type = mapLegacyToken( type );
                        if ( promiseGroup ) {
                                delete promiseGroup[ type + 'Token' ];
                        }
index 5e79039..0117cea 100644 (file)
         * @return {string}
         */
        ForeignStructuredUpload.prototype.getDescriptions = function () {
-               var i, desc, hasEquals, templateCalls = [];
+               var i, desc, templateCalls = [];
 
                for ( i = 0; i < this.descriptions.length; i++ ) {
                        desc = this.descriptions[ i ];
-                       hasEquals = desc.text.indexOf( '=' ) !== -1;
-                       templateCalls.push( '{{' + desc.language + ( hasEquals ? '|1=' : '|' ) + desc.text + '}}' );
+                       templateCalls.push( '{{' + desc.language + '|1=' + desc.text + '}}' );
                }
 
                return templateCalls.join( '\n' );
index ebf0e7d..7afb9d3 100644 (file)
@@ -38,6 +38,7 @@
         * @param {Object} [config] Configuration object
         * @cfg {mw.Title} [title="Feedback"] The title of the page where you collect
         *  feedback.
+        * @cfg {string} [apiUrl] api.php URL if the feedback page is on another wiki
         * @cfg {string} [dialogTitleMessageKey="feedback-dialog-title"] Message key for the
         *  title of the dialog box
         * @cfg {mw.Uri|string} [bugsLink="//phabricator.wikimedia.org/maniphest/task/create/"] URL where
@@ -57,7 +58,7 @@
                // Feedback page title
                this.feedbackPageTitle = config.title || new mw.Title( 'Feedback' );
 
-               this.messagePosterPromise = mw.messagePoster.factory.create( this.feedbackPageTitle );
+               this.messagePosterPromise = mw.messagePoster.factory.create( this.feedbackPageTitle, config.apiUrl );
 
                // Links
                this.bugsTaskSubmissionLink = config.bugsLink || '//phabricator.wikimedia.org/maniphest/task/create/';
diff --git a/resources/src/mediawiki/mediawiki.toc.css b/resources/src/mediawiki/mediawiki.toc.css
new file mode 100644 (file)
index 0000000..835a451
--- /dev/null
@@ -0,0 +1,11 @@
+.tochidden,
+.toctoggle {
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
+
+.toctoggle {
+       font-size: 94%;
+}
diff --git a/resources/src/mediawiki/mediawiki.toc.print.css b/resources/src/mediawiki/mediawiki.toc.print.css
new file mode 100644 (file)
index 0000000..da2c08f
--- /dev/null
@@ -0,0 +1,4 @@
+#toc.tochidden,
+.toctoggle {
+       display: none;
+}
index d858b62..a097b17 100644 (file)
        }
 
        $( function () {
-               if ( mw.config.get( 'wgNamespaceNumber' ) !== 6 ) {
+               if ( mw.config.get( 'wgCanonicalNamespace' ) !== 'File' ) {
                        return;
                }
                $multipageimage = $( 'table.multipageimage' );
index 708dcb5..f2509e2 100644 (file)
                 *   root)
                 */
                mw.hook( 'wikipage.content' ).fire( $( '#mw-content-text' ) );
+
+               var $diff = $( 'table.diff' );
+               if ( $diff.length ) {
+                       /**
+                        * Fired when the diff is added to a page containing a diff
+                        *
+                        * Similar to the {@link mw.hook#event-wikipage_content wikipage.content hook}
+                        * $diff may still be detached when the hook is fired.
+                        *
+                        * @event wikipage_diff
+                        * @member mw.hook
+                        * @param {jQuery} $diff The root element of the MediaWiki diff (`table.diff`).
+                        */
+                       mw.hook( 'wikipage.diff' ).fire( $diff.eq( 0 ) );
+               }
        } );
 
 }( mediaWiki, jQuery ) );
diff --git a/resources/src/oojs-ui-local.js b/resources/src/oojs-ui-local.js
new file mode 100644 (file)
index 0000000..84ec92d
--- /dev/null
@@ -0,0 +1,5 @@
+// Connect OOjs UI to MediaWiki's localisation system
+( function ( mw ) {
+       OO.ui.getUserLanguages = mw.language.getFallbackLanguageChain;
+       OO.ui.msg = mw.msg;
+}( mediaWiki ) );
diff --git a/serialized/commonpasswords.cdb b/serialized/commonpasswords.cdb
new file mode 100644 (file)
index 0000000..7b7b043
Binary files /dev/null and b/serialized/commonpasswords.cdb differ
index 58860e9..c456fcb 100644 (file)
@@ -26339,3 +26339,12 @@ Empty LI (T49673)
 <li>b</li>
 </ul>
 !! end
+
+!! test
+reserved data attributes stripped
+!! wikitext
+<div data-mw="foo" data-parsoid="bar" data-mw-someext="baz" data-ok="fred" data-ooui="xyzzy">d</div>
+!! html
+<div data-ok="fred">d</div>
+
+!! end
index 9e4a984..fc2f743 100644 (file)
@@ -520,10 +520,17 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @since 1.21
         */
        public static function teardownTestDB() {
+               global $wgJobClasses;
+
                if ( !self::$dbSetup ) {
                        return;
                }
 
+               foreach ( $wgJobClasses as $type => $class ) {
+                       // Delete any jobs under the clone DB (or old prefix in other stores)
+                       JobQueueGroup::singleton()->get( $type )->delete();
+               }
+
                CloneDatabase::changePrefix( self::$oldTablePrefix );
 
                self::$oldTablePrefix = false;
index 7b60fb3..46ec6bc 100644 (file)
@@ -21,7 +21,6 @@ class ExtraParserTest extends MediaWikiTestCase {
                        'wgLanguageCode' => 'en',
                        'wgContLang' => $contLang,
                        'wgLang' => Language::factory( 'en' ),
-                       'wgMemc' => new EmptyBagOStuff,
                        'wgCleanSignatures' => true,
                ) );
 
index 5f21e07..f5ef016 100644 (file)
@@ -375,7 +375,6 @@ class NullMessageBlobStore extends MessageBlobStore {
        }
 
        public function updateModule( $name, ResourceLoaderModule $module, $lang ) {
-               return;
        }
 
        public function updateMessage( $key ) {
index 3b37f4a..ddef24a 100644 (file)
@@ -12,7 +12,6 @@ class TemplateParserTest extends MediaWikiTestCase {
 
                $this->setMwGlobals( array(
                        'wgSecretKey' => 'foo',
-                       'wgMemc' => new EmptyBagOStuff(),
                ) );
 
                $this->templateDir = dirname( __DIR__ ) . '/data/templates/';
index 1318d10..4dc8350 100644 (file)
@@ -31,7 +31,6 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $localOffset = date( 'Z' ) / 60;
 
                $this->setMwGlobals( array(
-                       'wgMemc' => new EmptyBagOStuff,
                        'wgContLang' => $langObj,
                        'wgLanguageCode' => 'en',
                        'wgLang' => $langObj,
diff --git a/tests/phpunit/includes/UserArrayFromResultTest.php b/tests/phpunit/includes/UserArrayFromResultTest.php
deleted file mode 100644 (file)
index 469ad29..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-/**
- * @author Adam Shorland
- * @covers UserArrayFromResult
- */
-class UserArrayFromResultTest extends MediaWikiTestCase {
-
-       private function getMockResultWrapper( $row = null, $numRows = 1 ) {
-               $resultWrapper = $this->getMockBuilder( 'ResultWrapper' )
-                       ->disableOriginalConstructor();
-
-               $resultWrapper = $resultWrapper->getMock();
-               $resultWrapper->expects( $this->atLeastOnce() )
-                       ->method( 'current' )
-                       ->will( $this->returnValue( $row ) );
-               $resultWrapper->expects( $this->any() )
-                       ->method( 'numRows' )
-                       ->will( $this->returnValue( $numRows ) );
-
-               return $resultWrapper;
-       }
-
-       private function getRowWithUsername( $username = 'fooUser' ) {
-               $row = new stdClass();
-               $row->user_name = $username;
-               return $row;
-       }
-
-       private function getUserArrayFromResult( $resultWrapper ) {
-               return new UserArrayFromResult( $resultWrapper );
-       }
-
-       /**
-        * @covers UserArrayFromResult::__construct
-        */
-       public function testConstructionWithFalseRow() {
-               $row = false;
-               $resultWrapper = $this->getMockResultWrapper( $row );
-
-               $object = $this->getUserArrayFromResult( $resultWrapper );
-
-               $this->assertEquals( $resultWrapper, $object->res );
-               $this->assertSame( 0, $object->key );
-               $this->assertEquals( $row, $object->current );
-       }
-
-       /**
-        * @covers UserArrayFromResult::__construct
-        */
-       public function testConstructionWithRow() {
-               $username = 'addshore';
-               $row = $this->getRowWithUsername( $username );
-               $resultWrapper = $this->getMockResultWrapper( $row );
-
-               $object = $this->getUserArrayFromResult( $resultWrapper );
-
-               $this->assertEquals( $resultWrapper, $object->res );
-               $this->assertSame( 0, $object->key );
-               $this->assertInstanceOf( 'User', $object->current );
-               $this->assertEquals( $username, $object->current->mName );
-       }
-
-       public static function provideNumberOfRows() {
-               return array(
-                       array( 0 ),
-                       array( 1 ),
-                       array( 122 ),
-               );
-       }
-
-       /**
-        * @dataProvider provideNumberOfRows
-        * @covers UserArrayFromResult::count
-        */
-       public function testCountWithVaryingValues( $numRows ) {
-               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper(
-                       $this->getRowWithUsername(),
-                       $numRows
-               ) );
-               $this->assertEquals( $numRows, $object->count() );
-       }
-
-       /**
-        * @covers UserArrayFromResult::current
-        */
-       public function testCurrentAfterConstruction() {
-               $username = 'addshore';
-               $userRow = $this->getRowWithUsername( $username );
-               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper( $userRow ) );
-               $this->assertInstanceOf( 'User', $object->current() );
-               $this->assertEquals( $username, $object->current()->mName );
-       }
-
-       public function provideTestValid() {
-               return array(
-                       array( $this->getRowWithUsername(), true ),
-                       array( false, false ),
-               );
-       }
-
-       /**
-        * @dataProvider provideTestValid
-        * @covers UserArrayFromResult::valid
-        */
-       public function testValid( $input, $expected ) {
-               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper( $input ) );
-               $this->assertEquals( $expected, $object->valid() );
-       }
-
-       // @todo unit test for key()
-       // @todo unit test for next()
-       // @todo unit test for rewind()
-}
diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php
deleted file mode 100644 (file)
index 4c6f083..0000000
+++ /dev/null
@@ -1,534 +0,0 @@
-<?php
-
-define( 'NS_UNITTEST', 5600 );
-define( 'NS_UNITTEST_TALK', 5601 );
-
-/**
- * @group Database
- */
-class UserTest extends MediaWikiTestCase {
-       /**
-        * @var User
-        */
-       protected $user;
-
-       protected function setUp() {
-               parent::setUp();
-
-               $this->setMwGlobals( array(
-                       'wgGroupPermissions' => array(),
-                       'wgRevokePermissions' => array(),
-               ) );
-
-               $this->setUpPermissionGlobals();
-
-               $this->user = new User;
-               $this->user->addGroup( 'unittesters' );
-       }
-
-       private function setUpPermissionGlobals() {
-               global $wgGroupPermissions, $wgRevokePermissions;
-
-               # Data for regular $wgGroupPermissions test
-               $wgGroupPermissions['unittesters'] = array(
-                       'test' => true,
-                       'runtest' => true,
-                       'writetest' => false,
-                       'nukeworld' => false,
-               );
-               $wgGroupPermissions['testwriters'] = array(
-                       'test' => true,
-                       'writetest' => true,
-                       'modifytest' => true,
-               );
-
-               # Data for regular $wgRevokePermissions test
-               $wgRevokePermissions['formertesters'] = array(
-                       'runtest' => true,
-               );
-
-               # For the options test
-               $wgGroupPermissions['*'] = array(
-                       'editmyoptions' => true,
-               );
-       }
-
-       /**
-        * @covers User::getGroupPermissions
-        */
-       public function testGroupPermissions() {
-               $rights = User::getGroupPermissions( array( 'unittesters' ) );
-               $this->assertContains( 'runtest', $rights );
-               $this->assertNotContains( 'writetest', $rights );
-               $this->assertNotContains( 'modifytest', $rights );
-               $this->assertNotContains( 'nukeworld', $rights );
-
-               $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) );
-               $this->assertContains( 'runtest', $rights );
-               $this->assertContains( 'writetest', $rights );
-               $this->assertContains( 'modifytest', $rights );
-               $this->assertNotContains( 'nukeworld', $rights );
-       }
-
-       /**
-        * @covers User::getGroupPermissions
-        */
-       public function testRevokePermissions() {
-               $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) );
-               $this->assertNotContains( 'runtest', $rights );
-               $this->assertNotContains( 'writetest', $rights );
-               $this->assertNotContains( 'modifytest', $rights );
-               $this->assertNotContains( 'nukeworld', $rights );
-       }
-
-       /**
-        * @covers User::getRights
-        */
-       public function testUserPermissions() {
-               $rights = $this->user->getRights();
-               $this->assertContains( 'runtest', $rights );
-               $this->assertNotContains( 'writetest', $rights );
-               $this->assertNotContains( 'modifytest', $rights );
-               $this->assertNotContains( 'nukeworld', $rights );
-       }
-
-       /**
-        * @dataProvider provideGetGroupsWithPermission
-        * @covers User::getGroupsWithPermission
-        */
-       public function testGetGroupsWithPermission( $expected, $right ) {
-               $result = User::getGroupsWithPermission( $right );
-               sort( $result );
-               sort( $expected );
-
-               $this->assertEquals( $expected, $result, "Groups with permission $right" );
-       }
-
-       public static function provideGetGroupsWithPermission() {
-               return array(
-                       array(
-                               array( 'unittesters', 'testwriters' ),
-                               'test'
-                       ),
-                       array(
-                               array( 'unittesters' ),
-                               'runtest'
-                       ),
-                       array(
-                               array( 'testwriters' ),
-                               'writetest'
-                       ),
-                       array(
-                               array( 'testwriters' ),
-                               'modifytest'
-                       ),
-               );
-       }
-
-       /**
-        * @dataProvider provideIPs
-        * @covers User::isIP
-        */
-       public function testIsIP( $value, $result, $message ) {
-               $this->assertEquals( $this->user->isIP( $value ), $result, $message );
-       }
-
-       public static function provideIPs() {
-               return array(
-                       array( '', false, 'Empty string' ),
-                       array( ' ', false, 'Blank space' ),
-                       array( '10.0.0.0', true, 'IPv4 private 10/8' ),
-                       array( '10.255.255.255', true, 'IPv4 private 10/8' ),
-                       array( '192.168.1.1', true, 'IPv4 private 192.168/16' ),
-                       array( '203.0.113.0', true, 'IPv4 example' ),
-                       array( '2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff', true, 'IPv6 example' ),
-                       // Not valid IPs but classified as such by MediaWiki for negated asserting
-                       // of whether this might be the identifier of a logged-out user or whether
-                       // to allow usernames like it.
-                       array( '300.300.300.300', true, 'Looks too much like an IPv4 address' ),
-                       array( '203.0.113.xxx', true, 'Assigned by UseMod to cloaked logged-out users' ),
-               );
-       }
-
-       /**
-        * @dataProvider provideUserNames
-        * @covers User::isValidUserName
-        */
-       public function testIsValidUserName( $username, $result, $message ) {
-               $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message );
-       }
-
-       public static function provideUserNames() {
-               return array(
-                       array( '', false, 'Empty string' ),
-                       array( ' ', false, 'Blank space' ),
-                       array( 'abcd', false, 'Starts with small letter' ),
-                       array( 'Ab/cd', false, 'Contains slash' ),
-                       array( 'Ab cd', true, 'Whitespace' ),
-                       array( '192.168.1.1', false, 'IP' ),
-                       array( 'User:Abcd', false, 'Reserved Namespace' ),
-                       array( '12abcd232', true, 'Starts with Numbers' ),
-                       array( '?abcd', true, 'Start with ? mark' ),
-                       array( '#abcd', false, 'Start with #' ),
-                       array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ),
-                       array( 'ജോസ്‌തോമസ്', false, 'ZWNJ- Format control character' ),
-                       array( 'Ab cd', false, ' Ideographic space' ),
-                       array( '300.300.300.300', false, 'Looks too much like an IPv4 address' ),
-                       array( '302.113.311.900', false, 'Looks too much like an IPv4 address' ),
-                       array( '203.0.113.xxx', false, 'Reserved for usage by UseMod for cloaked logged-out users' ),
-               );
-       }
-
-       /**
-        * Test, if for all rights a right- message exist,
-        * which is used on Special:ListGroupRights as help text
-        * Extensions and core
-        */
-       public function testAllRightsWithMessage() {
-               // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights
-               $allRights = User::getAllRights();
-               $allMessageKeys = Language::getMessageKeysFor( 'en' );
-
-               $rightsWithMessage = array();
-               foreach ( $allMessageKeys as $message ) {
-                       // === 0: must be at beginning of string (position 0)
-                       if ( strpos( $message, 'right-' ) === 0 ) {
-                               $rightsWithMessage[] = substr( $message, strlen( 'right-' ) );
-                       }
-               }
-
-               sort( $allRights );
-               sort( $rightsWithMessage );
-
-               $this->assertEquals(
-                       $allRights,
-                       $rightsWithMessage,
-                       'Each user rights (core/extensions) has a corresponding right- message.'
-               );
-       }
-
-       /**
-        * Test User::editCount
-        * @group medium
-        * @covers User::getEditCount
-        */
-       public function testEditCount() {
-               $user = User::newFromName( 'UnitTestUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               // let the user have a few (3) edits
-               $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
-               for ( $i = 0; $i < 3; $i++ ) {
-                       $page->doEdit( (string)$i, 'test', 0, false, $user );
-               }
-
-               $user->clearInstanceCache();
-               $this->assertEquals(
-                       3,
-                       $user->getEditCount(),
-                       'After three edits, the user edit count should be 3'
-               );
-
-               // increase the edit count and clear the cache
-               $user->incEditCount();
-
-               $user->clearInstanceCache();
-               $this->assertEquals(
-                       4,
-                       $user->getEditCount(),
-                       'After increasing the edit count manually, the user edit count should be 4'
-               );
-       }
-
-       /**
-        * Test changing user options.
-        * @covers User::setOption
-        * @covers User::getOption
-        */
-       public function testOptions() {
-               $user = User::newFromName( 'UnitTestUser' );
-
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               $user->setOption( 'userjs-someoption', 'test' );
-               $user->setOption( 'cols', 200 );
-               $user->saveSettings();
-
-               $user = User::newFromName( 'UnitTestUser' );
-               $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
-               $this->assertEquals( 200, $user->getOption( 'cols' ) );
-       }
-
-       /**
-        * Bug 37963
-        * Make sure defaults are loaded when setOption is called.
-        * @covers User::loadOptions
-        */
-       public function testAnonOptions() {
-               global $wgDefaultUserOptions;
-               $this->user->setOption( 'userjs-someoption', 'test' );
-               $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) );
-               $this->assertEquals( 'test', $this->user->getOption( 'userjs-someoption' ) );
-       }
-
-       /**
-        * Test password validity checks. There are 3 checks in core,
-        *      - ensure the password meets the minimal length
-        *      - ensure the password is not the same as the username
-        *      - ensure the username/password combo isn't forbidden
-        * @covers User::checkPasswordValidity()
-        * @covers User::getPasswordValidity()
-        * @covers User::isValidPassword()
-        */
-       public function testCheckPasswordValidity() {
-               $this->setMwGlobals( array(
-                       'wgPasswordPolicy' => array(
-                               'policies' => array(
-                                       'sysop' => array(
-                                               'MinimalPasswordLength' => 8,
-                                               'MinimumPasswordLengthToLogin' => 1,
-                                               'PasswordCannotMatchUsername' => 1,
-                                       ),
-                                       'default' => array(
-                                               'MinimalPasswordLength' => 6,
-                                               'PasswordCannotMatchUsername' => true,
-                                               'PasswordCannotMatchBlacklist' => true,
-                                               'MaximalPasswordLength' => 30,
-                                       ),
-                               ),
-                               'checks' => array(
-                                       'MinimalPasswordLength' => 'PasswordPolicyChecks::checkMinimalPasswordLength',
-                                       'MinimumPasswordLengthToLogin' => 'PasswordPolicyChecks::checkMinimumPasswordLengthToLogin',
-                                       'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
-                                       'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
-                                       'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
-                               ),
-                       ),
-               ) );
-
-               $user = User::newFromName( 'Useruser' );
-               // Sanity
-               $this->assertTrue( $user->isValidPassword( 'Password1234' ) );
-
-               // Minimum length
-               $this->assertFalse( $user->isValidPassword( 'a' ) );
-               $this->assertFalse( $user->checkPasswordValidity( 'a' )->isGood() );
-               $this->assertTrue( $user->checkPasswordValidity( 'a' )->isOK() );
-               $this->assertEquals( 'passwordtooshort', $user->getPasswordValidity( 'a' ) );
-
-               // Maximum length
-               $longPass = str_repeat( 'a', 31 );
-               $this->assertFalse( $user->isValidPassword( $longPass ) );
-               $this->assertFalse( $user->checkPasswordValidity( $longPass )->isGood() );
-               $this->assertFalse( $user->checkPasswordValidity( $longPass )->isOK() );
-               $this->assertEquals( 'passwordtoolong', $user->getPasswordValidity( $longPass ) );
-
-               // Matches username
-               $this->assertFalse( $user->checkPasswordValidity( 'Useruser' )->isGood() );
-               $this->assertTrue( $user->checkPasswordValidity( 'Useruser' )->isOK() );
-               $this->assertEquals( 'password-name-match', $user->getPasswordValidity( 'Useruser' ) );
-
-               // On the forbidden list
-               $this->assertFalse( $user->checkPasswordValidity( 'Passpass' )->isGood() );
-               $this->assertEquals( 'password-login-forbidden', $user->getPasswordValidity( 'Passpass' ) );
-       }
-
-       /**
-        * @covers User::getCanonicalName()
-        * @dataProvider provideGetCanonicalName
-        */
-       public function testGetCanonicalName( $name, $expectedArray, $msg ) {
-               foreach ( $expectedArray as $validate => $expected ) {
-                       $this->assertEquals(
-                               $expected,
-                               User::getCanonicalName( $name, $validate === 'false' ? false : $validate ),
-                               $msg . ' (' . $validate . ')'
-                       );
-               }
-       }
-
-       public static function provideGetCanonicalName() {
-               return array(
-                       array( ' Trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ),
-                       // @todo FIXME: Maybe the creatable name should be 'Talk:Username' or false to reject?
-                       array( 'Talk:Username', array( 'creatable' => 'Username', 'usable' => 'Username',
-                               'valid' => 'Username', 'false' => 'Talk:Username' ), 'Namespace prefix' ),
-                       array( ' name with # hash', array( 'creatable' => false, 'usable' => false ), 'With hash' ),
-                       array( 'Multi  spaces', array( 'creatable' => 'Multi spaces',
-                               'usable' => 'Multi spaces' ), 'Multi spaces' ),
-                       array( 'lowercase', array( 'creatable' => 'Lowercase' ), 'Lowercase' ),
-                       array( 'in[]valid', array( 'creatable' => false, 'usable' => false, 'valid' => false,
-                               'false' => 'In[]valid' ), 'Invalid' ),
-                       array( 'with / slash', array( 'creatable' => false, 'usable' => false, 'valid' => false,
-                               'false' => 'With / slash' ), 'With slash' ),
-               );
-       }
-
-       /**
-        * @covers User::equals
-        */
-       public function testEquals() {
-               $first = User::newFromName( 'EqualUser' );
-               $second = User::newFromName( 'EqualUser' );
-
-               $this->assertTrue( $first->equals( $first ) );
-               $this->assertTrue( $first->equals( $second ) );
-               $this->assertTrue( $second->equals( $first ) );
-
-               $third = User::newFromName( '0' );
-               $fourth = User::newFromName( '000' );
-
-               $this->assertFalse( $third->equals( $fourth ) );
-               $this->assertFalse( $fourth->equals( $third ) );
-
-               // Test users loaded from db with id
-               $user = User::newFromName( 'EqualUnitTestUser' );
-               if ( !$user->getId() ) {
-                       $user->addToDatabase();
-               }
-
-               $id = $user->getId();
-
-               $fifth = User::newFromId( $id );
-               $sixth = User::newFromName( 'EqualUnitTestUser' );
-               $this->assertTrue( $fifth->equals( $sixth ) );
-       }
-
-       /**
-        * @covers User::getId
-        */
-       public function testGetId() {
-               $user = User::newFromName( 'UTSysop' );
-               $this->assertTrue( $user->getId() > 0 );
-
-       }
-
-       /**
-        * @covers User::isLoggedIn
-        * @covers User::isAnon
-        */
-       public function testLoggedIn() {
-               $user = User::newFromName( 'UTSysop' );
-               $this->assertTrue( $user->isLoggedIn() );
-               $this->assertFalse( $user->isAnon() );
-
-               // Non-existent users are perceived as anonymous
-               $user = User::newFromName( 'UTNonexistent' );
-               $this->assertFalse( $user->isLoggedIn() );
-               $this->assertTrue( $user->isAnon() );
-
-               $user = new User;
-               $this->assertFalse( $user->isLoggedIn() );
-               $this->assertTrue( $user->isAnon() );
-       }
-
-       /**
-        * @covers User::checkAndSetTouched
-        */
-       public function testCheckAndSetTouched() {
-               $user = TestingAccessWrapper::newFromObject( User::newFromName( 'UTSysop' ) );
-               $this->assertTrue( $user->isLoggedIn() );
-
-               $touched = $user->getDBTouched();
-               $this->assertTrue(
-                       $user->checkAndSetTouched(), "checkAndSetTouched() succeded" );
-               $this->assertGreaterThan(
-                       $touched, $user->getDBTouched(), "user_touched increased with casOnTouched()" );
-
-               $touched = $user->getDBTouched();
-               $this->assertTrue(
-                       $user->checkAndSetTouched(), "checkAndSetTouched() succeded #2" );
-               $this->assertGreaterThan(
-                       $touched, $user->getDBTouched(), "user_touched increased with casOnTouched() #2" );
-       }
-
-       public static function setExtendedLoginCookieDataProvider() {
-               $data = array();
-               $now = time();
-
-               $secondsInDay = 86400;
-
-               // Arbitrary durations, in units of days, to ensure it chooses the
-               // right one.  There is a 5-minute grace period (see testSetExtendedLoginCookie)
-               // to work around slow tests, since we're not currently mocking time() for PHP.
-
-               $durationOne = $secondsInDay * 5;
-               $durationTwo = $secondsInDay * 29;
-               $durationThree = $secondsInDay * 17;
-
-               // If $wgExtendedLoginCookieExpiration is null, then the expiry passed to
-               // set cookie is time() + $wgCookieExpiration
-               $data[] = array(
-                       null,
-                       $durationOne,
-                       $now + $durationOne,
-               );
-
-               // If $wgExtendedLoginCookieExpiration isn't null, then the expiry passed to
-               // set cookie is $now + $wgExtendedLoginCookieExpiration
-               $data[] = array(
-                       $durationTwo,
-                       $durationThree,
-                       $now + $durationTwo,
-               );
-
-               return $data;
-       }
-
-       /**
-        * @dataProvider setExtendedLoginCookieDataProvider
-        * @covers User::getRequest
-        * @covers User::setCookie
-        * @backupGlobals enabled
-        */
-       public function testSetExtendedLoginCookie(
-               $extendedLoginCookieExpiration,
-               $cookieExpiration,
-               $expectedExpiry
-       ) {
-               $this->setMwGlobals( array(
-                       'wgExtendedLoginCookieExpiration' => $extendedLoginCookieExpiration,
-                       'wgCookieExpiration' => $cookieExpiration,
-               ) );
-
-               $response = $this->getMock( 'WebResponse' );
-               $setcookieSpy = $this->any();
-               $response->expects( $setcookieSpy )
-                       ->method( 'setcookie' );
-
-               $request = new MockWebRequest( $response );
-               $user = new UserProxy( User::newFromSession( $request ) );
-               $user->setExtendedLoginCookie( 'name', 'value', true );
-
-               $setcookieInvocations = $setcookieSpy->getInvocations();
-               $setcookieInvocation = end( $setcookieInvocations );
-               $actualExpiry = $setcookieInvocation->parameters[2];
-
-               // TODO: ± 300 seconds compensates for
-               // slow-running tests. However, the dependency on the time
-               // function should be removed.  This requires some way
-               // to mock/isolate User->setExtendedLoginCookie's call to time()
-               $this->assertEquals( $expectedExpiry, $actualExpiry, '', 300 );
-       }
-}
-
-class UserProxy extends User {
-
-       /**
-        * @var User
-        */
-       protected $user;
-
-       public function __construct( User $user ) {
-               $this->user = $user;
-       }
-
-       public function setExtendedLoginCookie( $name, $value, $secure ) {
-               $this->user->setExtendedLoginCookie( $name, $value, $secure );
-       }
-}
index 3e5f355..a08a86e 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * @group API
  */
-class ApiErrorFormatterTest extends MediaWikiTestCase {
+class ApiErrorFormatterTest extends MediaWikiLangTestCase {
 
        /**
         * @covers ApiErrorFormatter
index d43db71..9dbde3d 100644 (file)
@@ -458,6 +458,13 @@ class ApiResultTest extends MediaWikiTestCase {
                        );
                }
 
+               // Add two values and some metadata, but ensure metadata is not counted
+               $result = new ApiResult( 100 );
+               $obj = array( 'attr' => '12345' );
+               ApiResult::setContentValue( $obj, 'content', '1234567890' );
+               $this->assertTrue( $result->addValue( null, 'foo', $obj ) );
+               $this->assertSame( 15, $result->getSize() );
+
                $result = new ApiResult( 10 );
                $formatter = new ApiErrorFormatter( $result, Language::factory( 'en' ), 'none', false );
                $result->setErrorFormatter( $formatter );
index 21345ac..01113a6 100644 (file)
@@ -37,7 +37,6 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                );
 
                $this->setMwGlobals( array(
-                       'wgMemc' => new EmptyBagOStuff(),
                        'wgAuth' => new StubObject( 'wgAuth', 'AuthPlugin' ),
                        'wgRequest' => new FauxRequest( array() ),
                        'wgUser' => self::$users['sysop']->user,
index 61b992b..eb1ad26 100644 (file)
@@ -61,7 +61,7 @@ class ApiQueryTest extends ApiTestCase {
        public function testTitlesAreRejectedIfInvalid() {
                $title = false;
                while ( !$title || Title::newFromText( $title )->exists() ) {
-                       $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) );
+                       $title = md5( mt_rand( 0, 100000 ) );
                }
 
                $data = $this->doApiRequest( array(
index 58735bc..4da8274 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-class CssContentHandlerTest extends MediaWikiTestCase {
+class CssContentHandlerTest extends MediaWikiLangTestCase {
 
        /**
         * @dataProvider provideMakeRedirectContent
index 69fc9af..d9487a0 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-class JavaScriptContentHandlerTest extends MediaWikiTestCase {
+class JavaScriptContentHandlerTest extends MediaWikiLangTestCase {
 
        /**
         * @dataProvider provideMakeRedirectContent
index 7e70439..5f2a6fe 100644 (file)
@@ -234,4 +234,30 @@ class DatabaseTest extends MediaWikiTestCase {
                $this->assertFalse( $this->db->tableExists( 'foobarbaz' ) );
                $this->assertInternalType( 'int', $res->numRows() );
        }
+
+       public function testTransactionIdle() {
+               $db = $this->db;
+
+               $db->setFlag( DBO_TRX );
+               $flagSet = null;
+               $db->onTransactionIdle( function() use ( $db, &$flagSet ) {
+                       $flagSet = $db->getFlag( DBO_TRX );
+               } );
+               $this->assertFalse( $flagSet, 'DBO_TRX off in callback' );
+               $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' );
+
+               $db->clearFlag( DBO_TRX );
+               $flagSet = null;
+               $db->onTransactionIdle( function() use ( $db, &$flagSet ) {
+                       $flagSet = $db->getFlag( DBO_TRX );
+               } );
+               $this->assertFalse( $flagSet, 'DBO_TRX off in callback' );
+               $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' );
+
+               $db->clearFlag( DBO_TRX );
+               $db->onTransactionIdle( function() use ( $db ) {
+                       $db->setFlag( DBO_TRX );
+               } );
+               $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' );
+       }
 }
diff --git a/tests/phpunit/includes/deferred/CdnCacheUpdateTest.php b/tests/phpunit/includes/deferred/CdnCacheUpdateTest.php
new file mode 100644 (file)
index 0000000..de77ad5
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+class CdnCacheUpdateTest extends MediaWikiTestCase {
+       public function testPurgeMergeWeb() {
+               $this->setMwGlobals( 'wgCommandLineMode', false );
+
+               $urls1 = array();
+               $title = Title::newMainPage();
+               $urls1[] = $title->getCanonicalURL( '?x=1' );
+               $urls1[] = $title->getCanonicalURL( '?x=2' );
+               $urls1[] = $title->getCanonicalURL( '?x=3' );
+               $update1 = new CdnCacheUpdate( $urls1 );
+               DeferredUpdates::addUpdate( $update1 );
+
+               $urls2 = array();
+               $urls2[] = $title->getCanonicalURL( '?x=2' );
+               $urls2[] = $title->getCanonicalURL( '?x=3' );
+               $urls2[] = $title->getCanonicalURL( '?x=4' );
+               $update2 = new CdnCacheUpdate( $urls2 );
+               DeferredUpdates::addUpdate( $update2 );
+
+               $wrapper = TestingAccessWrapper::newFromObject( $update1 );
+               $this->assertEquals( array_merge( $urls1, $urls2 ), $wrapper->urls );
+       }
+}
index df4213a..736f6e8 100644 (file)
@@ -34,6 +34,31 @@ class DeferredUpdatesTest extends MediaWikiTestCase {
                $this->expectOutputString( implode( '', $updates ) );
 
                DeferredUpdates::doUpdates();
+
+               $x = null;
+               $y = null;
+               DeferredUpdates::addCallableUpdate(
+                       function () use ( &$x ) {
+                               $x = 'Sherity';
+                       },
+                       DeferredUpdates::PRESEND
+               );
+               DeferredUpdates::addCallableUpdate(
+                       function () use ( &$y ) {
+                               $y = 'Marychu';
+                       },
+                       DeferredUpdates::POSTSEND
+               );
+
+               $this->assertNull( $x, "Update not run yet" );
+               $this->assertNull( $y, "Update not run yet" );
+
+               DeferredUpdates::doUpdates( 'run', DeferredUpdates::PRESEND );
+               $this->assertEquals( "Sherity", $x, "PRESEND update ran" );
+               $this->assertNull( $y, "POSTSEND update not run yet" );
+
+               DeferredUpdates::doUpdates( 'run', DeferredUpdates::POSTSEND );
+               $this->assertEquals( "Marychu", $y, "POSTSEND update ran" );
        }
 
        public function testDoUpdatesCLI() {
index 25ee5ec..016a7aa 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 
 /**
+ * @group LinksUpdate
  * @group Database
  * ^--- make sure temporary tables are used.
  */
-class LinksUpdateTest extends MediaWikiTestCase {
+class LinksUpdateTest extends MediaWikiLangTestCase {
+       protected $testingPageId;
 
        function __construct( $name = null, array $data = array(), $dataName = '' ) {
                parent::__construct( $name, $data, $dataName );
@@ -44,7 +46,8 @@ class LinksUpdateTest extends MediaWikiTestCase {
        }
 
        public function addDBData() {
-               $this->insertPage( 'Testing' );
+               $res = $this->insertPage( 'Testing' );
+               $this->testingPageId = $res['id'];
                $this->insertPage( 'Some_other_page' );
                $this->insertPage( 'Template:TestingTemplate' );
        }
@@ -63,8 +66,9 @@ class LinksUpdateTest extends MediaWikiTestCase {
         * @covers ParserOutput::addLink
         */
        public function testUpdate_pagelinks() {
+               /** @var Title $t */
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addLink( Title::newFromText( "Foo" ) );
                $po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored
@@ -77,7 +81,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        'pagelinks',
                        'pl_namespace,
                        pl_title',
-                       'pl_from = 111',
+                       'pl_from = ' . $this->testingPageId,
                        array( array( NS_MAIN, 'Foo' ) )
                );
                $this->assertArrayEquals( array(
@@ -96,7 +100,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        'pagelinks',
                        'pl_namespace,
                        pl_title',
-                       'pl_from = 111',
+                       'pl_from = ' . $this->testingPageId,
                        array(
                                array( NS_MAIN, 'Bar' ),
                                array( NS_TALK, 'Bar' ),
@@ -116,13 +120,20 @@ class LinksUpdateTest extends MediaWikiTestCase {
         */
        public function testUpdate_externallinks() {
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addExternalLink( "http://testing.com/wiki/Foo" );
 
-               $this->assertLinksUpdate( $t, $po, 'externallinks', 'el_to, el_index', 'el_from = 111', array(
-                       array( 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ),
-               ) );
+               $this->assertLinksUpdate(
+                       $t,
+                       $po,
+                       'externallinks',
+                       'el_to, el_index',
+                       'el_from = ' . $this->testingPageId,
+                       array(
+                               array( 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ),
+                       )
+               );
        }
 
        /**
@@ -132,13 +143,18 @@ class LinksUpdateTest extends MediaWikiTestCase {
                /** @var ParserOutput $po */
                $this->setMwGlobals( 'wgCategoryCollation', 'uppercase' );
 
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addCategory( "Foo", "FOO" );
 
-               $this->assertLinksUpdate( $t, $po, 'categorylinks', 'cl_to, cl_sortkey', 'cl_from = 111', array(
-                       array( 'Foo', "FOO\nTESTING" ),
-               ) );
+               $this->assertLinksUpdate(
+                       $t,
+                       $po,
+                       'categorylinks',
+                       'cl_to, cl_sortkey',
+                       'cl_from = ' . $this->testingPageId,
+                       array( array( 'Foo', "FOO\nTESTING" ) )
+               );
        }
 
        public function testOnAddingAndRemovingCategory_recentChangesRowIsAdded() {
@@ -147,6 +163,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
                $title = Title::newFromText( 'Testing' );
                $wikiPage = new WikiPage( $title );
                $wikiPage->doEditContent( new WikitextContent( '[[Category:Foo]]' ), 'added category' );
+               $this->runAllRelatedJobs();
 
                $this->assertRecentChangeByCategorization(
                        $title,
@@ -155,7 +172,9 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        array( array( 'Foo', '[[:Testing]] added to category' ) )
                );
 
-               $wikiPage->doEditContent( new WikitextContent( '[[Category:Bar]]' ), 'added category' );
+               $wikiPage->doEditContent( new WikitextContent( '[[Category:Bar]]' ), 'replaced category' );
+               $this->runAllRelatedJobs();
+
                $this->assertRecentChangeByCategorization(
                        $title,
                        $wikiPage->getParserOutput( new ParserOptions() ),
@@ -184,15 +203,27 @@ class LinksUpdateTest extends MediaWikiTestCase {
 
                $wikiPage = new WikiPage( Title::newFromText( 'Testing' ) );
                $wikiPage->doEditContent( new WikitextContent( '{{TestingTemplate}}' ), 'added template' );
+               $this->runAllRelatedJobs();
+
                $otherWikiPage = new WikiPage( Title::newFromText( 'Some_other_page' ) );
                $otherWikiPage->doEditContent( new WikitextContent( '{{TestingTemplate}}' ), 'added template' );
-               $templatePage->doEditContent( new WikitextContent( '[[Category:Foo]]' ), 'added category' );
+               $this->runAllRelatedJobs();
 
                $this->assertRecentChangeByCategorization(
                        $templateTitle,
                        $templatePage->getParserOutput( new ParserOptions() ),
-                       Title::newFromText( 'Foo' ),
-                       array( array( 'Foo', '[[:Template:TestingTemplate]] and 2 pages added to category' ) )
+                       Title::newFromText( 'Baz' ),
+                       array()
+               );
+
+               $templatePage->doEditContent( new WikitextContent( '[[Category:Baz]]' ), 'added category' );
+               $this->runAllRelatedJobs();
+
+               $this->assertRecentChangeByCategorization(
+                       $templateTitle,
+                       $templatePage->getParserOutput( new ParserOptions() ),
+                       Title::newFromText( 'Baz' ),
+                       array( array( 'Baz', '[[:Template:TestingTemplate]] and 2 pages added to category' ) )
                );
        }
 
@@ -201,14 +232,19 @@ class LinksUpdateTest extends MediaWikiTestCase {
         */
        public function testUpdate_iwlinks() {
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' );
                $po->addInterwikiLink( $target );
 
-               $this->assertLinksUpdate( $t, $po, 'iwlinks', 'iwl_prefix, iwl_title', 'iwl_from = 111', array(
-                       array( 'linksupdatetest', 'Foo' ),
-               ) );
+               $this->assertLinksUpdate(
+                       $t,
+                       $po,
+                       'iwlinks',
+                       'iwl_prefix, iwl_title',
+                       'iwl_from = ' . $this->testingPageId,
+                       array( array( 'linksupdatetest', 'Foo' ) )
+               );
        }
 
        /**
@@ -216,7 +252,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
         */
        public function testUpdate_templatelinks() {
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 );
 
@@ -226,7 +262,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        'templatelinks',
                        'tl_namespace,
                        tl_title',
-                       'tl_from = 111',
+                       'tl_from = ' . $this->testingPageId,
                        array( array( NS_TEMPLATE, 'Foo' ) )
                );
        }
@@ -236,13 +272,18 @@ class LinksUpdateTest extends MediaWikiTestCase {
         */
        public function testUpdate_imagelinks() {
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addImage( "Foo.png" );
 
-               $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array(
-                       array( 'Foo.png' ),
-               ) );
+               $this->assertLinksUpdate(
+                       $t,
+                       $po,
+                       'imagelinks',
+                       'il_to',
+                       'il_from = ' . $this->testingPageId,
+                       array( array( 'Foo.png' ) )
+               );
        }
 
        /**
@@ -254,13 +295,18 @@ class LinksUpdateTest extends MediaWikiTestCase {
                ) );
 
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() );
 
-               $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array(
-                       array( 'En', 'Foo' ),
-               ) );
+               $this->assertLinksUpdate(
+                       $t,
+                       $po,
+                       'langlinks',
+                       'll_lang, ll_title',
+                       'll_from = ' . $this->testingPageId,
+                       array( array( 'En', 'Foo' ) )
+               );
        }
 
        /**
@@ -270,7 +316,7 @@ class LinksUpdateTest extends MediaWikiTestCase {
                global $wgPagePropsHaveSortkey;
 
                /** @var ParserOutput $po */
-               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 );
+               list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", $this->testingPageId );
 
                $fields = array( 'pp_propname', 'pp_value' );
                $expected = array();
@@ -302,7 +348,8 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        }
                }
 
-               $this->assertLinksUpdate( $t, $po, 'page_props', $fields, 'pp_page = 111', $expected );
+               $this->assertLinksUpdate(
+                       $t, $po, 'page_props', $fields, 'pp_page = ' . $this->testingPageId, $expected );
        }
 
        public function testUpdate_page_props_without_sortkey() {
@@ -330,13 +377,6 @@ class LinksUpdateTest extends MediaWikiTestCase {
        protected function assertRecentChangeByCategorization(
                Title $pageTitle, ParserOutput $parserOutput, Title $categoryTitle, $expectedRows
        ) {
-               $update = new LinksUpdate( $pageTitle, $parserOutput );
-               $revision = Revision::newFromTitle( $pageTitle );
-               $update->setRevision( $revision );
-               $update->beginTransaction();
-               $update->doUpdate();
-               $update->commitTransaction();
-
                $this->assertSelect(
                        'recentchanges',
                        'rc_title, rc_comment',
@@ -348,4 +388,16 @@ class LinksUpdateTest extends MediaWikiTestCase {
                        $expectedRows
                );
        }
+
+       private function runAllRelatedJobs() {
+               $queueGroup = JobQueueGroup::singleton();
+               while ( $job = $queueGroup->pop( 'refreshLinksPrioritized' ) ) {
+                       $job->run();
+                       $queueGroup->ack( $job );
+               }
+               while ( $job = $queueGroup->pop( 'categoryMembershipChange' ) ) {
+                       $job->run();
+                       $queueGroup->ack( $job );
+               }
+       }
 }
index 9bef8e0..0763a2e 100644 (file)
@@ -18,7 +18,6 @@ class FileBackendTest extends MediaWikiTestCase {
        protected function setUp() {
                global $wgFileBackends;
                parent::setUp();
-               $uniqueId = time() . '-' . mt_rand();
                $tmpDir = $this->getNewTempDirectory();
                if ( $this->getCliArg( 'use-filebackend' ) ) {
                        if ( self::$backendToUse ) {
@@ -58,7 +57,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        'name' => 'localtesting',
                        'lockManager' => LockManagerGroup::singleton()->get( 'fsLockManager' ),
                        'parallelize' => 'implicit',
-                       'wikiId' => wfWikiId() . $uniqueId,
+                       'wikiId' => wfWikiId() . wfRandomString(),
                        'backends' => array(
                                array(
                                        'name' => 'localmultitesting1',
@@ -80,11 +79,6 @@ class FileBackendTest extends MediaWikiTestCase {
                ) );
        }
 
-       protected function tearDown() {
-               parent::tearDown();
-               DeferredUpdates::forceDeferral( false );
-       }
-
        private static function baseStorePath() {
                return 'mwstore://localtesting';
        }
@@ -2504,7 +2498,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        ) )
                );
 
-               DeferredUpdates::forceDeferral( true );
+               $this->setMwGlobals( 'wgCommandLineMode', false );
 
                $p = 'container/test-cont/file.txt';
                $be->quickCreate( array(
@@ -2522,7 +2516,6 @@ class FileBackendTest extends MediaWikiTestCase {
                );
 
                DeferredUpdates::doUpdates();
-               DeferredUpdates::forceDeferral( false );
 
                $this->assertEquals(
                        'cattitude',
index c839bc4..ee0cf2d 100644 (file)
@@ -11,7 +11,7 @@ class MigrateFileRepoLayoutTest extends MediaWikiTestCase {
 
                $filename = 'Foo.png';
 
-               $this->tmpPrefix = wfTempDir() . '/migratefilelayout-test-' . time() . '-' . mt_rand();
+               $this->tmpPrefix = $this->getNewTempDirectory();
 
                $backend = new FSFileBackend( array(
                        'name' => 'local-migratefilerepolayouttest',
index 9808a55..47277d9 100644 (file)
@@ -19,8 +19,6 @@ class JobQueueTest extends MediaWikiTestCase {
                global $wgJobTypeConf;
                parent::setUp();
 
-               $this->setMwGlobals( 'wgMemc', new HashBagOStuff() );
-
                if ( $this->getCliArg( 'use-jobqueue' ) ) {
                        $name = $this->getCliArg( 'use-jobqueue' );
                        if ( !isset( $wgJobTypeConf[$name] ) ) {
@@ -43,9 +41,6 @@ class JobQueueTest extends MediaWikiTestCase {
                foreach ( $variants as $q => $settings ) {
                        try {
                                $this->$q = JobQueue::factory( $settings + $baseConfig );
-                               if ( !( $this->$q instanceof JobQueueDB ) ) {
-                                       $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) );
-                               }
                        } catch ( MWException $e ) {
                                // unsupported?
                                // @todo What if it was another error?
@@ -334,6 +329,30 @@ class JobQueueTest extends MediaWikiTestCase {
                $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
        }
 
+       /**
+        * @covers JobQueue
+        */
+       public function testQueueAggregateTable() {
+               $queue = $this->queueFifo;
+               if ( !$queue || !method_exists( $queue, 'getServerQueuesWithJobs' ) ) {
+                       $this->markTestSkipped();
+               }
+
+               $this->assertNotContains(
+                       array( $queue->getType(), $queue->getWiki() ),
+                       $queue->getServerQueuesWithJobs(),
+                       "Null queue not in listing"
+               );
+
+               $queue->push( $this->newJob( 0 ) );
+
+               $this->assertContains(
+                       array( $queue->getType(), $queue->getWiki() ),
+                       $queue->getServerQueuesWithJobs(),
+                       "Null queue in listing"
+               );
+       }
+
        public static function provider_queueLists() {
                return array(
                        array( 'queueRand', false, 'Random queue without ack()' ),
index e2c6ac7..efc37d2 100644 (file)
@@ -247,7 +247,8 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $curTTLs = array();
                $this->assertEquals(
                        array( $key1 => $value1, $key2 => $value2 ),
-                       $cache->getMulti( array( $key1, $key2, $key3 ), $curTTLs )
+                       $cache->getMulti( array( $key1, $key2, $key3 ), $curTTLs ),
+                       'Result array populated'
                );
 
                $this->assertEquals( 2, count( $curTTLs ), "Two current TTLs in array" );
@@ -256,12 +257,6 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
                $cKey1 = wfRandomString();
                $cKey2 = wfRandomString();
-               $curTTLs = array();
-               $this->assertEquals(
-                       array( $key1 => $value1, $key2 => $value2 ),
-                       $cache->getMulti( array( $key1, $key2, $key3 ), $curTTLs ),
-                       'Result array populated'
-               );
 
                $priorTime = microtime( true );
                usleep( 1 );
@@ -308,9 +303,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                // Fake initial check key to be set in the past. Otherwise we'd have to sleep for
                // several seconds during the test to assert the behaviour.
                foreach ( array( $checkAll, $check1, $check2 ) as $checkKey ) {
-                       $this->internalCache->set( $cache::TIME_KEY_PREFIX . $checkKey,
-                               $cache::PURGE_VAL_PREFIX . microtime( true ) - $cache::HOLDOFF_TTL, $cache::CHECK_KEY_TTL );
+                       $cache->touchCheckKey( $checkKey, WANObjectCache::HOLDOFF_NONE );
                }
+               usleep( 100 );
 
                $cache->set( 'key1', $value1, 10 );
                $cache->set( 'key2', $value2, 10 );
@@ -327,14 +322,12 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                        $result,
                        'Initial values'
                );
-               $this->assertEquals(
-                       array( 'key1' => 0, 'key2' => 0 ),
-                       $curTTLs,
-                       'Initial ttls'
-               );
+               $this->assertGreaterThanOrEqual( 9.5, $curTTLs['key1'], 'Initial ttls' );
+               $this->assertLessThanOrEqual( 10.5, $curTTLs['key1'], 'Initial ttls' );
+               $this->assertGreaterThanOrEqual( 9.5, $curTTLs['key2'], 'Initial ttls' );
+               $this->assertLessThanOrEqual( 10.5, $curTTLs['key2'], 'Initial ttls' );
 
                $cache->touchCheckKey( $check1 );
-               usleep( 100 );
 
                $curTTLs = array();
                $result = $cache->getMulti( array( 'key1', 'key2', 'key3' ), $curTTLs, array(
@@ -349,10 +342,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                        'key1 expired by check1, but value still provided'
                );
                $this->assertLessThan( 0, $curTTLs['key1'], 'key1 TTL expired' );
-               $this->assertEquals( 0, $curTTLs['key2'], 'key2 still valid' );
+               $this->assertGreaterThan( 0, $curTTLs['key2'], 'key2 still valid' );
 
                $cache->touchCheckKey( $checkAll );
-               usleep( 100 );
 
                $curTTLs = array();
                $result = $cache->getMulti( array( 'key1', 'key2', 'key3' ), $curTTLs, array(
@@ -370,6 +362,39 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertLessThan( 0, $curTTLs['key2'], 'key2 expired by checkAll' );
        }
 
+       /**
+        * @covers WANObjectCache::get()
+        * @covers WANObjectCache::processCheckKeys()
+        */
+       public function testCheckKeyInitHoldoff() {
+               $cache = $this->cache;
+
+               for ( $i = 0; $i < 500; ++$i ) {
+                       $key = wfRandomString();
+                       $checkKey = wfRandomString();
+                       // miss, set, hit
+                       $cache->get( $key, $curTTL, array( $checkKey ) );
+                       $cache->set( $key, 'val', 10 );
+                       $curTTL = null;
+                       $v = $cache->get( $key, $curTTL, array( $checkKey ) );
+
+                       $this->assertEquals( 'val', $v );
+                       $this->assertLessThan( 0, $curTTL, "Step $i: CTL < 0 (miss/set/hit)" );
+               }
+
+               for ( $i = 0; $i < 500; ++$i ) {
+                       $key = wfRandomString();
+                       $checkKey = wfRandomString();
+                       // set, hit
+                       $cache->set( $key, 'val', 10 );
+                       $curTTL = null;
+                       $v = $cache->get( $key, $curTTL, array( $checkKey ) );
+
+                       $this->assertEquals( 'val', $v );
+                       $this->assertLessThan( 0, $curTTL, "Step $i: CTL < 0 (set/hit)" );
+               }
+       }
+
        /**
         * @covers WANObjectCache::delete()
         */
index 95822ad..cd0f139 100644 (file)
@@ -7,6 +7,7 @@ require_once __DIR__ . '/NewParserTest.php';
  * an PHPUnit_Framework_Test object
  *
  * @group Parser
+ * @group ParserTests
  * @group Database
  */
 class MediaWikiParserTest {
index 6948082..5c6c17d 100644 (file)
@@ -673,6 +673,7 @@ class NewParserTest extends MediaWikiTestCase {
 
        /**
         * @group medium
+        * @group ParserTests
         * @dataProvider parserTestProvider
         * @param string $desc
         * @param string $input
index 3de315a..776538a 100644 (file)
@@ -1,12 +1,31 @@
 <?php
 
 /**
- * @group Database
  * @group Cache
  * @covers MessageBlobStore
  */
-class MessageBlobStoreTest extends ResourceLoaderTestCase {
-       protected $tablesUsed = array( 'msg_resource' );
+class MessageBlobStoreTest extends PHPUnit_Framework_TestCase {
+
+       protected function setUp() {
+               parent::setUp();
+               // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE.
+               // Use hash instead so that caching is observed
+               $this->wanCache = $this->getMockBuilder( 'WANObjectCache' )
+                       ->setConstructorArgs( array( array(
+                               'cache' => new HashBagOStuff(),
+                               'pool' => 'test',
+                               'relayer' => new EventRelayerNull( array() )
+                       ) ) )
+                       ->setMethods( array( 'makePurgeValue' ) )
+                       ->getMock();
+
+               $this->wanCache->expects( $this->any() )
+                       ->method( 'makePurgeValue' )
+                       ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
+                               // Disable holdoff as it messes with testing
+                               return WANObjectCache::PURGE_VAL_PREFIX . (float)$timestamp . ':0';
+                       } ) );
+       }
 
        protected function makeBlobStore( $methods = null, $rl = null ) {
                $blobStore = $this->getMockBuilder( 'MessageBlobStore' )
@@ -14,6 +33,8 @@ class MessageBlobStoreTest extends ResourceLoaderTestCase {
                        ->setMethods( $methods )
                        ->getMock();
 
+               $access = TestingAccessWrapper::newFromObject( $blobStore );
+               $access->wanCache = $this->wanCache;
                return $blobStore;
        }
 
@@ -67,9 +88,9 @@ class MessageBlobStoreTest extends ResourceLoaderTestCase {
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
                $blobStore = $this->makeBlobStore( array( 'fetchMessage' ), $rl );
-               $blobStore->expects( $this->exactly( 2 ) )
+               $blobStore->expects( $this->once() )
                        ->method( 'fetchMessage' )
-                       ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
+                       ->will( $this->returnValue( 'First' ) );
 
                $blob = $blobStore->getBlob( $module, 'en' );
                $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
@@ -80,9 +101,9 @@ class MessageBlobStoreTest extends ResourceLoaderTestCase {
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
                $blobStore = $this->makeBlobStore( array( 'fetchMessage' ), $rl );
-               $blobStore->expects( $this->never() )
+               $blobStore->expects( $this->once() )
                        ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'Wrong' ) );
+                       ->will( $this->returnValue( 'Second' ) );
 
                $blob = $blobStore->getBlob( $module, 'en' );
                $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
@@ -122,4 +143,25 @@ class MessageBlobStoreTest extends ResourceLoaderTestCase {
                $blob = $blobStore->getBlob( $module, 'en' );
                $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
        }
+
+       public function testClear() {
+               $module = $this->makeModule( array( 'example' ) );
+               $rl = new ResourceLoader();
+               $rl->register( $module->getName(), $module );
+               $blobStore = $this->makeBlobStore( array( 'fetchMessage' ), $rl );
+               $blobStore->expects( $this->exactly( 2 ) )
+                       ->method( 'fetchMessage' )
+                       ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
+
+               $blob = $blobStore->getBlob( $module, 'en' );
+               $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
+
+               $blob = $blobStore->getBlob( $module, 'en' );
+               $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
+
+               $blobStore->clear();
+
+               $blob = $blobStore->getBlob( $module, 'en' );
+               $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
+       }
 }
index f700348..3f2a5e2 100644 (file)
@@ -4,7 +4,6 @@ class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
 
        /**
         * @covers ResourceLoaderModule::getVersionHash
-        * @group Broken
         */
        public function testGetVersionHash() {
                $context = $this->getResourceLoaderContext();
@@ -69,6 +68,8 @@ class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
         * @covers ResourceLoaderModule::validateScriptFile
         */
        public function testValidateScriptFile() {
+               $this->setMwGlobals( 'wgResourceLoaderValidateJS', true );
+
                $context = $this->getResourceLoaderContext();
 
                $module = new ResourceLoaderTestModule( array(
index c552b80..9a36d18 100644 (file)
@@ -5,7 +5,7 @@ class ResourceLoaderStartUpModuleTest extends ResourceLoaderTestCase {
        // Version hash for a blank file module.
        // Result of ResourceLoader::makeHash(), ResourceLoaderTestModule
        // and ResourceLoaderFileModule::getDefinitionSummary().
-       protected static $blankVersion = 'wvTifjse';
+       protected static $blankVersion = 'GqV9IPpY';
 
        protected static function expandPlaceholders( $text ) {
                return strtr( $text, array(
index df9b552..f32eeca 100644 (file)
@@ -181,6 +181,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        ->will( $this->returnValue( $mockSearchEngine ) );
 
                $search->getContext()->setTitle( Title::makeTitle( NS_SPECIAL, 'Search' ) );
+               $search->getContext()->setLanguage( Language::factory( 'en' ) );
                $search->load();
                $search->showResults( 'this is a fake search' );
 
diff --git a/tests/phpunit/includes/user/CentralIdLookupTest.php b/tests/phpunit/includes/user/CentralIdLookupTest.php
new file mode 100644 (file)
index 0000000..386e7ab
--- /dev/null
@@ -0,0 +1,181 @@
+<?php
+
+/**
+ * @covers CentralIdLookup
+ * @group Database
+ */
+class CentralIdLookupTest extends MediaWikiTestCase {
+
+       public function testFactory() {
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+
+               $this->setMwGlobals( array(
+                       'wgCentralIdLookupProviders' => array(
+                               'local' => array( 'class' => 'LocalIdLookup' ),
+                               'local2' => array( 'class' => 'LocalIdLookup' ),
+                               'mock' => array( 'factory' => function () use ( $mock ) {
+                                       return $mock;
+                               } ),
+                               'bad' => array( 'class' => 'stdClass' ),
+                       ),
+                       'wgCentralIdLookupProvider' => 'mock',
+               ) );
+
+               $this->assertSame( $mock, CentralIdLookup::factory() );
+               $this->assertSame( $mock, CentralIdLookup::factory( 'mock' ) );
+               $this->assertSame( 'mock', $mock->getProviderId() );
+
+               $local = CentralIdLookup::factory( 'local' );
+               $this->assertNotSame( $mock, $local );
+               $this->assertInstanceOf( 'LocalIdLookup', $local );
+               $this->assertSame( $local, CentralIdLookup::factory( 'local' ) );
+               $this->assertSame( 'local', $local->getProviderId() );
+
+               $local2 = CentralIdLookup::factory( 'local2' );
+               $this->assertNotSame( $local, $local2 );
+               $this->assertInstanceOf( 'LocalIdLookup', $local2 );
+               $this->assertSame( 'local2', $local2->getProviderId() );
+
+               $this->assertNull( CentralIdLookup::factory( 'unconfigured' ) );
+               $this->assertNull( CentralIdLookup::factory( 'bad' ) );
+       }
+
+       public function testCheckAudience() {
+               $mock = TestingAccessWrapper::newFromObject(
+                       $this->getMockForAbstractClass( 'CentralIdLookup' )
+               );
+
+               $user = User::newFromName( 'UTSysop' );
+               $this->assertSame( $user, $mock->checkAudience( $user ) );
+
+               $user = $mock->checkAudience( CentralIdLookup::AUDIENCE_PUBLIC );
+               $this->assertInstanceOf( 'User', $user );
+               $this->assertSame( 0, $user->getId() );
+
+               $this->assertNull( $mock->checkAudience( CentralIdLookup::AUDIENCE_RAW ) );
+
+               try {
+                       $mock->checkAudience( 100 );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+                       $this->assertSame( 'Invalid audience', $ex->getMessage() );
+               }
+       }
+
+       public function testNameFromCentralId() {
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->once() )->method( 'lookupCentralIds' )
+                       ->with(
+                               $this->equalTo( array( 15 => null ) ),
+                               $this->equalTo( CentralIdLookup::AUDIENCE_RAW ),
+                               $this->equalTo( CentralIdLookup::READ_LATEST )
+                       )
+                       ->will( $this->returnValue( array( 15 => 'FooBar' ) ) );
+
+               $this->assertSame(
+                       'FooBar',
+                       $mock->nameFromCentralId( 15, CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST )
+               );
+       }
+
+       /**
+        * @dataProvider provideLocalUserFromCentralId
+        * @param string $name
+        * @param bool $succeeds
+        */
+       public function testLocalUserFromCentralId( $name, $succeeds ) {
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->any() )->method( 'isAttached' )
+                       ->will( $this->returnValue( true ) );
+               $mock->expects( $this->once() )->method( 'lookupCentralIds' )
+                       ->with(
+                               $this->equalTo( array( 42 => null ) ),
+                               $this->equalTo( CentralIdLookup::AUDIENCE_RAW ),
+                               $this->equalTo( CentralIdLookup::READ_LATEST )
+                       )
+                       ->will( $this->returnValue( array( 42 => $name ) ) );
+
+               $user = $mock->localUserFromCentralId(
+                       42, CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST
+               );
+               if ( $succeeds ) {
+                       $this->assertInstanceOf( 'User', $user );
+                       $this->assertSame( $name, $user->getName() );
+               } else {
+                       $this->assertNull( $user );
+               }
+
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->any() )->method( 'isAttached' )
+                       ->will( $this->returnValue( false ) );
+               $mock->expects( $this->once() )->method( 'lookupCentralIds' )
+                       ->with(
+                               $this->equalTo( array( 42 => null ) ),
+                               $this->equalTo( CentralIdLookup::AUDIENCE_RAW ),
+                               $this->equalTo( CentralIdLookup::READ_LATEST )
+                       )
+                       ->will( $this->returnValue( array( 42 => $name ) ) );
+               $this->assertNull(
+                       $mock->localUserFromCentralId( 42, CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST )
+               );
+       }
+
+       public static function provideLocalUserFromCentralId() {
+               return array(
+                       array( 'UTSysop', true ),
+                       array( 'UTDoesNotExist', false ),
+                       array( null, false ),
+                       array( '', false ),
+                       array( '<X>', false ),
+               );
+       }
+
+       public function testCentralIdFromName() {
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->once() )->method( 'lookupUserNames' )
+                       ->with(
+                               $this->equalTo( array( 'FooBar' => 0 ) ),
+                               $this->equalTo( CentralIdLookup::AUDIENCE_RAW ),
+                               $this->equalTo( CentralIdLookup::READ_LATEST )
+                       )
+                       ->will( $this->returnValue( array( 'FooBar' => 23 ) ) );
+
+               $this->assertSame(
+                       23,
+                       $mock->centralIdFromName( 'FooBar', CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST )
+               );
+       }
+
+       public function testCentralIdFromLocalUser() {
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->any() )->method( 'isAttached' )
+                       ->will( $this->returnValue( true ) );
+               $mock->expects( $this->once() )->method( 'lookupUserNames' )
+                       ->with(
+                               $this->equalTo( array( 'FooBar' => 0 ) ),
+                               $this->equalTo( CentralIdLookup::AUDIENCE_RAW ),
+                               $this->equalTo( CentralIdLookup::READ_LATEST )
+                       )
+                       ->will( $this->returnValue( array( 'FooBar' => 23 ) ) );
+
+               $this->assertSame(
+                       23,
+                       $mock->centralIdFromLocalUser(
+                               User::newFromName( 'FooBar' ), CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST
+                       )
+               );
+
+               $mock = $this->getMockForAbstractClass( 'CentralIdLookup' );
+               $mock->expects( $this->any() )->method( 'isAttached' )
+                       ->will( $this->returnValue( false ) );
+               $mock->expects( $this->never() )->method( 'lookupUserNames' );
+
+               $this->assertSame(
+                       0,
+                       $mock->centralIdFromLocalUser(
+                               User::newFromName( 'FooBar' ), CentralIdLookup::AUDIENCE_RAW, CentralIdLookup::READ_LATEST
+                       )
+               );
+       }
+
+}
diff --git a/tests/phpunit/includes/user/LocalIdLookupTest.php b/tests/phpunit/includes/user/LocalIdLookupTest.php
new file mode 100644 (file)
index 0000000..2bea575
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @covers LocalIdLookup
+ * @group Database
+ */
+class LocalIdLookupTest extends MediaWikiTestCase {
+       private $localUsers = array();
+
+       protected function setUp() {
+               global $wgGroupPermissions;
+
+               parent::setUp();
+
+               $this->stashMwGlobals( array( 'wgGroupPermissions' ) );
+               $wgGroupPermissions['local-id-lookup-test']['hideuser'] = true;
+       }
+
+       public function addDBData() {
+               for ( $i = 1; $i <= 4; $i++ ) {
+                       $user = User::newFromName( "UTLocalIdLookup$i" );
+                       if ( $user->getId() == 0 ) {
+                               $user->addToDatabase();
+                       }
+                       $this->localUsers["UTLocalIdLookup$i"] = $user->getId();
+               }
+
+               User::newFromName( 'UTLocalIdLookup1' )->addGroup( 'local-id-lookup-test' );
+
+               $block = new Block( array(
+                       'address' => 'UTLocalIdLookup3',
+                       'by' => User::idFromName( 'UTSysop' ),
+                       'reason' => __METHOD__,
+                       'expiry' => '1 day',
+                       'hideName' => false,
+               ) );
+               $block->insert();
+
+               $block = new Block( array(
+                       'address' => 'UTLocalIdLookup4',
+                       'by' => User::idFromName( 'UTSysop' ),
+                       'reason' => __METHOD__,
+                       'expiry' => '1 day',
+                       'hideName' => true,
+               ) );
+               $block->insert();
+       }
+
+       public function testLookupCentralIds() {
+               $lookup = new LocalIdLookup();
+               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+               $user2 = User::newFromName( 'UTLocalIdLookup2' );
+
+               $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' );
+               $this->assertFalse( $user2->isAllowed( 'hideuser' ), 'sanity check' );
+
+               $this->assertSame( array(), $lookup->lookupCentralIds( array() ) );
+
+               $expect = array_flip( $this->localUsers );
+               $expect[123] = 'X';
+               ksort( $expect );
+
+               $expect2 = $expect;
+               $expect2[$this->localUsers['UTLocalIdLookup4']] = '';
+
+               $arg = array_fill_keys( array_keys( $expect ), 'X' );
+
+               $this->assertSame( $expect2, $lookup->lookupCentralIds( $arg ) );
+               $this->assertSame( $expect, $lookup->lookupCentralIds( $arg, CentralIdLookup::AUDIENCE_RAW ) );
+               $this->assertSame( $expect, $lookup->lookupCentralIds( $arg, $user1 ) );
+               $this->assertSame( $expect2, $lookup->lookupCentralIds( $arg, $user2 ) );
+       }
+
+       public function testLookupUserNames() {
+               $lookup = new LocalIdLookup();
+               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+               $user2 = User::newFromName( 'UTLocalIdLookup2' );
+
+               $this->assertTrue( $user1->isAllowed( 'hideuser' ), 'sanity check' );
+               $this->assertFalse( $user2->isAllowed( 'hideuser' ), 'sanity check' );
+
+               $this->assertSame( array(), $lookup->lookupUserNames( array() ) );
+
+               $expect = $this->localUsers;
+               $expect['UTDoesNotExist'] = 'X';
+               ksort( $expect );
+
+               $expect2 = $expect;
+               $expect2['UTLocalIdLookup4'] = 'X';
+
+               $arg = array_fill_keys( array_keys( $expect ), 'X' );
+
+               $this->assertSame( $expect2, $lookup->lookupUserNames( $arg ) );
+               $this->assertSame( $expect, $lookup->lookupUserNames( $arg, CentralIdLookup::AUDIENCE_RAW ) );
+               $this->assertSame( $expect, $lookup->lookupUserNames( $arg, $user1 ) );
+               $this->assertSame( $expect2, $lookup->lookupUserNames( $arg, $user2 ) );
+       }
+
+       public function testIsAttached() {
+               $lookup = new LocalIdLookup();
+               $user1 = User::newFromName( 'UTLocalIdLookup1' );
+               $user2 = User::newFromName( 'DoesNotExist' );
+
+               $this->assertTrue( $lookup->isAttached( $user1 ) );
+               $this->assertFalse( $lookup->isAttached( $user2 ) );
+
+               $wiki = wfWikiId();
+               $this->assertTrue( $lookup->isAttached( $user1, $wiki ) );
+               $this->assertFalse( $lookup->isAttached( $user2, $wiki ) );
+
+               $wiki = 'not-' . wfWikiId();
+               $this->assertFalse( $lookup->isAttached( $user1, $wiki ) );
+               $this->assertFalse( $lookup->isAttached( $user2, $wiki ) );
+       }
+
+       /**
+        * @dataProvider provideIsAttachedShared
+        * @param bool $sharedDB $wgSharedDB is set
+        * @param bool $sharedTable $wgSharedTables contains 'user'
+        * @param bool $localDBSet $wgLocalDatabases contains the shared DB
+        */
+       public function testIsAttachedShared( $sharedDB, $sharedTable, $localDBSet ) {
+               global $wgDBName;
+               $this->setMwGlobals( array(
+                       'wgSharedDB' => $sharedDB ? $wgDBName : null,
+                       'wgSharedTables' => $sharedTable ? array( 'user' ) : array(),
+                       'wgLocalDatabases' => $localDBSet ? array( 'shared' ) : array(),
+               ) );
+
+               $lookup = new LocalIdLookup();
+               $this->assertSame(
+                       $sharedDB && $sharedTable && $localDBSet,
+                       $lookup->isAttached( User::newFromName( 'UTLocalIdLookup1' ), 'shared' )
+               );
+       }
+
+       public static function provideIsAttachedShared() {
+               $ret = array();
+               for ( $i = 0; $i < 7; $i++ ) {
+                       $ret[] = array(
+                               (bool)( $i & 1 ),
+                               (bool)( $i & 2 ),
+                               (bool)( $i & 4 ),
+                       );
+               }
+               return $ret;
+       }
+
+}
diff --git a/tests/phpunit/includes/user/UserArrayFromResultTest.php b/tests/phpunit/includes/user/UserArrayFromResultTest.php
new file mode 100644 (file)
index 0000000..469ad29
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @author Adam Shorland
+ * @covers UserArrayFromResult
+ */
+class UserArrayFromResultTest extends MediaWikiTestCase {
+
+       private function getMockResultWrapper( $row = null, $numRows = 1 ) {
+               $resultWrapper = $this->getMockBuilder( 'ResultWrapper' )
+                       ->disableOriginalConstructor();
+
+               $resultWrapper = $resultWrapper->getMock();
+               $resultWrapper->expects( $this->atLeastOnce() )
+                       ->method( 'current' )
+                       ->will( $this->returnValue( $row ) );
+               $resultWrapper->expects( $this->any() )
+                       ->method( 'numRows' )
+                       ->will( $this->returnValue( $numRows ) );
+
+               return $resultWrapper;
+       }
+
+       private function getRowWithUsername( $username = 'fooUser' ) {
+               $row = new stdClass();
+               $row->user_name = $username;
+               return $row;
+       }
+
+       private function getUserArrayFromResult( $resultWrapper ) {
+               return new UserArrayFromResult( $resultWrapper );
+       }
+
+       /**
+        * @covers UserArrayFromResult::__construct
+        */
+       public function testConstructionWithFalseRow() {
+               $row = false;
+               $resultWrapper = $this->getMockResultWrapper( $row );
+
+               $object = $this->getUserArrayFromResult( $resultWrapper );
+
+               $this->assertEquals( $resultWrapper, $object->res );
+               $this->assertSame( 0, $object->key );
+               $this->assertEquals( $row, $object->current );
+       }
+
+       /**
+        * @covers UserArrayFromResult::__construct
+        */
+       public function testConstructionWithRow() {
+               $username = 'addshore';
+               $row = $this->getRowWithUsername( $username );
+               $resultWrapper = $this->getMockResultWrapper( $row );
+
+               $object = $this->getUserArrayFromResult( $resultWrapper );
+
+               $this->assertEquals( $resultWrapper, $object->res );
+               $this->assertSame( 0, $object->key );
+               $this->assertInstanceOf( 'User', $object->current );
+               $this->assertEquals( $username, $object->current->mName );
+       }
+
+       public static function provideNumberOfRows() {
+               return array(
+                       array( 0 ),
+                       array( 1 ),
+                       array( 122 ),
+               );
+       }
+
+       /**
+        * @dataProvider provideNumberOfRows
+        * @covers UserArrayFromResult::count
+        */
+       public function testCountWithVaryingValues( $numRows ) {
+               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper(
+                       $this->getRowWithUsername(),
+                       $numRows
+               ) );
+               $this->assertEquals( $numRows, $object->count() );
+       }
+
+       /**
+        * @covers UserArrayFromResult::current
+        */
+       public function testCurrentAfterConstruction() {
+               $username = 'addshore';
+               $userRow = $this->getRowWithUsername( $username );
+               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper( $userRow ) );
+               $this->assertInstanceOf( 'User', $object->current() );
+               $this->assertEquals( $username, $object->current()->mName );
+       }
+
+       public function provideTestValid() {
+               return array(
+                       array( $this->getRowWithUsername(), true ),
+                       array( false, false ),
+               );
+       }
+
+       /**
+        * @dataProvider provideTestValid
+        * @covers UserArrayFromResult::valid
+        */
+       public function testValid( $input, $expected ) {
+               $object = $this->getUserArrayFromResult( $this->getMockResultWrapper( $input ) );
+               $this->assertEquals( $expected, $object->valid() );
+       }
+
+       // @todo unit test for key()
+       // @todo unit test for next()
+       // @todo unit test for rewind()
+}
diff --git a/tests/phpunit/includes/user/UserTest.php b/tests/phpunit/includes/user/UserTest.php
new file mode 100644 (file)
index 0000000..45c4b8c
--- /dev/null
@@ -0,0 +1,534 @@
+<?php
+
+define( 'NS_UNITTEST', 5600 );
+define( 'NS_UNITTEST_TALK', 5601 );
+
+/**
+ * @group Database
+ */
+class UserTest extends MediaWikiTestCase {
+       /**
+        * @var User
+        */
+       protected $user;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( array(
+                       'wgGroupPermissions' => array(),
+                       'wgRevokePermissions' => array(),
+               ) );
+
+               $this->setUpPermissionGlobals();
+
+               $this->user = new User;
+               $this->user->addGroup( 'unittesters' );
+       }
+
+       private function setUpPermissionGlobals() {
+               global $wgGroupPermissions, $wgRevokePermissions;
+
+               # Data for regular $wgGroupPermissions test
+               $wgGroupPermissions['unittesters'] = array(
+                       'test' => true,
+                       'runtest' => true,
+                       'writetest' => false,
+                       'nukeworld' => false,
+               );
+               $wgGroupPermissions['testwriters'] = array(
+                       'test' => true,
+                       'writetest' => true,
+                       'modifytest' => true,
+               );
+
+               # Data for regular $wgRevokePermissions test
+               $wgRevokePermissions['formertesters'] = array(
+                       'runtest' => true,
+               );
+
+               # For the options test
+               $wgGroupPermissions['*'] = array(
+                       'editmyoptions' => true,
+               );
+       }
+
+       /**
+        * @covers User::getGroupPermissions
+        */
+       public function testGroupPermissions() {
+               $rights = User::getGroupPermissions( array( 'unittesters' ) );
+               $this->assertContains( 'runtest', $rights );
+               $this->assertNotContains( 'writetest', $rights );
+               $this->assertNotContains( 'modifytest', $rights );
+               $this->assertNotContains( 'nukeworld', $rights );
+
+               $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) );
+               $this->assertContains( 'runtest', $rights );
+               $this->assertContains( 'writetest', $rights );
+               $this->assertContains( 'modifytest', $rights );
+               $this->assertNotContains( 'nukeworld', $rights );
+       }
+
+       /**
+        * @covers User::getGroupPermissions
+        */
+       public function testRevokePermissions() {
+               $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) );
+               $this->assertNotContains( 'runtest', $rights );
+               $this->assertNotContains( 'writetest', $rights );
+               $this->assertNotContains( 'modifytest', $rights );
+               $this->assertNotContains( 'nukeworld', $rights );
+       }
+
+       /**
+        * @covers User::getRights
+        */
+       public function testUserPermissions() {
+               $rights = $this->user->getRights();
+               $this->assertContains( 'runtest', $rights );
+               $this->assertNotContains( 'writetest', $rights );
+               $this->assertNotContains( 'modifytest', $rights );
+               $this->assertNotContains( 'nukeworld', $rights );
+       }
+
+       /**
+        * @dataProvider provideGetGroupsWithPermission
+        * @covers User::getGroupsWithPermission
+        */
+       public function testGetGroupsWithPermission( $expected, $right ) {
+               $result = User::getGroupsWithPermission( $right );
+               sort( $result );
+               sort( $expected );
+
+               $this->assertEquals( $expected, $result, "Groups with permission $right" );
+       }
+
+       public static function provideGetGroupsWithPermission() {
+               return array(
+                       array(
+                               array( 'unittesters', 'testwriters' ),
+                               'test'
+                       ),
+                       array(
+                               array( 'unittesters' ),
+                               'runtest'
+                       ),
+                       array(
+                               array( 'testwriters' ),
+                               'writetest'
+                       ),
+                       array(
+                               array( 'testwriters' ),
+                               'modifytest'
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideIPs
+        * @covers User::isIP
+        */
+       public function testIsIP( $value, $result, $message ) {
+               $this->assertEquals( $this->user->isIP( $value ), $result, $message );
+       }
+
+       public static function provideIPs() {
+               return array(
+                       array( '', false, 'Empty string' ),
+                       array( ' ', false, 'Blank space' ),
+                       array( '10.0.0.0', true, 'IPv4 private 10/8' ),
+                       array( '10.255.255.255', true, 'IPv4 private 10/8' ),
+                       array( '192.168.1.1', true, 'IPv4 private 192.168/16' ),
+                       array( '203.0.113.0', true, 'IPv4 example' ),
+                       array( '2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff', true, 'IPv6 example' ),
+                       // Not valid IPs but classified as such by MediaWiki for negated asserting
+                       // of whether this might be the identifier of a logged-out user or whether
+                       // to allow usernames like it.
+                       array( '300.300.300.300', true, 'Looks too much like an IPv4 address' ),
+                       array( '203.0.113.xxx', true, 'Assigned by UseMod to cloaked logged-out users' ),
+               );
+       }
+
+       /**
+        * @dataProvider provideUserNames
+        * @covers User::isValidUserName
+        */
+       public function testIsValidUserName( $username, $result, $message ) {
+               $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message );
+       }
+
+       public static function provideUserNames() {
+               return array(
+                       array( '', false, 'Empty string' ),
+                       array( ' ', false, 'Blank space' ),
+                       array( 'abcd', false, 'Starts with small letter' ),
+                       array( 'Ab/cd', false, 'Contains slash' ),
+                       array( 'Ab cd', true, 'Whitespace' ),
+                       array( '192.168.1.1', false, 'IP' ),
+                       array( 'User:Abcd', false, 'Reserved Namespace' ),
+                       array( '12abcd232', true, 'Starts with Numbers' ),
+                       array( '?abcd', true, 'Start with ? mark' ),
+                       array( '#abcd', false, 'Start with #' ),
+                       array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ),
+                       array( 'ജോസ്‌തോമസ്', false, 'ZWNJ- Format control character' ),
+                       array( 'Ab cd', false, ' Ideographic space' ),
+                       array( '300.300.300.300', false, 'Looks too much like an IPv4 address' ),
+                       array( '302.113.311.900', false, 'Looks too much like an IPv4 address' ),
+                       array( '203.0.113.xxx', false, 'Reserved for usage by UseMod for cloaked logged-out users' ),
+               );
+       }
+
+       /**
+        * Test, if for all rights a right- message exist,
+        * which is used on Special:ListGroupRights as help text
+        * Extensions and core
+        */
+       public function testAllRightsWithMessage() {
+               // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights
+               $allRights = User::getAllRights();
+               $allMessageKeys = Language::getMessageKeysFor( 'en' );
+
+               $rightsWithMessage = array();
+               foreach ( $allMessageKeys as $message ) {
+                       // === 0: must be at beginning of string (position 0)
+                       if ( strpos( $message, 'right-' ) === 0 ) {
+                               $rightsWithMessage[] = substr( $message, strlen( 'right-' ) );
+                       }
+               }
+
+               sort( $allRights );
+               sort( $rightsWithMessage );
+
+               $this->assertEquals(
+                       $allRights,
+                       $rightsWithMessage,
+                       'Each user rights (core/extensions) has a corresponding right- message.'
+               );
+       }
+
+       /**
+        * Test User::editCount
+        * @group medium
+        * @covers User::getEditCount
+        */
+       public function testEditCount() {
+               $user = User::newFromName( 'UnitTestUser' );
+
+               if ( !$user->getId() ) {
+                       $user->addToDatabase();
+               }
+
+               // let the user have a few (3) edits
+               $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
+               for ( $i = 0; $i < 3; $i++ ) {
+                       $page->doEdit( (string)$i, 'test', 0, false, $user );
+               }
+
+               $user->clearInstanceCache();
+               $this->assertEquals(
+                       3,
+                       $user->getEditCount(),
+                       'After three edits, the user edit count should be 3'
+               );
+
+               // increase the edit count and clear the cache
+               $user->incEditCount();
+
+               $user->clearInstanceCache();
+               $this->assertEquals(
+                       4,
+                       $user->getEditCount(),
+                       'After increasing the edit count manually, the user edit count should be 4'
+               );
+       }
+
+       /**
+        * Test changing user options.
+        * @covers User::setOption
+        * @covers User::getOption
+        */
+       public function testOptions() {
+               $user = User::newFromName( 'UnitTestUser' );
+
+               if ( !$user->getId() ) {
+                       $user->addToDatabase();
+               }
+
+               $user->setOption( 'userjs-someoption', 'test' );
+               $user->setOption( 'cols', 200 );
+               $user->saveSettings();
+
+               $user = User::newFromName( 'UnitTestUser' );
+               $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
+               $this->assertEquals( 200, $user->getOption( 'cols' ) );
+       }
+
+       /**
+        * Bug 37963
+        * Make sure defaults are loaded when setOption is called.
+        * @covers User::loadOptions
+        */
+       public function testAnonOptions() {
+               global $wgDefaultUserOptions;
+               $this->user->setOption( 'userjs-someoption', 'test' );
+               $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) );
+               $this->assertEquals( 'test', $this->user->getOption( 'userjs-someoption' ) );
+       }
+
+       /**
+        * Test password validity checks. There are 3 checks in core,
+        *      - ensure the password meets the minimal length
+        *      - ensure the password is not the same as the username
+        *      - ensure the username/password combo isn't forbidden
+        * @covers User::checkPasswordValidity()
+        * @covers User::getPasswordValidity()
+        * @covers User::isValidPassword()
+        */
+       public function testCheckPasswordValidity() {
+               $this->setMwGlobals( array(
+                       'wgPasswordPolicy' => array(
+                               'policies' => array(
+                                       'sysop' => array(
+                                               'MinimalPasswordLength' => 8,
+                                               'MinimumPasswordLengthToLogin' => 1,
+                                               'PasswordCannotMatchUsername' => 1,
+                                       ),
+                                       'default' => array(
+                                               'MinimalPasswordLength' => 6,
+                                               'PasswordCannotMatchUsername' => true,
+                                               'PasswordCannotMatchBlacklist' => true,
+                                               'MaximalPasswordLength' => 30,
+                                       ),
+                               ),
+                               'checks' => array(
+                                       'MinimalPasswordLength' => 'PasswordPolicyChecks::checkMinimalPasswordLength',
+                                       'MinimumPasswordLengthToLogin' => 'PasswordPolicyChecks::checkMinimumPasswordLengthToLogin',
+                                       'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
+                                       'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
+                                       'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
+                               ),
+                       ),
+               ) );
+
+               $user = User::newFromName( 'Useruser' );
+               // Sanity
+               $this->assertTrue( $user->isValidPassword( 'Password1234' ) );
+
+               // Minimum length
+               $this->assertFalse( $user->isValidPassword( 'a' ) );
+               $this->assertFalse( $user->checkPasswordValidity( 'a' )->isGood() );
+               $this->assertTrue( $user->checkPasswordValidity( 'a' )->isOK() );
+               $this->assertEquals( 'passwordtooshort', $user->getPasswordValidity( 'a' ) );
+
+               // Maximum length
+               $longPass = str_repeat( 'a', 31 );
+               $this->assertFalse( $user->isValidPassword( $longPass ) );
+               $this->assertFalse( $user->checkPasswordValidity( $longPass )->isGood() );
+               $this->assertFalse( $user->checkPasswordValidity( $longPass )->isOK() );
+               $this->assertEquals( 'passwordtoolong', $user->getPasswordValidity( $longPass ) );
+
+               // Matches username
+               $this->assertFalse( $user->checkPasswordValidity( 'Useruser' )->isGood() );
+               $this->assertTrue( $user->checkPasswordValidity( 'Useruser' )->isOK() );
+               $this->assertEquals( 'password-name-match', $user->getPasswordValidity( 'Useruser' ) );
+
+               // On the forbidden list
+               $this->assertFalse( $user->checkPasswordValidity( 'Passpass' )->isGood() );
+               $this->assertEquals( 'password-login-forbidden', $user->getPasswordValidity( 'Passpass' ) );
+       }
+
+       /**
+        * @covers User::getCanonicalName()
+        * @dataProvider provideGetCanonicalName
+        */
+       public function testGetCanonicalName( $name, $expectedArray, $msg ) {
+               foreach ( $expectedArray as $validate => $expected ) {
+                       $this->assertEquals(
+                               $expected,
+                               User::getCanonicalName( $name, $validate === 'false' ? false : $validate ),
+                               $msg . ' (' . $validate . ')'
+                       );
+               }
+       }
+
+       public static function provideGetCanonicalName() {
+               return array(
+                       array( ' Trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ),
+                       // @todo FIXME: Maybe the creatable name should be 'Talk:Username' or false to reject?
+                       array( 'Talk:Username', array( 'creatable' => 'Username', 'usable' => 'Username',
+                               'valid' => 'Username', 'false' => 'Talk:Username' ), 'Namespace prefix' ),
+                       array( ' name with # hash', array( 'creatable' => false, 'usable' => false ), 'With hash' ),
+                       array( 'Multi  spaces', array( 'creatable' => 'Multi spaces',
+                               'usable' => 'Multi spaces' ), 'Multi spaces' ),
+                       array( 'lowercase', array( 'creatable' => 'Lowercase' ), 'Lowercase' ),
+                       array( 'in[]valid', array( 'creatable' => false, 'usable' => false, 'valid' => false,
+                               'false' => 'In[]valid' ), 'Invalid' ),
+                       array( 'with / slash', array( 'creatable' => false, 'usable' => false, 'valid' => false,
+                               'false' => 'With / slash' ), 'With slash' ),
+               );
+       }
+
+       /**
+        * @covers User::equals
+        */
+       public function testEquals() {
+               $first = User::newFromName( 'EqualUser' );
+               $second = User::newFromName( 'EqualUser' );
+
+               $this->assertTrue( $first->equals( $first ) );
+               $this->assertTrue( $first->equals( $second ) );
+               $this->assertTrue( $second->equals( $first ) );
+
+               $third = User::newFromName( '0' );
+               $fourth = User::newFromName( '000' );
+
+               $this->assertFalse( $third->equals( $fourth ) );
+               $this->assertFalse( $fourth->equals( $third ) );
+
+               // Test users loaded from db with id
+               $user = User::newFromName( 'EqualUnitTestUser' );
+               if ( !$user->getId() ) {
+                       $user->addToDatabase();
+               }
+
+               $id = $user->getId();
+
+               $fifth = User::newFromId( $id );
+               $sixth = User::newFromName( 'EqualUnitTestUser' );
+               $this->assertTrue( $fifth->equals( $sixth ) );
+       }
+
+       /**
+        * @covers User::getId
+        */
+       public function testGetId() {
+               $user = User::newFromName( 'UTSysop' );
+               $this->assertTrue( $user->getId() > 0 );
+
+       }
+
+       /**
+        * @covers User::isLoggedIn
+        * @covers User::isAnon
+        */
+       public function testLoggedIn() {
+               $user = User::newFromName( 'UTSysop' );
+               $this->assertTrue( $user->isLoggedIn() );
+               $this->assertFalse( $user->isAnon() );
+
+               // Non-existent users are perceived as anonymous
+               $user = User::newFromName( 'UTNonexistent' );
+               $this->assertFalse( $user->isLoggedIn() );
+               $this->assertTrue( $user->isAnon() );
+
+               $user = new User;
+               $this->assertFalse( $user->isLoggedIn() );
+               $this->assertTrue( $user->isAnon() );
+       }
+
+       /**
+        * @covers User::checkAndSetTouched
+        */
+       public function testCheckAndSetTouched() {
+               $user = TestingAccessWrapper::newFromObject( User::newFromName( 'UTSysop' ) );
+               $this->assertTrue( $user->isLoggedIn() );
+
+               $touched = $user->getDBTouched();
+               $this->assertTrue(
+                       $user->checkAndSetTouched(), "checkAndSetTouched() succeded" );
+               $this->assertGreaterThan(
+                       $touched, $user->getDBTouched(), "user_touched increased with casOnTouched()" );
+
+               $touched = $user->getDBTouched();
+               $this->assertTrue(
+                       $user->checkAndSetTouched(), "checkAndSetTouched() succeded #2" );
+               $this->assertGreaterThan(
+                       $touched, $user->getDBTouched(), "user_touched increased with casOnTouched() #2" );
+       }
+
+       public static function setExtendedLoginCookieDataProvider() {
+               $data = array();
+               $now = time();
+
+               $secondsInDay = 86400;
+
+               // Arbitrary durations, in units of days, to ensure it chooses the
+               // right one.  There is a 5-minute grace period (see testSetExtendedLoginCookie)
+               // to work around slow tests, since we're not currently mocking time() for PHP.
+
+               $durationOne = $secondsInDay * 5;
+               $durationTwo = $secondsInDay * 29;
+               $durationThree = $secondsInDay * 17;
+
+               // If $wgExtendedLoginCookieExpiration is null, then the expiry passed to
+               // set cookie is time() + $wgCookieExpiration
+               $data[] = array(
+                       null,
+                       $durationOne,
+                       $now + $durationOne,
+               );
+
+               // If $wgExtendedLoginCookieExpiration isn't null, then the expiry passed to
+               // set cookie is $now + $wgExtendedLoginCookieExpiration
+               $data[] = array(
+                       $durationTwo,
+                       $durationThree,
+                       $now + $durationTwo,
+               );
+
+               return $data;
+       }
+
+       /**
+        * @dataProvider setExtendedLoginCookieDataProvider
+        * @covers User::getRequest
+        * @covers User::setCookie
+        * @backupGlobals enabled
+        */
+       public function testSetExtendedLoginCookie(
+               $extendedLoginCookieExpiration,
+               $cookieExpiration,
+               $expectedExpiry
+       ) {
+               $this->setMwGlobals( array(
+                       'wgExtendedLoginCookieExpiration' => $extendedLoginCookieExpiration,
+                       'wgCookieExpiration' => $cookieExpiration,
+               ) );
+
+               $response = $this->getMock( 'WebResponse' );
+               $setcookieSpy = $this->any();
+               $response->expects( $setcookieSpy )
+                       ->method( 'setcookie' );
+
+               $request = new MockWebRequest( $response );
+               $user = new UserProxy( User::newFromSession( $request ) );
+               $user->setExtendedLoginCookie( 'name', 'value', true );
+
+               $setcookieInvocations = $setcookieSpy->getInvocations();
+               $setcookieInvocation = end( $setcookieInvocations );
+               $actualExpiry = $setcookieInvocation->parameters[2];
+
+               // TODO: ± 600 seconds compensates for
+               // slow-running tests. However, the dependency on the time
+               // function should be removed.  This requires some way
+               // to mock/isolate User->setExtendedLoginCookie's call to time()
+               $this->assertEquals( $expectedExpiry, $actualExpiry, '', 600 );
+       }
+}
+
+class UserProxy extends User {
+
+       /**
+        * @var User
+        */
+       protected $user;
+
+       public function __construct( User $user ) {
+               $this->user = $user;
+       }
+
+       public function setExtendedLoginCookie( $name, $value, $secure ) {
+               $this->user->setExtendedLoginCookie( $name, $value, $secure );
+       }
+}
index 89b2c17..7123b94 100644 (file)
@@ -62,16 +62,46 @@ class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
                );
        }
 
+       /**
+        * @covers UIDGenerator::newUUIDv1
+        */
+       public function testUUIDv1() {
+               $ids = array();
+               for ( $i = 0; $i < 100; $i++ ) {
+                       $id = UIDGenerator::newUUIDv1();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
+                               "UID $id has the right format" );
+                       $ids[] = $id;
+
+                       $id = UIDGenerator::newRawUUIDv1();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}1[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+
+                       $id = UIDGenerator::newRawUUIDv1( UIDGenerator::QUICK_RAND );
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}1[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+               }
+
+               $this->assertEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
+       }
+
        /**
         * @covers UIDGenerator::newUUIDv4
         */
        public function testUUIDv4() {
+               $ids = array();
                for ( $i = 0; $i < 100; $i++ ) {
                        $id = UIDGenerator::newUUIDv4();
+                       $ids[] = $id;
                        $this->assertEquals( true,
                                preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
                                "UID $id has the right format" );
                }
+
+               $this->assertEquals( array_unique( $ids ), $ids, 'All generated IDs are unique.' );
        }
 
        /**
index d4ccca9..8fc0bee 100644 (file)
@@ -13,7 +13,6 @@ class LanguageConverterTest extends MediaWikiLangTestCase {
                        'wgContLang' => Language::factory( 'tg' ),
                        'wgLanguageCode' => 'tg',
                        'wgDefaultLanguageVariant' => false,
-                       'wgMemc' => new EmptyBagOStuff,
                        'wgRequest' => new FauxRequest( array() ),
                        'wgUser' => new User,
                ) );
index d93dafb..bdabdc1 100644 (file)
@@ -24,6 +24,10 @@ phpunit.php enables colors for other OSs at runtime
                <testsuite name="languages">
                        <directory>languages</directory>
                </testsuite>
+               <testsuite name="parsertests">
+                       <file>includes/parser/MediaWikiParserTest.php</file>
+                       <file>suites/ExtensionsParserTestSuite.php</file>
+               </testsuite>
                <testsuite name="skins">
                        <directory>skins</directory>
                        <directory>structure</directory>
index e867250..80893da 100644 (file)
@@ -21,6 +21,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                        $wgParserCacheType, $wgNamespaceAliases, $wgNamespaceProtection,
                        $parserMemc;
 
+               $tmpDir = $this->getNewTempDirectory();
                $tmpGlobals = array();
 
                $tmpGlobals['wgScript'] = '/index.php';
@@ -38,10 +39,10 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                                'name' => 'local-backend',
                                'wikiId' => wfWikiId(),
                                'containerPaths' => array(
-                                       'local-public' => wfTempDir() . '/test-repo/public',
-                                       'local-thumb' => wfTempDir() . '/test-repo/thumb',
-                                       'local-temp' => wfTempDir() . '/test-repo/temp',
-                                       'local-deleted' => wfTempDir() . '/test-repo/delete',
+                                       'local-public' => "{$tmpDir}/test-repo/public",
+                                       'local-thumb' => "{$tmpDir}/test-repo/thumb",
+                                       'local-temp' => "{$tmpDir}/test-repo/temp",
+                                       'local-deleted' => "{$tmpDir}/test-repo/delete",
                                )
                        ) ),
                );
@@ -176,17 +177,11 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                                return $dir;
                        }
                } else {
-                       $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images";
+                       $dir = $this->getNewTempDirectory();
                }
 
                wfDebug( "Creating upload directory $dir\n" );
 
-               if ( file_exists( $dir ) ) {
-                       wfDebug( "Already exists!\n" );
-
-                       return $dir;
-               }
-
                wfMkdirParents( $dir . '/3/3a', null, __METHOD__ );
                copy( "$IP/tests/phpunit/data/upload/headbg.jpg", "$dir/3/3a/Foobar.jpg" );
 
index a34a5af..394f3bd 100644 (file)
 
        } );
 
+       QUnit.test( 'badToken( legacy )', function ( assert ) {
+               QUnit.expect( 2 );
+               var api = new mw.Api( { ajax: { url: '/badTokenLegacy/api.php' } } ),
+                       test = this;
+
+               this.server.respondWith( /type=csrf/, sequenceBodies( 200, { 'Content-Type': 'application/json' },
+                       [
+                               '{ "query": { "tokens": { "csrftoken": "badlegacy" } } }',
+                               '{ "query": { "tokens": { "csrftoken": "goodlegacy" } } }'
+                       ]
+               ) );
+
+               api.getToken( 'options' )
+                       .then( function () {
+                               api.badToken( 'options' );
+                               return api.getToken( 'options' );
+                       } )
+                       .then( function ( token ) {
+                               assert.equal( token, 'goodlegacy', 'The token' );
+                               assert.equal( test.server.requests.length, 2, 'Request made' );
+                       } );
+
+       } );
+
        QUnit.test( 'postWithToken( tokenType, params )', function ( assert ) {
                QUnit.expect( 1 );
                var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } } );