Merge "wfTempDir try harder to get a tmp dir on Windows"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 12 May 2016 19:10:25 +0000 (19:10 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 12 May 2016 19:10:25 +0000 (19:10 +0000)
441 files changed:
Gemfile
Gemfile.lock
RELEASE-NOTES-1.27
RELEASE-NOTES-1.28 [new file with mode: 0644]
Rakefile
autoload.php
composer.json
docs/extension.schema.json
docs/hooks.txt
docs/injection.txt
extensions/README
includes/AuthPlugin.php
includes/CategoryViewer.php
includes/DefaultSettings.php
includes/DummyLinker.php
includes/EditPage.php
includes/EventRelayerGroup.php
includes/GlobalFunctions.php
includes/Linker.php
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/Message.php
includes/MovePage.php
includes/OutputPage.php
includes/ProtectionForm.php
includes/Revision.php
includes/ServiceWiring.php
includes/Services/CannotReplaceActiveServiceException.php [new file with mode: 0644]
includes/Services/ContainerDisabledException.php [new file with mode: 0644]
includes/Services/DestructibleService.php [new file with mode: 0644]
includes/Services/NoSuchServiceException.php [new file with mode: 0644]
includes/Services/ServiceAlreadyDefinedException.php [new file with mode: 0644]
includes/Services/ServiceContainer.php
includes/Services/ServiceDisabledException.php [new file with mode: 0644]
includes/Setup.php
includes/SiteStats.php
includes/Title.php
includes/WatchedItem.php
includes/WatchedItemStore.php
includes/WebRequest.php
includes/actions/InfoAction.php
includes/api/ApiBase.php
includes/api/ApiHelp.php
includes/api/ApiMain.php
includes/api/ApiOpenSearch.php
includes/api/ApiOptions.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryPrefixSearch.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQuerySearch.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiStashEdit.php
includes/api/ApiUpload.php
includes/api/i18n/eo.json
includes/api/i18n/id.json
includes/api/i18n/it.json
includes/api/i18n/jv.json [new file with mode: 0644]
includes/api/i18n/ko.json
includes/api/i18n/ku-latn.json
includes/api/i18n/mk.json
includes/api/i18n/pl.json
includes/api/i18n/sv.json
includes/api/i18n/vi.json
includes/api/i18n/zh-hans.json
includes/cache/GenderCache.php
includes/cache/LinkCache.php
includes/changes/EnhancedChangesList.php
includes/changetags/ChangeTags.php
includes/collation/IcuCollation.php
includes/compat/normal/UtfNormalUtil.php
includes/composer/ComposerPackageModifier.php
includes/config/ConfigFactory.php
includes/content/ContentHandler.php
includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LoadBalancer.php
includes/debug/MWDebug.php
includes/deferred/CdnCacheUpdate.php
includes/deferred/DeferredUpdates.php
includes/deferred/LinksUpdate.php
includes/deferred/SearchUpdate.php
includes/diff/DairikiDiff.php
includes/diff/DifferenceEngine.php
includes/filebackend/FileBackendMultiWrite.php
includes/filerepo/FileRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLFormFieldCloner.php
includes/htmlform/OOUIHTMLForm.php
includes/installer/DatabaseInstaller.php
includes/installer/Installer.php
includes/installer/MssqlInstaller.php
includes/installer/MssqlUpdater.php
includes/installer/WebInstallerPage.php
includes/installer/i18n/jv.json
includes/installer/i18n/ko.json
includes/installer/i18n/mai.json
includes/installer/i18n/nds-nl.json
includes/installer/i18n/nl.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/vi.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/interwiki/Interwiki.php
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/jobs/RecentChangesUpdateJob.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/libs/CSSMin.php
includes/libs/eventrelayer/EventRelayer.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/IExpiringStore.php
includes/libs/objectcache/MemcachedClient.php
includes/libs/objectcache/WANObjectCache.php
includes/linker/LinkTarget.php
includes/mail/EmailNotification.php
includes/media/Bitmap.php
includes/media/GIF.php
includes/media/PNG.php
includes/media/TransformationalImageHandler.php
includes/mime.types
includes/objectcache/ObjectCache.php
includes/objectcache/RedisBagOStuff.php
includes/page/WikiFilePage.php
includes/page/WikiPage.php
includes/parser/BlockLevelPass.php [new file with mode: 0644]
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserOutput.php
includes/password/PasswordPolicyChecks.php
includes/poolcounter/PoolCounter.php
includes/poolcounter/PoolCounterWork.php
includes/poolcounter/PoolCounterWorkViaCallback.php
includes/poolcounter/PoolWorkArticleView.php
includes/registration/ExtensionProcessor.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/resourceloader/ResourceLoaderUserGroupsModule.php
includes/resourceloader/ResourceLoaderUserModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelList.php
includes/search/SearchEngine.php
includes/search/SearchEngineConfig.php [new file with mode: 0644]
includes/search/SearchEngineFactory.php [new file with mode: 0644]
includes/search/SearchNearMatchResultSet.php
includes/search/SearchNearMatcher.php [new file with mode: 0644]
includes/search/SearchResult.php
includes/session/Session.php
includes/session/SessionInfo.php
includes/session/SessionManager.php
includes/session/SessionManagerInterface.php
includes/session/SessionProvider.php
includes/skins/Skin.php
includes/skins/SkinFactory.php
includes/specialpage/QueryPage.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialChangeContentModel.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialLockdb.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMediaStatistics.php
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUnlockdb.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/pagers/ActiveUsersPager.php
includes/title/MediaWikiTitleCodec.php
includes/title/TitleFormatter.php
includes/title/TitleValue.php
includes/user/User.php
includes/widget/SearchInputWidget.php [changed mode: 0644->0755]
languages/Language.php
languages/classes/LanguageAz.php
languages/classes/LanguageEo.php
languages/classes/LanguageKaa.php
languages/classes/LanguageKk.php
languages/classes/LanguageQqx.php
languages/classes/LanguageTr.php
languages/classes/LanguageWa.php
languages/data/ZhConversion.php
languages/i18n/af.json
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dty.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/frp.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/gom-latn.json
languages/i18n/gsw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/ht.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kiu.json
languages/i18n/kk-cyrl.json
languages/i18n/km.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lki.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/mai.json
languages/i18n/mg.json
languages/i18n/min.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/nds-nl.json
languages/i18n/nds.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/olo.json
languages/i18n/or.json
languages/i18n/pa.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/roa-tara.json
languages/i18n/ru.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sd.json
languages/i18n/sh.json
languages/i18n/si.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/war.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/MessagesCs.php
load.php
maintenance/convertExtensionToRegistration.php
maintenance/language/zhtable/toCN.manual
maintenance/language/zhtable/toHK.manual
maintenance/language/zhtable/toTW.manual
maintenance/language/zhtable/toTrad.manual
maintenance/language/zhtable/tradphrases.manual
maintenance/language/zhtable/tradphrases_exclude.manual
maintenance/mssql/archives/named_constraints.sql [deleted file]
maintenance/mssql/archives/patch-add-cl_collation_ext_index.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-archive-drop-fks.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-bot_passwords.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-categorylinks-constraints.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-drop-page_counter.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-drop-rc_cur_time.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-drop-ss_total_views.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-drop-user_options.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-filearchive-constraints.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-filearchive-schema.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-il_from_namespace.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-image-constraints.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-image-schema.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-kill-cl_collation_index.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-logging-drop-fks.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-oldimage-constraints.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-oldimage-schema.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-pl_from_namespace.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-pp_sortkey.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-recentchanges-drop-fks.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-tl_from_namespace.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-uploadstash-constraints.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/resources/update-oojs-ui.sh
maintenance/resources/update-oojs.sh
maintenance/updateCollation.php
opensearch_desc.php
profileinfo.php
resources/Resources.php
resources/lib/oojs-router/AUTHORS.txt [new file with mode: 0644]
resources/lib/oojs-router/LICENSE-MIT [new file with mode: 0644]
resources/lib/oojs-router/oojs-router.js [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/icons-media.json
resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/icons-media.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.svg [new file with mode: 0644]
resources/src/jquery/jquery.makeCollapsible.js
resources/src/mediawiki.action/mediawiki.action.view.metadata.js
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.router/index.js [new file with mode: 0644]
resources/src/mediawiki.skinning/content.parsoid.less
resources/src/mediawiki.special/mediawiki.special.upload.css [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.upload.js
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js [changed mode: 0644->0755]
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
resources/src/mediawiki/ForeignApi.js
resources/src/mediawiki/api.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js
resources/src/mediawiki/mediawiki.apihelp.css
resources/src/moment-local-dmy.js [deleted file]
resources/src/moment-locale-overrides.js [new file with mode: 0644]
skins/README
tests/browser/ci.yml [new file with mode: 0644]
tests/browser/features/step_definitions/create_account_steps.rb
tests/browser/features/step_definitions/file_steps.rb
tests/browser/features/step_definitions/login_steps.rb
tests/browser/features/step_definitions/preferences_appearance_steps.rb
tests/browser/features/step_definitions/preferences_editing_steps.rb
tests/browser/features/step_definitions/preferences_user_profile_steps.rb
tests/browser/features/support/pages/create_account_page.rb
tests/browser/features/support/pages/file_does_not_exist_page.rb
tests/browser/features/support/pages/preferences_appearance_page.rb
tests/browser/features/support/pages/preferences_editing_page.rb
tests/browser/features/support/pages/preferences_page.rb
tests/browser/features/support/pages/preferences_user_profile_page.rb
tests/parser/parserTest.inc
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/data/media/yuv420.jpg [new file with mode: 0644]
tests/phpunit/data/media/yuv444.jpg [new file with mode: 0644]
tests/phpunit/includes/GlobalFunctions/wfAppendQueryTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/MergeHistoryTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/PrefixSearchTest.php
tests/phpunit/includes/Services/ServiceContainerTest.php
tests/phpunit/includes/TestUser.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/WatchedItemStoreIntegrationTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/WatchedItemUnitTest.php
tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php [new file with mode: 0644]
tests/phpunit/includes/changes/RecentChangeTest.php
tests/phpunit/includes/config/ConfigFactoryTest.php
tests/phpunit/includes/deferred/SearchUpdateTest.php
tests/phpunit/includes/htmlform/HTMLFormTest.php [new file with mode: 0644]
tests/phpunit/includes/interwiki/InterwikiTest.php [new file with mode: 0644]
tests/phpunit/includes/media/GIFTest.php
tests/phpunit/includes/media/JpegPixelFormatTest.php [new file with mode: 0644]
tests/phpunit/includes/media/MediaHandlerTest.php
tests/phpunit/includes/media/PNGTest.php
tests/phpunit/includes/page/WikiCategoryPageTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/poolcounter/PoolCounterTest.php
tests/phpunit/includes/registration/ExtensionProcessorTest.php
tests/phpunit/includes/search/SearchEnginePrefixTest.php
tests/phpunit/includes/session/SessionInfoTest.php
tests/phpunit/includes/session/SessionManagerTest.php
tests/phpunit/includes/session/SessionProviderTest.php
tests/phpunit/includes/session/SessionTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/title/MediaWikiTitleCodecTest.php
tests/phpunit/includes/title/TitleValueTest.php
tests/phpunit/phpunit.php
tests/phpunit/tests/MediaWikiTestCaseTest.php

diff --git a/Gemfile b/Gemfile
index 636d4ee..fa3a025 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,5 @@
 source 'https://rubygems.org'
 
-gem 'mediawiki_selenium', '~> 1.6.5'
+gem 'mediawiki_selenium', '~> 1.7'
+gem 'rake', '~> 11.1', '>= 11.1.1'
 gem 'rubocop', '~> 0.32.1', require: false
index 8684be9..2bbabd1 100644 (file)
@@ -17,9 +17,9 @@ GEM
       faker (>= 1.1.2)
       yml_reader (>= 0.6)
     diff-lcs (1.2.5)
-    domain_name (0.5.20160128)
+    domain_name (0.5.20160310)
       unf (>= 0.0.5, < 1.0.0)
-    faker (1.6.1)
+    faker (1.6.3)
       i18n (~> 0.5)
     faraday (0.9.2)
       multipart-post (>= 1.2, < 3)
@@ -29,7 +29,7 @@ GEM
     ffi (1.9.10)
     gherkin (2.12.2)
       multi_json (~> 1.3)
-    headless (2.2.0)
+    headless (2.2.3)
     http-cookie (1.0.2)
       domain_name (~> 0.5)
     i18n (0.7.0)
@@ -37,7 +37,7 @@ GEM
     mediawiki_api (0.5.0)
       faraday (~> 0.9, >= 0.9.0)
       faraday-cookie_jar (~> 0.0, >= 0.0.6)
-    mediawiki_selenium (1.6.5)
+    mediawiki_selenium (1.7.0)
       cucumber (~> 1.3, >= 1.3.20)
       headless (~> 2.0, >= 2.1.0)
       json (~> 1.8, >= 1.8.1)
@@ -48,8 +48,8 @@ GEM
       rspec-expectations (~> 2.14, >= 2.14.4)
       syntax (~> 1.2, >= 1.2.0)
       thor (~> 0.19, >= 0.19.1)
-    mime-types (2.99)
-    multi_json (1.11.2)
+    mime-types (2.99.1)
+    multi_json (1.11.3)
     multi_test (0.1.2)
     multipart-post (2.0.0)
     netrc (0.11.0)
@@ -63,6 +63,7 @@ GEM
       ast (>= 1.1, < 3.0)
     powerpack (0.1.1)
     rainbow (2.0.0)
+    rake (11.1.1)
     rest-client (1.8.0)
       http-cookie (>= 1.0.2, < 2.0)
       mime-types (>= 1.16, < 3.0)
@@ -77,25 +78,28 @@ GEM
       rainbow (>= 1.99.1, < 3.0)
       ruby-progressbar (~> 1.4)
     ruby-progressbar (1.7.5)
-    rubyzip (1.1.7)
-    selenium-webdriver (2.50.0)
+    rubyzip (1.2.0)
+    selenium-webdriver (2.53.0)
       childprocess (~> 0.5)
-      multi_json (~> 1.0)
       rubyzip (~> 1.0)
       websocket (~> 1.0)
     syntax (1.2.0)
     thor (0.19.1)
     unf (0.1.4)
       unf_ext
-    unf_ext (0.0.7.1)
+    unf_ext (0.0.7.2)
     watir-webdriver (0.9.1)
       selenium-webdriver (>= 2.46.2)
-    websocket (1.2.2)
+    websocket (1.2.3)
     yml_reader (0.7)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  mediawiki_selenium (~> 1.6.5)
+  mediawiki_selenium (~> 1.7)
+  rake (~> 11.1, >= 11.1.1)
   rubocop (~> 0.32.1)
+
+BUNDLED WITH
+   1.10.6
index 7ddcdfb..3a0326e 100644 (file)
@@ -13,6 +13,8 @@ HHVM 3.1. Additionally, the following PHP extensions are required:
 * json
 * mbstring
 * xml
+The following PHP extensions are strongly recommended:
+* openssl
 
 === Configuration changes in 1.27 ===
 * $wgAllowMicrodataAttributes and $wgAllowRdfaAttributes were removed,
@@ -114,6 +116,9 @@ HHVM 3.1. Additionally, the following PHP extensions are required:
   module should express a dependency on it.
 * Removed configuration option $wgCopyrightIcon (deprecated since 1.18). Use
   $wgFooterIcons['copyright']['copyright'] instead.
+* If the openssl and mcrypt PHP extensions are both unavailable, secure
+  session storage (soon to be used for login) will raise an exception. This
+  exception may be bypassed by setting $wgSessionInsecureSecrets = true.
 
 === New features in 1.27 ===
 * $wgDataCenterUpdateStickTTL was also added. This decides how long a user
@@ -190,6 +195,9 @@ HHVM 3.1. Additionally, the following PHP extensions are required:
   is deprecated.
 * (T33313) Add a preference for watching uploads by default, also applies
   to API-based upload tools.
+* $wgJpegPixelFormat was added to override chroma subsampling for JPEG image
+  thumbnails created via ImageMagick. Defaults to 'yuv420', providing bandwidth
+  savings versus the previous behavior on many files.
 
 === External library changes in 1.27 ===
 
@@ -463,6 +471,10 @@ changes to languages because of Phabricator reports.
 * Skin::tooltipAndAccesskeyAttribs was removed (deprecated since 1.21).
 * Skin::userTalkLink was removed (deprecated since 1.21).
 * Skin::userToolLinksRedContribs was removed (deprecated since 1.21).
+* wikidiff3 is now the default and only PHP diff engine. It provides improved diff
+  performance on complex changes. $wgExternalDiffEngine = 'wikidiff3' therefore
+  makes no difference now. Users are still recommended to use wikidiff2 if possible,
+  though.
 
 == Compatibility ==
 
diff --git a/RELEASE-NOTES-1.28 b/RELEASE-NOTES-1.28
new file mode 100644 (file)
index 0000000..e365486
--- /dev/null
@@ -0,0 +1,111 @@
+== MediaWiki 1.28 ==
+
+THIS IS NOT A RELEASE YET
+
+MediaWiki 1.28 is an alpha-quality branch and is not recommended for use in
+production.
+
+=== Configuration changes in 1.28 ===
+* The load.php entry point now enforces the existing policy of not allowing
+  access to session data, which includes the session user and the session
+  user's language. If such access is attempted, an exception will be thrown.
+
+=== New features in 1.28 ===
+* User::isBot() method for checking if an account is a bot role account.
+* Added a new hook, 'UserIsBot', to aid in determining if a user is a bot.
+
+
+=== External library changes in 1.28 ===
+
+==== Upgraded external libraries ====
+
+
+==== New external libraries ====
+
+
+==== Removed and replaced external libraries ====
+
+
+=== Bug fixes in 1.28 ===
+
+
+=== Action API changes in 1.28 ===
+
+
+=== Action API internal changes in 1.28 ===
+
+
+=== Languages updated in 1.28 ===
+
+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.
+
+=== Other changes in 1.27 ===
+
+
+== Compatibility ==
+
+MediaWiki 1.28 requires PHP 5.5.9 or later. There is experimental support for
+HHVM 3.6.5 or later.
+
+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.28 has several database changes since 1.27, 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.27.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 6eef121..59f5480 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -8,6 +8,9 @@ RuboCop::RakeTask.new(:rubocop) do |task|
   task.options = ['-c', '.rubocop.yml']
 end
 
+require 'mediawiki_selenium/rake_task'
+MediawikiSelenium::RakeTask.new(site_tag: false)
+
 task default: [:test]
 
 desc 'Run all build/tests commands (CI entry point)'
index 9b155bb..1e656e4 100644 (file)
@@ -180,6 +180,7 @@ $wgAutoloadLocalClasses = [
        'BitmapMetadataHandler' => __DIR__ . '/includes/media/BitmapMetadataHandler.php',
        'Blob' => __DIR__ . '/includes/db/DatabaseUtility.php',
        'Block' => __DIR__ . '/includes/Block.php',
+       'BlockLevelPass' => __DIR__ . '/includes/parser/BlockLevelPass.php',
        'BlockListPager' => __DIR__ . '/includes/specials/pagers/BlockListPager.php',
        'BlockLogFormatter' => __DIR__ . '/includes/logging/BlockLogFormatter.php',
        'BmpHandler' => __DIR__ . '/includes/media/BMP.php',
@@ -711,6 +712,7 @@ $wgAutoloadLocalClasses = [
        'LoadMonitorNull' => __DIR__ . '/includes/db/loadbalancer/LoadMonitor.php',
        'LocalFile' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
        'LocalFileDeleteBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
+       'LocalFileLockError' => __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',
@@ -795,7 +797,13 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\NullSpi' => __DIR__ . '/includes/debug/logger/NullSpi.php',
        'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
        'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
+       'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/Services/CannotReplaceActiveServiceException.php',
+       'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/Services/ContainerDisabledException.php',
+       'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/Services/DestructibleService.php',
+       'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/Services/NoSuchServiceException.php',
+       'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/Services/ServiceAlreadyDefinedException.php',
        'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/Services/ServiceContainer.php',
+       'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/Services/ServiceDisabledException.php',
        'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php',
        'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php',
        'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php',
@@ -1135,12 +1143,15 @@ $wgAutoloadLocalClasses = [
        'SearchDatabase' => __DIR__ . '/includes/search/SearchDatabase.php',
        'SearchDump' => __DIR__ . '/maintenance/dumpIterator.php',
        'SearchEngine' => __DIR__ . '/includes/search/SearchEngine.php',
+       'SearchEngineConfig' => __DIR__ . '/includes/search/SearchEngineConfig.php',
        'SearchEngineDummy' => __DIR__ . '/includes/search/SearchEngine.php',
+       'SearchEngineFactory' => __DIR__ . '/includes/search/SearchEngineFactory.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',
        'SearchNearMatchResultSet' => __DIR__ . '/includes/search/SearchNearMatchResultSet.php',
+       'SearchNearMatcher' => __DIR__ . '/includes/search/SearchNearMatcher.php',
        'SearchOracle' => __DIR__ . '/includes/search/SearchOracle.php',
        'SearchPostgres' => __DIR__ . '/includes/search/SearchPostgres.php',
        'SearchResult' => __DIR__ . '/includes/search/SearchResult.php',
index 3bea9ea..ef85ec4 100644 (file)
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.16.6",
+               "oojs/oojs-ui": "0.17.2",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.0",
                "wikimedia/assert": "0.2.2",
                "wikimedia/base-convert": "1.0.1",
-               "wikimedia/cdb": "1.3.0",
+               "wikimedia/cdb": "1.4.0",
                "wikimedia/cldr-plural-rule-parser": "1.0.0",
                "wikimedia/composer-merge-plugin": "1.3.1",
                "wikimedia/html-formatter": "1.0.1",
-               "wikimedia/ip-set": "1.0.1",
+               "wikimedia/ip-set": "1.1.0",
                "wikimedia/php-session-serializer": "1.0.3",
                "wikimedia/relpath": "1.0.3",
                "wikimedia/running-stat": "1.1.0",
@@ -46,7 +46,7 @@
        "require-dev": {
                "jakub-onderka/php-parallel-lint": "0.9.2",
                "justinrainbow/json-schema": "~1.3",
-               "mediawiki/mediawiki-codesniffer": "0.6.0",
+               "mediawiki/mediawiki-codesniffer": "0.7.1",
                "monolog/monolog": "~1.18.2",
                "nikic/php-parser": "1.4.1",
                "nmred/kafka-php": "0.1.5",
index f1decd3..ed3eaa9 100644 (file)
                },
                "TrackingCategories": {
                        "type": "array",
-                       "description": "Tracking category message keys"
+                       "description": "Tracking category message keys",
+                       "items": {
+                               "type": "string"
+                       }
                },
                "DefaultUserOptions": {
                        "type": "object",
                },
                "HiddenPrefs": {
                        "type": "array",
-                       "description": "Preferences users cannot set"
+                       "description": "Preferences users cannot set",
+                       "items": {
+                               "type": "string"
+                       }
                },
                "GroupPermissions": {
                        "type": "object",
-                       "description": "Default permissions to give to user groups"
+                       "description": "Default permissions to give to user groups",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z]+$": {
+                                                       "type": "boolean"
+                                               }
+                                       }
+                               }
+                       }
                },
                "RevokePermissions": {
                        "type": "object",
-                       "description": "Default permissions to revoke from user groups"
+                       "description": "Default permissions to revoke from user groups",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z]+$": {
+                                                       "type": "boolean"
+                                               }
+                                       }
+                               }
+                       }
                },
                "ImplicitGroups": {
                        "type": "array",
                },
                "AvailableRights": {
                        "type": "array",
-                       "description": "User rights added by the extension"
+                       "description": "User rights added by the extension",
+                       "items": {
+                               "type": "string"
+                       }
                },
                "ContentHandlers": {
                        "type": "object",
-                       "description": "Mapping of model ID to class name"
+                       "description": "Mapping of model ID to class name",
+                       "patternProperties": {
+                               "^[A-Za-z]+$": {
+                                       "type": "string"
+                               }
+                       }
                },
                "RateLimits": {
                        "type": "object",
                                "array",
                                "string"
                        ],
-                       "description": "Function to call after setup has finished"
+                       "description": "Function to call after setup has finished",
+                       "items": {
+                               "type": "string"
+                       }
                },
                "ExtensionMessagesFiles": {
                        "type": "object",
                        "type": "object"
                },
                "Hooks": {
-                       "type": "object",
+                       "type": [ "string", "object" ],
                        "description": "Hooks this extension uses (mapping of hook name to callback)"
                },
                "JobClasses": {
index 31e9d92..2d5f6bc 100644 (file)
@@ -1997,9 +1997,10 @@ $user: $wgUser
 $request: $wgRequest
 $mediaWiki: The $mediawiki object
 
-'MediaWikiServices': Override services in the default MediaWikiServices instance.
-Extensions may use this to define, replace, or wrap existing services.
-However, the preferred way to define a new service is the $wgServiceWiringFiles array.
+'MediaWikiServices': Called when a global MediaWikiServices instance is
+initialized. Extensions may use this to define, replace, or wrap services.
+However, the preferred way to define a new service is
+the $wgServiceWiringFiles array.
 $services: MediaWikiServices
 
 'MessageCache::get': When fetching a message. Can be used to override the key
@@ -2127,6 +2128,7 @@ $sk: The Skin that called OutputPage::headElement
 since the last visit.
 &$modifiedTimes: array of timestamps.
   The following keys are set: page, user, epoch
+$out: OutputPage object (since 1.28)
 
 'OutputPageMakeCategoryLinks': Links are about to be generated for the page's
 categories. Implementations should return false if they generate the category
@@ -3215,6 +3217,10 @@ $mime: (string) The uploaded file's MIME type, as detected by MediaWiki.
   representing the problem with the file, where the first element is the message
   key and the remaining elements are used as parameters to the message.
 
+'UserIsBot': when determining whether a user is a bot account
+$user: the user
+&$isBot: whether this is user a bot or not (boolean)
+
 'User::mailPasswordInternal': before creation and mailing of a user's new
 temporary password
 &$user: the user who sent the message out
index e0466c4..2badea9 100644 (file)
@@ -60,6 +60,27 @@ MediaWikiServices::getInstance() should ideally be accessed only in "static
 entry points" such as hook handler functions. See "Migration" below.
 
 
+== Service Reset ==
+
+Services get their configuration injected, and changes to global
+configuration variables will not have any effect on services that were already
+instantiated. This would typically be the case for low level services like
+the ConfigFactory or the ObjectCacheManager, which are used during extension
+registration. To address this issue, Setup.php resets the global service
+locator instance by calling MediaWikiServices::resetGlobalInstance() once
+configuration and extension registration is complete.
+
+Note that "unmanaged" legacy services services that manage their own singleton
+must not keep references to services managed by MediaWikiServices, to allow a
+clean reset. After the global MediaWikiServices instance got reset, any such
+references would be stale, and using a stale service will result in an error.
+
+Services should either have all dependencies injected and be themselves managed
+by MediaWikiServices, or they should use the Service Locator pattern, accessing
+service instances via the global MediaWikiServices instance state when needed.
+This ensures that no stale service references remain after a reset.
+
+
 == Configuration ==
 
 When the default MediaWikiServices instance is created, a Config object is
index bad230e..923a19b 100644 (file)
@@ -11,8 +11,7 @@ directory and make a symbolic link:
  mediawiki/extensions$ ln -s ../../extensions-trunk/FooBar
 
 Most extensions are available through Git:
-    https://gerrit.wikimedia.org/r/#/admin/projects/?filter=mediawiki%252Fextensions%252F
-    https://git.wikimedia.org/project/mediawiki
+    https://phabricator.wikimedia.org/diffusion/MEXT/
 
 
 Please note that under POSIX systems (Linux...), parent of a symbolic path
index 6449d37..add5876 100644 (file)
@@ -352,6 +352,9 @@ class AuthPluginUser {
                return false;
        }
 
+       /**
+        * @deprecated since 1.28, use SessionManager::invalidateSessionForUser() instead.
+        */
        public function resetAuthToken() {
                # Override this!
                return true;
index f749003..389b077 100644 (file)
@@ -138,9 +138,13 @@ class CategoryViewer extends ContextSource {
                }
 
                $lang = $this->getLanguage();
-               $langAttribs = [ 'lang' => $lang->getHtmlCode(), 'dir' => $lang->getDir() ];
+               $attribs = [
+                       'class' => 'mw-category-generated',
+                       'lang' => $lang->getHtmlCode(),
+                       'dir' => $lang->getDir()
+               ];
                # put a div around the headings which are in the user language
-               $r = Html::openElement( 'div', $langAttribs ) . $r . '</div>';
+               $r = Html::openElement( 'div', $attribs ) . $r . '</div>';
 
                return $r;
        }
index 2a30352..383f0ad 100644 (file)
@@ -75,7 +75,7 @@ $wgConfigRegistry = [
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.27.0-alpha';
+$wgVersion = '1.28.0-alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -980,6 +980,27 @@ $wgCustomConvertCommand = false;
  */
 $wgJpegTran = '/usr/bin/jpegtran';
 
+/**
+ * At default setting of 'yuv420', JPEG thumbnails will use 4:2:0 chroma
+ * subsampling to reduce file size, at the cost of possible color fringing
+ * at sharp edges.
+ *
+ * See https://en.wikipedia.org/wiki/Chroma_subsampling
+ *
+ * Supported values:
+ *   false - use scaling system's default (same as pre-1.27 behavior)
+ *   'yuv444' - luma and chroma at same resolution
+ *   'yuv422' - chroma at 1/2 resolution horizontally, full vertically
+ *   'yuv420' - chroma at 1/2 resolution in both dimensions
+ *
+ * This setting is currently supported only for the ImageMagick backend;
+ * others may default to 4:2:0 or 4:4:4 or maintaining the source file's
+ * sampling in the thumbnail.
+ *
+ * @since 1.27
+ */
+$wgJpegPixelFormat = 'yuv420';
+
 /**
  * Some tests and extensions use exiv2 to manipulate the Exif metadata in some
  * image formats.
@@ -2223,27 +2244,24 @@ $wgMainWANCache = false;
  *
  * The format is an associative array where the key is a cache identifier, and
  * the value is an associative array of parameters. The "cacheId" parameter is
- * a cache identifier from $wgObjectCaches. The "relayerConfig" parameter is an
- * array used to construct an EventRelayer object. The "pool" parameter is a
- * string that is used as a PubSub channel prefix. The "loggroup" parameter
- * controls where log events are sent.
+ * a cache identifier from $wgObjectCaches. The "channels" parameter is a map of
+ * actions ('purge') to PubSub channels defined in $wgEventRelayerConfig.
+ * The "loggroup" parameter controls where log events are sent.
  *
  * @since 1.26
  */
 $wgWANObjectCaches = [
        CACHE_NONE => [
-               'class'         => 'WANObjectCache',
-               'cacheId'       => CACHE_NONE,
-               'pool'          => 'mediawiki-main-none',
-               'relayerConfig' => [ 'class' => 'EventRelayerNull' ]
+               'class'    => 'WANObjectCache',
+               'cacheId'  => CACHE_NONE,
+               'channels' => []
        ]
        /* Example of a simple single data-center cache:
-       'memcached-php' => array(
-               'class'         => 'WANObjectCache',
-               'cacheId'       => 'memcached-php',
-               'pool'          => 'mediawiki-main-memcached',
-               'relayerConfig' => array( 'class' => 'EventRelayerNull' )
-       )
+       'memcached-php' => [
+               'class'    => 'WANObjectCache',
+               'cacheId'  => 'memcached-php',
+               'channels' => [ 'purge' => 'wancache-main-memcached-purge' ]
+       ]
        */
 ];
 
@@ -4474,9 +4492,9 @@ $wgPasswordConfig = [
        ],
        'pbkdf2' => [
                'class' => 'Pbkdf2Password',
-               'algo' => 'sha256',
-               'cost' => '10000',
-               'length' => '128',
+               'algo' => 'sha512',
+               'cost' => '30000',
+               'length' => '64',
        ],
 ];
 
@@ -7273,7 +7291,7 @@ $wgActionFilteredLogs = [
        ],
        'newusers' => [
                'create' => [ 'create', 'newusers' ],
-               'create2' => ['create2' ],
+               'create2' => [ 'create2' ],
                'autocreate' => [ 'autocreate' ],
                'byemail' => [ 'byemail' ],
        ],
@@ -7285,7 +7303,7 @@ $wgActionFilteredLogs = [
                'protect' => [ 'protect' ],
                'modify' => [ 'modify' ],
                'unprotect' => [ 'unprotect' ],
-               'move_prot' => ['move_prot'],
+               'move_prot' => [ 'move_prot' ],
        ],
        'rights' => [
                'rights' => [ 'rights' ],
@@ -7815,9 +7833,9 @@ $wgUpdateRowsPerQuery = 100;
 
 /**
  * Name of the external diff engine to use. Supported values:
- * * false: default PHP implementation, DairikiDiff
+ * * false: default PHP implementation
  * * 'wikidiff2': Wikimedia's fast difference engine implemented as a PHP/HHVM module
- * * 'wikidiff3': newer PHP-based difference engine
+ * * 'wikidiff' and 'wikidiff3' are treated as false for backwards compatibility
  * * any other string is treated as a path to external diff executable
  */
 $wgExternalDiffEngine = false;
@@ -7972,6 +7990,23 @@ $wgPagePropsHaveSortkey = true;
  */
 $wgHttpsPort = 443;
 
+/**
+ * Secret for session storage.
+ * This should be set in LocalSettings.php, otherwise wgSecretKey will
+ * be used.
+ * @since 1.27
+ */
+$wgSessionSecret = false;
+
+/**
+ * If for some reason you can't install the PHP OpenSSL or mcrypt extensions,
+ * you can set this to true to make MediaWiki work again at the cost of storing
+ * sensitive session data insecurely. But it would be much more secure to just
+ * install the OpenSSL extension.
+ * @since 1.27
+ */
+$wgSessionInsecureSecrets = false;
+
 /**
  * Secret for hmac-based key derivation function (fast,
  * cryptographically secure random numbers).
@@ -8060,7 +8095,7 @@ $wgPopularPasswordFile = __DIR__ . '/../serialized/commonpasswords.cdb';
 $wgMaxUserDBWriteDuration = false;
 
 /**
- * Mapping of event channels to EventRelayer configuration.
+ * Mapping of event channels (or channel categories) to EventRelayer configuration.
  *
  * By setting up a PubSub system (like Kafka) and enabling a corresponding EventRelayer class
  * that uses it, MediaWiki can broadcast events to all subscribers. Certain features like WAN
@@ -8068,7 +8103,13 @@ $wgMaxUserDBWriteDuration = false;
  * subscribe to the channel and take actions based on the events. For example, a local daemon
  * can run on each CDN cache node and perfom local purges based on the URL purge channel events.
  *
- * The 'default' channel is for all channels without an explicit entry here.
+ * Some extensions may want to use "channel categories" so that different channels can also share
+ * the same custom relayer instance (e.g. when it's likely to be overriden). They can use
+ * EventRelayerGroup::getRelayer() based on the category but call notify() on various different
+ * actual channels. One reason for this would be that some system have very different performance
+ * vs durability needs, so one system (e.g. Kafka) may not be suitable for all uses.
+ *
+ * The 'default' key is for all channels (or channel categories) without an explicit entry here.
  *
  * @since 1.27
  */
index 45535ce..6545c4a 100644 (file)
@@ -54,9 +54,9 @@ class DummyLinker {
        public function link(
                $target,
                $html = null,
-               $customAttribs = [ ],
-               $query = [ ],
-               $options = [ ]
+               $customAttribs = [],
+               $query = [],
+               $options = []
        ) {
                return Linker::link(
                        $target,
@@ -70,8 +70,8 @@ class DummyLinker {
        public function linkKnown(
                $target,
                $html = null,
-               $customAttribs = [ ],
-               $query = [ ],
+               $customAttribs = [],
+               $query = [],
                $options = [ 'known', 'noclasses' ]
        ) {
                return Linker::linkKnown(
@@ -123,8 +123,8 @@ class DummyLinker {
                Parser $parser,
                Title $title,
                $file,
-               $frameParams = [ ],
-               $handlerParams = [ ],
+               $frameParams = [],
+               $handlerParams = [],
                $time = false,
                $query = "",
                $widthOption = null
@@ -147,7 +147,7 @@ class DummyLinker {
                $label = '',
                $alt,
                $align = 'right',
-               $params = [ ],
+               $params = [],
                $framed = false,
                $manualthumb = ""
        ) {
@@ -166,8 +166,8 @@ class DummyLinker {
        public function makeThumbLink2(
                Title $title,
                $file,
-               $frameParams = [ ],
-               $handlerParams = [ ],
+               $frameParams = [],
+               $handlerParams = [],
                $time = false,
                $query = ""
        ) {
@@ -232,7 +232,7 @@ class DummyLinker {
                $text,
                $escape = true,
                $linktype = '',
-               $attribs = [ ],
+               $attribs = [],
                $title = null
        ) {
                return Linker::makeExternalLink(
@@ -329,7 +329,7 @@ class DummyLinker {
                Title $title,
                $text,
                $wikiId = null,
-               $options = [ ]
+               $options = []
        ) {
                return Linker::makeCommentLink(
                        $title,
@@ -471,7 +471,7 @@ class DummyLinker {
                return Linker::formatSize( $size );
        }
 
-       public function titleAttrib( $name, $options = null, array $msgParams = [ ] ) {
+       public function titleAttrib( $name, $options = null, array $msgParams = [] ) {
                return Linker::titleAttrib(
                        $name,
                        $options,
@@ -491,7 +491,7 @@ class DummyLinker {
                );
        }
 
-       public function revDeleteLink( $query = [ ], $restricted = false, $delete = true ) {
+       public function revDeleteLink( $query = [], $restricted = false, $delete = true ) {
                return Linker::revDeleteLink(
                        $query,
                        $restricted,
@@ -503,7 +503,7 @@ class DummyLinker {
                return Linker::revDeleteLinkDisabled( $delete );
        }
 
-       public function tooltipAndAccesskeyAttribs( $name, array $msgParams = [ ] ) {
+       public function tooltipAndAccesskeyAttribs( $name, array $msgParams = [] ) {
                return Linker::tooltipAndAccesskeyAttribs(
                        $name,
                        $msgParams
index 3522531..02093ff 100644 (file)
@@ -2838,7 +2838,7 @@ class EditPage {
                                                '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}' ]
                                );
                        } else {
-                               $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\">\n$1</div>",
+                               $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
                                        'anonpreviewwarning'
                                );
                        }
@@ -3596,7 +3596,7 @@ HTML
         */
        function getPreviewText() {
                global $wgOut, $wgUser, $wgRawHtml, $wgLang;
-               global $wgAllowUserCss, $wgAllowUserJs;
+               global $wgAllowUserCss, $wgAllowUserJs, $wgAjaxEditStash;
 
                $stats = $wgOut->getContext()->getStats();
 
@@ -3708,10 +3708,12 @@ HTML
 
                        # Try to stash the edit for the final submission step
                        # @todo: different date format preferences cause cache misses
-                       ApiStashEdit::stashEditFromPreview(
-                               $this->getArticle(), $content, $pstContent,
-                               $parserOutput, $parserOptions, $parserOptions, wfTimestampNow()
-                       );
+                       if ( $wgAjaxEditStash ) {
+                               ApiStashEdit::stashEditFromPreview(
+                                       $this->getArticle(), $content, $pstContent,
+                                       $parserOutput, $parserOptions, $parserOptions, wfTimestampNow()
+                               );
+                       }
 
                        $parserOutput->setEditSectionTokens( false ); // no section edit links
                        $previewHTML = $parserOutput->getText();
@@ -3777,7 +3779,7 @@ HTML
         * Shows a bulletin board style toolbar for common editing functions.
         * It can be disabled in the user preferences.
         *
-        * @param $title Title object for the page being edited (optional)
+        * @param Title $title Title object for the page being edited (optional)
         * @return string
         */
        static function getEditToolbar( $title = null ) {
index 9dfac79..9360693 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * Factory class for spawning EventRelayer objects using configuration
  *
@@ -12,25 +14,19 @@ class EventRelayerGroup {
        /** @var EventRelayer[] */
        protected $relayers = [];
 
-       /** @var EventRelayerGroup */
-       protected static $instance = null;
-
        /**
-        * @param Config $config
+        * @param array[] $config Channel configuration
         */
-       protected function __construct( Config $config ) {
-               $this->configByChannel = $config->get( 'EventRelayerConfig' );
+       public function __construct( array $config ) {
+               $this->configByChannel = $config;
        }
 
        /**
+        * @deprecated since 1.27 Use MediaWikiServices::getInstance()->getEventRelayerGroup()
         * @return EventRelayerGroup
         */
        public static function singleton() {
-               if ( !self::$instance ) {
-                       self::$instance = new self( RequestContext::getMain()->getConfig() );
-               }
-
-               return self::$instance;
+               return MediaWikiServices::getInstance()->getEventRelayerGroup();
        }
 
        /**
index 0544c00..618fa4c 100644 (file)
@@ -501,12 +501,26 @@ function wfAppendQuery( $url, $query ) {
                $query = wfArrayToCgi( $query );
        }
        if ( $query != '' ) {
+               // Remove the fragment, if there is one
+               $fragment = false;
+               $hashPos = strpos( $url, '#' );
+               if ( $hashPos !== false ) {
+                       $fragment = substr( $url, $hashPos );
+                       $url = substr( $url, 0, $hashPos );
+               }
+
+               // Add parameter
                if ( false === strpos( $url, '?' ) ) {
                        $url .= '?';
                } else {
                        $url .= '&';
                }
                $url .= $query;
+
+               // Put the fragment back
+               if ( $fragment !== false ) {
+                       $url .= $fragment;
+               }
        }
        return $url;
 }
@@ -3127,6 +3141,9 @@ function wfSplitWikiID( $wiki ) {
  * Note 2: use $this->getDB() in maintenance scripts that may be invoked by
  * updater to ensure that a proper database is being updated.
  *
+ * @todo Replace calls to wfGetDB with calls to LoadBalancer::getConnection()
+ *       on an injected instance of LoadBalancer.
+ *
  * @return DatabaseBase
  */
 function wfGetDB( $db, $groups = [], $wiki = false ) {
@@ -3136,20 +3153,30 @@ function wfGetDB( $db, $groups = [], $wiki = false ) {
 /**
  * Get a load balancer object.
  *
+ * @deprecated since 1.27, use MediaWikiServices::getDBLoadBalancer()
+ *              or MediaWikiServices::getDBLoadBalancerFactory() instead.
+ *
  * @param string|bool $wiki Wiki ID, or false for the current wiki
  * @return LoadBalancer
  */
 function wfGetLB( $wiki = false ) {
-       return wfGetLBFactory()->getMainLB( $wiki );
+       if ( $wiki === false ) {
+               return \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancer();
+       } else {
+               $factory = \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               return $factory->getMainLB( $wiki );
+       }
 }
 
 /**
  * Get the load balancer factory object
  *
+ * @deprecated since 1.27, use MediaWikiServices::getDBLoadBalancerFactory() instead.
+ *
  * @return LBFactory
  */
 function wfGetLBFactory() {
-       return LBFactory::singleton();
+       return \MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
 }
 
 /**
index ccf948a..6a869dd 100644 (file)
@@ -40,6 +40,7 @@ class Linker {
        /**
         * Get the appropriate HTML attributes to add to the "a" element of an interwiki link.
         *
+        * @since 1.16.3
         * @deprecated since 1.25
         *
         * @param string $title The title text for the link, URL-encoded (???) but
@@ -66,6 +67,7 @@ class Linker {
        /**
         * Get the appropriate HTML attributes to add to the "a" element of an internal link.
         *
+        * @since 1.16.3
         * @deprecated since 1.25
         *
         * @param string $title The title text for the link, URL-encoded (???) but
@@ -86,6 +88,7 @@ class Linker {
         * Get the appropriate HTML attributes to add to the "a" element of an internal
         * link, given the Title object for the page we want to link to.
         *
+        * @since 1.16.3
         * @deprecated since 1.25
         *
         * @param Title $nt
@@ -107,6 +110,7 @@ class Linker {
        /**
         * Common code for getLinkAttributesX functions
         *
+        * @since 1.16.3
         * @deprecated since 1.25
         *
         * @param string $title
@@ -132,6 +136,7 @@ class Linker {
        /**
         * Return the CSS colour of a known link
         *
+        * @since 1.16.3
         * @param Title $t
         * @param int $threshold User defined threshold
         * @return string CSS class
@@ -258,6 +263,7 @@ class Linker {
 
        /**
         * Identical to link(), except $options defaults to 'known'.
+        * @since 1.16.3
         * @see Linker::link
         * @return string
         */
@@ -398,6 +404,7 @@ class Linker {
         * same as the other make*LinkObj static functions, despite $query not
         * being used.
         *
+        * @since 1.16.3
         * @param Title $nt
         * @param string $html [optional]
         * @param string $query [optional]
@@ -446,19 +453,20 @@ class Linker {
        }
 
        /**
-        * @param Title $title
-        * @return Title
+        * @since 1.16.3
+        * @param LinkTarget $target
+        * @return LinkTarget|Title You will get back the same type you passed in, or a Title object
         */
-       static function normaliseSpecialPage( Title $title ) {
-               if ( $title->isSpecialPage() ) {
-                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+       public static function normaliseSpecialPage( LinkTarget $target ) {
+               if ( $target->getNamespace() == NS_SPECIAL ) {
+                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $target->getDBkey() );
                        if ( !$name ) {
-                               return $title;
+                               return $target;
                        }
-                       $ret = SpecialPage::getTitleFor( $name, $subpage, $title->getFragment() );
+                       $ret = SpecialPage::getTitleFor( $name, $subpage, $target->getFragment() );
                        return $ret;
                } else {
-                       return $title;
+                       return $target;
                }
        }
 
@@ -484,6 +492,7 @@ class Linker {
         * Return the code for images which were added via external links,
         * via Parser::maybeMakeExternalImage().
         *
+        * @since 1.16.3
         * @param string $url
         * @param string $alt
         *
@@ -901,6 +910,7 @@ class Linker {
        /**
         * Make a "broken" link to an image
         *
+        * @since 1.16.3
         * @param Title $title
         * @param string $label Link label (plain text)
         * @param string $query Query string
@@ -946,6 +956,7 @@ class Linker {
        /**
         * Get the URL to upload a certain file
         *
+        * @since 1.16.3
         * @param Title $destFile Title object of the file to upload
         * @param string $query Urlencoded query string to prepend
         * @return string Urlencoded URL
@@ -970,6 +981,7 @@ class Linker {
        /**
         * Create a direct link to a given uploaded file.
         *
+        * @since 1.16.3
         * @param Title $title
         * @param string $html Pre-sanitized HTML
         * @param string $time MW timestamp of file creation time
@@ -984,6 +996,7 @@ class Linker {
         * Create a direct link to a given uploaded file.
         * This will make a broken link if $file is false.
         *
+        * @since 1.16.3
         * @param Title $title
         * @param File|bool $file File object or false
         * @param string $html Pre-sanitized HTML
@@ -1027,6 +1040,7 @@ class Linker {
         * a message key from the link text.
         * Usage example: Linker::specialLink( 'Recentchanges' )
         *
+        * @since 1.16.3
         * @param string $name
         * @param string $key
         * @return string
@@ -1041,6 +1055,7 @@ class Linker {
 
        /**
         * Make an external link
+        * @since 1.16.3. $title added in 1.21
         * @param string $url URL to link to
         * @param string $text Text of link
         * @param bool $escape Do we escape the link text?
@@ -1088,7 +1103,7 @@ class Linker {
         * @param string $userName User name in database.
         * @param string $altUserName Text to display instead of the user name (optional)
         * @return string HTML fragment
-        * @since 1.19 Method exists for a long time. $altUserName was added in 1.19.
+        * @since 1.16.3. $altUserName was added in 1.19.
         */
        public static function userLink( $userId, $userName, $altUserName = false ) {
                $classes = 'mw-userlink';
@@ -1112,6 +1127,7 @@ class Linker {
        /**
         * Generate standard user tool links (talk, contributions, block link, etc.)
         *
+        * @since 1.16.3
         * @param int $userId User identifier
         * @param string $userText User name or IP address
         * @param bool $redContribsWhenNoEdits Should the contributions link be
@@ -1171,6 +1187,7 @@ class Linker {
 
        /**
         * Alias for userToolLinks( $userId, $userText, true );
+        * @since 1.16.3
         * @param int $userId User identifier
         * @param string $userText User name or IP address
         * @param int $edits User edit count (optional, for performance)
@@ -1181,6 +1198,7 @@ class Linker {
        }
 
        /**
+        * @since 1.16.3
         * @param int $userId User id in database.
         * @param string $userText User name in database.
         * @return string HTML fragment with user talk link
@@ -1192,6 +1210,7 @@ class Linker {
        }
 
        /**
+        * @since 1.16.3
         * @param int $userId Userid
         * @param string $userText User name in database.
         * @return string HTML fragment with block link
@@ -1215,6 +1234,7 @@ class Linker {
 
        /**
         * Generate a user link if the current user is allowed to view it
+        * @since 1.16.3
         * @param Revision $rev
         * @param bool $isPublic Show only if all users can see it
         * @return string HTML fragment
@@ -1236,6 +1256,7 @@ class Linker {
 
        /**
         * Generate a user tool link cluster if the current user is allowed to view it
+        * @since 1.16.3
         * @param Revision $rev
         * @param bool $isPublic Show only if all users can see it
         * @return string HTML
@@ -1264,6 +1285,7 @@ class Linker {
         * auto-generated comments (from section editing) and formats [[wikilinks]].
         *
         * @author Erik Moeller <moeller@scireview.de>
+        * @since 1.16.3. $wikiId added in 1.26
         *
         * Note: there's not always a title to pass to this function.
         * Since you can't set a default parameter for a reference, I've turned it
@@ -1389,7 +1411,9 @@ class Linker {
         * Formats wiki links and media links in text; all other wiki formatting
         * is ignored
         *
+        * @since 1.16.3. $wikiId added in 1.26
         * @todo FIXME: Doesn't handle sub-links as in image thumb texts like the main parser
+        *
         * @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
@@ -1612,6 +1636,7 @@ class Linker {
         * Wrap a comment in standard punctuation and formatting if
         * it's non-empty, otherwise return empty string.
         *
+        * @since 1.16.3. $wikiId added in 1.26
         * @param string $comment
         * @param Title|null $title Title object (to generate link to section in autocomment) or null
         * @param bool $local Whether section links should refer to local page
@@ -1639,6 +1664,7 @@ class Linker {
         * Wrap and format the given revision's comment block, if the current
         * user is allowed to view it.
         *
+        * @since 1.16.3
         * @param Revision $rev
         * @param bool $local Whether section links should refer to local page
         * @param bool $isPublic Show only if all users can see it
@@ -1663,6 +1689,7 @@ class Linker {
        }
 
        /**
+        * @since 1.16.3
         * @param int $size
         * @return string
         */
@@ -1679,6 +1706,7 @@ class Linker {
        /**
         * Add another level to the Table of Contents
         *
+        * @since 1.16.3
         * @return string
         */
        public static function tocIndent() {
@@ -1688,6 +1716,7 @@ class Linker {
        /**
         * Finish one or more sublevels on the Table of Contents
         *
+        * @since 1.16.3
         * @param int $level
         * @return string
         */
@@ -1698,6 +1727,7 @@ class Linker {
        /**
         * parameter level defines if we are on an indentation level
         *
+        * @since 1.16.3
         * @param string $anchor
         * @param string $tocline
         * @param string $tocnumber
@@ -1720,6 +1750,7 @@ class Linker {
         * End a Table Of Contents line.
         * tocUnindent() will be used instead if we're ending a line below
         * the new level.
+        * @since 1.16.3
         * @return string
         */
        public static function tocLineEnd() {
@@ -1729,6 +1760,7 @@ class Linker {
        /**
         * Wraps the TOC in a table and provides the hide/collapse javascript.
         *
+        * @since 1.16.3
         * @param string $toc Html of the Table Of Contents
         * @param string|Language|bool $lang Language for the toc title, defaults to user language
         * @return string Full html of the TOC
@@ -1746,6 +1778,7 @@ class Linker {
        /**
         * Generate a table of contents from a section tree.
         *
+        * @since 1.16.3. $lang added in 1.17
         * @param array $tree Return value of ParserOutput::getSections()
         * @param string|Language|bool $lang Language for the toc title, defaults to user language
         * @return string HTML fragment
@@ -1775,6 +1808,7 @@ class Linker {
        /**
         * Create a headline for content
         *
+        * @since 1.16.3
         * @param int $level The level of the headline (1-6)
         * @param string $attribs Any attributes for the headline, starting with
         *   a space and ending with '>'
@@ -1840,6 +1874,8 @@ class Linker {
         *
         * If the option noBrackets is set the rollback link wont be enclosed in []
         *
+        * @since 1.16.3. $context added in 1.20. $options added in 1.21
+        *
         * @param Revision $rev
         * @param IContextSource $context Context to use or null for the main context.
         * @param array $options
@@ -1938,6 +1974,7 @@ class Linker {
        /**
         * Build a raw rollback link, useful for collections of "tool" links
         *
+        * @since 1.16.3. $context added in 1.20. $editCount added in 1.21
         * @param Revision $rev
         * @param IContextSource|null $context Context to use or null for the main context.
         * @param int $editCount Number of edits that would be reverted
@@ -2021,6 +2058,7 @@ class Linker {
         * directly paste it in as the link (escaping needs to be done manually).
         * Finally, if $more is a Message, call toString().
         *
+        * @since 1.16.3. $more added in 1.21
         * @param Title[] $templates Array of templates
         * @param bool $preview Whether this is for a preview
         * @param bool $section Whether this is for a section edit
@@ -2116,6 +2154,7 @@ class Linker {
        /**
         * Returns HTML for the "hidden categories on this page" list.
         *
+        * @since 1.16.3
         * @param array $hiddencats Array of hidden categories from Article::getHiddenCategories
         *   or similar
         * @return string HTML output
@@ -2144,6 +2183,7 @@ class Linker {
         * Format a size in bytes for output, using an appropriate
         * unit (B, KB, MB or GB) according to the magnitude in question
         *
+        * @since 1.16.3
         * @param int $size Size to format
         * @return string
         */
@@ -2158,6 +2198,7 @@ class Linker {
         * isn't always, because sometimes the accesskey needs to go on a different
         * element than the id, for reverse-compatibility, etc.)
         *
+        * @since 1.16.3 $msgParams added in 1.27
         * @param string $name Id of the element, minus prefixes.
         * @param string|null $options Null or the string 'withaccess' to add an access-
         *   key hint
@@ -2204,6 +2245,7 @@ class Linker {
         * the id but isn't always, because sometimes the accesskey needs to go on
         * a different element than the id, for reverse-compatibility, etc.)
         *
+        * @since 1.16.3
         * @param string $name Id of the element, minus prefixes.
         * @return string Contents of the accesskey attribute (which you must HTML-
         *   escape), or false for no accesskey attribute
@@ -2301,6 +2343,7 @@ class Linker {
        /**
         * Creates a dead (show/hide) link for deleting revisions/log entries
         *
+        * @since 1.16.3
         * @param bool $delete Set to true to use (show/hide) rather than (show)
         *
         * @return string HTML text wrapped in a span to allow for customization
@@ -2318,6 +2361,7 @@ class Linker {
        /**
         * Returns the attributes for the tooltip and access key.
         *
+        * @since 1.16.3. $msgParams introduced in 1.27
         * @param string $name
         * @param array $msgParams Params for constructing the message
         *
@@ -2342,6 +2386,7 @@ class Linker {
 
        /**
         * Returns raw bits of HTML, use titleAttrib()
+        * @since 1.16.3
         * @param string $name
         * @param array|null $options
         * @return null|string
index 3dd7420..ff469e4 100644 (file)
@@ -487,6 +487,7 @@ class MediaWiki {
                        $trxProfiler = Profiler::instance()->getTransactionProfiler();
                        if ( $request->wasPosted() && !$action->doesWrites() ) {
                                $trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
+                               $request->markAsSafeRequest();
                        }
 
                        # Let CDN cache things if we can purge them.
index 3f4d8ed..5bb5597 100644 (file)
@@ -1,16 +1,27 @@
 <?php
 namespace MediaWiki;
 
+use Config;
 use ConfigFactory;
+use EventRelayerGroup;
+use GenderCache;
 use GlobalVarConfig;
-use Config;
 use Hooks;
 use LBFactory;
 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 use LoadBalancer;
 use MediaWiki\Services\ServiceContainer;
+use MWException;
+use ResourceLoader;
+use SearchEngine;
+use SearchEngineConfig;
+use SearchEngineFactory;
 use SiteLookup;
 use SiteStore;
+use WatchedItemStore;
+use SkinFactory;
+use TitleFormatter;
+use TitleParser;
 
 /**
  * Service locator for MediaWiki core services.
@@ -50,9 +61,16 @@ use SiteStore;
  */
 class MediaWikiServices extends ServiceContainer {
 
+       /**
+        * @var MediaWikiServices|null
+        */
+       private static $instance = null;
+
        /**
         * Returns the global default instance of the top level service locator.
         *
+        * @since 1.27
+        *
         * The default instance is initialized using the service instantiator functions
         * defined in ServiceWiring.php.
         *
@@ -63,27 +81,237 @@ class MediaWikiServices extends ServiceContainer {
         * @return MediaWikiServices
         */
        public static function getInstance() {
-               static $instance = null;
-
-               if ( $instance === null ) {
+               if ( self::$instance === null ) {
                        // NOTE: constructing GlobalVarConfig here is not particularly pretty,
                        // but some information from the global scope has to be injected here,
                        // even if it's just a file name or database credentials to load
                        // configuration from.
-                       $config = new GlobalVarConfig();
-                       $instance = new self( $config );
+                       $bootstrapConfig = new GlobalVarConfig();
+                       self::$instance = self::newInstance( $bootstrapConfig );
+               }
+
+               return self::$instance;
+       }
+
+       /**
+        * Replaces the global MediaWikiServices instance.
+        *
+        * @since 1.28
+        *
+        * @note This is for use in PHPUnit tests only!
+        *
+        * @throws MWException if called outside of PHPUnit tests.
+        *
+        * @param MediaWikiServices $services The new MediaWikiServices object.
+        *
+        * @return MediaWikiServices The old MediaWikiServices object, so it can be restored later.
+        */
+       public static function forceGlobalInstance( MediaWikiServices $services ) {
+               if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
+                       throw new MWException( __METHOD__ . ' must not be used outside unit tests.' );
+               }
+
+               $old = self::getInstance();
+               self::$instance = $services;
+
+               return $old;
+       }
+
+       /**
+        * Creates a new instance of MediaWikiServices and sets it as the global default
+        * instance. getInstance() will return a different MediaWikiServices object
+        * after every call to resetGlobalServiceLocator().
+        *
+        * @since 1.28
+        *
+        * @warning This should not be used during normal operation. It is intended for use
+        * when the configuration has changed significantly since bootstrap time, e.g.
+        * during the installation process or during testing.
+        *
+        * @warning Calling resetGlobalServiceLocator() may leave the application in an inconsistent
+        * state. Calling this is only safe under the ASSUMPTION that NO REFERENCE to
+        * any of the services managed by MediaWikiServices exist. If any service objects
+        * managed by the old MediaWikiServices instance remain in use, they may INTERFERE
+        * with the operation of the services managed by the new MediaWikiServices.
+        * Operating with a mix of services created by the old and the new
+        * MediaWikiServices instance may lead to INCONSISTENCIES and even DATA LOSS!
+        * Any class implementing LAZY LOADING is especially prone to this problem,
+        * since instances would typically retain a reference to a storage layer service.
+        *
+        * @see forceGlobalInstance()
+        * @see resetGlobalInstance()
+        * @see resetBetweenTest()
+        *
+        * @param Config|null $bootstrapConfig The Config object to be registered as the
+        *        'BootstrapConfig' service. This has to contain at least the information
+        *        needed to set up the 'ConfigFactory' service. If not given, the bootstrap
+        *        config of the old instance of MediaWikiServices will be re-used. If there
+        *        was no previous instance, a new GlobalVarConfig object will be used to
+        *        bootstrap the services.
+        *
+        * @throws MWException If called after MW_SERVICE_BOOTSTRAP_COMPLETE has been defined in
+        *         Setup.php (unless MW_PHPUNIT_TEST or MEDIAWIKI_INSTALL or RUN_MAINTENANCE_IF_MAIN
+        *          is defined).
+        */
+       public static function resetGlobalInstance( Config $bootstrapConfig = null ) {
+               if ( self::$instance === null ) {
+                       // no global instance yet, nothing to reset
+                       return;
+               }
 
-                       // Load the default wiring from the specified files.
-                       $wiringFiles = $config->get( 'ServiceWiringFiles' );
-                       $instance->loadWiringFiles( $wiringFiles );
+               self::failIfResetNotAllowed( __METHOD__ );
 
-                       // Provide a traditional hook point to allow extensions to configure services.
-                       Hooks::run( 'MediaWikiServices', [ $instance ] );
+               if ( $bootstrapConfig === null ) {
+                       $bootstrapConfig = self::$instance->getBootstrapConfig();
                }
 
+               self::$instance->destroy();
+
+               self::$instance = self::newInstance( $bootstrapConfig );
+       }
+
+       /**
+        * Creates a new MediaWikiServices instance and initializes it according to the
+        * given $bootstrapConfig. In particular, all wiring files defined in the
+        * ServiceWiringFiles setting are loaded, and the MediaWikiServices hook is called.
+        *
+        * @param Config|null $bootstrapConfig The Config object to be registered as the
+        *        'BootstrapConfig' service. This has to contain at least the information
+        *        needed to set up the 'ConfigFactory' service. If not provided, any call
+        *        to getBootstrapConfig(), getConfigFactory, or getMainConfig will fail.
+        *        A MediaWikiServices instance without access to configuration is called
+        *        "primordial".
+        *
+        * @return MediaWikiServices
+        * @throws MWException
+        */
+       private static function newInstance( Config $bootstrapConfig ) {
+               $instance = new self( $bootstrapConfig );
+
+               // Load the default wiring from the specified files.
+               $wiringFiles = $bootstrapConfig->get( 'ServiceWiringFiles' );
+               $instance->loadWiringFiles( $wiringFiles );
+
+               // Provide a traditional hook point to allow extensions to configure services.
+               Hooks::run( 'MediaWikiServices', [ $instance ] );
+
                return $instance;
        }
 
+       /**
+        * Disables all storage layer services. After calling this, any attempt to access the
+        * storage layer will result in an error. Use resetGlobalInstance() to restore normal
+        * operation.
+        *
+        * @since 1.28
+        *
+        * @warning This is intended for extreme situations only and should never be used
+        * while serving normal web requests. Legitimate use cases for this method include
+        * the installation process. Test fixtures may also use this, if the fixture relies
+        * on globalState.
+        *
+        * @see resetGlobalInstance()
+        * @see resetChildProcessServices()
+        */
+       public static function disableStorageBackend() {
+               // TODO: also disable some Caches, JobQueues, etc
+               $destroy = [ 'DBLoadBalancer', 'DBLoadBalancerFactory' ];
+               $services = self::getInstance();
+
+               foreach ( $destroy as $name ) {
+                       $services->disableService( $name );
+               }
+       }
+
+       /**
+        * Resets any services that may have become stale after a child process
+        * returns from after pcntl_fork(). It's also safe, but generally unnecessary,
+        * to call this method from the parent process.
+        *
+        * @since 1.28
+        *
+        * @note This is intended for use in the context of process forking only!
+        *
+        * @see resetGlobalInstance()
+        * @see disableStorageBackend()
+        */
+       public static function resetChildProcessServices() {
+               // NOTE: for now, just reset everything. Since we don't know the interdependencies
+               // between services, we can't do this more selectively at this time.
+               self::resetGlobalInstance();
+
+               // Child, reseed because there is no bug in PHP:
+               // http://bugs.php.net/bug.php?id=42465
+               mt_srand( getmypid() );
+       }
+
+       /**
+        * Resets the given service for testing purposes.
+        *
+        * @since 1.28
+        *
+        * @warning This is generally unsafe! Other services may still retain references
+        * to the stale service instance, leading to failures and inconsistencies. Subclasses
+        * may use this method to reset specific services under specific instances, but
+        * it should not be exposed to application logic.
+        *
+        * @note With proper dependency injection used throughout the codebase, this method
+        * should not be needed. It is provided to allow tests that pollute global service
+        * instances to clean up.
+        *
+        * @param string $name
+        * @param string $destroy Whether the service instance should be destroyed if it exists.
+        *        When set to false, any existing service instance will effectively be detached
+        *        from the container.
+        *
+        * @throws MWException if called outside of PHPUnit tests.
+        */
+       public function resetServiceForTesting( $name, $destroy = true ) {
+               if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
+                       throw new MWException( 'resetServiceForTesting() must not be used outside unit tests.' );
+               }
+
+               $this->resetService( $name, $destroy );
+       }
+
+       /**
+        * Convenience method that throws an exception unless it is called during a phase in which
+        * resetting of global services is allowed. In general, services should not be reset
+        * individually, since that may introduce inconsistencies.
+        *
+        * @since 1.28
+        *
+        * This method will throw an exception if:
+        *
+        * - self::$resetInProgress is false (to allow all services to be reset together
+        *   via resetGlobalInstance)
+        * - and MEDIAWIKI_INSTALL is not defined (to allow services to be reset during installation)
+        * - and MW_PHPUNIT_TEST is not defined (to allow services to be reset during testing)
+        *
+        * This method is intended to be used to safeguard against accidentally resetting
+        * global service instances that are not yet managed by MediaWikiServices. It is
+        * defined here in the MediaWikiServices services class to have a central place
+        * for managing service bootstrapping and resetting.
+        *
+        * @param string $method the name of the caller method, as given by __METHOD__.
+        *
+        * @throws MWException if called outside bootstrap mode.
+        *
+        * @see resetGlobalInstance()
+        * @see forceGlobalInstance()
+        * @see disableStorageBackend()
+        */
+       public static function failIfResetNotAllowed( $method ) {
+               if ( !defined( 'MW_PHPUNIT_TEST' )
+                       && !defined( 'MW_PARSER_TEST' )
+                       && !defined( 'MEDIAWIKI_INSTALL' )
+                       && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
+                       && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
+               ) {
+                       throw new MWException( $method . ' may only be called during bootstrapping and unit tests!' );
+               }
+       }
+
        /**
         * @param Config $config The Config object to be registered as the 'BootstrapConfig' service.
         *        This has to contain at least the information needed to set up the 'ConfigFactory'
@@ -92,12 +320,14 @@ class MediaWikiServices extends ServiceContainer {
        public function __construct( Config $config ) {
                parent::__construct();
 
-               // register the given Config object as the bootstrap config service.
+               // Register the given Config object as the bootstrap config service.
                $this->defineService( 'BootstrapConfig', function() use ( $config ) {
                        return $config;
                } );
        }
 
+       // CONVENIENCE GETTERS ////////////////////////////////////////////////////
+
        /**
         * Returns the Config object containing the bootstrap configuration.
         * Bootstrap configuration would typically include database credentials
@@ -108,6 +338,7 @@ class MediaWikiServices extends ServiceContainer {
         * when creating the MainConfig service. Application logic should
         * use getMainConfig() to get a Config instances.
         *
+        * @since 1.27
         * @return Config
         */
        public function getBootstrapConfig() {
@@ -115,6 +346,7 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
+        * @since 1.27
         * @return ConfigFactory
         */
        public function getConfigFactory() {
@@ -125,6 +357,7 @@ class MediaWikiServices extends ServiceContainer {
         * Returns the Config object that provides configuration for MediaWiki core.
         * This may or may not be the same object that is returned by getBootstrapConfig().
         *
+        * @since 1.27
         * @return Config
         */
        public function getMainConfig() {
@@ -132,6 +365,7 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
+        * @since 1.27
         * @return SiteLookup
         */
        public function getSiteLookup() {
@@ -139,6 +373,7 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
+        * @since 1.27
         * @return SiteStore
         */
        public function getSiteStore() {
@@ -146,12 +381,101 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
+        * @since 1.27
         * @return StatsdDataFactory
         */
        public function getStatsdDataFactory() {
                return $this->getService( 'StatsdDataFactory' );
        }
 
+       /**
+        * @since 1.27
+        * @return EventRelayerGroup
+        */
+       public function getEventRelayerGroup() {
+               return $this->getService( 'EventRelayerGroup' );
+       }
+
+       /**
+        * @since 1.27
+        * @return SearchEngine
+        */
+       public function newSearchEngine() {
+               // New engine object every time, since they keep state
+               return $this->getService( 'SearchEngineFactory' )->create();
+       }
+
+       /**
+        * @since 1.27
+        * @return SearchEngineFactory
+        */
+       public function getSearchEngineFactory() {
+               return $this->getService( 'SearchEngineFactory' );
+       }
+
+       /**
+        * @since 1.27
+        * @return SearchEngineConfig
+        */
+       public function getSearchEngineConfig() {
+               return $this->getService( 'SearchEngineConfig' );
+       }
+
+       /**
+        * @since 1.27
+        * @return SkinFactory
+        */
+       public function getSkinFactory() {
+               return $this->getService( 'SkinFactory' );
+       }
+
+       /**
+        * @since 1.28
+        * @return LBFactory
+        */
+       public function getDBLoadBalancerFactory() {
+               return $this->getService( 'DBLoadBalancerFactory' );
+       }
+
+       /**
+        * @since 1.28
+        * @return LoadBalancer The main DB load balancer for the local wiki.
+        */
+       public function getDBLoadBalancer() {
+               return $this->getService( 'DBLoadBalancer' );
+       }
+
+       /**
+        * @since 1.28
+        * @return WatchedItemStore
+        */
+       public function getWatchedItemStore() {
+               return $this->getService( 'WatchedItemStore' );
+       }
+
+       /**
+        * @since 1.28
+        * @return GenderCache
+        */
+       public function getGenderCache() {
+               return $this->getService( 'GenderCache' );
+       }
+       /**
+        * @since 1.28
+        * @return TitleFormatter
+        */
+       public function getTitleFormatter() {
+               return $this->getService( 'TitleFormatter' );
+       }
+
+       /**
+        * @since 1.28
+        * @return TitleParser
+        */
+       public function getTitleParser() {
+               return $this->getService( 'TitleParser' );
+       }
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service getter here, don't forget to add a test
        // case for it in MediaWikiServicesTest::provideGetters() and in
index fd016fc..c7752aa 100644 (file)
@@ -382,6 +382,32 @@ class Message implements MessageSpecifier, Serializable {
                return new self( $key, $params );
        }
 
+       /**
+        * Transform a MessageSpecifier or a primitive value used interchangeably with
+        * specifiers (a message key string, or a key + params array) into a proper Message
+        * @param string|array|MessageSpecifier $value
+        * @return Message
+        * @throws InvalidArgumentException
+        * @since 1.27
+        */
+       public static function newFromSpecifier( $value ) {
+               if ( $value instanceof RawMessage ) {
+                       $message = new RawMessage( $value->getKey(), $value->getParams() );
+               } elseif ( $value instanceof MessageSpecifier ) {
+                       $message = new Message( $value );
+               } elseif ( is_array( $value ) ) {
+                       $key = array_shift( $value );
+                       $message = new Message( $key, $value );
+               } elseif ( is_string( $value ) ) {
+                       $message = new Message( $value );
+               } else {
+                       throw new InvalidArgumentException( __METHOD__ . ': invalid argument type '
+                               . gettype( $value ) );
+               }
+
+               return $message;
+       }
+
        /**
         * Factory function accepting multiple message keys and returning a message instance
         * for the first message which is non-empty. If all messages are empty then an
index b9af755..708dea1 100644 (file)
@@ -19,6 +19,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Handles the backend logic of moving a page from one title
  * to another.
@@ -369,7 +371,7 @@ class MovePage {
                $oldsnamespace = MWNamespace::getSubject( $this->oldTitle->getNamespace() );
                $newsnamespace = MWNamespace::getSubject( $this->newTitle->getNamespace() );
                if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
-                       $store = WatchedItemStore::getDefaultInstance();
+                       $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                        $store->duplicateAllAssociatedEntries( $this->oldTitle, $this->newTitle );
                }
 
index c724207..67e9a4f 100644 (file)
@@ -780,7 +780,7 @@ class OutputPage extends ContextSource {
                        // bug 44570: the core page itself may not change, but resources might
                        $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $config->get( 'SquidMaxage' ) );
                }
-               Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes ] );
+               Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
 
                $maxModified = max( $modifiedTimes );
                $this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
index 70192b9..451635e 100644 (file)
@@ -70,7 +70,9 @@ class ProtectionForm {
                // Check if the form should be disabled.
                // If it is, the form will be available in read-only to show levels.
                $this->mPermErrors = $this->mTitle->getUserPermissionsErrors(
-                       'protect', $this->mContext->getUser()
+                       'protect',
+                       $this->mContext->getUser(),
+                       $this->mContext->getRequest()->wasPosted() ? 'secure' : 'full' // T92357
                );
                if ( wfReadOnly() ) {
                        $this->mPermErrors[] = [ 'readonlytext', wfReadOnlyReason() ];
index 40daf3d..0e45b25 100644 (file)
@@ -1553,7 +1553,6 @@ class Revision implements IDBAccessObject {
                        }
                        $text = $cache->get( $key );
                        if ( is_string( $text ) ) {
-                               wfDebug( __METHOD__ . ": got id $textId from cache\n" );
                                $processCache->set( $key, $text );
                                return $text;
                        }
index 7e1d4e3..aa99a71 100644 (file)
 use MediaWiki\MediaWikiServices;
 
 return [
+       'DBLoadBalancerFactory' => function( MediaWikiServices $services ) {
+               $config = $services->getMainConfig()->get( 'LBFactoryConf' );
+
+               $class = LBFactory::getLBFactoryClass( $config );
+               if ( !isset( $config['readOnlyReason'] ) ) {
+                       // TODO: replace the global wfConfiguredReadOnlyReason() with a service.
+                       $config['readOnlyReason'] = wfConfiguredReadOnlyReason();
+               }
+
+               return new $class( $config );
+       },
+
+       'DBLoadBalancer' => function( MediaWikiServices $services ) {
+               // just return the default LB from the DBLoadBalancerFactory service
+               return $services->getDBLoadBalancerFactory()->getMainLB();
+       },
+
        'SiteStore' => function( MediaWikiServices $services ) {
-               $loadBalancer = wfGetLB(); // TODO: use LB from MediaWikiServices
-               $rawSiteStore = new DBSiteStore( $loadBalancer );
+               $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
 
                // TODO: replace wfGetCache with a CacheFactory service.
                // TODO: replace wfIsHHVM with a capabilities service.
@@ -78,6 +94,73 @@ return [
                );
        },
 
+       'EventRelayerGroup' => function( MediaWikiServices $services ) {
+               return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) );
+       },
+
+       'SearchEngineFactory' => function( MediaWikiServices $services ) {
+               return new SearchEngineFactory( $services->getSearchEngineConfig() );
+       },
+
+       'SearchEngineConfig' => function( MediaWikiServices $services ) {
+               global $wgContLang;
+               return new SearchEngineConfig( $services->getMainConfig(), $wgContLang );
+       },
+
+       'SkinFactory' => function( MediaWikiServices $services ) {
+               $factory = new SkinFactory();
+
+               $names = $services->getMainConfig()->get( 'ValidSkinNames' );
+
+               foreach ( $names as $name => $skin ) {
+                       $factory->register( $name, $skin, function () use ( $name, $skin ) {
+                               $class = "Skin$skin";
+                               return new $class( $name );
+                       } );
+               }
+               // Register a hidden "fallback" skin
+               $factory->register( 'fallback', 'Fallback', function () {
+                       return new SkinFallback;
+               } );
+               // Register a hidden skin for api output
+               $factory->register( 'apioutput', 'ApiOutput', function () {
+                       return new SkinApi;
+               } );
+
+               return $factory;
+       },
+
+       'WatchedItemStore' => function( MediaWikiServices $services ) {
+               $store = new WatchedItemStore(
+                       $services->getDBLoadBalancer(),
+                       new HashBagOStuff( [ 'maxKeys' => 100 ] )
+               );
+               $store->setStatsdDataFactory( $services->getStatsdDataFactory() );
+               return $store;
+       },
+
+       'GenderCache' => function( MediaWikiServices $services ) {
+               return new GenderCache();
+       },
+
+       '_MediaWikiTitleCodec' => function( MediaWikiServices $services ) {
+               global $wgContLang;
+
+               return new MediaWikiTitleCodec(
+                       $wgContLang,
+                       $services->getGenderCache(),
+                       $services->getMainConfig()->get( 'LocalInterwikis' )
+               );
+       },
+
+       'TitleFormatter' => function( MediaWikiServices $services ) {
+               return $services->getService( '_MediaWikiTitleCodec' );
+       },
+
+       'TitleParser' => function( MediaWikiServices $services ) {
+               return $services->getService( '_MediaWikiTitleCodec' );
+       },
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service here, don't forget to add a getter function
        // in the MediaWikiServices class. The convenience getter should just call
diff --git a/includes/Services/CannotReplaceActiveServiceException.php b/includes/Services/CannotReplaceActiveServiceException.php
new file mode 100644 (file)
index 0000000..4993073
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+namespace MediaWiki\Services;
+
+use Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when trying to replace an already active 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * Exception thrown when trying to replace an already active service.
+ */
+class CannotReplaceActiveServiceException extends RuntimeException {
+
+       /**
+        * @param string $serviceName
+        * @param Exception|null $previous
+        */
+       public function __construct( $serviceName, Exception $previous = null ) {
+               parent::__construct( "Cannot replace an active service: $serviceName", 0, $previous );
+       }
+
+}
diff --git a/includes/Services/ContainerDisabledException.php b/includes/Services/ContainerDisabledException.php
new file mode 100644 (file)
index 0000000..ede076d
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+namespace MediaWiki\Services;
+
+use Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when trying to access a service on a disabled container or factory.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * Exception thrown when trying to access a service on a disabled container or factory.
+ */
+class ContainerDisabledException extends RuntimeException {
+
+       /**
+        * @param Exception|null $previous
+        */
+       public function __construct( Exception $previous = null ) {
+               parent::__construct( 'Container disabled!', 0, $previous );
+       }
+
+}
diff --git a/includes/Services/DestructibleService.php b/includes/Services/DestructibleService.php
new file mode 100644 (file)
index 0000000..6ce9af2
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+namespace MediaWiki\Services;
+
+/**
+ * Interface for destructible services.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * DestructibleService defines a standard interface for shutting down a service instance.
+ * The intended use is for a service container to be able to shut down services that should
+ * no longer be used, and allow such services to release any system resources.
+ *
+ * @note There is no expectation that services will be destroyed when the process (or web request)
+ * terminates.
+ */
+interface DestructibleService {
+
+       /**
+        * Notifies the service object that it should expect to no longer be used, and should release
+        * any system resources it may own. The behavior of all service methods becomes undefined after
+        * destroy() has been called. It is recommended that implementing classes should throw an
+        * exception when service methods are accessed after destroy() has been called.
+        */
+       public function destroy();
+
+}
diff --git a/includes/Services/NoSuchServiceException.php b/includes/Services/NoSuchServiceException.php
new file mode 100644 (file)
index 0000000..36e50d2
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+namespace MediaWiki\Services;
+
+use Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when the requested service is not known.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * Exception thrown when the requested service is not known.
+ */
+class NoSuchServiceException extends RuntimeException {
+
+       /**
+        * @param string $serviceName
+        * @param Exception|null $previous
+        */
+       public function __construct( $serviceName, Exception $previous = null ) {
+               parent::__construct( "No such service: $serviceName", 0, $previous );
+       }
+
+}
diff --git a/includes/Services/ServiceAlreadyDefinedException.php b/includes/Services/ServiceAlreadyDefinedException.php
new file mode 100644 (file)
index 0000000..c6344d3
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+namespace MediaWiki\Services;
+
+use Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when a service was already defined, but the
+ * caller expected it to not exist.
+ *
+ * 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * Exception thrown when a service was already defined, but the
+ * caller expected it to not exist.
+ */
+class ServiceAlreadyDefinedException extends RuntimeException {
+
+       /**
+        * @param string $serviceName
+        * @param Exception|null $previous
+        */
+       public function __construct( $serviceName, Exception $previous = null ) {
+               parent::__construct( "Service already defined: $serviceName", 0, $previous );
+       }
+
+}
index e3cda2e..66ee918 100644 (file)
@@ -43,7 +43,7 @@ use Wikimedia\Assert\Assert;
  * @see docs/injection.txt for an overview of using dependency injection in the
  *      MediaWiki code base.
  */
-class ServiceContainer {
+class ServiceContainer implements DestructibleService {
 
        /**
         * @var object[]
@@ -60,6 +60,11 @@ class ServiceContainer {
         */
        private $extraInstantiationParams;
 
+       /**
+        * @var boolean
+        */
+       private $destroyed = false;
+
        /**
         * @param array $extraInstantiationParams Any additional parameters to be passed to the
         * instantiator function when creating a service. This is typically used to provide
@@ -69,6 +74,25 @@ class ServiceContainer {
                $this->extraInstantiationParams = $extraInstantiationParams;
        }
 
+       /**
+        * Destroys all contained service instances that implement the DestructibleService
+        * interface. This will render all services obtained from this MediaWikiServices
+        * instance unusable. In particular, this will disable access to the storage backend
+        * via any of these services. Any future call to getService() will throw an exception.
+        *
+        * @see resetGlobalInstance()
+        */
+       public function destroy() {
+               foreach ( $this->getServiceNames() as $name ) {
+                       $service = $this->peekService( $name );
+                       if ( $service !== null && $service instanceof DestructibleService ) {
+                               $service->destroy();
+                       }
+               }
+
+               $this->destroyed = true;
+       }
+
        /**
         * @param array $wiringFiles A list of PHP files to load wiring information from.
         * Each file is loaded using PHP's include mechanism. Each file is expected to
@@ -114,6 +138,29 @@ class ServiceContainer {
                return isset( $this->serviceInstantiators[$name] );
        }
 
+       /**
+        * Returns the service instance for $name only if that service has already been instantiated.
+        * This is intended for situations where services get destroyed/cleaned up, so we can
+        * avoid creating a service just to destroy it again.
+        *
+        * @note This is intended for internal use and for test fixtures.
+        * Application logic should use getService() instead.
+        *
+        * @see getService().
+        *
+        * @param string $name
+        *
+        * @return object|null The service instance, or null if the service has not yet been instantiated.
+        * @throws RuntimeException if $name does not refer to a known service.
+        */
+       public function peekService( $name ) {
+               if ( !$this->hasService( $name ) ) {
+                       throw new NoSuchServiceException( $name );
+               }
+
+               return isset( $this->services[$name] ) ? $this->services[$name] : null;
+       }
+
        /**
         * @return string[]
         */
@@ -139,7 +186,7 @@ class ServiceContainer {
                Assert::parameterType( 'string', $name, '$name' );
 
                if ( $this->hasService( $name ) ) {
-                       throw new RuntimeException( 'Service already defined: ' . $name );
+                       throw new ServiceAlreadyDefinedException( $name );
                }
 
                $this->serviceInstantiators[$name] = $instantiator;
@@ -165,16 +212,78 @@ class ServiceContainer {
                Assert::parameterType( 'string', $name, '$name' );
 
                if ( !$this->hasService( $name ) ) {
-                       throw new RuntimeException( 'Service not defined: ' . $name );
+                       throw new NoSuchServiceException( $name );
                }
 
                if ( isset( $this->services[$name] ) ) {
-                       throw new RuntimeException( 'Cannot redefine a service that is already in use: ' . $name );
+                       throw new CannotReplaceActiveServiceException( $name );
                }
 
                $this->serviceInstantiators[$name] = $instantiator;
        }
 
+       /**
+        * Disables a service.
+        *
+        * @note Attempts to call getService() for a disabled service will result
+        * in a DisabledServiceException. Calling peekService for a disabled service will
+        * return null. Disabled services are listed by getServiceNames(). A disabled service
+        * can be enabled again using redefineService().
+        *
+        * @note If the service was already active (that is, instantiated) when getting disabled,
+        * and the service instance implements DestructibleService, destroy() is called on the
+        * service instance.
+        *
+        * @see redefineService()
+        * @see resetService()
+        *
+        * @param string $name The name of the service to disable.
+        *
+        * @throws RuntimeException if $name is not a known service.
+        */
+       public function disableService( $name ) {
+               $this->resetService( $name );
+
+               $this->redefineService( $name, function() use ( $name ) {
+                       throw new ServiceDisabledException( $name );
+               } );
+       }
+
+       /**
+        * Resets a service by dropping the service instance.
+        * If the service instances implements DestructibleService, destroy()
+        * is called on the service instance.
+        *
+        * @warning This is generally unsafe! Other services may still retain references
+        * to the stale service instance, leading to failures and inconsistencies. Subclasses
+        * may use this method to reset specific services under specific instances, but
+        * it should not be exposed to application logic.
+        *
+        * @note This is declared final so subclasses can not interfere with the expectations
+        * disableService() has when calling resetService().
+        *
+        * @see redefineService()
+        * @see disableService().
+        *
+        * @param string $name The name of the service to reset.
+        * @param bool $destroy Whether the service instance should be destroyed if it exists.
+        *        When set to false, any existing service instance will effectively be detached
+        *        from the container.
+        *
+        * @throws RuntimeException if $name is not a known service.
+        */
+       final protected function resetService( $name, $destroy = true ) {
+               Assert::parameterType( 'string', $name, '$name' );
+
+               $instance = $this->peekService( $name );
+
+               if ( $destroy && $instance instanceof DestructibleService )  {
+                       $instance->destroy();
+               }
+
+               unset( $this->services[$name] );
+       }
+
        /**
         * Returns a service object of the kind associated with $name.
         * Services instances are instantiated lazily, on demand.
@@ -189,10 +298,16 @@ class ServiceContainer {
         *
         * @param string $name The service name
         *
-        * @throws InvalidArgumentException if $name is not a known service.
+        * @throws NoSuchServiceException if $name is not a known service.
+        * @throws ServiceDisabledException if this container has already been destroyed.
+        *
         * @return object The service instance
         */
        public function getService( $name ) {
+               if ( $this->destroyed ) {
+                       throw new ContainerDisabledException();
+               }
+
                if ( !isset( $this->services[$name] ) ) {
                        $this->services[$name] = $this->createService( $name );
                }
@@ -213,7 +328,7 @@ class ServiceContainer {
                                array_merge( [ $this ], $this->extraInstantiationParams )
                        );
                } else {
-                       throw new InvalidArgumentException( 'Unknown service: ' . $name );
+                       throw new NoSuchServiceException( $name );
                }
 
                return $service;
diff --git a/includes/Services/ServiceDisabledException.php b/includes/Services/ServiceDisabledException.php
new file mode 100644 (file)
index 0000000..ae15b7c
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+namespace MediaWiki\Services;
+
+use Exception;
+use RuntimeException;
+
+/**
+ * Exception thrown when trying to access a disabled 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
+ *
+ * @since 1.27
+ */
+
+/**
+ * Exception thrown when trying to access a disabled service.
+ */
+class ServiceDisabledException extends RuntimeException {
+
+       /**
+        * @param string $serviceName
+        * @param Exception|null $previous
+        */
+       public function __construct( $serviceName, Exception $previous = null ) {
+               parent::__construct( "Service disabled: $serviceName", 0, $previous );
+       }
+
+}
index cddb436..9db997a 100644 (file)
@@ -23,6 +23,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * This file is not a valid entry point, perform no further processing unless
@@ -290,25 +291,6 @@ if ( $wgSkipSkin ) {
        $wgSkipSkins[] = $wgSkipSkin;
 }
 
-// Register skins
-// Use a closure to avoid leaking into global state
-call_user_func( function () use ( $wgValidSkinNames ) {
-       $factory = SkinFactory::getDefaultInstance();
-       foreach ( $wgValidSkinNames as $name => $skin ) {
-               $factory->register( $name, $skin, function () use ( $name, $skin ) {
-                       $class = "Skin$skin";
-                       return new $class( $name );
-               } );
-       }
-       // Register a hidden "fallback" skin
-       $factory->register( 'fallback', 'Fallback', function () {
-               return new SkinFallback;
-       } );
-       // Register a hidden skin for api output
-       $factory->register( 'apioutput', 'ApiOutput', function () {
-               return new SkinApi;
-       } );
-} );
 $wgSkipSkins[] = 'fallback';
 $wgSkipSkins[] = 'apioutput';
 
@@ -517,6 +499,14 @@ if ( !class_exists( 'AutoLoader' ) ) {
        require_once "$IP/includes/AutoLoader.php";
 }
 
+// Reset the global service locator, so any services that have already been created will be
+// re-created while taking into account any custom settings and extensions.
+MediaWikiServices::resetGlobalInstance( new GlobalVarConfig() );
+
+// Define a constant that indicates that the bootstrapping of the service locator
+// is complete.
+define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
+
 // Install a header callback to prevent caching of responses with cookies (T127993)
 if ( !$wgCommandLineMode ) {
        header_register_callback( function () {
@@ -618,10 +608,9 @@ if ( $wgMainWANCache === false ) {
        // Sites using multiple datacenters can configure a relayer.
        $wgMainWANCache = 'mediawiki-main-default';
        $wgWANObjectCaches[$wgMainWANCache] = [
-               'class'         => 'WANObjectCache',
-               'cacheId'       => $wgMainCacheType,
-               'pool'          => 'mediawiki-main-default',
-               'relayerConfig' => [ 'class' => 'EventRelayerNull' ]
+               'class'    => 'WANObjectCache',
+               'cacheId'  => $wgMainCacheType,
+               'channels' => [ 'purge' => 'wancache-main-default-purge' ]
        ];
 }
 
index 215378b..6c536dd 100644 (file)
@@ -193,7 +193,7 @@ class SiteStats {
                                        __METHOD__
                                );
                        },
-                       [ 'pcTTL' => 10 ]
+                       [ 'pcTTL' => $cache::TTL_PROC_LONG ]
                );
        }
 
index 6f38283..d070609 100644 (file)
@@ -22,6 +22,7 @@
  * @file
  */
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Represents a title within MediaWiki.
@@ -157,42 +158,6 @@ class Title implements LinkTarget {
        private $mIsBigDeletion = null;
        // @}
 
-       /**
-        * B/C kludge: provide a TitleParser for use by Title.
-        * Ideally, Title would have no methods that need this.
-        * Avoid usage of this singleton by using TitleValue
-        * and the associated services when possible.
-        *
-        * @return MediaWikiTitleCodec
-        */
-       private static function getMediaWikiTitleCodec() {
-               global $wgContLang, $wgLocalInterwikis;
-
-               static $titleCodec = null;
-               static $titleCodecFingerprint = null;
-
-               // $wgContLang and $wgLocalInterwikis may change (especially while testing),
-               // make sure we are using the right one. To detect changes over the course
-               // of a request, we remember a fingerprint of the config used to create the
-               // codec singleton, and re-create it if the fingerprint doesn't match.
-               $fingerprint = spl_object_hash( $wgContLang ) . '|' . implode( '+', $wgLocalInterwikis );
-
-               if ( $fingerprint !== $titleCodecFingerprint ) {
-                       $titleCodec = null;
-               }
-
-               if ( !$titleCodec ) {
-                       $titleCodec = new MediaWikiTitleCodec(
-                               $wgContLang,
-                               GenderCache::singleton(),
-                               $wgLocalInterwikis
-                       );
-                       $titleCodecFingerprint = $fingerprint;
-               }
-
-               return $titleCodec;
-       }
-
        /**
         * B/C kludge: provide a TitleParser for use by Title.
         * Ideally, Title would have no methods that need this.
@@ -202,9 +167,7 @@ class Title implements LinkTarget {
         * @return TitleFormatter
         */
        private static function getTitleFormatter() {
-               // NOTE: we know that getMediaWikiTitleCodec() returns a MediaWikiTitleCodec,
-               //      which implements TitleFormatter.
-               return self::getMediaWikiTitleCodec();
+               return MediaWikiServices::getInstance()->getTitleFormatter();
        }
 
        function __construct() {
@@ -256,7 +219,9 @@ class Title implements LinkTarget {
                return self::makeTitle(
                        $linkTarget->getNamespace(),
                        $linkTarget->getText(),
-                       $linkTarget->getFragment() );
+                       $linkTarget->getFragment(),
+                       $linkTarget->getInterwiki()
+               );
        }
 
        /**
@@ -871,7 +836,9 @@ class Title implements LinkTarget {
                                $this->mTitleValue = new TitleValue(
                                        $this->getNamespace(),
                                        $this->getDBkey(),
-                                       $this->getFragment() );
+                                       $this->getFragment(),
+                                       $this->getInterwiki()
+                               );
                        } catch ( InvalidArgumentException $ex ) {
                                wfDebug( __METHOD__ . ': Can\'t create a TitleValue for [[' .
                                        $this->getPrefixedText() . ']]: ' . $ex->getMessage() . "\n" );
@@ -3328,9 +3295,11 @@ class Title implements LinkTarget {
                // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share
                //        the parsing code with Title, while avoiding massive refactoring.
                // @todo: get rid of secureAndSplit, refactor parsing code.
-               $titleParser = self::getMediaWikiTitleCodec();
+               // @note: getTitleParser() returns a TitleParser implementation which does not have a
+               //        splitTitleString method, but the only implementation (MediaWikiTitleCodec) does
+               $titleCodec = MediaWikiServices::getInstance()->getTitleParser();
                // MalformedTitleException can be thrown here
-               $parts = $titleParser->splitTitleString( $dbkey, $this->getDefaultNamespace() );
+               $parts = $titleCodec->splitTitleString( $dbkey, $this->getDefaultNamespace() );
 
                # Fill fields
                $this->setFragment( '#' . $parts['fragment'] );
@@ -4434,7 +4403,8 @@ class Title implements LinkTarget {
                        $this->mNotificationTimestamp = [];
                }
 
-               $watchedItem = WatchedItemStore::getDefaultInstance()->getWatchedItem( $user, $this );
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+               $watchedItem = $store->getWatchedItem( $user, $this );
                if ( $watchedItem ) {
                        $this->mNotificationTimestamp[$uid] = $watchedItem->getNotificationTimestamp();
                } else {
index db6ce87..50c79dc 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Watchlist
  */
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Linker\LinkTarget;
 
 /**
@@ -118,7 +119,7 @@ class WatchedItem {
                        if ( $this->checkRights && !$this->user->isAllowed( 'viewmywatchlist' ) ) {
                                return false;
                        }
-                       $item = WatchedItemStore::getDefaultInstance()
+                       $item = MediaWikiServices::getInstance()->getWatchedItemStore()
                                ->loadWatchedItem( $this->user, $this->linkTarget );
                        if ( $item ) {
                                $this->notificationTimestamp = $item->getNotificationTimestamp();
@@ -163,7 +164,7 @@ class WatchedItem {
                if ( $this->checkRights && !$this->user->isAllowed( 'editmywatchlist' ) ) {
                        return;
                }
-               WatchedItemStore::getDefaultInstance()->resetNotificationTimestamp(
+               MediaWikiServices::getInstance()->getWatchedItemStore()->resetNotificationTimestamp(
                        $this->user,
                        $this->getTitle(),
                        $force,
@@ -194,7 +195,7 @@ class WatchedItem {
                        $targets[$userId][] = $watchedItem->getTitle()->getTalkPage();
                }
 
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                $success = true;
                foreach ( $users as $userId => $user ) {
                        $success &= $store->addWatchBatchForUser( $user, $targets[$userId] );
@@ -240,7 +241,7 @@ class WatchedItem {
         */
        public static function duplicateEntries( Title $oldTitle, Title $newTitle ) {
                // wfDeprecated( __METHOD__, '1.27' );
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                $store->duplicateAllAssociatedEntries( $oldTitle, $newTitle );
        }
 
index 2180b2d..eb652ce 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
 
@@ -50,11 +51,6 @@ class WatchedItemStore implements StatsdAwareInterface {
         */
        private $stats;
 
-       /**
-        * @var self|null
-        */
-       private static $instance;
-
        /**
         * @param LoadBalancer $loadBalancer
         * @param HashBagOStuff $cache
@@ -125,46 +121,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                } );
        }
 
-       /**
-        * Overrides the default instance of this class
-        * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
-        *
-        * If this method is used it MUST also be called with null after a test to ensure a new
-        * default instance is created next time getDefaultInstance is called.
-        *
-        * @param WatchedItemStore|null $store
-        *
-        * @return ScopedCallback to reset the overridden value
-        * @throws MWException
-        */
-       public static function overrideDefaultInstance( WatchedItemStore $store = null ) {
-               if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
-                       throw new MWException(
-                               'Cannot override ' . __CLASS__ . 'default instance in operation.'
-                       );
-               }
-
-               $previousValue = self::$instance;
-               self::$instance = $store;
-               return new ScopedCallback( function() use ( $previousValue ) {
-                       self::$instance = $previousValue;
-               } );
-       }
-
-       /**
-        * @return self
-        */
-       public static function getDefaultInstance() {
-               if ( !self::$instance ) {
-                       self::$instance = new self(
-                               wfGetLB(),
-                               new HashBagOStuff( [ 'maxKeys' => 100 ] )
-                       );
-                       self::$instance->setStatsdDataFactory( RequestContext::getMain()->getStats() );
-               }
-               return self::$instance;
-       }
-
        private function getCacheKey( User $user, LinkTarget $target ) {
                return $this->cache->makeKey(
                        (string)$target->getNamespace(),
@@ -621,7 +577,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                $this->reuseConnection( $dbr );
 
                foreach ( $res as $row ) {
-                       $timestamps[(int)$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
+                       $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
                }
 
                return $timestamps;
index b159f79..2333c78 100644 (file)
@@ -80,6 +80,9 @@ class WebRequest {
         */
        protected $sessionId = null;
 
+       /** @var bool Whether this HTTP request is "safe" (even if it is an HTTP post) */
+       protected $markedAsSafe = false;
+
        public function __construct() {
                $this->requestTime = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
                        ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime( true );
@@ -318,7 +321,7 @@ class WebRequest {
         *
         * @param string $path The URL path given from the client
         * @param array $bases One or more URLs, optionally with $1 at the end
-        * @param string $key If provided, the matching key in $bases will be
+        * @param string|bool $key If provided, the matching key in $bases will be
         *    passed on as the value of this URL parameter
         * @return array Array of URL variables to interpolate; empty if no match
         */
@@ -1022,7 +1025,7 @@ class WebRequest {
         * @param mixed $data
         */
        public function setSessionData( $key, $data ) {
-               return $this->getSession()->set( $key, $data );
+               $this->getSession()->set( $key, $data );
        }
 
        /**
@@ -1245,4 +1248,50 @@ HTML;
        public function setIP( $ip ) {
                $this->ip = $ip;
        }
+
+       /**
+        * Whether this request should be identified as being "safe"
+        *
+        * This means that the client is not requesting any state changes and that database writes
+        * are not inherently required. Ideally, no visible updates would happen at all. If they
+        * must, then they should not be publically attributed to the end user.
+        *
+        * In more detail:
+        *   - Cache populations and refreshes MAY occur.
+        *   - Private user session updates and private server logging MAY occur.
+        *   - Updates to private viewing activity data MAY occur via DeferredUpdates.
+        *   - Other updates SHOULD NOT occur (e.g. modifying content assets).
+        *
+        * @return bool
+        * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
+        * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
+        * @since 1.28
+        */
+       public function isSafeRequest() {
+               if ( !isset( $_SERVER['REQUEST_METHOD'] ) ) {
+                       return false; // CLI mode
+               }
+
+               if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
+                       return $this->markedAsSafe;
+               } elseif ( in_array( $_SERVER['REQUEST_METHOD'], [ 'GET', 'HEAD', 'OPTIONS' ] ) ) {
+                       return true; // HTTP "safe methods"
+               }
+
+               return false; // PUT/DELETE
+       }
+
+       /**
+        * Mark this request is identified as being nullipotent even if it is a POST request
+        *
+        * POST requests are often used due to the need for a client payload, even if the request
+        * is otherwise equivalent to a "safe method" request.
+        *
+        * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
+        * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
+        * @since 1.28
+        */
+       public function markAsSafeRequest() {
+               $this->markedAsSafe = true;
+       }
 }
index f7c30b7..b5f7ff2 100644 (file)
@@ -22,6 +22,8 @@
  * @ingroup Actions
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Displays information about a page.
  *
@@ -677,7 +679,7 @@ class InfoAction extends FormlessAction {
 
                                $setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
 
-                               $watchedItemStore = WatchedItemStore::getDefaultInstance();
+                               $watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore();
 
                                $result = [];
                                $result['watchers'] = $watchedItemStore->countWatchers( $title );
index da64c03..7d0ae32 100644 (file)
@@ -1522,20 +1522,20 @@ abstract class ApiBase extends ContextSource {
                        throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
                }
 
-               $errors = $status->getErrorsArray();
+               $errors = $status->getErrorsByType( 'error' );
                if ( !$errors ) {
                        // No errors? Assume the warnings should be treated as errors
-                       $errors = $status->getWarningsArray();
+                       $errors = $status->getErrorsByType( 'warning' );
                }
                if ( !$errors ) {
                        // Still no errors? Punt
-                       $errors = [ [ 'unknownerror-nocode' ] ];
+                       $errors = [ [ 'message' => 'unknownerror-nocode', 'params' => [] ] ];
                }
 
                // Cannot use dieUsageMsg() because extensions might return custom
                // error messages.
-               if ( $errors[0] instanceof Message ) {
-                       $msg = $errors[0];
+               if ( $errors[0]['message'] instanceof Message ) {
+                       $msg = $errors[0]['message'];
                        if ( $msg instanceof IApiMessage ) {
                                $extraData = $msg->getApiData();
                                $code = $msg->getApiCode();
@@ -1543,8 +1543,8 @@ abstract class ApiBase extends ContextSource {
                                $code = $msg->getKey();
                        }
                } else {
-                       $code = array_shift( $errors[0] );
-                       $msg = wfMessage( $code, $errors[0] );
+                       $code = $errors[0]['message'];
+                       $msg = wfMessage( $code, $errors[0]['params'] );
                }
                if ( isset( ApiBase::$messageMap[$code] ) ) {
                        // Translate message to code, for backwards compatibility
index f7539ce..0f0fbdc 100644 (file)
@@ -255,28 +255,43 @@ class ApiHelp extends ApiBase {
                                }
 
                                if ( $module->isMain() ) {
-                                       $header = $context->msg( 'api-help-main-header' )->parse();
+                                       $headerContent = $context->msg( 'api-help-main-header' )->parse();
+                                       $headerAttr = [
+                                               'class' => 'apihelp-header',
+                                       ];
                                } else {
                                        $name = $module->getModuleName();
-                                       $header = $module->getParent()->getModuleManager()->getModuleGroup( $name ) .
+                                       $headerContent = $module->getParent()->getModuleManager()->getModuleGroup( $name ) .
                                                "=$name";
                                        if ( $module->getModulePrefix() !== '' ) {
-                                               $header .= ' ' .
+                                               $headerContent .= ' ' .
                                                        $context->msg( 'parentheses', $module->getModulePrefix() )->parse();
                                        }
+                                       // Module names are always in English and not localized,
+                                       // so English language and direction must be set explicitly,
+                                       // otherwise parentheses will get broken in RTL wikis
+                                       $headerAttr = [
+                                               'class' => 'apihelp-header apihelp-module-name',
+                                               'dir' => 'ltr',
+                                               'lang' => 'en',
+                                       ];
                                }
+
+                               $headerAttr['id'] = $anchor;
+
                                $haveModules[$anchor] = [
                                        'toclevel' => count( $tocnumber ),
                                        'level' => $level,
                                        'anchor' => $anchor,
-                                       'line' => $header,
+                                       'line' => $headerContent,
                                        'number' => implode( '.', $tocnumber ),
                                        'index' => false,
                                ];
                                if ( empty( $options['noheader'] ) ) {
-                                       $help['header'] .= Html::element( 'h' . min( 6, $level ),
-                                               [ 'id' => $anchor, 'class' => 'apihelp-header' ],
-                                               $header
+                                       $help['header'] .= Html::element(
+                                               'h' . min( 6, $level ),
+                                               $headerAttr,
+                                               $headerContent
                                        );
                                }
                        } else {
index 07642c4..685a9ef 100644 (file)
@@ -134,7 +134,9 @@ class ApiMain extends ApiBase {
        private $mModuleMgr, $mResult, $mErrorFormatter, $mContinuationManager;
        private $mAction;
        private $mEnableWrite;
-       private $mInternalMode, $mSquidMaxage, $mModule;
+       private $mInternalMode, $mSquidMaxage;
+       /** @var ApiBase */
+       private $mModule;
 
        private $mCacheMode = 'private';
        private $mCacheControl = [];
@@ -397,13 +399,7 @@ class ApiMain extends ApiBase {
                if ( $this->mInternalMode ) {
                        $this->executeAction();
                } else {
-                       $start = microtime( true );
                        $this->executeActionWithErrorHandling();
-                       if ( $this->isWriteMode() && $this->getRequest()->wasPosted() ) {
-                               $timeMs = 1000 * max( 0, microtime( true ) - $start );
-                               $this->getStats()->timing(
-                                       'api.' . $this->getModuleName() . '.executeTiming', $timeMs );
-                       }
                }
        }
 
@@ -433,8 +429,12 @@ class ApiMain extends ApiBase {
                $isError = false;
                try {
                        $this->executeAction();
-                       $this->logRequest( microtime( true ) - $t );
-
+                       $runTime = microtime( true ) - $t;
+                       $this->logRequest( $runTime );
+                       if ( $this->mModule->isWriteMode() && $this->getRequest()->wasPosted() ) {
+                               $this->getStats()->timing(
+                                       'api.' . $this->getModuleName() . '.executeTiming', 1000 * $runTime );
+                       }
                } catch ( Exception $e ) {
                        $this->handleException( $e );
                        $this->logRequest( microtime( true ) - $t, $e );
@@ -1355,6 +1355,7 @@ class ApiMain extends ApiBase {
                                $trxProfiler->setExpectations( $limits['POST'], __METHOD__ );
                        } else {
                                $trxProfiler->setExpectations( $limits['POST-nonwrite'], __METHOD__ );
+                               $this->getRequest()->markAsSafeRequest();
                        }
                } else {
                        $trxProfiler->setExpectations( $limits['GET'], __METHOD__ );
index effa520..058e0a3 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @ingroup API
  */
@@ -123,8 +125,7 @@ class ApiOpenSearch extends ApiBase {
         * @param array &$results Put results here. Keys have to be integers.
         */
        protected function search( $search, $limit, $namespaces, $resolveRedir, &$results ) {
-
-               $searchEngine = SearchEngine::create();
+               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
                $searchEngine->setLimitOffset( $limit );
                $searchEngine->setNamespaces( $namespaces );
                $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
@@ -350,24 +351,25 @@ class ApiOpenSearch extends ApiBase {
         * @throws MWException
         */
        public static function getOpenSearchTemplate( $type ) {
-               global $wgOpenSearchTemplate, $wgCanonicalServer;
+               $config = MediaWikiServices::getInstance()->getSearchEngineConfig();
+               $template = $config->getConfig()->get( 'OpenSearchTemplate' );
 
-               if ( $wgOpenSearchTemplate && $type === 'application/x-suggestions+json' ) {
-                       return $wgOpenSearchTemplate;
+               if ( $template && $type === 'application/x-suggestions+json' ) {
+                       return $template;
                }
 
-               $ns = implode( '|', SearchEngine::defaultNamespaces() );
+               $ns = implode( '|', $config->defaultNamespaces() );
                if ( !$ns ) {
                        $ns = '0';
                }
 
                switch ( $type ) {
                        case 'application/x-suggestions+json':
-                               return $wgCanonicalServer . wfScript( 'api' )
+                               return $config->getConfig()->get( 'CanonicalServer' ) . wfScript( 'api' )
                                        . '?action=opensearch&search={searchTerms}&namespace=' . $ns;
 
                        case 'application/x-suggestions+xml':
-                               return $wgCanonicalServer . wfScript( 'api' )
+                               return $config->getConfig()->get( 'CanonicalServer' ) . wfScript( 'api' )
                                        . '?action=opensearch&format=xml&search={searchTerms}&namespace=' . $ns;
 
                        default:
index e51d46d..8bfe447 100644 (file)
@@ -86,8 +86,7 @@ class ApiOptions extends ApiBase {
                                                // We need a dummy HTMLForm for the validate callback...
                                                $htmlForm = new HTMLForm( [], $this );
                                        }
-                                       $field = HTMLForm::loadInputFromParameters( $key, $prefs[$key] );
-                                       $field->mParent = $htmlForm;
+                                       $field = HTMLForm::loadInputFromParameters( $key, $prefs[$key], $htmlForm );
                                        $validation = $field->validate( $value, $user->getOptions() );
                                        break;
                                case 'registered-multiselect':
index 13e6340..d1fcfa3 100644 (file)
@@ -325,8 +325,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
         * allows us to catch certain error conditions early (such as missing
         * required parameter).
         *
-        * @param $image File
-        * @param $finalParams array List of parameters to transform image with
+        * @param File $image
+        * @param array $finalParams List of parameters to transform image with
         */
        protected function checkParameterNormalise( $image, $finalParams ) {
                $h = $image->getHandler();
index b94f567..f5c49ad 100644 (file)
@@ -23,6 +23,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Linker\LinkTarget;
 
 /**
@@ -760,7 +761,7 @@ class ApiQueryInfo extends ApiQueryBase {
                $this->watched = [];
                $this->notificationtimestamps = [];
 
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                $timestamps = $store->getNotificationTimestampsBatch( $user, $this->everything );
 
                if ( $this->fld_watched ) {
@@ -800,7 +801,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        $countOptions['minimumWatchers'] = $unwatchedPageThreshold;
                }
 
-               $this->watchers = WatchedItemStore::getDefaultInstance()->countWatchersMultiple(
+               $this->watchers = MediaWikiServices::getInstance()->getWatchedItemStore()->countWatchersMultiple(
                        $this->everything,
                        $countOptions
                );
@@ -867,8 +868,8 @@ class ApiQueryInfo extends ApiQueryBase {
                                )
                        );
                }
-
-               $this->visitingwatchers = WatchedItemStore::getDefaultInstance()->countVisitingWatchersMultiple(
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+               $this->visitingwatchers = $store->countVisitingWatchersMultiple(
                        $titlesWithThresholds,
                        !$canUnwatchedpages ? $unwatchedPageThreshold : null
                );
index d04796c..5c50273 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * 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
@@ -45,7 +47,7 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                $namespaces = $params['namespace'];
                $offset = $params['offset'];
 
-               $searchEngine = SearchEngine::create();
+               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
                $searchEngine->setLimitOffset( $limit + 1, $offset );
                $searchEngine->setNamespaces( $namespaces );
                $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
index 74c2214..f0fd2f4 100644 (file)
@@ -206,7 +206,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        ) {
                                if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                        $this->dieUsage(
-                                               'You need the patrol right to request the patrolled flag',
+                                               'You need patrol or patrolmarks permission to request the patrolled flag',
                                                'permissiondenied'
                                        );
                                }
@@ -277,7 +277,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                        if ( $this->fld_patrolled && !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                $this->dieUsage(
-                                       'You need the patrol right to request the patrolled flag',
+                                       'You need patrol or patrolmarks permission to request the patrolled flag',
                                        'permissiondenied'
                                );
                        }
index 3955cc5..f57d3a3 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Query module to perform full text search within wiki titles and content
  *
@@ -78,8 +80,9 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                }
 
                // Create search engine instance and set options
-               $search = isset( $params['backend'] ) && $params['backend'] != self::BACKEND_NULL_PARAM ?
-                       SearchEngine::create( $params['backend'] ) : SearchEngine::create();
+               $type = isset( $params['backend'] ) && $params['backend'] != self::BACKEND_NULL_PARAM ?
+                       $params['backend'] : null;
+               $search = MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
                $search->setLimitOffset( $limit + 1, $params['offset'] );
                $search->setNamespaces( $params['namespace'] );
                $search->setFeatureData( 'rewrite', (bool)$params['enablerewrites'] );
@@ -95,7 +98,8 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                } elseif ( $what == 'nearmatch' ) {
                        // near matches must receive the user input as provided, otherwise
                        // the near matches within namespaces are lost.
-                       $matches = SearchEngine::getNearMatchResultSet( $params['search'] );
+                       $matches = $search->getNearMatcher( $this->getConfig() )
+                               ->getNearMatchResultSet( $params['search'] );
                } else {
                        // We default to title searches; this is a terrible legacy
                        // of the way we initially set up the MySQL fulltext-based
@@ -358,13 +362,14 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                        'enablerewrites' => false,
                ];
 
-               $alternatives = SearchEngine::getSearchTypes();
+               $searchConfig = MediaWikiServices::getInstance()->getSearchEngineConfig();
+               $alternatives = $searchConfig->getSearchTypes();
                if ( count( $alternatives ) > 1 ) {
                        if ( $alternatives[0] === null ) {
                                $alternatives[0] = self::BACKEND_NULL_PARAM;
                        }
                        $params['backend'] = [
-                               ApiBase::PARAM_DFLT => $this->getConfig()->get( 'SearchType' ),
+                               ApiBase::PARAM_DFLT => $searchConfig->getSearchType(),
                                ApiBase::PARAM_TYPE => $alternatives,
                        ];
                }
index 0fc443a..d3cd0c4 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Query module to get information about the currently logged-in user
  *
@@ -225,7 +227,8 @@ class ApiQueryUserInfo extends ApiQueryBase {
                }
 
                if ( isset( $this->prop['unreadcount'] ) ) {
-                       $unreadNotifications = WatchedItemStore::getDefaultInstance()->countUnreadNotifications(
+                       $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+                       $unreadNotifications = $store->countUnreadNotifications(
                                $user,
                                self::WL_UNREAD_LIMIT
                        );
index cc8e390..5efefbd 100644 (file)
@@ -40,6 +40,8 @@ class ApiStashEdit extends ApiBase {
        const ERROR_CACHE = 'error_cache';
        const ERROR_UNCACHEABLE = 'uncacheable';
 
+       const PRESUME_FRESH_TTL_SEC = 30;
+
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
@@ -217,6 +219,9 @@ class ApiStashEdit extends ApiBase {
                        return false;
                }
 
+               // Set the time the output was generated
+               $pOut->setCacheTime( wfTimestampNow() );
+
                // Build a value to cache with a proper TTL
                list( $stashInfo, $ttl ) = self::buildStashValue( $pstContent, $pOut, $timestamp );
                if ( !$stashInfo ) {
@@ -281,10 +286,10 @@ class ApiStashEdit extends ApiBase {
                        return false;
                }
 
-               $time = wfTimestamp( TS_UNIX, $editInfo->output->getTimestamp() );
-               if ( ( time() - $time ) <= 3 ) {
+               $age = time() - wfTimestamp( TS_UNIX, $editInfo->output->getCacheTime() );
+               if ( $age <= self::PRESUME_FRESH_TTL_SEC ) {
                        $stats->increment( 'editstash.cache_hits.presumed_fresh' );
-                       $logger->debug( "Timestamp-based cache hit for key '$key'." );
+                       $logger->debug( "Timestamp-based cache hit for key '$key' (age: $age sec)." );
                        return $editInfo; // assume nothing changed
                }
 
@@ -313,7 +318,7 @@ class ApiStashEdit extends ApiBase {
 
                        if ( $changed || $res->numRows() != $templateUses ) {
                                $stats->increment( 'editstash.cache_misses.proven_stale' );
-                               $logger->info( "Stale cache for key '$key'; template changed." );
+                               $logger->info( "Stale cache for key '$key'; template changed. (age: $age sec)" );
                                return false;
                        }
                }
@@ -337,13 +342,13 @@ class ApiStashEdit extends ApiBase {
 
                        if ( $changed || $res->numRows() != count( $files ) ) {
                                $stats->increment( 'editstash.cache_misses.proven_stale' );
-                               $logger->info( "Stale cache for key '$key'; file changed." );
+                               $logger->info( "Stale cache for key '$key'; file changed. (age: $age sec)" );
                                return false;
                        }
                }
 
                $stats->increment( 'editstash.cache_hits.proven_fresh' );
-               $logger->debug( "Cache hit for key '$key'." );
+               $logger->debug( "Verified cache hit for key '$key' (age: $age sec)." );
 
                return $editInfo;
        }
index 1571b27..0a79aa4 100644 (file)
@@ -488,6 +488,16 @@ class ApiUpload extends ApiBase {
 
                        $this->dieUsageMsg( 'badaccess-groups' );
                }
+
+               // Check blocks
+               if ( $user->isBlocked() ) {
+                       $this->dieBlocked( $user->getBlock() );
+               }
+
+               // Global blocks
+               if ( $user->isBlockedGlobally() ) {
+                       $this->dieBlocked( $user->getGlobalBlock() );
+               }
        }
 
        /**
index 45060c2..ff97cc8 100644 (file)
@@ -1,12 +1,28 @@
 {
        "@metadata": {
                "authors": [
-                       "Robin van der Vliet"
+                       "Robin van der Vliet",
+                       "Renardo"
                ]
        },
+       "apihelp-main-param-format": "La formo de la eligaĵo.",
+       "apihelp-block-description": "Forbari uzulon.",
+       "apihelp-block-param-user": "Salutnomo, IP-adreso aŭ IP-adresa intervalo forbarota.",
+       "apihelp-block-param-expiry": "Eksvalidiĝa tempo. Ĝi povas esti relativa (ekz. <kbd>5 months</kbd> aŭ <kbd>2 weeks</kbd> aŭ absoluta (ekz. <kbd>2014-09-18T12:34:56Z</kbd>). Se vi indikas <kbd>infinite</kbd> (senfine), <kbd>indefinite</kbd> (nedifinite) aŭ <kbd>never</kbd> (neniam), la forbaro neniam eksvalidiĝos.",
        "apihelp-createaccount-param-name": "Uzantnomo.",
        "apihelp-delete-description": "Forigi paĝon.",
+       "apihelp-edit-param-minor": "Redakteto.",
        "apihelp-edit-example-edit": "Redakti paĝon.",
+       "apihelp-feedrecentchanges-param-hideminor": "Kaŝi redaktetojn.",
+       "apihelp-feedrecentchanges-param-hidebots": "Kaŝi robotajn ŝanĝojn.",
+       "apihelp-feedrecentchanges-param-hideanons": "Kaŝi redaktojn de anonimuloj.",
+       "apihelp-feedrecentchanges-param-hideliu": "Kaŝi redaktojn de ensalutintaj uzantoj.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Kaŝi reviziitajn ŝanĝojn.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Kaŝi redaktojn de la nun ensalutinta uzulo (= vi).",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Kaŝi ŝanĝojn de kategoria aneco.",
+       "apihelp-feedrecentchanges-example-simple": "Montri ĵusajn ŝanĝojn.",
+       "apihelp-filerevert-description": "Restarigi malnovan version de dosiero.",
+       "apihelp-filerevert-param-comment": "Alŝuta komento.",
        "apihelp-login-param-name": "Uzantnomo.",
        "apihelp-login-param-password": "Pasvorto.",
        "apihelp-login-example-login": "Ensaluti."
index 480ad24..b114289 100644 (file)
@@ -2,9 +2,12 @@
        "@metadata": {
                "authors": [
                        "WongKentir",
-                       "Beeyan"
+                       "Beeyan",
+                       "Rachmat.Wahidi"
                ]
        },
+       "apihelp-block-description": "Blokir pengguna.",
+       "apihelp-block-param-user": "Nama pengguna, alamat IP, atau rentang alamat IP untuk diblokir.",
        "apihelp-createaccount-param-name": "Nama pengguna",
        "apihelp-revisiondelete-param-ids": "Penanda untuk perubahan yang akan dihapus"
 }
index d26b996..6b0cab6 100644 (file)
@@ -11,7 +11,8 @@
                        "Sannita",
                        "Macofe",
                        "Nemo bis",
-                       "JackLantern"
+                       "JackLantern",
+                       "Urielejh"
                ]
        },
        "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 le API sono ancora in fase attiva di sviluppo, e potrebbero cambiare in qualsiasi momento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la mailing list sugli annunci delle API MediaWiki] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite alle API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e, sia il valore dell'intestazione, sia il codice d'errore, verranno impostati con lo stesso valore. Per maggiori informazioni leggi [[mw:API:Errors_and_warnings|API:Errori ed avvertimenti]] (in inglese).\n\n<strong>Test:</strong> per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].",
        "apihelp-expandtemplates-param-text": "Wikitesto da convertire.",
        "apihelp-expandtemplates-param-prop": "Quale informazione ottenere.\n\nNota che se non è selezionato alcun valore, il risultato conterrà il codice wiki, ma l'output sarà in un formato obsoleto.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Il wikitext espanso.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "Proprietà della pagina definite dalle parole magiche estese nel wikitesto.",
        "apihelp-expandtemplates-paramvalue-prop-volatile": "Se l'output sia volatile e non debba essere riutilizzato altrove all'interno della pagina.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "Il tempo massimo dopo il quale le memorizzazioni temporanee (cache) del risultato dovrebbero essere invalidate.",
        "apihelp-feedcontributions-param-feedformat": "Il formato del feed.",
        "apihelp-feedcontributions-param-year": "Dall'anno (e precedenti).",
        "apihelp-feedcontributions-param-month": "Dal mese (e precedenti).",
        "apihelp-feedrecentchanges-param-namespace": "Namespace a cui limitare i risultati.",
        "apihelp-feedrecentchanges-param-associated": "Includi namespace associato (discussione o principale)",
        "apihelp-feedrecentchanges-param-limit": "Numero massimo di risultati da restituire.",
+       "apihelp-feedrecentchanges-param-from": "Mostra i cambiamenti da allora.",
        "apihelp-feedrecentchanges-param-hideminor": "Nascondi le modifiche minori.",
        "apihelp-feedrecentchanges-param-hidebots": "Nascondi le modifiche apportate da bot.",
        "apihelp-feedrecentchanges-param-hideanons": "Nascondi le modifiche fatte da utenti anonimi.",
        "apihelp-login-example-gettoken": "Recupera un token di login.",
        "apihelp-login-example-login": "Entra.",
        "apihelp-logout-description": "Esci e cancella i dati della sessione.",
+       "apihelp-logout-example-logout": "Disconnetti l'utente attuale.",
        "apihelp-mergehistory-description": "Unisce cronologie pagine.",
        "apihelp-mergehistory-param-from": "Il titolo della pagina da cui cronologia sarà unita. Non può essere usato insieme a <var>$1fromid</var>.",
        "apihelp-mergehistory-param-fromid": "L'ID della pagina da cui cronologia sarà unita. Non può essere usato insieme a <var>$1from</var>.",
        "apihelp-paraminfo-description": "Ottieni informazioni sui moduli API.",
        "apihelp-paraminfo-param-helpformat": "Formato delle stringhe di aiuto.",
        "apihelp-parse-param-summary": "Oggetto da analizzare.",
+       "apihelp-parse-param-redirects": "Se <var>$1page</var> o <var>$1pageid</var> è impostato come reindirizzamento, lo risolve.",
        "apihelp-parse-param-prop": "Quali pezzi di informazioni ottenere:",
        "apihelp-parse-example-text": "Analizza wikitext.",
        "apihelp-parse-example-texttitle": "Analizza wikitext, specificando il titolo della pagina.",
        "apihelp-query+allpages-param-prefix": "Ricerca per tutti i titoli delle pagine che iniziano con questo valore.",
        "apihelp-query+allpages-param-namespace": "Il namespace da elencare.",
        "apihelp-query+allpages-param-filterredir": "Quali pagine elencare.",
+       "apihelp-query+allpages-param-prtype": "Limita alle sole pagine protette.",
        "apihelp-query+allpages-param-limit": "Quante pagine totali restituire.",
        "apihelp-query+allpages-param-dir": "La direzione in cui elencare.",
        "apihelp-query+allredirects-param-from": "Il titolo del reindirizzamento da cui iniziare l'elenco.",
        "apihelp-query+blocks-paramvalue-prop-by": "Aggiunge il nome utente dell'utente che ha effettuato il blocco.",
        "apihelp-query+blocks-paramvalue-prop-byid": "Aggiunge l'ID utente dell'utente che ha effettuato il blocco.",
        "apihelp-query+blocks-example-simple": "Elenca i blocchi.",
+       "apihelp-query+categories-description": "Elenca tutte le categorie a cui appartengono le pagine.",
+       "apihelp-query+categories-param-prop": "Quali proprietà aggiuntive ottenere per ogni categoria.",
        "apihelp-query+categories-param-show": "Quale tipo di categorie mostrare.",
        "apihelp-query+categories-param-limit": "Quante categorie restituire.",
        "apihelp-query+categories-param-dir": "La direzione in cui elencare.",
        "apihelp-query+imageusage-param-namespace": "Il namespace da elencare.",
        "apihelp-query+imageusage-param-dir": "La direzione in cui elencare.",
        "apihelp-query+imageusage-param-redirect": "Se la pagina collegata è un redirect, trova tutte le pagine che puntano al redirect. Il limite massimo è dimezzato.",
+       "apihelp-query+info-description": "Ottieni informazioni base sulla pagina.",
+       "apihelp-query+info-param-prop": "Quali proprietà aggiuntive ottenere:",
        "apihelp-query+info-paramvalue-prop-visitingwatchers": "Il numero di osservatori di ogni pagina che hanno visitato le ultime modifiche alla pagina, se consentito.",
        "apihelp-query+iwbacklinks-param-prefix": "Prefisso per l'interwiki.",
        "apihelp-query+iwbacklinks-param-limit": "Quante pagine totali restituire.",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Aggiunge il titolo del collegamento linguistico.",
        "apihelp-query+langbacklinks-param-dir": "La direzione in cui elencare.",
        "apihelp-query+langlinks-paramvalue-prop-url": "Aggiunge l'URL completo.",
+       "apihelp-query+langlinks-paramvalue-prop-autonym": "Aggiunge il nome nativo della lingua.",
        "apihelp-query+langlinks-param-dir": "La direzione in cui elencare.",
        "apihelp-query+links-param-namespace": "Mostra collegamenti solo in questi namespace.",
        "apihelp-query+links-param-limit": "Quanti collegamenti restituire.",
        "apihelp-query+revisions-param-tag": "Elenca solo le versioni etichettate con questa etichetta.",
        "apihelp-query+revisions+base-paramvalue-prop-ids": "L'ID della versione.",
        "apihelp-query+revisions+base-paramvalue-prop-timestamp": "Il timestamp della versione.",
+       "apihelp-query+revisions+base-paramvalue-prop-user": "Utente che ha effettuato la versione.",
+       "apihelp-query+revisions+base-paramvalue-prop-userid": "ID utente dell'autore della versione.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Testo della versione.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Etichette della versione.",
+       "apihelp-query+search-description": "Eseguire una ricerca di testo completa.",
        "apihelp-query+search-param-what": "Quale tipo di ricerca effettuare.",
        "apihelp-query+search-param-info": "Quali metadati restituire.",
        "apihelp-query+search-param-prop": "Quali proprietà restituire.",
        "apihelp-query+search-paramvalue-prop-sectiontitle": "Aggiunge il titolo della sezione corrispondente.",
        "apihelp-query+search-param-limit": "Quante pagine totali restituire.",
        "apihelp-query+siteinfo-param-prop": "Quali informazioni ottenere:",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "Restituisce le statistiche del sito.",
        "apihelp-query+siteinfo-paramvalue-prop-libraries": "Restituisci librerie installate sul wiki.",
        "apihelp-query+siteinfo-paramvalue-prop-extensions": "Restituisci estensioni installate sul wiki.",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "Restituisce informazioni sui tipi di restrizione (protezione) disponibili.",
+       "apihelp-query+siteinfo-example-simple": "Recupera informazioni sul sito.",
        "apihelp-query+tags-param-prop": "Quali proprietà ottenere:",
        "apihelp-query+templates-param-limit": "Quanti template restituire.",
        "apihelp-query+templates-param-dir": "La direzione in cui elencare.",
        "apihelp-query+watchlist-param-prop": "Quali proprietà aggiuntive ottenere:",
        "apihelp-query+watchlist-paramvalue-prop-ids": "Aggiunge l'ID versione e l'ID pagina.",
        "apihelp-query+watchlist-paramvalue-prop-title": "Aggiungi il titolo della pagina.",
+       "apihelp-query+watchlist-paramvalue-type-new": "Creazioni pagina.",
        "apihelp-query+watchlistraw-param-namespace": "Elenca solo le pagine nei namespace indicati.",
+       "apihelp-query+watchlistraw-param-limit": "Numero totale di risultati da restituire per ogni richiesta.",
+       "apihelp-query+watchlistraw-param-prop": "Quali proprietà aggiuntive ottenere:",
+       "apihelp-query+watchlistraw-paramvalue-prop-changed": "Aggiunge data e ora dell'ultima notifica all'utente riguardo la modifica.",
        "apihelp-query+watchlistraw-param-fromtitle": "Il titolo (con prefisso namespace) da cui iniziare l'elenco.",
        "apihelp-query+watchlistraw-param-totitle": "Il titolo (con prefisso namespace) al quale interrompere l'elenco.",
        "apihelp-query+watchlistraw-example-simple": "Elenca le pagine fra gli osservati speciali dell'utente attuale.",
        "apihelp-query+watchlistraw-example-generator": "Recupera le informazioni sulle pagine fra gli osservati speciali dell'utente attuale.",
+       "apihelp-revisiondelete-description": "Cancella e ripristina le versioni.",
+       "apihelp-revisiondelete-param-type": "Tipo di cancellazione della versione effettuata.",
+       "apihelp-revisiondelete-param-hide": "Cosa nascondere per ogni versione.",
+       "apihelp-revisiondelete-param-show": "Cosa mostrare per ogni versione.",
+       "apihelp-revisiondelete-param-reason": "Motivo per l'eliminazione o il ripristino.",
+       "apihelp-stashedit-param-title": "Titolo della pagina che si sta modificando.",
        "apihelp-stashedit-param-sectiontitle": "Il titolo per una nuova sezione.",
        "apihelp-stashedit-param-text": "Contenuto della pagina.",
        "apihelp-stashedit-param-contentmodel": "Modello di contenuto dei nuovi contenuti.",
+       "apihelp-tag-param-reason": "Motivo per la modifica.",
        "apihelp-tokens-param-type": "Tipi di token da richiedere.",
        "apihelp-tokens-example-edit": "Recupera un token di modifica (il predefinito).",
        "apihelp-unblock-description": "Sblocca un utente",
+       "apihelp-unblock-param-reason": "Motivo dello sblocco.",
        "apihelp-unblock-param-tags": "Modifica etichette da applicare all'elemento del registro dei blocchi.",
        "apihelp-undelete-param-title": "Titolo della pagina da ripristinare.",
+       "apihelp-undelete-param-reason": "Motivo per il ripristino.",
        "apihelp-undelete-param-tags": "Modifica etichette da applicare all'elemento del registro delle cancellazioni.",
+       "apihelp-upload-param-watch": "Osserva la pagina.",
        "apihelp-upload-param-file": "Contenuto del file.",
        "apihelp-upload-example-url": "Carica da un URL.",
        "apihelp-userrights-param-user": "Nome utente.",
diff --git a/includes/api/i18n/jv.json b/includes/api/i18n/jv.json
new file mode 100644 (file)
index 0000000..af1ca9c
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "@metadata": {
+               "authors": [
+                       "NoiX180"
+               ]
+       },
+       "apihelp-delete-example-simple": "Busak <kbd>Kaca Pokok</kbd>.",
+       "apihelp-query+backlinks-example-simple": "Tuduhaké pranala menyang <kbd>Kaca utama</kbd>.",
+       "apihelp-query+backlinks-example-generator": "Deleng pratélan bab kaca-kaca sing nggayut <kbd>Kaca utama</kbd>.",
+       "apihelp-query+contributors-example-simple": "Tuduhaké para nyumbang <kbd>Kaca Utama</kbd>."
+}
index 0618a88..713dfc5 100644 (file)
@@ -11,7 +11,8 @@
                        "Kurousagi",
                        "Revi",
                        "Yearning",
-                       "Priviet"
+                       "Priviet",
+                       "Ykhwong"
                ]
        },
        "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 버그 및 요청]\n</div>\n<strong>상태:</strong> 이 페이지에 보여지는 모든 기능은 정상적으로 작동하지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 변경될 수 있습니다. 업데이트 공지를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 [[mw:API:Errors_and_warnings|API:오류와 경고]]를 참조하십시오.\n\n<strong>테스트하기:</strong> API 요청을 테스트의 편의를 위해, [[Special:ApiSandbox]]를 보세요.",
@@ -63,6 +64,8 @@
        "apihelp-createaccount-example-pass": "사용자 <kbd>testuser</kbd>를 만들고 비밀번호를 <kbd>test123</kbd>으로 설정합니다.",
        "apihelp-createaccount-example-mail": "사용자 <kbd>testmailuser</kbd>를 만들고 자동 생성된 비밀번호를 이메일로 보냅니다.",
        "apihelp-delete-description": "문서 삭제",
+       "apihelp-delete-param-pageid": "삭제할 문서의 ID. <var>$1title</var>과 함께 사용할 수 없습니다.",
+       "apihelp-delete-param-reason": "삭제의 이유. 설정하지 않으면 자동 생성되는 이유를 사용합니다.",
        "apihelp-delete-param-unwatch": "문서를 현재 사용자의 주시문서 목록에서 제거합니다.",
        "apihelp-delete-example-simple": "<kbd>Main Page</kbd>를 삭제합니다.",
        "apihelp-disabled-description": "이 모듈은 해제되었습니다.",
@@ -95,6 +98,7 @@
        "apihelp-feedcontributions-param-deletedonly": "삭제된 기여만 봅니다.",
        "apihelp-feedcontributions-param-toponly": "최신 판인 편집만 봅니다.",
        "apihelp-feedrecentchanges-param-feedformat": "피드 포맷.",
+       "apihelp-feedrecentchanges-param-invert": "선택한 항목을 제외한 모든 이름공간.",
        "apihelp-feedrecentchanges-param-hideminor": "사소한 편집을 숨깁니다.",
        "apihelp-feedrecentchanges-param-hidebots": "봇의 편집을 숨깁니다.",
        "apihelp-feedrecentchanges-param-hideanons": "익명 사용자의 편집을 숨깁니다.",
        "apihelp-feedrecentchanges-example-30days": "30일간의 최근 바뀜을 봅니다.",
        "apihelp-filerevert-description": "파일을 이전 판으로 되돌립니다.",
        "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd>를 <kbd>2011-03-05T15:27:40Z</kbd> 판으로 되돌립니다.",
+       "apihelp-help-param-helpformat": "도움말 출력 포맷.",
        "apihelp-import-param-xml": "업로드한 XML 파일.",
        "apihelp-login-param-name": "계정 이름.",
        "apihelp-login-param-password": "비밀번호.",
        "apihelp-login-param-domain": "도메인 (선택).",
        "apihelp-login-example-login": "로그인.",
+       "apihelp-mergehistory-param-reason": "문서 병합 이유.",
        "apihelp-move-description": "문서 이동하기.",
        "apihelp-move-param-reason": "제목을 변경하는 이유",
        "apihelp-move-param-movetalk": "토론 문서가 존재한다면, 토론 문서도 이름을 변경해주세요.",
        "apihelp-opensearch-description": "OpenSearch 프로토콜을 이용하여 위키 검색하기",
        "apihelp-opensearch-param-search": "문자열 검색",
        "apihelp-opensearch-param-limit": "반환할 결과의 최대 수",
+       "apihelp-opensearch-param-format": "출력 포맷.",
        "apihelp-options-param-reset": "사이트 기본으로 설정 초기화",
        "apihelp-options-example-reset": "모든 설정 초기화",
+       "apihelp-paraminfo-param-helpformat": "도움말 문자열 포맷.",
+       "apihelp-protect-param-reason": "보호 또는 보호 해제의 이유.",
        "apihelp-protect-example-protect": "문서 보호",
        "apihelp-query+allmessages-example-ipb": "<kbd>ipb-</kbd>로 시작하는 메시지를 보입니다.",
        "apihelp-query+allrevisions-description": "모든 판 표시.",
index 3cab41c..12ec506 100644 (file)
@@ -11,6 +11,7 @@
        "apihelp-createaccount-param-name": "Navê bikarhêner.",
        "apihelp-delete-description": "Rûpelekê jê bibe.",
        "apihelp-delete-example-simple": "<kbd>Main Page</kbd>ê jê bibe.",
+       "apihelp-edit-description": "Rûpelan çêke û biguherîne.",
        "apihelp-edit-param-sectiontitle": "Sernavê bo beşeke nû.",
        "apihelp-edit-param-text": "Naveroka rûpelê.",
        "apihelp-edit-param-minor": "Guhertina biçûk.",
        "apihelp-feedcontributions-param-deletedonly": "Tenê beşdariyên jêbirî nîşan bide.",
        "apihelp-feedrecentchanges-example-simple": "Guherandinên dawî nîşan bide.",
        "apihelp-feedrecentchanges-example-30days": "Guherandinên dawî yên 30 rojan nîşan bide",
+       "apihelp-filerevert-param-comment": "Şîroveyê bar bike.",
        "apihelp-help-example-recursive": "Hemû alîkarî di rûpelekê de.",
        "apihelp-login-param-name": "Navê bikarhêner.",
        "apihelp-login-param-password": "Şîfre.",
        "apihelp-login-example-login": "Têkeve.",
        "apihelp-move-param-reason": "Sedemê bo guherandina nav.",
        "apihelp-move-param-ignorewarnings": "Guh nede hişyariyan.",
+       "apihelp-opensearch-example-te": "Rûpelên ku bi <kbd>Te</kbd> dest pê dikin bibîne.",
+       "apihelp-parse-example-page": "Rûpelekê analîz bike.",
+       "apihelp-parse-example-summary": "Kurteyekê analîz bike",
+       "apihelp-protect-description": "Asta parastinê ya rûpelekê biguherîne.",
+       "apihelp-protect-example-protect": "Rûpelekê biparêze.",
        "apihelp-tag-param-reason": "Sedemê bo guherandinê."
 }
index 97de05f..8240e08 100644 (file)
        "apihelp-parse-example-text": "Расчлени викитекст.",
        "apihelp-parse-example-texttitle": "Расчлени страница, укажувајќи го насловот на страницата.",
        "apihelp-parse-example-summary": "Расчлени опис.",
-       "apihelp-patrol-description": "Испатролирај страница или ревизија.",
+       "apihelp-patrol-description": "Испатролирај страница или преработка.",
        "apihelp-patrol-param-rcid": "Назнака на спорешните промени за патролирање.",
        "apihelp-patrol-param-revid": "Назнака на преработката за патролирање.",
        "apihelp-patrol-example-rcid": "Испатролирај скорешна промена",
        "apihelp-upload-param-offset": "Зафатнина на делот во бајти.",
        "apihelp-upload-param-chunk": "Содржина на делот.",
        "apihelp-upload-param-async": "Направи ги работите со потенцијално големи податотеки неусогласени, кога е можно.",
-       "apihelp-upload-param-asyncdownload": "Направи го добивањето на URL-адреса неусогласено.",
-       "apihelp-upload-param-leavemessage": "Ако се користи неусогласено преземање, остави порака на страницата за разговор на корисникот ако е готово.",
-       "apihelp-upload-param-statuskey": "Дај ја состојбата на подигнатост за овој податотечен клуч (подигање по URL).",
        "apihelp-upload-param-checkstatus": "Дај ја состојбата на подигнатост само за дадениот податотечен клуч.",
        "apihelp-upload-example-url": "Подигни од URL",
        "apihelp-userrights-param-user": "Корисничко име.",
        "apihelp-watch-example-unwatch": "Отстрани ја страницата <kbd>Главна страница</kbd> од набљудуваните.",
        "apihelp-watch-example-generator": "Набљудувај ги првите неколку страници во главниот именски простор",
        "apihelp-format-example-generic": "Дај го исходот од барањето во $1-формат.",
-       "apihelp-dbg-description": "Давај го изводот во PHP-форматот <code>var_export()</code> .",
-       "apihelp-dbgfm-description": "Давај го изводот во PHP-форматот <code>var_export()</code> (подобрен испис во HTML).",
        "apihelp-json-description": "Давај го изводот во JSON-формат.",
        "apihelp-json-param-callback": "Ако е укажано, го обвива изводот во даден повик на функција. За безбедност, ќе се ограничат сите податоци што се однесуваат на корисниците.",
        "apihelp-json-param-utf8": "Ако е укажано, ги шифрира највеќето (но не сите) не-ASCII знаци како UTF-8 наместо да ги заменува со хексадецимални изводни низи. Ова е стандардно кога <var>formatversion</var> не е <kbd>1</kbd>.",
        "apihelp-php-param-formatversion": "Форматирање на изводот:\n;1:Назадно-складен формат (булови во XML-стил, клучеви <samp>*</samp> за содржински јазли и тн.).\n;2:Пробен современ формат. Поединостите може да се изменат!\n;најнов:Користење на најновиот формат (тековно <kbd>2</kbd>), може да се смени без предупредување.",
        "apihelp-phpfm-description": "Давај го изводот во серијализиран PHP-формат (подобрен испис во HTML).",
        "apihelp-rawfm-description": "Давај го изводот со елементи за отстранување грешки во JSON-формат (подобрен испис во HTML).",
-       "apihelp-txt-description": "Давај го изводот во PHP-форматот <code>print_r()</code>.",
-       "apihelp-txtfm-description": "Давај го изводот во PHP-форматот <code>print_r()</code> (подобрен испис во HTML).",
        "apihelp-xml-description": "Давај го изводот во XML-формат.",
        "apihelp-xml-param-xslt": "Ако е укажано, ја додава именуваната страница како XSL-стилска страница. Вредноста мора да биде наслов во именскиот простор „{{ns:mediawiki}}“ што ќе завршува со <code>.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "Ако е укажано, додава именски простор XML.",
        "apihelp-xmlfm-description": "Давај го изводот во XML-формат (подобрен испис во HTML).",
-       "apihelp-yaml-description": "Давај го изводот во YAML-формат.",
-       "apihelp-yamlfm-description": "Давај го изводот во YAML-формат (подобрен испис во HTML).",
        "api-format-title": "Резултат од Извршникот на МедијаВики",
        "api-format-prettyprint-header": "Ова е HTML-претстава на форматот $1. HTML е добар за отстранување на грешки, но не е погоден за употреба во извршник.\n\nУкажете го параметарот <var>format</var> за да го смените изводниот формат. За да ги видите претставите на форматот $1 вон HTML, задајте <kbd>format=$2</kbd>.\n\nПовеќе информации ќе најдете на [[mw:API|целосната документација]], или пак [[Special:ApiHelp/main|помош со извршникот]].",
-       "api-orm-param-props": "Полиња за пребарување.",
-       "api-orm-param-limit": "Макс. број на редови во изводот.",
        "api-pageset-param-titles": "Список на наслови на кои ќе се работи",
        "api-pageset-param-pageids": "Список на назнаки за страници на кои ќе се работи",
        "api-pageset-param-revids": "Список на назнаки на преработки на кои ќе се работи",
index 0c9f12f..a9b9099 100644 (file)
        "apihelp-main-param-curtimestamp": "Dołącz obecny znacznik czasu do wyniku.",
        "apihelp-block-description": "Zablokuj użytkownika.",
        "apihelp-block-param-user": "Nazwa użytkownika, adres IP lub zakres adresów IP, które chcesz zablokować.",
+       "apihelp-block-param-expiry": "Czas trwania. Może być względny (np. <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) lub konkretny (np. <kbd>2014-09-18T12:34:56Z</kbd>). Jeśli jest ustawiony na <kbd>infinite</kbd>, <kbd>indefinite</kbd>, lub <kbd>never</kbd>, blokada nigdy nie wygaśnie.",
        "apihelp-block-param-reason": "Powód blokady.",
        "apihelp-block-param-anononly": "Blokuj tylko anonimowych użytkowników (blokuje anonimowe edycje z tego adresu IP).",
        "apihelp-block-param-nocreate": "Zapobiegnij utworzeniu konta.",
        "apihelp-block-param-autoblock": "Zablokuj ostatni adres IP tego użytkownika i automatycznie wszystkie kolejne, z których będzie się logował.",
+       "apihelp-block-param-noemail": "Uniemożliwia użytkownikowi wysyłanie wiadomości e-mail za pośrednictwem interfejsu wiki. (Wymagane uprawnienie <code>blockemail</code>).",
        "apihelp-block-param-hidename": "Ukryj nazwę użytkownika z rejestru blokad. (Wymagane uprawnienia <code>hideuser</code>)",
+       "apihelp-block-param-allowusertalk": "Pozwala użytkownikowi edytować własną stronę dyskusji (zależy od <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Jeżeli ten użytkownik jest już zablokowany, nadpisz blokadę.",
        "apihelp-block-param-watchuser": "Obserwuj stronę użytkownika i jego IP oraz ich strony dyskusji.",
        "apihelp-block-example-ip-simple": "Zablokuj IP <kbd>192.0.2.5</kbd> na 3 dni za <kbd>Pierwszy atak</kbd>.",
        "api-help-param-multi-max": "Maksymalna liczba wartości to {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} dla botów).",
        "api-help-param-default": "Domyślnie: $1",
        "api-help-param-default-empty": "Domyślnie: <span class=\"apihelp-empty\">(puste)</span>",
+       "api-help-param-token": "Token \"$1\" zdobyty z [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(bez opisu)</span>",
        "api-help-examples": "{{PLURAL:$1|Przykład|Przykłady}}:",
        "api-help-permissions": "{{PLURAL:$2|Uprawnienie|Uprawnienia}}:",
index 14e32ba..246b05c 100644 (file)
        "apihelp-managetags-example-delete": "Radera <kbd>vandalims</kbd> taggen med andledningen: <kbd>Felstavat</kbd>",
        "apihelp-managetags-example-activate": "Aktivera en tagg med namn <kbd>spam</kbd> med anledningen: <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-deactivate": "Inaktivera en tagg vid namn <kbd>spam</kbd> med anledningen: <kbd>No longer required</kbd>",
+       "apihelp-mergehistory-description": "Sammanfoga sidhistoriker.",
+       "apihelp-mergehistory-param-reason": "Orsaken till sammanfogning av historik.",
+       "apihelp-mergehistory-example-merge": "Sammanfoga hela historiken för <kbd>Oldpage</kbd> i <kbd>Newpage</kbd>.",
+       "apihelp-mergehistory-example-merge-timestamp": "Sammanfoga den sidversion av <kbd>Oldpage</kbd> daterad fram till <kbd>2015-12-31T04:37:41Z</kbd> till <kbd>Newpage</kbd>.",
        "apihelp-move-description": "Flytta en sida.",
        "apihelp-move-param-from": "Titeln på sidan du vill flytta. Kan inte användas tillsammans med <var>$1fromid</var>.",
        "apihelp-move-param-fromid": "Sid-ID för sidan att byta namn. Kan inte användas tillsammans med <var>$1from</var>.",
index 6e2ff5a..4a4989f 100644 (file)
@@ -15,6 +15,8 @@
        "apihelp-block-param-reason": "Lý do cấm.",
        "apihelp-block-param-nocreate": "Cấm tạo tài khoản.",
        "apihelp-block-param-reblock": "Nếu người dùng này đã bị cấm, ghi đè lên vụ cấm đã tồn tại.",
+       "apihelp-block-param-watchuser": "Xem người dùng hoặc địa chỉ IP của người dùng và trang thảo luận.",
+       "apihelp-block-example-ip-simple": "Khóa địa chỉ IP <kbd>192.0.2.5</kbd> trong ba ngày với lý do <kbd>khiển trách lần đầu</kbd>.",
        "apihelp-checktoken-param-type": "Kiểu dấu hiệu được kiểm thử.",
        "apihelp-checktoken-param-token": "Dấu hiệu để kiểm thử.",
        "apihelp-checktoken-example-simple": "Kiểm thử dấu hiệu <kbd>csrf</kbd> có hợp lệ hay không.",
@@ -62,6 +64,7 @@
        "apihelp-edit-param-undo": "Hoàn tác sửa đổi này. Ghi đè $1text, $1prependtext và $ 1appendtext.",
        "apihelp-edit-param-undoafter": "Hoàn tác tất cả các sửa đổi từ $1undo cho tới sửa đổi này. Nếu không được thiết lập, chỉ cần lùi lại một sửa đổi.",
        "apihelp-edit-param-redirect": "Tự động giải quyết các chuyển hướng.",
+       "apihelp-edit-param-contentmodel": "Mô hình nội dung của nội dung mới.",
        "apihelp-edit-example-edit": "Sửa đổi trang",
        "apihelp-edit-example-prepend": "Đưa <kbd>_&#95;NOTOC_&#95;</kbd> vào đầu trang",
        "apihelp-edit-example-undo": "Lùi sửa các thay đổi 13579–13585 và tự động tóm lược",
        "apihelp-login-param-token": "Dấu hiệu đăng nhập được lấy trong yêu cầu đầu tiên.",
        "apihelp-login-example-gettoken": "Lấy dấu hiệu đăng nhập",
        "apihelp-login-example-login": "Đăng nhập",
+       "apihelp-logout-description": "Thoát ra và xóa dữ liệu phiên làm việc.",
        "apihelp-logout-example-logout": "Đăng xuất người dùng hiện tại",
        "apihelp-mergehistory-description": "Hợp nhất lịch sử trang.",
        "apihelp-mergehistory-param-reason": "Lý do hợp nhất lịch sử.",
        "apihelp-move-description": "Di chuyển trang.",
+       "apihelp-move-param-to": "Đặt tiêu đề để đổi tên trang.",
        "apihelp-move-param-reason": "Lý do đổi tên.",
+       "apihelp-move-param-movetalk": "Đổi tên trang thảo luận, nếu nó tồn tại.",
        "apihelp-move-param-movesubpages": "Đổi tên trang con, nếu có thể áp dụng.",
        "apihelp-move-param-noredirect": "Không tạo trang đổi hướng.",
        "apihelp-move-param-ignorewarnings": "Bỏ qua tất cả các cảnh báo.",
        "apihelp-opensearch-param-search": "Chuỗi tìm kiếm.",
        "apihelp-opensearch-param-limit": "Đa số kết quả để cho ra.",
        "apihelp-opensearch-param-namespace": "Không gian tên để tìm kiếm.",
+       "apihelp-opensearch-param-suggest": "Không làm gì nếu <var> [[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> sai/lỗi.",
        "apihelp-opensearch-param-format": "Định dạng kết quả được cho ra.",
        "apihelp-opensearch-example-te": "Tìm trang bắt đầu với <kbd>Te</kbd>.",
        "apihelp-options-example-reset": "Mặc định lại các tùy chọn",
        "apihelp-paraminfo-description": "Lấy thông tin về các module API.",
        "apihelp-paraminfo-param-helpformat": "Định dạng chuỗi trợ giúp.",
        "apihelp-parse-param-summary": "Lời tóm lược để phân tích.",
+       "apihelp-parse-param-prop": "Những mẩu thông tin nào muốn có:",
        "apihelp-parse-param-section": "Chỉ phân tích nội dung của số phần này.\n\nNếu có <kbd>new</kbd> thì phân tích <var>$1text</var> và <var>$1sectiontitle</var> như thể thêm phần mới vào trang.\n\nPhần <kbd>new</kbd> chỉ được chấp nhận khi định rõ <var>text</var>.",
        "apihelp-parse-param-disablelimitreport": "Bỏ qua thông báo bộ tiền xử lý (“NewPP limit report”) khi cho ra kết quả bộ xử lý.",
        "apihelp-parse-example-page": "Phân tích trang.",
        "apihelp-query-param-prop": "Các thuộc tính để lấy khi truy vấn các trang.",
        "apihelp-query-param-list": "Các danh sách để lấy.",
        "apihelp-query-param-meta": "Siêu dữ liệu để lấy.",
+       "apihelp-query+allcategories-description": "Liệt kê tất cả các thể loại.",
+       "apihelp-query+allcategories-param-from": "Chọn thể loại để bắt đầu đếm.",
+       "apihelp-query+allcategories-param-to": "Chọn thể loại để dừng đếm.",
        "apihelp-query+allcategories-param-dir": "Hướng xếp loại.",
+       "apihelp-query+allcategories-param-limit": "Có bao nhiêu thể loại được trả về.",
+       "apihelp-query+allfileusages-param-limit": "Có bao nhiêu số hạng mục được trả về.",
+       "apihelp-query+allimages-param-limit": "Có bao nhiêu hình ảnh trong tổng số được trả về.",
+       "apihelp-query+alllinks-param-limit": "Có bao nhiêu số hạng mục được trả về.",
+       "apihelp-query+allpages-param-limit": "Có bao nhiêu trang được trả về.",
+       "apihelp-query+allredirects-param-limit": "Có bao nhiêu số hạng mục được trả về.",
+       "apihelp-query+mystashedfiles-param-limit": "Có bao nhiêu tập tin nhận được.",
+       "apihelp-query+alltransclusions-param-limit": "Có bao nhiêu số hạng mục được trả về.",
+       "apihelp-query+allusers-param-limit": "Có bao nhiêu tên người dùng được trả về.",
+       "apihelp-query+backlinks-param-limit": "Tất cả có bao nhiêu trang trả về. Nếu <var>$1redirect</var> được kích hoạt, giới hạn áp dụng cho mỗi cấp độ riêng biệt (có nghĩa là lên đến 2*<var>$1limit</var> kết quả có thể được trả lại).",
+       "apihelp-query+categories-param-limit": "Có bao nhiêu thể loại được trả về.",
+       "apihelp-query+extlinks-param-limit": "Có bao nhiêu liên kết được trả về.",
+       "apihelp-query+exturlusage-param-limit": "Có bao nhiêu trang được trả về.",
+       "apihelp-query+filearchive-param-limit": "Tổng cộng có bao nhiêu hình ảnh được trả về.",
+       "apihelp-query+fileusage-param-limit": "Có bao nhiêu được trả về.",
+       "apihelp-query+images-param-limit": "Có bao nhiêu tập tin được trả về.",
+       "apihelp-query+langbacklinks-param-limit": "Tổng cộng có bao nhiêu trang được trả về.",
+       "apihelp-query+links-param-limit": "Có bao nhiêu liên kết được trả về.",
+       "apihelp-query+linkshere-param-limit": "Có bao nhiêu được trả về.",
+       "apihelp-query+logevents-param-limit": "Tổng cộng có bao nhiêu bài viết sự kiện được trả về.",
+       "apihelp-query+transcludedin-param-limit": "Có bao nhiêu được trả về.",
+       "apihelp-query+watchlist-param-limit": "Cả bao nhiêu kết quả được trả về trên mỗi yêu cầu.",
        "apihelp-rollback-description": "Lùi lại sửa đổi cuối cùng của trang này.\n\nNếu người dùng cuối cùng đã sửa đổi trang này nhiều lần, tất cả chúng sẽ được lùi lại cùng một lúc.",
        "apihelp-format-example-generic": "Cho ra kết quả truy vấn dưới dạng $1.",
        "apihelp-json-description": "Cho ra dữ liệu dưới dạng JSON.",
index c3ea00a..71daba7 100644 (file)
        "apihelp-mergehistory-param-fromid": "将被合并历史的页面的页面ID。不能与<var>$1from</var>一起使用。",
        "apihelp-mergehistory-param-to": "将要合并历史的页面的标题。不能与<var>$1toid</var>一起使用。",
        "apihelp-mergehistory-param-toid": "将要合并历史的页面的页面ID。不能与<var>$1to</var>一起使用。",
+       "apihelp-mergehistory-param-timestamp": "指定时间戳,决定源页面的哪些修订历史被移动到目标页面的历史中。如果省略,源页面的所有历史记录都将被合并到目标页面。",
        "apihelp-mergehistory-param-reason": "历史合并的原因。",
        "apihelp-mergehistory-example-merge": "将<kbd>Oldpage</kbd>的完整历史合并至<kbd>Newpage</kbd>。",
        "apihelp-mergehistory-example-merge-timestamp": "将<kbd>Oldpage</kbd>直到<kbd>2015-12-31T04:37:41Z</kbd>的页面修订版本合并至<kbd>Newpage</kbd>。",
        "apihelp-query+pageswithprop-param-dir": "排序的方向。",
        "apihelp-query+pageswithprop-example-simple": "列出前10个使用<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>的页面。",
        "apihelp-query+pageswithprop-example-generator": "获取有关前10个使用<code>_&#95;NOTOC_&#95;</code>的页面的额外信息。",
-       "apihelp-query+prefixsearch-description": "为页面标题执行前缀搜索。\n\nDespite the similarity in names, this module is not intended to be equivalent to [[Special:PrefixIndex]]; for that, see <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> with the <kbd>apprefix</kbd> parameter. The purpose of this module is similar to <kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd>: to take user input and provide the best-matching titles. Depending on the search engine backend, this might include typo correction, redirect avoidance, or other heuristics.",
+       "apihelp-query+prefixsearch-description": "执行页面标题的带前缀搜索。\n\n尽管名称类似,但此模块不等于[[Special:PrefixIndex]];详见<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>中的<kbd>apprefix</kbd>参数。此模块的目的类似<kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd>:基于用户的输入提供最佳匹配的标题。取决于搜索引擎后端,这可能包括错拼纠正、避免重定向和其他启发性行为。",
        "apihelp-query+prefixsearch-param-search": "搜索字符串。",
        "apihelp-query+prefixsearch-param-namespace": "搜索的名字空间。",
        "apihelp-query+prefixsearch-param-limit": "要返回的结果最大数。",
        "apihelp-upload-param-sessionkey": "与$1filekey相同,基于向后兼容而维护。",
        "apihelp-upload-param-stash": "如果设置,服务器将临时藏匿文件而不是加入存储库。",
        "apihelp-upload-param-filesize": "全部上传的文件大小。",
-       "apihelp-upload-param-offset": "块的偏移量(字节)。",
+       "apihelp-upload-param-offset": "数据块的偏移量(字节)。",
        "apihelp-upload-param-chunk": "大块内容。",
        "apihelp-upload-param-async": "在可能的情况下,使潜在的大文件操作异步进行。",
        "apihelp-upload-param-checkstatus": "只检索指定文件密钥的上传状态。",
index 19695df..80f04ce 100644 (file)
@@ -21,6 +21,7 @@
  * @author Niklas Laxström
  * @ingroup Cache
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Caches user genders when needed to use correct namespace aliases.
@@ -34,18 +35,11 @@ class GenderCache {
        protected $missLimit = 1000;
 
        /**
+        * @deprecated in 1.28 see MediaWikiServices::getInstance()->getGenderCache()
         * @return GenderCache
         */
        public static function singleton() {
-               static $that = null;
-               if ( $that === null ) {
-                       $that = new self();
-               }
-
-               return $that;
-       }
-
-       protected function __construct() {
+               return MediaWikiServices::getInstance()->getGenderCache();
        }
 
        /**
index 8a79bd8..b8f2329 100644 (file)
@@ -58,7 +58,7 @@ class LinkCache {
         *
         * @return LinkCache
         */
-       public static function &singleton() {
+       public static function singleton() {
                if ( !self::$instance ) {
                        self::$instance = new LinkCache;
                }
@@ -105,7 +105,7 @@ class LinkCache {
        }
 
        /**
-        * @param string $title
+        * @param string $title Prefixed DB key
         * @return int Page ID or zero
         */
        public function getGoodLinkID( $title ) {
@@ -123,7 +123,7 @@ class LinkCache {
         * @param string $field ('length','redirect','revision','model')
         * @return string|int|null
         */
-       public function getGoodLinkFieldObj( $title, $field ) {
+       public function getGoodLinkFieldObj( Title $title, $field ) {
                $dbkey = $title->getPrefixedDBkey();
                $info = $this->mGoodLinks->get( $dbkey );
                if ( !$info ) {
@@ -133,7 +133,7 @@ class LinkCache {
        }
 
        /**
-        * @param string $title
+        * @param string $title Prefixed DB key
         * @return bool
         */
        public function isBadLink( $title ) {
@@ -195,14 +195,17 @@ class LinkCache {
                }
        }
 
+       /**
+        * @param string $title Prefixed DB key
+        */
        public function clearBadLink( $title ) {
-               $this->mBadLinks->clear( [ $title ] );
+               $this->mBadLinks->delete( $title );
        }
 
        /**
         * @param Title $title
         */
-       public function clearLink( $title ) {
+       public function clearLink( Title $title ) {
                $dbkey = $title->getPrefixedDBkey();
                $this->mBadLinks->delete( $dbkey );
                $this->mGoodLinks->delete( $dbkey );
@@ -211,7 +214,7 @@ class LinkCache {
        /**
         * Add a title to the link cache, return the page_id or zero if non-existent
         *
-        * @param string $title Title to add
+        * @param string $title Prefixed DB key
         * @return int Page ID or zero
         */
        public function addLink( $title ) {
index a808516..1070877 100644 (file)
@@ -262,6 +262,7 @@ class EnhancedChangesList extends ChangesList {
                        if ( !$line ) {
                                // completely ignore this RC entry if we don't want to render it
                                unset( $block[$i] );
+                               continue;
                        }
 
                        // Roll up flags
@@ -286,6 +287,7 @@ class EnhancedChangesList extends ChangesList {
 
                        $lines[] = $line;
                }
+
                // Further down are some assumptions that $block is a 0-indexed array
                // with (count-1) as last key. Let's make sure it is.
                $block = array_values( $block );
index 9db1697..2d4d20f 100644 (file)
@@ -1134,7 +1134,7 @@ class ChangeTags {
        public static function listExtensionActivatedTags() {
                return ObjectCache::getMainWANInstance()->getWithSetCallback(
                        wfMemcKey( 'active-tags' ),
-                       300,
+                       WANObjectCache::TTL_MINUTE * 5,
                        function ( $oldValue, &$ttl, array &$setOpts ) {
                                $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
 
@@ -1145,8 +1145,8 @@ class ChangeTags {
                        },
                        [
                                'checkKeys' => [ wfMemcKey( 'active-tags' ) ],
-                               'lockTSE' => 300,
-                               'pcTTL' => 30
+                               'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
+                               'pcTTL' => WANObjectCache::TTL_PROC_LONG
                        ]
                );
        }
@@ -1179,7 +1179,7 @@ class ChangeTags {
 
                return ObjectCache::getMainWANInstance()->getWithSetCallback(
                        wfMemcKey( 'valid-tags-db' ),
-                       300,
+                       WANObjectCache::TTL_MINUTE * 5,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
                                $dbr = wfGetDB( DB_SLAVE );
 
@@ -1191,8 +1191,8 @@ class ChangeTags {
                        },
                        [
                                'checkKeys' => [ wfMemcKey( 'valid-tags-db' ) ],
-                               'lockTSE' => 300,
-                               'pcTTL' => 30
+                               'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
+                               'pcTTL' => WANObjectCache::TTL_PROC_LONG
                        ]
                );
        }
@@ -1209,7 +1209,7 @@ class ChangeTags {
        public static function listExtensionDefinedTags() {
                return ObjectCache::getMainWANInstance()->getWithSetCallback(
                        wfMemcKey( 'valid-tags-hook' ),
-                       300,
+                       WANObjectCache::TTL_MINUTE * 5,
                        function ( $oldValue, &$ttl, array &$setOpts ) {
                                $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
 
@@ -1219,8 +1219,8 @@ class ChangeTags {
                        },
                        [
                                'checkKeys' => [ wfMemcKey( 'valid-tags-hook' ) ],
-                               'lockTSE' => 300,
-                               'pcTTL' => 30
+                               'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
+                               'pcTTL' => WANObjectCache::TTL_PROC_LONG
                        ]
                );
        }
@@ -1264,7 +1264,7 @@ class ChangeTags {
                $fname = __METHOD__;
                return ObjectCache::getMainWANInstance()->getWithSetCallback(
                        wfMemcKey( 'change-tag-statistics' ),
-                       300,
+                       WANObjectCache::TTL_MINUTE * 5,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
                                $dbr = wfGetDB( DB_SLAVE, 'vslow' );
 
@@ -1287,8 +1287,8 @@ class ChangeTags {
                        },
                        [
                                'checkKeys' => [ wfMemcKey( 'change-tag-statistics' ) ],
-                               'lockTSE' => 300,
-                               'pcTTL' => 30
+                               'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
+                               'pcTTL' => WANObjectCache::TTL_PROC_LONG
                        ]
                );
        }
index 942036b..a374b13 100644 (file)
@@ -234,32 +234,33 @@ class IcuCollation extends Collation {
 
        /**
         * @since 1.16.3
+        * @return array
         */
        public function getFirstLetterData() {
-               if ( $this->firstLetterData !== null ) {
-                       return $this->firstLetterData;
-               }
-
-               $cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
-               $cacheKey = $cache->makeKey(
-                       'first-letters',
-                       $this->locale,
-                       $this->digitTransformLanguage->getCode(),
-                       self::getICUVersion()
-               );
-               $cacheEntry = $cache->get( $cacheKey );
-
-               if ( $cacheEntry && isset( $cacheEntry['version'] )
-                       && $cacheEntry['version'] == self::FIRST_LETTER_VERSION
-               ) {
-                       $this->firstLetterData = $cacheEntry;
-                       return $this->firstLetterData;
+               if ( $this->firstLetterData === null ) {
+                       $cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
+                       $cacheKey = $cache->makeKey(
+                               'first-letters',
+                               $this->locale,
+                               $this->digitTransformLanguage->getCode(),
+                               self::getICUVersion(),
+                               self::FIRST_LETTER_VERSION
+                       );
+                       $this->firstLetterData = $cache->getWithSetCallback( $cacheKey, $cache::TTL_WEEK, function () {
+                               return $this->fetchFirstLetterData();
+                       } );
                }
+               return $this->firstLetterData;
+       }
 
+       /**
+        * @return array
+        * @throws MWException
+        */
+       private function fetchFirstLetterData() {
                // Generate data from serialized data file
-
                if ( isset( self::$tailoringFirstLetters[$this->locale] ) ) {
-                       $letters = wfGetPrecompiledData( "first-letters-root.ser" );
+                       $letters = wfGetPrecompiledData( 'first-letters-root.ser' );
                        // Append additional characters
                        $letters = array_merge( $letters, self::$tailoringFirstLetters[$this->locale] );
                        // Remove unnecessary ones, if any
@@ -374,15 +375,11 @@ class IcuCollation extends Collation {
                $data = [
                        'chars' => array_values( $letterMap ),
                        'keys' => array_keys( $letterMap ),
-                       'version' => self::FIRST_LETTER_VERSION,
                ];
 
                // Reduce memory usage before caching
                unset( $letterMap );
 
-               // Save to cache
-               $this->firstLetterData = $data;
-               $cache->set( $cacheKey, $data, $cache::TTL_WEEK );
                return $data;
        }
 
@@ -390,30 +387,21 @@ class IcuCollation extends Collation {
         * @since 1.16.3
         */
        public function getLetterByIndex( $index ) {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return $this->firstLetterData['chars'][$index];
+               return $this->getFirstLetterData()['chars'][$index];
        }
 
        /**
         * @since 1.16.3
         */
        public function getSortKeyByLetterIndex( $index ) {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return $this->firstLetterData['keys'][$index];
+               return $this->getFirstLetterData()['keys'][$index];
        }
 
        /**
         * @since 1.16.3
         */
        public function getFirstLetterCount() {
-               if ( $this->firstLetterData === null ) {
-                       $this->getFirstLetterData();
-               }
-               return count( $this->firstLetterData['chars'] );
+               return count( $this->getFirstLetterData()['chars'] );
        }
 
        /**
index 0bc8d0f..8791e4c 100644 (file)
@@ -30,8 +30,8 @@ use UtfNormal\Utils;
 /**
  * Return UTF-8 sequence for a given Unicode code point.
  *
- * @param $codepoint Integer:
- * @return String
+ * @param int $codepoint
+ * @return string
  * @throws InvalidArgumentException if fed out of range data.
  * @public
  * @deprecated since 1.25, use UtfNormal\Utils directly
@@ -45,8 +45,8 @@ function codepointToUtf8( $codepoint ) {
  * Unicode code points and return a UTF-8 string composed of those
  * characters. Used by UTF-8 data generation and testing routines.
  *
- * @param $sequence String
- * @return String
+ * @param string $sequence
+ * @return string
  * @throws InvalidArgumentException if fed out of range data.
  * @private
  * @deprecated since 1.25, use UtfNormal\Utils directly
@@ -77,8 +77,8 @@ function utf8ToHexSequence( $str ) {
  * Determine the Unicode codepoint of a single-character UTF-8 sequence.
  * Does not check for invalid input data.
  *
- * @param $char String
- * @return Integer
+ * @param string $char
+ * @return int
  * @public
  * @deprecated since 1.25, use UtfNormal\Utils directly
  */
index 20290ef..9f60394 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 
 use Composer\Package\Link;
-use Composer\Package\LinkConstraint\VersionConstraint;
 use Composer\Package\Package;
+use Composer\Semver\Constraint\Constraint;
 
 /**
  * @licence GNU GPL v2+
@@ -50,7 +50,7 @@ class ComposerPackageModifier {
                $mvVersion = $this->versionFetcher->fetchVersion();
                $mvVersion = $this->versionNormalizer->normalizeSuffix( $mvVersion );
 
-               $version = new VersionConstraint(
+               $version = new Constraint(
                        '==',
                        $this->versionNormalizer->normalizeLevelCount( $mvVersion )
                );
index 4b803d8..09b0baa 100644 (file)
@@ -51,16 +51,39 @@ class ConfigFactory {
        }
 
        /**
-        * Register a new config factory function
-        * Will override if it's already registered
+        * @return string[]
+        */
+       public function getConfigNames() {
+               return array_keys( $this->factoryFunctions );
+       }
+
+       /**
+        * Register a new config factory function.
+        * Will override if it's already registered.
+        * Use "*" for $name to provide a fallback config for all unknown names.
         * @param string $name
-        * @param callable $callback That takes this ConfigFactory as an argument
+        * @param callable|Config $callback A factory callabck that takes this ConfigFactory
+        *        as an argument and returns a Config instance, or an existing Config instance.
         * @throws InvalidArgumentException If an invalid callback is provided
         */
        public function register( $name, $callback ) {
+               if ( $callback instanceof Config ) {
+                       $instance = $callback;
+
+                       // Register a callback anyway, for consistency. Note that getConfigNames()
+                       // relies on $factoryFunctions to have all config names.
+                       $callback = function() use ( $instance ) {
+                               return $instance;
+                       };
+               } else {
+                       $instance = null;
+               }
+
                if ( !is_callable( $callback ) ) {
                        throw new InvalidArgumentException( 'Invalid callback provided' );
                }
+
+               $this->configs[$name] = $instance;
                $this->factoryFunctions[$name] = $callback;
        }
 
@@ -75,10 +98,14 @@ class ConfigFactory {
         */
        public function makeConfig( $name ) {
                if ( !isset( $this->configs[$name] ) ) {
-                       if ( !isset( $this->factoryFunctions[$name] ) ) {
+                       $key = $name;
+                       if ( !isset( $this->factoryFunctions[$key] ) ) {
+                               $key = '*';
+                       }
+                       if ( !isset( $this->factoryFunctions[$key] ) ) {
                                throw new ConfigException( "No registered builder available for $name." );
                        }
-                       $conf = call_user_func( $this->factoryFunctions[$name], $this );
+                       $conf = call_user_func( $this->factoryFunctions[$key], $this );
                        if ( $conf instanceof Config ) {
                                $this->configs[$name] = $conf;
                        } else {
@@ -88,4 +115,5 @@ class ConfigFactory {
 
                return $this->configs[$name];
        }
+
 }
index 7430caf..f3d6781 100644 (file)
@@ -892,7 +892,7 @@ abstract class ContentHandler {
         * have it / want it.
         */
        public function getAutoDeleteReason( Title $title, &$hasHistory ) {
-               $dbw = wfGetDB( DB_MASTER );
+               $dbr = wfGetDB( DB_SLAVE );
 
                // Get the last revision
                $rev = Revision::newFromTitle( $title );
@@ -922,10 +922,10 @@ abstract class ContentHandler {
 
                // Find out if there was only one contributor
                // Only scan the last 20 revisions
-               $res = $dbw->select( 'revision', 'rev_user_text',
+               $res = $dbr->select( 'revision', 'rev_user_text',
                        [
                                'rev_page' => $title->getArticleID(),
-                               $dbw->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
+                               $dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
                        ],
                        __METHOD__,
                        [ 'LIMIT' => 20 ]
@@ -937,7 +937,7 @@ abstract class ContentHandler {
                }
 
                $hasHistory = ( $res->numRows() > 1 );
-               $row = $dbw->fetchObject( $res );
+               $row = $dbr->fetchObject( $res );
 
                if ( $row ) { // $row is false if the only contributor is hidden
                        $onlyAuthor = $row->rev_user_text;
index c36cfdb..92e89b0 100644 (file)
@@ -1847,7 +1847,7 @@ abstract class DatabaseBase implements IDatabase {
                if ( !$alias || (string)$alias === (string)$name ) {
                        return $name;
                } else {
-                       return $name . ' AS ' . $alias; // PostgreSQL needs AS
+                       return $name . ' AS ' . $this->addIdentifierQuotes( $alias ); // PostgreSQL needs AS
                }
        }
 
@@ -2589,17 +2589,13 @@ abstract class DatabaseBase implements IDatabase {
                        } elseif ( !$this->mTrxAutomatic ) {
                                // We want to warn about inadvertently nested begin/commit pairs, but not about
                                // auto-committing implicit transactions that were started by query() via DBO_TRX
-                               $msg = "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
-                                       " performing implicit commit!";
-                               wfWarn( $msg );
-                               wfLogDBError( $msg,
-                                       $this->getLogContext( [
-                                               'method' => __METHOD__,
-                                               'fname' => $fname,
-                                       ] )
+                               throw new DBUnexpectedError(
+                                       $this,
+                                       "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
+                                               " performing implicit commit!"
                                );
                        } else {
-                               // if the transaction was automatic and has done write operations
+                               // The transaction was automatic and has done write operations
                                if ( $this->mTrxDoneWrites ) {
                                        wfDebug( "$fname: Automatic transaction with writes in progress" .
                                                " (from {$this->mTrxFname}), performing implicit commit!\n"
index 5c46c1a..33f8162 100644 (file)
@@ -38,6 +38,7 @@ class DatabaseMssql extends Database {
        protected $mBinaryColumnCache = null;
        protected $mBitColumnCache = null;
        protected $mIgnoreDupKeyErrors = false;
+       protected $mIgnoreErrors = [];
 
        protected $mPort;
 
@@ -206,35 +207,31 @@ class DatabaseMssql extends Database {
                        $success = (bool)$stmt;
                }
 
+               // make a copy so that anything we add below does not get reflected in future queries
+               $ignoreErrors = $this->mIgnoreErrors;
+
                if ( $this->mIgnoreDupKeyErrors ) {
-                       // ignore duplicate key errors, but nothing else
+                       // ignore duplicate key errors
                        // this emulates INSERT IGNORE in MySQL
-                       if ( $success === false ) {
-                               $errors = sqlsrv_errors( SQLSRV_ERR_ERRORS );
-                               $success = true;
-
-                               foreach ( $errors as $err ) {
-                                       if ( $err['SQLSTATE'] == '23000' && $err['code'] == '2601' ) {
-                                               continue; // duplicate key error caused by unique index
-                                       } elseif ( $err['SQLSTATE'] == '23000' && $err['code'] == '2627' ) {
-                                               continue; // duplicate key error caused by primary key
-                                       } elseif ( $err['SQLSTATE'] == '01000' && $err['code'] == '3621' ) {
-                                               continue; // generic "the statement has been terminated" error
-                                       }
+                       $ignoreErrors[] = '2601'; // duplicate key error caused by unique index
+                       $ignoreErrors[] = '2627'; // duplicate key error caused by primary key
+                       $ignoreErrors[] = '3621'; // generic "the statement has been terminated" error
+               }
 
-                                       $success = false; // getting here means we got an error we weren't expecting
-                                       break;
-                               }
+               if ( $success === false ) {
+                       $errors = sqlsrv_errors();
+                       $success = true;
 
-                               if ( $success ) {
-                                       $this->mAffectedRows = 0;
-                                       return $stmt;
+                       foreach ( $errors as $err ) {
+                               if ( !in_array( $err['code'], $ignoreErrors ) ) {
+                                       $success = false;
+                                       break;
                                }
                        }
-               }
 
-               if ( $success === false ) {
-                       return false;
+                       if ( $success === false ) {
+                               return false;
+                       }
                }
                // remember number of rows affected
                $this->mAffectedRows = sqlsrv_rows_affected( $stmt );
@@ -276,7 +273,15 @@ class DatabaseMssql extends Database {
                        $res = $res->result;
                }
 
-               return sqlsrv_num_rows( $res );
+               $ret = sqlsrv_num_rows( $res );
+
+               if ( $ret === false ) {
+                       // we cannot get an amount of rows from this cursor type
+                       // has_rows returns bool true/false if the result has rows
+                       $ret = (int)sqlsrv_has_rows( $res );
+               }
+
+               return $ret;
        }
 
        /**
@@ -536,8 +541,9 @@ class DatabaseMssql extends Database {
                # This does not return the same info as MYSQL would, but that's OK
                # because MediaWiki never uses the returned value except to check for
                # the existance of indexes.
-               $sql = "sp_helpindex '" . $table . "'";
+               $sql = "sp_helpindex '" . $this->tableName( $table ) . "'";
                $res = $this->query( $sql, $fname );
+
                if ( !$res ) {
                        return null;
                }
@@ -696,6 +702,12 @@ class DatabaseMssql extends Database {
                                $row = $ret->fetchObject();
                                if ( is_object( $row ) ) {
                                        $this->mInsertId = $row->$identity;
+
+                                       // it seems that mAffectedRows is -1 sometimes when OUTPUT INSERTED.identity is used
+                                       // if we got an identity back, we know for sure a row was affected, so adjust that here
+                                       if ( $this->mAffectedRows == -1 ) {
+                                               $this->mAffectedRows = 1;
+                                       }
                                }
                        }
                }
@@ -1351,6 +1363,24 @@ class DatabaseMssql extends Database {
                return $table;
        }
 
+       /**
+        * Delete a table
+        * @param string $tableName
+        * @param string $fName
+        * @return bool|ResultWrapper
+        * @since 1.18
+        */
+       public function dropTable( $tableName, $fName = __METHOD__ ) {
+               if ( !$this->tableExists( $tableName, $fName ) ) {
+                       return false;
+               }
+
+               // parent function incorrectly appends CASCADE, which we don't want
+               $sql = "DROP TABLE " . $this->tableName( $tableName );
+
+               return $this->query( $sql, $fName );
+       }
+
        /**
         * Called in the installer and updater.
         * Probably doesn't need to be called anywhere else in the codebase.
@@ -1370,6 +1400,16 @@ class DatabaseMssql extends Database {
        public function scrollableCursor( $value = null ) {
                return wfSetVar( $this->mScrollableCursor, $value );
        }
+
+       /**
+        * Called in the installer and updater.
+        * Probably doesn't need to be called anywhere else in the codebase.
+        * @param array|null $value
+        * @return array|null
+        */
+       public function ignoreErrors( array $value = null ) {
+               return wfSetVar( $this->mIgnoreErrors, $value );
+       }
 } // end DatabaseMssql class
 
 /**
index f39596b..b78793f 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Database
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Services\DestructibleService;
 use Psr\Log\LoggerInterface;
 use MediaWiki\Logger\LoggerFactory;
 
@@ -28,7 +30,8 @@ use MediaWiki\Logger\LoggerFactory;
  * An interface for generating database load balancers
  * @ingroup Database
  */
-abstract class LBFactory {
+abstract class LBFactory implements DestructibleService {
+
        /** @var ChronologyProtector */
        protected $chronProt;
 
@@ -38,9 +41,6 @@ abstract class LBFactory {
        /** @var LoggerInterface */
        protected $logger;
 
-       /** @var LBFactory */
-       private static $instance;
-
        /** @var string|bool Reason all LBs are read-only or false if not */
        protected $readOnlyReason = false;
 
@@ -60,38 +60,40 @@ abstract class LBFactory {
                $this->logger = LoggerFactory::getInstance( 'DBTransaction' );
        }
 
+       /**
+        * Disables all load balancers. All connections are closed, and any attempt to
+        * open a new connection will result in a DBAccessError.
+        * @see LoadBalancer::disable()
+        */
+       public function destroy() {
+               $this->shutdown();
+               $this->forEachLBCallMethod( 'disable' );
+       }
+
        /**
         * Disables all access to the load balancer, will cause all database access
         * to throw a DBAccessError
         */
        public static function disableBackend() {
-               global $wgLBFactoryConf;
-               self::$instance = new LBFactoryFake( $wgLBFactoryConf );
+               MediaWikiServices::disableStorageBackend();
        }
 
        /**
         * Get an LBFactory instance
         *
+        * @deprecated since 1.27, use MediaWikiServices::getDBLoadBalancerFactory() instead.
+        *
         * @return LBFactory
         */
        public static function singleton() {
-               global $wgLBFactoryConf;
-
-               if ( is_null( self::$instance ) ) {
-                       $class = self::getLBFactoryClass( $wgLBFactoryConf );
-                       $config = $wgLBFactoryConf;
-                       if ( !isset( $config['readOnlyReason'] ) ) {
-                               $config['readOnlyReason'] = wfConfiguredReadOnlyReason();
-                       }
-                       self::$instance = new $class( $config );
-               }
-
-               return self::$instance;
+               return MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
        }
 
        /**
         * Returns the LBFactory class to use and the load balancer configuration.
         *
+        * @todo instead of this, use a ServiceContainer for managing the different implementations.
+        *
         * @param array $config (e.g. $wgLBFactoryConf)
         * @return string Class name
         */
@@ -120,23 +122,11 @@ abstract class LBFactory {
 
        /**
         * Shut down, close connections and destroy the cached instance.
-        */
-       public static function destroyInstance() {
-               if ( self::$instance ) {
-                       self::$instance->shutdown();
-                       self::$instance->forEachLBCallMethod( 'closeAll' );
-                       self::$instance = null;
-               }
-       }
-
-       /**
-        * Set the instance to be the given object
         *
-        * @param LBFactory $instance
+        * @deprecated since 1.27, use LBFactory::destroy()
         */
-       public static function setInstance( $instance ) {
-               self::destroyInstance();
-               self::$instance = $instance;
+       public static function destroyInstance() {
+               self::singleton()->destroy();
        }
 
        /**
@@ -470,7 +460,7 @@ abstract class LBFactory {
 class DBAccessError extends MWException {
        public function __construct() {
                parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
-                       "This is not allowed." );
+                       "This is not allowed, because database access has been disabled." );
        }
 }
 
index 741999c..5578099 100644 (file)
@@ -77,6 +77,11 @@ class LoadBalancer {
        /** @var integer Max time to wait for a slave to catch up (e.g. ChronologyProtector) */
        const POS_WAIT_TIMEOUT = 10;
 
+       /**
+        * @var boolean
+        */
+       private $disabled = false;
+
        /**
         * @param array $params Array with keys:
         *  - servers : Required. Array of server info structures.
@@ -666,6 +671,8 @@ class LoadBalancer {
         * On error, returns false, and the connection which caused the
         * error will be available via $this->mErrorConnection.
         *
+        * @note If disable() was called on this LoadBalancer, this method will throw a DBAccessError.
+        *
         * @param int $i Server index
         * @param string|bool $wiki Wiki ID, or false for the current wiki
         * @return DatabaseBase|bool Returns false on errors
@@ -716,6 +723,8 @@ class LoadBalancer {
         * On error, returns false, and the connection which caused the
         * error will be available via $this->mErrorConnection.
         *
+        * @note If disable() was called on this LoadBalancer, this method will throw a DBAccessError.
+        *
         * @param int $i Server index
         * @param string $wiki Wiki ID to open
         * @return DatabaseBase
@@ -803,6 +812,10 @@ class LoadBalancer {
         * @return DatabaseBase
         */
        protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
+               if ( $this->disabled ) {
+                       throw new DBAccessError();
+               }
+
                if ( !is_array( $server ) ) {
                        throw new MWException( 'You must update your load-balancing configuration. ' .
                                'See DefaultSettings.php entry for $wgDBservers.' );
@@ -976,6 +989,17 @@ class LoadBalancer {
                return false;
        }
 
+       /**
+        * Disable this load balancer. All connections are closed, and any attempt to
+        * open a new connection will result in a DBAccessError.
+        *
+        * @since 1.27
+        */
+       public function disable() {
+               $this->closeAll();
+               $this->disabled = true;
+       }
+
        /**
         * Close all open connections
         */
index 81770d5..13d25a8 100644 (file)
@@ -368,6 +368,9 @@ class MWDebug {
                        $sql
                );
 
+               // last check for invalid utf8
+               $sql = UtfNormal\Validator::cleanUp( $sql );
+
                self::$query[] = [
                        'sql' => $sql,
                        'function' => $function,
index 32f6adc..65ff9f3 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Assert\Assert;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Handles purging appropriate CDN URLs given a title (or titles)
@@ -109,7 +110,8 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate {
                wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
 
                // Reliably broadcast the purge to all edge nodes
-               $relayer = EventRelayerGroup::singleton()->getRelayer( 'cdn-url-purges' );
+               $relayer = MediaWikiServices::getInstance()->getEventRelayerGroup()
+                                       ->getRelayer( 'cdn-url-purges' );
                $relayer->notify(
                        'cdn-url-purges',
                        [
index 249b207..e3b7570 100644 (file)
@@ -144,7 +144,12 @@ class DeferredUpdates {
                        }
 
                        // Delegate DataUpdate execution to the DataUpdate class
-                       DataUpdate::runUpdates( $dataUpdates, $mode );
+                       try {
+                               DataUpdate::runUpdates( $dataUpdates, $mode );
+                       } catch ( Exception $e ) {
+                               // Let the other updates occur if these had to rollback
+                               MWExceptionHandler::logException( $e );
+                       }
                        // Execute the non-DataUpdate tasks
                        foreach ( $otherUpdates as $update ) {
                                try {
index 4215ed0..c0205be 100644 (file)
@@ -55,6 +55,9 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
        /** @var array Map of language codes to titles */
        public $mInterlangs;
 
+       /** @var array 2-D map of (prefix => DBK => 1) */
+       public $mInterwikis;
+
        /** @var array Map of arbitrary name to value */
        public $mProperties;
 
index 2abf028..62c8b00 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup Search
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Database independant search index updater
  *
@@ -75,14 +77,15 @@ class SearchUpdate implements DeferrableUpdate {
         * Perform actual update for the entry
         */
        public function doUpdate() {
-               global $wgDisableSearchUpdate;
+               $config = MediaWikiServices::getInstance()->getSearchEngineConfig();
 
-               if ( $wgDisableSearchUpdate || !$this->id ) {
+               if ( $config->getConfig()->get( 'DisableSearchUpdate' ) || !$this->id ) {
                        return;
                }
 
-               foreach ( SearchEngine::getSearchTypes() as $type ) {
-                       $search = SearchEngine::create( $type );
+               $seFactory = MediaWikiServices::getInstance()->getSearchEngineFactory();
+               foreach ( $config->getSearchTypes() as $type ) {
+                       $search = $seFactory->create( $type );
                        if ( !$search->supports( 'search-update' ) ) {
                                continue;
                        }
@@ -99,7 +102,7 @@ class SearchUpdate implements DeferrableUpdate {
 
                        $text = $search->getTextFromContent( $this->title, $this->content );
                        if ( !$search->textAlreadyUpdatedForIndex() ) {
-                               $text = self::updateText( $text );
+                               $text = $this->updateText( $text, $search );
                        }
 
                        # Perform the actual update
@@ -113,14 +116,16 @@ class SearchUpdate implements DeferrableUpdate {
         * If you're using a real search engine, you'll probably want to override
         * this behavior and do something nicer with the original wikitext.
         * @param string $text
+        * @param SearchEngine $se Search engine
         * @return string
         */
-       public static function updateText( $text ) {
+       public function updateText( $text, SearchEngine $se = null ) {
                global $wgContLang;
 
                # Language-specific strip/conversion
                $text = $wgContLang->normalizeForSearch( $text );
-               $lc = SearchEngine::legalSearchChars() . '&#;';
+               $se = $se ?: MediaWikiServices::getInstance()->newSearchEngine();
+               $lc = $se->legalSearchChars() . '&#;';
 
                $text = preg_replace( "/<\\/?\\s*[A-Za-z][^>]*?>/",
                        ' ', $wgContLang->lc( " " . $text . " " ) ); # Strip HTML markup
index 6272e7e..e5e082f 100644 (file)
@@ -292,290 +292,10 @@ class DiffEngine {
         * @param string[] $to_lines
         */
        private function diffLocal( $from_lines, $to_lines ) {
-               global $wgExternalDiffEngine;
-
-               if ( $wgExternalDiffEngine == 'wikidiff3' ) {
-                       // wikidiff3
-                       $wikidiff3 = new WikiDiff3();
-                       $wikidiff3->diff( $from_lines, $to_lines );
-                       $this->xchanged = $wikidiff3->removed;
-                       $this->ychanged = $wikidiff3->added;
-                       unset( $wikidiff3 );
-               } else {
-                       // old diff
-                       $n_from = count( $from_lines );
-                       $n_to = count( $to_lines );
-                       $this->xchanged = $this->ychanged = [];
-                       $this->xv = $this->yv = [];
-                       $this->xind = $this->yind = [];
-                       $this->seq = [];
-                       $this->in_seq = [];
-                       $this->lcs = 0;
-
-                       // Skip leading common lines.
-                       for ( $skip = 0; $skip < $n_from && $skip < $n_to; $skip++ ) {
-                               if ( $from_lines[$skip] !== $to_lines[$skip] ) {
-                                       break;
-                               }
-                               $this->xchanged[$skip] = $this->ychanged[$skip] = false;
-                       }
-                       // Skip trailing common lines.
-                       $xi = $n_from;
-                       $yi = $n_to;
-                       for ( $endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++ ) {
-                               if ( $from_lines[$xi] !== $to_lines[$yi] ) {
-                                       break;
-                               }
-                               $this->xchanged[$xi] = $this->ychanged[$yi] = false;
-                       }
-
-                       // Ignore lines which do not exist in both files.
-                       for ( $xi = $skip; $xi < $n_from - $endskip; $xi++ ) {
-                               $xhash[$this->lineHash( $from_lines[$xi] )] = 1;
-                       }
-
-                       for ( $yi = $skip; $yi < $n_to - $endskip; $yi++ ) {
-                               $line = $to_lines[$yi];
-                               $this->ychanged[$yi] = empty( $xhash[$this->lineHash( $line )] );
-                               if ( $this->ychanged[$yi] ) {
-                                       continue;
-                               }
-                               $yhash[$this->lineHash( $line )] = 1;
-                               $this->yv[] = $line;
-                               $this->yind[] = $yi;
-                       }
-                       for ( $xi = $skip; $xi < $n_from - $endskip; $xi++ ) {
-                               $line = $from_lines[$xi];
-                               $this->xchanged[$xi] = empty( $yhash[$this->lineHash( $line )] );
-                               if ( $this->xchanged[$xi] ) {
-                                       continue;
-                               }
-                               $this->xv[] = $line;
-                               $this->xind[] = $xi;
-                       }
-
-                       // Find the LCS.
-                       $this->compareSeq( 0, count( $this->xv ), 0, count( $this->yv ) );
-               }
-       }
-
-       /**
-        * Returns the whole line if it's small enough, or the MD5 hash otherwise
-        *
-        * @param string $line
-        *
-        * @return string
-        */
-       private function lineHash( $line ) {
-               if ( strlen( $line ) > self::MAX_XREF_LENGTH ) {
-                       return md5( $line );
-               } else {
-                       return $line;
-               }
-       }
-
-       /**
-        * Divide the Largest Common Subsequence (LCS) of the sequences
-        * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
-        * sized segments.
-        *
-        * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
-        * array of NCHUNKS+1 (X, Y) indexes giving the diving points between
-        * sub sequences.  The first sub-sequence is contained in [X0, X1),
-        * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on.  Note
-        * that (X0, Y0) == (XOFF, YOFF) and
-        * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
-        *
-        * This function assumes that the first lines of the specified portions
-        * of the two files do not match, and likewise that the last lines do not
-        * match.  The caller must trim matching lines from the beginning and end
-        * of the portions it is going to specify.
-        *
-        * @param int $xoff
-        * @param int $xlim
-        * @param int $yoff
-        * @param int $ylim
-        * @param int $nchunks
-        *
-        * @return array List of two elements, integer and array[].
-        */
-       private function diag( $xoff, $xlim, $yoff, $ylim, $nchunks ) {
-               $flip = false;
-
-               if ( $xlim - $xoff > $ylim - $yoff ) {
-                       // Things seems faster (I'm not sure I understand why)
-                       // when the shortest sequence in X.
-                       $flip = true;
-                       list( $xoff, $xlim, $yoff, $ylim ) = [ $yoff, $ylim, $xoff, $xlim ];
-               }
-
-               if ( $flip ) {
-                       for ( $i = $ylim - 1; $i >= $yoff; $i-- ) {
-                               $ymatches[$this->xv[$i]][] = $i;
-                       }
-               } else {
-                       for ( $i = $ylim - 1; $i >= $yoff; $i-- ) {
-                               $ymatches[$this->yv[$i]][] = $i;
-                       }
-               }
-
-               $this->lcs = 0;
-               $this->seq[0] = $yoff - 1;
-               $this->in_seq = [];
-               $ymids[0] = [];
-
-               $numer = $xlim - $xoff + $nchunks - 1;
-               $x = $xoff;
-               for ( $chunk = 0; $chunk < $nchunks; $chunk++ ) {
-                       if ( $chunk > 0 ) {
-                               for ( $i = 0; $i <= $this->lcs; $i++ ) {
-                                       $ymids[$i][$chunk - 1] = $this->seq[$i];
-                               }
-                       }
-
-                       $x1 = $xoff + (int)( ( $numer + ( $xlim - $xoff ) * $chunk ) / $nchunks );
-                       // @codingStandardsIgnoreStart Ignore Squiz.WhiteSpace.SemicolonSpacing.Incorrect
-                       for ( ; $x < $x1; $x++ ) {
-                               // @codingStandardsIgnoreEnd
-                               $line = $flip ? $this->yv[$x] : $this->xv[$x];
-                               if ( empty( $ymatches[$line] ) ) {
-                                       continue;
-                               }
-
-                               $k = 0;
-                               $matches = $ymatches[$line];
-                               reset( $matches );
-                               while ( list( , $y ) = each( $matches ) ) {
-                                       if ( empty( $this->in_seq[$y] ) ) {
-                                               $k = $this->lcsPos( $y );
-                                               assert( $k > 0 );
-                                               $ymids[$k] = $ymids[$k - 1];
-                                               break;
-                                       }
-                               }
-
-                               while ( list( , $y ) = each( $matches ) ) {
-                                       if ( $y > $this->seq[$k - 1] ) {
-                                               assert( $y < $this->seq[$k] );
-                                               // Optimization: this is a common case:
-                                               // next match is just replacing previous match.
-                                               $this->in_seq[$this->seq[$k]] = false;
-                                               $this->seq[$k] = $y;
-                                               $this->in_seq[$y] = 1;
-                                       } elseif ( empty( $this->in_seq[$y] ) ) {
-                                               $k = $this->lcsPos( $y );
-                                               assert( $k > 0 );
-                                               $ymids[$k] = $ymids[$k - 1];
-                                       }
-                               }
-                       }
-               }
-
-               $seps[] = $flip ? [ $yoff, $xoff ] : [ $xoff, $yoff ];
-               $ymid = $ymids[$this->lcs];
-               for ( $n = 0; $n < $nchunks - 1; $n++ ) {
-                       $x1 = $xoff + (int)( ( $numer + ( $xlim - $xoff ) * $n ) / $nchunks );
-                       $y1 = $ymid[$n] + 1;
-                       $seps[] = $flip ? [ $y1, $x1 ] : [ $x1, $y1 ];
-               }
-               $seps[] = $flip ? [ $ylim, $xlim ] : [ $xlim, $ylim ];
-
-               return [ $this->lcs, $seps ];
-       }
-
-       /**
-        * @param int $ypos
-        *
-        * @return int
-        */
-       private function lcsPos( $ypos ) {
-               $end = $this->lcs;
-               if ( $end == 0 || $ypos > $this->seq[$end] ) {
-                       $this->seq[++$this->lcs] = $ypos;
-                       $this->in_seq[$ypos] = 1;
-
-                       return $this->lcs;
-               }
-
-               $beg = 1;
-               while ( $beg < $end ) {
-                       $mid = (int)( ( $beg + $end ) / 2 );
-                       if ( $ypos > $this->seq[$mid] ) {
-                               $beg = $mid + 1;
-                       } else {
-                               $end = $mid;
-                       }
-               }
-
-               assert( $ypos != $this->seq[$end] );
-
-               $this->in_seq[$this->seq[$end]] = false;
-               $this->seq[$end] = $ypos;
-               $this->in_seq[$ypos] = 1;
-
-               return $end;
-       }
-
-       /**
-        * Find LCS of two sequences.
-        *
-        * The results are recorded in the vectors $this->{x,y}changed[], by
-        * storing a 1 in the element for each line that is an insertion
-        * or deletion (ie. is not in the LCS).
-        *
-        * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
-        *
-        * Note that XLIM, YLIM are exclusive bounds.
-        * All line numbers are origin-0 and discarded lines are not counted.
-        *
-        * @param int $xoff
-        * @param int $xlim
-        * @param int $yoff
-        * @param int $ylim
-        */
-       private function compareSeq( $xoff, $xlim, $yoff, $ylim ) {
-               // Slide down the bottom initial diagonal.
-               while ( $xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff] ) {
-                       ++$xoff;
-                       ++$yoff;
-               }
-
-               // Slide up the top initial diagonal.
-               while ( $xlim > $xoff && $ylim > $yoff
-                       && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]
-               ) {
-                       --$xlim;
-                       --$ylim;
-               }
-
-               if ( $xoff == $xlim || $yoff == $ylim ) {
-                       $lcs = 0;
-               } else {
-                       // This is ad hoc but seems to work well.
-                       // $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
-                       // $nchunks = max(2,min(8,(int)$nchunks));
-                       $nchunks = min( 7, $xlim - $xoff, $ylim - $yoff ) + 1;
-                       list( $lcs, $seps ) = $this->diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
-               }
-
-               if ( $lcs == 0 ) {
-                       // X and Y sequences have no common subsequence:
-                       // mark all changed.
-                       while ( $yoff < $ylim ) {
-                               $this->ychanged[$this->yind[$yoff++]] = 1;
-                       }
-                       while ( $xoff < $xlim ) {
-                               $this->xchanged[$this->xind[$xoff++]] = 1;
-                       }
-               } else {
-                       // Use the partitions to split this problem into subproblems.
-                       reset( $seps );
-                       $pt1 = $seps[0];
-                       while ( $pt2 = next( $seps ) ) {
-                               $this->compareSeq( $pt1[0], $pt2[0], $pt1[1], $pt2[1] );
-                               $pt1 = $pt2;
-                       }
-               }
+               $wikidiff3 = new WikiDiff3();
+               $wikidiff3->diff( $from_lines, $to_lines );
+               $this->xchanged = $wikidiff3->removed;
+               $this->ychanged = $wikidiff3->added;
        }
 
        /**
index 1508cf1..e2345ca 100644 (file)
@@ -870,8 +870,8 @@ class DifferenceEngine extends ContextSource {
                $otext = str_replace( "\r\n", "\n", $otext );
                $ntext = str_replace( "\r\n", "\n", $ntext );
 
-               if ( $wgExternalDiffEngine == 'wikidiff' ) {
-                       wfDeprecated( 'wikidiff support', '1.27' );
+               if ( $wgExternalDiffEngine == 'wikidiff' || $wgExternalDiffEngine == 'wikidiff3' ) {
+                       wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27' );
                        $wgExternalDiffEngine = false;
                }
 
@@ -884,7 +884,7 @@ class DifferenceEngine extends ContextSource {
 
                                return $text;
                        }
-               } elseif ( $wgExternalDiffEngine != 'wikidiff3' && $wgExternalDiffEngine !== false ) {
+               } elseif ( $wgExternalDiffEngine !== false ) {
                        # Diff via the shell
                        $tmpDir = wfTempDir();
                        $tempName1 = tempnam( $tmpDir, 'diff_' );
index 0d7bf66..3b20048 100644 (file)
@@ -241,6 +241,12 @@ class FileBackendMultiWrite extends FileBackend {
                        return $status; // skip checks
                }
 
+               // Preload all of the stat info in as few round trips as possible...
+               foreach ( $this->backends as $backend ) {
+                       $realPaths = $this->substPaths( $paths, $backend );
+                       $backend->preloadFileStat( [ 'srcs' => $realPaths, 'latest' => true ] );
+               }
+
                $mBackend = $this->backends[$this->masterIndex];
                foreach ( $paths as $path ) {
                        $params = [ 'src' => $path, 'latest' => true ];
@@ -379,6 +385,11 @@ class FileBackendMultiWrite extends FileBackend {
                        }
                }
 
+               if ( !$status->isOK() ) {
+                       wfDebugLog( 'FileOperation', get_class( $this ) .
+                               " failed to resync: " . FormatJson::encode( $paths ) );
+               }
+
                return $status;
        }
 
index 15821ea..9ad2428 100644 (file)
@@ -815,7 +815,6 @@ class FileRepo {
         * @param string $dstZone Destination zone
         * @param string $dstRel Destination relative path
         * @param int $flags Bitwise combination of the following flags:
-        *   self::DELETE_SOURCE     Delete the source file after upload
         *   self::OVERWRITE         Overwrite an existing destination file instead of failing
         *   self::OVERWRITE_SAME    Overwrite the file if the destination exists and has the
         *                           same contents as the source
@@ -838,7 +837,6 @@ class FileRepo {
         *
         * @param array $triplets (src, dest zone, dest rel) triplets as per store()
         * @param int $flags Bitwise combination of the following flags:
-        *   self::DELETE_SOURCE     Delete the source file after upload
         *   self::OVERWRITE         Overwrite an existing destination file instead of failing
         *   self::OVERWRITE_SAME    Overwrite the file if the destination exists and has the
         *                           same contents as the source
@@ -849,11 +847,14 @@ class FileRepo {
        public function storeBatch( array $triplets, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
 
+               if ( $flags & self::DELETE_SOURCE ) {
+                       throw new InvalidArgumentException( "DELETE_SOURCE not supported in " . __METHOD__ );
+               }
+
                $status = $this->newGood();
                $backend = $this->backend; // convenience
 
                $operations = [];
-               $sourceFSFilesToDelete = []; // cleanup for disk source files
                // Validate each triplet and get the store operation...
                foreach ( $triplets as $triplet ) {
                        list( $srcPath, $dstZone, $dstRel ) = $triplet;
@@ -881,12 +882,9 @@ class FileRepo {
 
                        // Get the appropriate file operation
                        if ( FileBackend::isStoragePath( $srcPath ) ) {
-                               $opName = ( $flags & self::DELETE_SOURCE ) ? 'move' : 'copy';
+                               $opName = 'copy';
                        } else {
                                $opName = 'store';
-                               if ( $flags & self::DELETE_SOURCE ) {
-                                       $sourceFSFilesToDelete[] = $srcPath;
-                               }
                        }
                        $operations[] = [
                                'op' => $opName,
@@ -903,12 +901,6 @@ class FileRepo {
                        $opts['nonLocking'] = true;
                }
                $status->merge( $backend->doOperations( $operations, $opts ) );
-               // Cleanup for disk source files...
-               foreach ( $sourceFSFilesToDelete as $file ) {
-                       MediaWiki\suppressWarnings();
-                       unlink( $file ); // FS cleanup
-                       MediaWiki\restoreWarnings();
-               }
 
                return $status;
        }
index 8248699..eaec151 100644 (file)
@@ -227,7 +227,7 @@ class LocalRepo extends FileRepo {
                                        ? Title::makeTitle( $row->rd_namespace, $row->rd_title )->getDBkey()
                                        : ''; // negative cache
                        },
-                       [ 'pcTTL' => 30 ]
+                       [ 'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
                );
 
                // @note: also checks " " for b/c
index c037516..8175b58 100644 (file)
@@ -1065,7 +1065,6 @@ abstract class File implements IDBAccessObject {
                        if ( $this->repo ) {
                                // Defer rendering if a 404 handler is set up...
                                if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) {
-                                       wfDebug( __METHOD__ . " transformation deferred.\n" );
                                        // XXX: Pass in the storage path even though we are not rendering anything
                                        // and the path is supposed to be an FS path. This is due to getScalerType()
                                        // getting called on the path and clobbering $thumb->getUrl() if it's false.
index aa278aa..f7275fc 100644 (file)
@@ -559,11 +559,11 @@ class LocalFile extends File {
                        return;
                }
 
+               $upgrade = false;
                if ( is_null( $this->media_type ) ||
                        $this->mime == 'image/svg'
                ) {
-                       $this->upgradeRow();
-                       $this->upgraded = true;
+                       $upgrade = true;
                } else {
                        $handler = $this->getHandler();
                        if ( $handler ) {
@@ -571,11 +571,19 @@ class LocalFile extends File {
                                if ( $validity === MediaHandler::METADATA_BAD
                                        || ( $validity === MediaHandler::METADATA_COMPATIBLE && $wgUpdateCompatibleMetadata )
                                ) {
-                                       $this->upgradeRow();
-                                       $this->upgraded = true;
+                                       $upgrade = true;
                                }
                        }
                }
+
+               if ( $upgrade ) {
+                       try {
+                               $this->upgradeRow();
+                       } catch ( LocalFileLockError $e ) {
+                               // let the other process handle it (or do it next time)
+                       }
+                       $this->upgraded = true; // avoid rework/retries
+               }
        }
 
        function getUpgraded() {
@@ -586,7 +594,6 @@ class LocalFile extends File {
         * Fix assorted version-related problems with the image row by reloading it from the file
         */
        function upgradeRow() {
-
                $this->lock(); // begin
 
                $this->loadFromFile();
@@ -1898,18 +1905,16 @@ class LocalFile extends File {
        /**
         * Start a transaction and lock the image for update
         * Increments a reference counter if the lock is already held
-        * @throws MWException Throws an error if the lock was not acquired
+        * @throws LocalFileLockError Throws an error if the lock was not acquired
         * @return bool Whether the file lock owns/spawned the DB transaction
         */
        function lock() {
-               $dbw = $this->repo->getMasterDB();
-
                if ( !$this->locked ) {
+                       $dbw = $this->repo->getMasterDB();
                        if ( !$dbw->trxLevel() ) {
                                $dbw->begin( __METHOD__ );
                                $this->lockedOwnTrx = true;
                        }
-                       $this->locked++;
                        // Bug 54736: use simple lock to handle when the file does not exist.
                        // SELECT FOR UPDATE prevents changes, not other SELECTs with FOR UPDATE.
                        // Also, that would cause contention on INSERT of similarly named rows.
@@ -1917,10 +1922,15 @@ class LocalFile extends File {
                        $lockPaths = [ $this->getPath() ]; // represents all versions of the file
                        $status = $backend->lockFiles( $lockPaths, LockManager::LOCK_EX, 5 );
                        if ( !$status->isGood() ) {
-                               throw new MWException( "Could not acquire lock for '{$this->getName()}.'" );
+                               if ( $this->lockedOwnTrx ) {
+                                       $dbw->rollback( __METHOD__ );
+                               }
+                               throw new LocalFileLockError( "Could not acquire lock for '{$this->getName()}.'" );
                        }
+                       // Release the lock *after* commit to avoid row-level contention
+                       $this->locked++;
                        $dbw->onTransactionIdle( function () use ( $backend, $lockPaths ) {
-                               $backend->unlockFiles( $lockPaths, LockManager::LOCK_EX ); // release on commit
+                               $backend->unlockFiles( $lockPaths, LockManager::LOCK_EX );
                        } );
                }
 
@@ -3031,3 +3041,7 @@ class LocalFileMoveBatch {
                $this->file->repo->cleanupBatch( $files );
        }
 }
+
+class LocalFileLockError extends Exception {
+
+}
index 6f88975..0dab3bb 100644 (file)
@@ -569,7 +569,7 @@ class HTMLForm extends ContextSource {
 
                # Check for cancelled submission
                foreach ( $this->mFlatFields as $fieldname => $field ) {
-                       if ( !empty( $field->mParams['nodata'] ) ) {
+                       if ( !array_key_exists( $fieldname, $this->mFieldData ) ) {
                                continue;
                        }
                        if ( $field->cancelSubmit( $this->mFieldData[$fieldname], $this->mFieldData ) ) {
@@ -580,7 +580,7 @@ class HTMLForm extends ContextSource {
 
                # Check for validation
                foreach ( $this->mFlatFields as $fieldname => $field ) {
-                       if ( !empty( $field->mParams['nodata'] ) ) {
+                       if ( !array_key_exists( $fieldname, $this->mFieldData ) ) {
                                continue;
                        }
                        if ( $field->isHidden( $this->mFieldData ) ) {
@@ -1117,7 +1117,7 @@ class HTMLForm extends ContextSource {
                        ];
 
                        if ( isset( $button['label-message'] ) ) {
-                               $label = $this->msg( $button['label-message'] )->parse();
+                               $label = $this->getMessage( $button['label-message'] )->parse();
                        } elseif ( isset( $button['label'] ) ) {
                                $label = htmlspecialchars( $button['label'] );
                        } elseif ( isset( $button['label-raw'] ) ) {
@@ -1198,17 +1198,10 @@ class HTMLForm extends ContextSource {
                $errorstr = '';
 
                foreach ( $errors as $error ) {
-                       if ( is_array( $error ) ) {
-                               $msg = array_shift( $error );
-                       } else {
-                               $msg = $error;
-                               $error = [];
-                       }
-
                        $errorstr .= Html::rawElement(
                                'li',
                                [],
-                               $this->msg( $msg, $error )->parse()
+                               $this->getMessage( $error )->parse()
                        );
                }
 
@@ -1474,13 +1467,22 @@ class HTMLForm extends ContextSource {
         * @param string $fieldsetIDPrefix ID prefix for the "<fieldset>" tag of
         *   each subsection, ignored if empty.
         * @param bool &$hasUserVisibleFields Whether the section had user-visible fields.
+        * @throws LogicException When called on uninitialized field data, e.g. When
+        *  HTMLForm::displayForm was called without calling HTMLForm::prepareForm
+        *  first.
         *
         * @return string
         */
        public function displaySection( $fields,
                $sectionName = '',
                $fieldsetIDPrefix = '',
-               &$hasUserVisibleFields = false ) {
+               &$hasUserVisibleFields = false
+       ) {
+               if ( $this->mFieldData === null ) {
+                       throw new LogicException( 'HTMLForm::displaySection() called on uninitialized field data. '
+                               . 'You probably called displayForm() without calling prepareForm() first.' );
+               }
+
                $displayFormat = $this->getDisplayFormat();
 
                $html = [];
@@ -1493,7 +1495,7 @@ class HTMLForm extends ContextSource {
 
                foreach ( $fields as $key => $value ) {
                        if ( $value instanceof HTMLFormField ) {
-                               $v = isset( $this->mFieldData[$key] )
+                               $v = array_key_exists( $key, $this->mFieldData )
                                        ? $this->mFieldData[$key]
                                        : $value->getDefault();
 
@@ -1716,4 +1718,14 @@ class HTMLForm extends ContextSource {
 
                return $this;
        }
+
+       /**
+        * Turns a *-message parameter (which could be a MessageSpecifier, or a message name, or a
+        * name + parameters array) into a Message.
+        * @param mixed $value
+        * @return Message
+        */
+       protected function getMessage( $value ) {
+               return Message::newFromSpecifier( $value )->setContext( $this );
+       }
 }
index d5f4cc0..9f5e728 100644 (file)
@@ -28,7 +28,7 @@ abstract class HTMLFormField {
        protected $mShowEmptyLabels = true;
 
        /**
-        * @var HTMLForm
+        * @var HTMLForm|null
         */
        public $mParent;
 
@@ -117,8 +117,8 @@ abstract class HTMLFormField {
                        $tmp = $m[1];
                }
                if ( substr( $tmp, 0, 2 ) == 'wp' &&
-                       !isset( $alldata[$tmp] ) &&
-                       isset( $alldata[substr( $tmp, 2 )] )
+                       !array_key_exists( $tmp, $alldata ) &&
+                       array_key_exists( substr( $tmp, 2 ), $alldata )
                ) {
                        // Adjust for name mangling.
                        $tmp = substr( $tmp, 2 );
@@ -139,7 +139,7 @@ abstract class HTMLFormField {
                        $data = $alldata;
                        while ( $keys ) {
                                $key = array_shift( $keys );
-                               if ( !is_array( $data ) || !isset( $data[$key] ) ) {
+                               if ( !is_array( $data ) || !array_key_exists( $key, $data ) ) {
                                        continue 2;
                                }
                                $data = $data[$key];
@@ -1095,16 +1095,13 @@ abstract class HTMLFormField {
         * @return Message
         */
        protected function getMessage( $value ) {
-               if ( $value instanceof Message ) {
-                       return $value;
-               } elseif ( $value instanceof MessageSpecifier ) {
-                       return Message::newFromKey( $value );
-               } elseif ( is_array( $value ) ) {
-                       $msg = array_shift( $value );
-                       return $this->msg( $msg, $value );
-               } else {
-                       return $this->msg( $value, [] );
+               $message = Message::newFromSpecifier( $value );
+
+               if ( $this->mParent ) {
+                       $message->setContext( $this->mParent );
                }
+
+               return $message;
        }
 
        /**
index 7359092..ec1bd84 100644 (file)
@@ -207,7 +207,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                foreach ( $values as $key => $value ) {
                        $fields = $this->createFieldsForKey( $key );
                        foreach ( $fields as $fieldname => $field ) {
-                               if ( !empty( $field->mParams['nodata'] ) ) {
+                               if ( !array_key_exists( $fieldname, $value ) ) {
                                        continue;
                                }
                                if ( $field->cancelSubmit( $value[$fieldname], $alldata ) ) {
@@ -237,7 +237,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                foreach ( $values as $key => $value ) {
                        $fields = $this->createFieldsForKey( $key );
                        foreach ( $fields as $fieldname => $field ) {
-                               if ( !empty( $field->mParams['nodata'] ) ) {
+                               if ( !array_key_exists( $fieldname, $value ) ) {
                                        continue;
                                }
                                $ok = $field->validate( $value[$fieldname], $alldata );
@@ -271,7 +271,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
 
                $fields = $this->createFieldsForKey( $key );
                foreach ( $fields as $fieldname => $field ) {
-                       $v = isset( $values[$fieldname] )
+                       $v = array_key_exists( $fieldname, $values )
                                ? $values[$fieldname]
                                : $field->getDefault();
 
index 278d453..7a2ed50 100644 (file)
@@ -100,7 +100,7 @@ class OOUIHTMLForm extends HTMLForm {
                        if ( $isBadIE ) {
                                $label = $button['value'];
                        } elseif ( isset( $button['label-message'] ) ) {
-                               $label = new OOUI\HtmlSnippet( $this->msg( $button['label-message'] )->parse() );
+                               $label = new OOUI\HtmlSnippet( $this->getMessage( $button['label-message'] )->parse() );
                        } elseif ( isset( $button['label'] ) ) {
                                $label = $button['label'];
                        } elseif ( isset( $button['label-raw'] ) ) {
@@ -198,18 +198,7 @@ class OOUIHTMLForm extends HTMLForm {
                }
 
                foreach ( $errors as &$error ) {
-                       if ( is_array( $error ) ) {
-                               $msg = array_shift( $error );
-                       } else {
-                               $msg = $error;
-                               $error = [];
-                       }
-                       // if the error is already a message object, don't use it as a message key
-                       if ( !$msg instanceof Message ) {
-                               $error = $this->msg( $msg, $error )->parse();
-                       } else {
-                               $error = $msg->parse();
-                       }
+                       $error = $this->getMessage( $error )->parse();
                        $error = new OOUI\HtmlSnippet( $error );
                }
 
index 79bd961..701403e 100644 (file)
@@ -287,8 +287,16 @@ abstract class DatabaseInstaller {
                if ( !$status->isOK() ) {
                        throw new MWException( __METHOD__ . ': unexpected DB connection error' );
                }
-               LBFactory::setInstance( new LBFactorySingle( [
-                       'connection' => $status->value ] ) );
+
+               \MediaWiki\MediaWikiServices::resetGlobalInstance();
+               $services = \MediaWiki\MediaWikiServices::getInstance();
+
+               $connection = $status->value;
+               $services->redefineService( 'DBLoadBalancerFactory', function() use ( $connection ) {
+                       return new LBFactorySingle( [
+                               'connection' => $connection ] );
+               } );
+
        }
 
        /**
index 3d1c860..a9f219f 100644 (file)
@@ -351,37 +351,67 @@ abstract class Installer {
         */
        abstract public function showStatusMessage( Status $status );
 
+       /**
+        * Constructs a Config object that contains configuration settings that should be
+        * overwritten for the installation process.
+        *
+        * @since 1.27
+        *
+        * @param Config $baseConfig
+        *
+        * @return Config The config to use during installation.
+        */
+       public static function getInstallerConfig( Config $baseConfig ) {
+               $configOverrides = new HashConfig();
+
+               // disable (problematic) object cache types explicitly, preserving all other (working) ones
+               // bug T113843
+               $emptyCache = [ 'class' => 'EmptyBagOStuff' ];
+
+               $objectCaches = [
+                               CACHE_NONE => $emptyCache,
+                               CACHE_DB => $emptyCache,
+                               CACHE_ANYTHING => $emptyCache,
+                               CACHE_MEMCACHED => $emptyCache,
+                       ] + $baseConfig->get( 'ObjectCaches' );
+
+               $configOverrides->set( 'ObjectCaches', $objectCaches );
+
+               // Load the installer's i18n.
+               $messageDirs = $baseConfig->get( 'MessagesDirs' );
+               $messageDirs['MediawikiInstaller'] = __DIR__ . '/i18n';
+
+               $configOverrides->set( 'MessagesDirs', $messageDirs );
+
+               return new MultiConfig( [ $configOverrides, $baseConfig ] );
+       }
+
        /**
         * Constructor, always call this from child classes.
         */
        public function __construct() {
-               global $wgMessagesDirs, $wgUser;
+               global $wgMemc, $wgUser;
+
+               $defaultConfig = new GlobalVarConfig(); // all the stuff from DefaultSettings.php
+               $installerConfig = self::getInstallerConfig( $defaultConfig );
+
+               // Reset all services and inject config overrides
+               MediaWiki\MediaWikiServices::resetGlobalInstance( $installerConfig );
 
                // Don't attempt to load user language options (T126177)
                // This will be overridden in the web installer with the user-specified language
                RequestContext::getMain()->setLanguage( 'en' );
 
                // Disable the i18n cache
+               // TODO: manage LocalisationCache singleton in MediaWikiServices
                Language::getLocalisationCache()->disableBackend();
-               // Disable LoadBalancer and wfGetDB etc.
-               LBFactory::disableBackend();
+
+               // Disable all global services, since we don't have any configuration yet!
+               MediaWiki\MediaWikiServices::disableStorageBackend();
 
                // Disable object cache (otherwise CACHE_ANYTHING will try CACHE_DB and
                // SqlBagOStuff will then throw since we just disabled wfGetDB)
-               $GLOBALS['wgMemc'] = new EmptyBagOStuff;
-               ObjectCache::clear();
-               $emptyCache = [ 'class' => 'EmptyBagOStuff' ];
-               // disable (problematic) object cache types explicitly, preserving all other (working) ones
-               // bug T113843
-               $GLOBALS['wgObjectCaches'] = [
-                       CACHE_NONE => $emptyCache,
-                       CACHE_DB => $emptyCache,
-                       CACHE_ANYTHING => $emptyCache,
-                       CACHE_MEMCACHED => $emptyCache,
-               ] + $GLOBALS['wgObjectCaches'];
-
-               // Load the installer's i18n.
-               $wgMessagesDirs['MediawikiInstaller'] = __DIR__ . '/i18n';
+               $wgMemc = ObjectCache::getInstance( CACHE_NONE );
 
                // Having a user with id = 0 safeguards us from DB access via User::loadOptions().
                $wgUser = User::newFromId( 0 );
@@ -1697,7 +1727,7 @@ abstract class Installer {
                                wfMessage( 'mainpagedocfooter' )->inContentLanguage()->text()
                        );
 
-                       $page->doEditContent( $content,
+                       $status = $page->doEditContent( $content,
                                '',
                                EDIT_NEW,
                                false,
index c6b8960..62cd883 100644 (file)
@@ -500,19 +500,19 @@ class MssqlInstaller extends DatabaseInstaller {
                                "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ),
                                __METHOD__
                        );
-                       $conn->selectDB( $dbName );
-                       if ( !$this->schemaExists( $schemaName ) ) {
-                               $conn->query(
-                                       "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ),
-                                       __METHOD__
-                               );
-                       }
-                       if ( !$this->catalogExists( $schemaName ) ) {
-                               $conn->query(
-                                       "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ),
-                                       __METHOD__
-                               );
-                       }
+               }
+               $conn->selectDB( $dbName );
+               if ( !$this->schemaExists( $schemaName ) ) {
+                       $conn->query(
+                               "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ),
+                               __METHOD__
+                       );
+               }
+               if ( !$this->catalogExists( $schemaName ) ) {
+                       $conn->query(
+                               "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ),
+                               __METHOD__
+                       );
                }
                $this->setupSchemaVars();
 
index bdaf4c8..accc42f 100644 (file)
@@ -41,22 +41,24 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'addField', 'mwuser', 'user_password_expires', 'patch-user_password_expires.sql' ],
 
                        // 1.24
-                       [ 'addField', 'page', 'page_lang', 'patch-page-page_lang.sql' ],
+                       [ 'addField', 'page', 'page_lang', 'patch-page_page_lang.sql' ],
 
                        // 1.25
                        [ 'dropTable', 'hitcounter' ],
                        [ 'dropField', 'site_stats', 'ss_total_views', 'patch-drop-ss_total_views.sql' ],
                        [ 'dropField', 'page', 'page_counter', 'patch-drop-page_counter.sql' ],
-                       // Constraint updates
-                       [ 'updateConstraints', 'category_types', 'categorylinks', 'cl_type' ],
-                       [ 'updateConstraints', 'major_mime', 'filearchive', 'fa_major_mime' ],
-                       [ 'updateConstraints', 'media_type', 'filearchive', 'fa_media_type' ],
-                       [ 'updateConstraints', 'major_mime', 'oldimage', 'oi_major_mime' ],
-                       [ 'updateConstraints', 'media_type', 'oldimage', 'oi_media_type' ],
-                       [ 'updateConstraints', 'major_mime', 'image', 'img_major_mime' ],
-                       [ 'updateConstraints', 'media_type', 'image', 'img_media_type' ],
-                       [ 'updateConstraints', 'media_type', 'uploadstash', 'us_media_type' ],
-                       // END: Constraint updates
+                       // scripts were updated in 1.27 due to SQL errors; retaining old updatekeys so that people
+                       // updating from 1.23->1.25->1.27 do not execute these scripts twice even though the
+                       // updatekeys no longer make sense as they are.
+                       [ 'updateSchema', 'categorylinks', 'cl_type-category_types-ck',
+                               'patch-categorylinks-constraints.sql' ],
+                       [ 'updateSchema', 'filearchive', 'fa_major_mime-major_mime-ck',
+                               'patch-filearchive-constraints.sql' ],
+                       [ 'updateSchema', 'oldimage', 'oi_major_mime-major_mime-ck',
+                               'patch-oldimage-constraints.sql' ],
+                       [ 'updateSchema', 'image', 'img_major_mime-major_mime-ck', 'patch-image-constraints.sql' ],
+                       [ 'updateSchema', 'uploadstash', 'us_media_type-media_type-ck',
+                               'patch-uploadstash-constraints.sql' ],
 
                        [ 'modifyField', 'image', 'img_major_mime',
                                'patch-img_major_mime-chemical.sql' ],
@@ -69,79 +71,53 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'dropTable', 'msg_resource_links' ],
                        [ 'dropTable', 'msg_resource' ],
                        [ 'addField', 'watchlist', 'wl_id', 'patch-watchlist-wl_id.sql' ],
+                       [ 'dropField', 'mwuser', 'user_options', 'patch-drop-user_options.sql' ],
+                       [ 'addTable', 'bot_passwords', 'patch-bot_passwords.sql' ],
+                       [ 'addField', 'pagelinks', 'pl_from_namespace', 'patch-pl_from_namespace.sql' ],
+                       [ 'addField', 'templatelinks', 'tl_from_namespace', 'patch-tl_from_namespace.sql' ],
+                       [ 'addField', 'imagelinks', 'il_from_namespace', 'patch-il_from_namespace.sql' ],
+                       [ 'dropIndex', 'categorylinks', 'cl_collation', 'patch-kill-cl_collation_index.sql' ],
+                       [ 'addIndex', 'categorylinks', 'cl_collation_ext',
+                               'patch-add-cl_collation_ext_index.sql' ],
+                       [ 'dropField', 'recentchanges', 'rc_cur_time', 'patch-drop-rc_cur_time.sql' ],
+                       [ 'addField', 'page_props', 'pp_sortkey', 'patch-pp_sortkey.sql' ],
+                       [ 'updateSchema', 'oldimage', 'oldimage varchar', 'patch-oldimage-schema.sql' ],
+                       [ 'updateSchema', 'filearchive', 'filearchive varchar', 'patch-filearchive-schema.sql' ],
+                       [ 'updateSchema', 'image', 'image varchar', 'patch-image-schema.sql' ],
+                       [ 'updateSchema', 'recentchanges', 'recentchanges-drop-fks',
+                               'patch-recentchanges-drop-fks.sql' ],
+                       [ 'updateSchema', 'logging', 'logging-drop-fks', 'patch-logging-drop-fks.sql' ],
+                       [ 'updateSchema', 'archive', 'archive-drop-fks', 'patch-archive-drop-fks.sql' ]
                ];
        }
 
+       protected function applyPatch( $path, $isFullPath = false, $msg = null ) {
+               $prevScroll = $this->db->scrollableCursor( false );
+               $prevPrep = $this->db->prepareStatements( false );
+               parent::applyPatch( $path, $isFullPath, $msg );
+               $this->db->scrollableCursor( $prevScroll );
+               $this->db->prepareStatements( $prevPrep );
+       }
+
        /**
-        * Drops unnamed and creates named constraints following the pattern
-        * <column>_ckc
+        * General schema update for a table that touches more than one field or requires
+        * destructive actions (such as dropping and recreating the table).
         *
-        * @param string $constraintType
-        * @param string $table Name of the table to which the field belongs
-        * @param string $field Name of the field to modify
-        * @return bool False if patch is skipped.
+        * @param string $table
+        * @param string $updatekey
+        * @param string $patch
+        * @param bool $fullpath
         */
-       protected function updateConstraints( $constraintType, $table, $field ) {
-               global $wgDBname, $wgDBmwschema;
-
-               if ( !$this->doTable( $table ) ) {
-                       return true;
-               }
-
-               $this->output( "...updating constraints on [$table].[$field] ..." );
-               $updateKey = "$field-$constraintType-ck";
+       protected function updateSchema( $table, $updatekey, $patch, $fullpath = false ) {
                if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
-                       $this->output( "...$table table does not exist, skipping modify field patch.\n" );
-                       return true;
-               } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) {
-                       $this->output( "...$field field does not exist in $table table, " .
-                               "skipping modify field patch.\n" );
-                       return true;
-               } elseif ( $this->updateRowExists( $updateKey ) ) {
-                       $this->output( "...$field in table $table already patched.\n" );
-                       return true;
-               }
-
-               # After all checks passed, start the update
-               $this->insertUpdateRow( $updateKey );
-               $path = 'named_constraints.sql';
-               $constraintMap = [
-                       'category_types' =>
-                               "($field in('page', 'subcat', 'file'))",
-                       'major_mime'     =>
-                               "($field in('unknown', 'application', 'audio', 'image', 'text', 'video'," .
-                               " 'message', 'model', 'multipart'))",
-                       'media_type'     =>
-                               "($field in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA'," .
-                               "'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))"
-               ];
-               $constraint = $constraintMap[$constraintType];
-
-               # and hack-in those variables that should be replaced
-               # in our template file right now
-               $this->db->setSchemaVars( [
-                       'tableName'       => $table,
-                       'fieldName'       => $field,
-                       'checkConstraint' => $constraint,
-                       'wgDBname'        => $wgDBname,
-                       'wgDBmwschema'    => $wgDBmwschema,
-               ] );
-
-               # Full path from file name
-               $path = $this->db->patchPath( $path );
-
-               # No need for a cursor allowing result-iteration; just apply a patch
-               # store old value for re-setting later
-               $wasScrollable = $this->db->scrollableCursor( false );
+                       $this->output( "...$table table does not exist, skipping schema update patch.\n" );
+               } elseif ( $this->updateRowExists( $updatekey ) ) {
+                       $this->output( "...$table already had schema updated by $patch.\n" );
+               } else {
+                       $this->insertUpdateRow( $updatekey );
 
-               # Apply patch
-               $this->db->sourceFile( $path );
-
-               # Reset DB instance to have original state
-               $this->db->setSchemaVars( false );
-               $this->db->scrollableCursor( $wasScrollable );
-
-               $this->output( "done.\n" );
+                       return $this->applyPatch( $patch, $fullpath, "Updating schema of table $table" );
+               }
 
                return true;
        }
index daa429a..2ab0554 100644 (file)
@@ -98,7 +98,7 @@ abstract class WebInstallerPage {
                                wfMessage( "config-$continue" )->text(),
                                [
                                        'name' => "enter-$continue",
-                                       'style' => 'visibility:hidden;overflow:hidden;width:1px;margin:0'
+                                       'style' => 'width:0;border:0;height:0;padding:0'
                                ]
                        ) . "\n";
                }
index d33e03b..ee8ba4b 100644 (file)
@@ -1,9 +1,11 @@
 {
        "@metadata": {
                "authors": [
-                       "Anggoro"
+                       "Anggoro",
+                       "NoiX180"
                ]
        },
+       "config-install-mainpage-failed": "Ora bisa nglebokaké kaca pokok: $1",
        "mainpagetext": "'''Prangkat empuk wiki wis suksès dipasang.'''",
        "mainpagedocfooter": "Mangga maca [//meta.wikimedia.org/wiki/Help:Contents User's Guide] kanggo katrangan luwih langkung prakara panggunan prangkat empuk wiki\n== Miwiti panggunan  ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Daftar pangaturan préférènsi]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Milis rilis MediaWiki]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]"
 }
index f621fe4..14c0820 100644 (file)
@@ -10,7 +10,8 @@
                        "Alex00728",
                        "Hwangjy9",
                        "Macofe",
-                       "Mooozi"
+                       "Mooozi",
+                       "Ykhwong"
                ]
        },
        "config-desc": "미디어위키를 위한 설치 관리자",
        "config-ns-site-name": "위키 이름과 같은 이름: $1",
        "config-ns-other": "기타 (지정)",
        "config-ns-other-default": "내위키",
-       "config-project-namespace-help": "위키백과의 예에 따르면, 많은 위키는 정책 문서를 일반 문서와는 별도로 \"'''프로젝트 이름공간'''\"에 보관합니다.\n이 이름공간에 있는 모든 문서의 제목은 여기서 지정할 수 있는 특정 접두어로 시작합니다.\n보통 이 접두어는 위키의 이름에서 파생되지만, \"#\" 또는 \":\"와 같은 특수 문자를 포함할 수 없습니다.",
+       "config-project-namespace-help": "위키백과의 예에 따르면, 많은 위키는 정책 문서를 일반 문서와는 별도로 '''프로젝트 이름공간'''에 보관합니다.\n이 이름공간에 있는 모든 문서의 제목은 여기서 지정할 수 있는 특정 접두어로 시작합니다.\n보통 이 접두어는 위키의 이름에서 파생되지만, \"#\" 또는 \":\"와 같은 특수 문자를 포함할 수 없습니다.",
        "config-ns-invalid": "특정 \"<nowiki>$1</nowiki>\" 이름공간이 잘못되었습니다.\n다른 프로젝트 이름공간을 지정하세요.",
        "config-ns-conflict": "특정 \"<nowiki>$1</nowiki>\" 이름공간이 기본 미디어위키 이름공간과 충돌합니다.\n다른 프로젝트 이름공간을 지정하세요.",
        "config-admin-box": "관리자 계정",
index e3f800e..9d5865c 100644 (file)
@@ -34,6 +34,6 @@
        "config-env-good": "पर्यावरण क जाँच कएल गेल अछि।\nआहाँ मीडियाविकि स्थापित कर सकै चिए।",
        "config-env-bad": "पर्यावरण क जाँच कएल गेल अछि।\nआहाँ मीडियाविकि स्थापित नै कर सकै चिए।",
        "config-env-php": "PHP $1 स्थापित कएल ग्याल अछि।",
-       "mainpagetext": "'''मेडियाविकी नीक जकाँ प्रस्थापित भेल।'''",
+       "mainpagetext": "<strong>मेडियाविकी नीक जकाँ प्रस्थापित भेल।</strong>",
        "mainpagedocfooter": "सम्पर्क करू [//meta.wikimedia.org/wiki/Help:Contents User's Guide] विकि तंत्रांशक प्रयोगक जानकारी लेल।\n\n==प्रारम्भ कोना करी==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]"
 }
index c33ae7b..d9a0026 100644 (file)
@@ -4,6 +4,7 @@
                        "Servien"
                ]
        },
+       "config-help": "hulpe",
        "mainpagetext": "'''’t Installeren van de MediaWiki programmatuur is succesvol.'''",
        "mainpagedocfooter": "Bekiek de [//meta.wikimedia.org/wiki/Help:Contents haandleiding] veur informasie over t gebruuk van de wikiprogrammatuur.\n\n== Meer hulpe ==\n* [//www.mediawiki.org/wiki/Help:Configuration_settings Lieste mit instellingen]\n* [//www.mediawiki.org/wiki/Help:FAQ MediaWiki-vragen die vake esteld wörden]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-postlieste veur nieje versies]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Maak MediaWiki beschikbaor in joew taal]"
 }
index 9286446..992107f 100644 (file)
        "config-help-tooltip": "klik om uit te vouwen",
        "config-nofile": "Het bestand \"$1\" is niet gevonden. Is het verwijderd?",
        "config-extension-link": "Weet u dat u [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions uitbreidingen] kunt gebruiken voor uw wiki?\n\nU kunt [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category uitbreidingen op categorie] bekijken of ga naar de [//www.mediawiki.org/wiki/Extension_Matrix uitbreidingenmatrix] om de volledige lijst met uitbreidingen te bekijken.",
-       "mainpagetext": "'''De installatie van MediaWiki is geslaagd.'''",
+       "mainpagetext": "<strong>De installatie van MediaWiki is geslaagd.</strong>",
        "mainpagedocfooter": "Raadpleeg de [//meta.wikimedia.org/wiki/Special:MyLanguage/Help:Contents handleiding] voor informatie over het gebruik van de wikisoftware.\n\n== Meer hulp over MediaWiki ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lijst met instellingen]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Veelgestelde vragen (FAQ)]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglijst voor aankondigingen van nieuwe versies]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Maak MediaWiki beschikbaar in uw taal]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Leer hoe u spam kunt voorkomen op uw wiki]"
 }
index 677908b..f1e4d4c 100644 (file)
@@ -87,7 +87,7 @@
        "config-mod-security": "<strong>Aviso:</strong> Seu servidor web tem [http://modsecurity.org/ mod_security] habilitado. Se configurado incorretamente, pode causar problemas para o MediaWiki ou outro software que permite aos usuários postar conteúdo arbitrário.\nConsulte a [http://modsecurity.org/documentation/ documentação do mod_security] ou entre em contato com o suporte do seu host se você encontrar erros aleatórios.",
        "config-diff3-bad": "O GNU diff3 não foi encontrado.",
        "config-git": "Foi encontrado o software de controle de versão Git: <code>$1</code>.",
-       "config-git-bad": "Não foi encontrado o software de controle de versão Git.",
+       "config-git-bad": "O software de controle de versão Git não foi encontrado.",
        "config-imagemagick": "ImageMagick encontrado: <code>$1</code> .\nRedimensionamento de imagem será ativado se você permitir uploads.",
        "config-gd": "Encontrada biblioteca gráfica GD embutida\nO redimensionamento de imagens será habilitado se você permitir uploads.",
        "config-no-scaling": "Não foi possível encontrar biblioteca GD ou ImageMagick. \nO redimensionamento de imagens será desabilitado.",
index 2644f3f..aabf541 100644 (file)
@@ -67,6 +67,7 @@
        "config-ctype": "<strong>Lỗi chí tử:</strong> PHP phải được biên dịch với hỗ trợ cho [http://www.php.net/manual/en/ctype.installation.php phần mở rộng Ctype].",
        "config-iconv": "<strong>Lỗi chí tử:</strong> PHP phải được biên dịch với hỗ trợ cho [http://www.php.net/manual/en/iconv.installation.php phần mở rộng iconv].",
        "config-json": "<strong>Lỗi chí tử:</strong> PHP được biên dịch mà không có hỗ trợ cho JSON.\nBạn phải cài đặt hoặc phần mở rộng JSON PHP hoặc phần mở rộng [http://pecl.php.net/package/jsonc PECL jsonc] trước khi cài đặt MediaWiki.\n* Phần mở rộng PHP có sẵn trong Red Hat Enterprise Linux (CentOS) 5 và 6 nhưng phải được kích hoạt trong <code>/etc/php.ini</code> hoặc <code>/etc/php.d/json.ini</code>.\n* Một số phiên bản Linux được phát hành sau tháng 5 năm 2013 bỏ qua phần mở rộng PHP và gói lại phần mở rộng PECL là <code>php5-json</code> hoặc <code>php-pecl-jsonc</code> thay thế.",
+       "config-mbstring-absent": "<strong>Lỗi chí tử:</strong> PHP phải được biên dịch với hỗ trợ cho [http://www.php.net/manual/en/mbstring.setup.php phần mở rộng mbstring].",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] đã được cài đặt",
        "config-apc": "[http://www.php.net/apc APC] đã được cài đặt",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] đã được cài đặt",
index 7d2926c..59968e2 100644 (file)
        "config-email-watchlist": "启用监视列表通知",
        "config-email-watchlist-help": "允许用户收到与其监视列表有关的通知,假若他们启用了该功能。",
        "config-email-auth": "启用电子邮件身份验证",
-       "config-email-auth-help": "如果启用此选项,在用户设置或修改电子邮件地址时,就会收到一封邮件,内含确认电子地址的链接。只有经过身份验证的电子邮件地址,才能收到来自其他用户的电子邮件,或任何修改通知的邮件。'''建议'''公开wiki启用本选项,以防对电子邮件功能的滥用。",
+       "config-email-auth-help": "如果启用此选项,在用户设置或修改电子邮件地址时,就会收到一封邮件,内含确认电子地址的链接。只有经过身份验证的电子邮件地址,才能收到来自其他用户的电子邮件,或任何修改通知的邮件。<strong>建议</strong>公开wiki启用本选项,以防对电子邮件功能的滥用。",
        "config-email-sender": "回复电子邮件地址:",
        "config-email-sender-help": "输入要用来发送出站电子邮件的地址,该地址将会收到被拒收的邮件。许多邮件服务器要求域名部分必须有效。",
        "config-upload-settings": "图像和文件上传",
        "config-upload-deleted": "已删除文件的目录:",
        "config-upload-deleted-help": "指定用于存放被删除文件的目录。理想情况下,该目录不应能通过web访问。",
        "config-logo": "标志URL:",
-       "config-logo-help": "在MediaWiki的默认外观中,左侧栏菜单之上有一块135x160像素的标志区。请上传一幅相应大小的图像,并在此输入URL。\n\n可以用<code>$wgStylePath</code>或<code>$wgScriptPath</code>来表示相对于这些位置的路径。\n\n如果您不希望使用标志,请将本处留空。",
+       "config-logo-help": "在MediaWiki的默认外观中,左侧栏菜单之上有一块135x160像素的标志区。请上传一幅相应大小的图像,并在此输入URL。\n\n可以用<code>$wgStylePath</code>或<code>$wgScriptPath</code>来表示相对于这些位置的路径。\n\n如果您不希望使用标志,请将本处留空。",
        "config-instantcommons": "启用即时共享资源",
        "config-instantcommons-help": "[//www.mediawiki.org/wiki/InstantCommons 即时共享资源]可以让wiki使用来自[//commons.wikimedia.org/ 维基共享资源]网站的图像、音频和其他媒体文件。要启用该功能,MediaWiki必须能够访问互联网。\n\n有关此功能的详细信息,包括如何将其他wiki网站设为具有类似共享功能的方法,请参考[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos 手册]。",
        "config-cc-error": "知识共享许可证挑选器无法找到结果,请手动输入许可证的名称。",
        "config-cc-again": "重新挑选……",
-       "config-cc-not-chosen": "选择想要的知识共享许可协议并单击“proceed”。",
+       "config-cc-not-chosen": "选择想要的知识共享许可协议并单击“proceed”。",
        "config-advanced-settings": "高级设置",
        "config-cache-options": "对象缓存设置:",
        "config-cache-help": "对象缓存可通过缓存频繁使用的数据来提高MediaWiki的速度。高度推荐中到大型的网站启用该功能,小型网站亦能从其中受益。",
        "config-skins-missing": "没有找到皮肤;MediaWiki将使用备选皮肤直到您自行安装一个后。",
        "config-skins-must-enable-some": "您必须选择至少一个皮肤以起用。",
        "config-skins-must-enable-default": "默认选择的皮肤必须启用。",
-       "config-install-alreadydone": "'''警告:'''您似乎已经安装了MediaWiki,并试图重新安装它。请前往下一个页面。",
+       "config-install-alreadydone": "<strong>警告:</strong>您似乎已经安装了MediaWiki,并试图重新安装它。请前往下一个页面。",
        "config-install-begin": "点击“{{int:config-continue}}”后,您将开始安装MediaWiki。如果您还想对配置作一些修改,请点击“{{int:config-back}}”。",
        "config-install-step-done": "完成",
        "config-install-step-failed": "失败",
        "config-install-user-missing": "指定的用户“$1”不存在。",
        "config-install-user-missing-create": "指定的用户“$1”不存在。如果您想要创建一名,请点选“创建帐户”下面的复选框。",
        "config-install-tables": "正在创建数据表",
-       "config-install-tables-exist": "'''警告''':MediaWiki的数据表似乎已经存在,跳过创建。",
-       "config-install-tables-failed": "'''错误''':创建数据表出错,下为错误信息:$1",
+       "config-install-tables-exist": "<strong>警告:</strong>MediaWiki的数据表似乎已经存在,跳过创建。",
+       "config-install-tables-failed": "<strong>错误:</strong>创建数据表出错,下为错误信息:$1",
        "config-install-interwiki": "正在填充默认的跨wiki数据表",
-       "config-install-interwiki-list": "æ\89¾ä¸\8då\88°文件<code>interwiki.list</code>。",
-       "config-install-interwiki-exists": "'''警告''':跨wiki数据表似乎已有内容,跳过默认列表。",
+       "config-install-interwiki-list": "æ\97 æ³\95读å\8f\96文件<code>interwiki.list</code>。",
+       "config-install-interwiki-exists": "<strong>警告:</strong>跨wiki数据表似乎已有内容,跳过默认列表。",
        "config-install-stats": "初始化统计",
        "config-install-keys": "生成密钥中",
-       "config-insecure-keys": "'''警告''':在安装过程中生成的{{PLURAL:$2|安全密钥|安全密钥}}($1){{PLURAL:$2|并|并}}不一定安全。请考虑手动更改{{PLURAL:$2|它|它们}}。",
+       "config-insecure-keys": "<strong>警告:</strong>在安装过程中生成的{{PLURAL:$2|安全密钥}}($1){{PLURAL:$2|并}}不一定安全。请考虑手动更改{{PLURAL:$2|它|它们}}。",
        "config-install-updates": "防止运行不需要的更新",
        "config-install-updates-failed": "<strong>错误:</strong>表格中插入更新关键字失败并出现如下错误:$1",
        "config-install-sysop": "正在创建管理员用户帐号",
        "config-help": "帮助",
        "config-help-tooltip": "单击展开",
        "config-nofile": "找不到文件“$1”。它是否已被删除?",
-       "config-extension-link": "æ\82¨æ\98¯å\90¦ç\9f¥é\81\93æ\82¨ç\9a\84wikiæ\94¯æ\8c\81[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions æ\8b\93å±\95]ï¼\9f\næ\82¨å\8f¯æµ\8fè§\88[//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category æ\8b\93å±\95å\88\86ç±»]。",
+       "config-extension-link": "æ\82¨æ\98¯å\90¦ç\9f¥é\81\93æ\82¨ç\9a\84wikiæ\94¯æ\8c\81[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions æ\89©å±\95]ï¼\9f\n\næ\82¨å\8f¯ä»¥æµ\8fè§\88[//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category æ\89©å±\95å\88\86ç±»]æ\88\96[//www.mediawiki.org/wiki/Extension_Matrix æ\89©å±\95ç\9f©é\98µ]以æ\9f¥ç\9c\8bå®\8cæ\95´ç\9a\84æ\89©å±\95å\88\97表。",
        "mainpagetext": "<strong>已安装MediaWiki。</strong>",
        "mainpagedocfooter": "请查阅[//meta.wikimedia.org/wiki/Help:Contents 用户指南]以获取使用本wiki软件的信息!\n\n== 入门 ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings MediaWiki配置设置列表]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/zh-hans 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 了解如何在您的wiki上打击破坏]"
 }
index 4f57b1f..4f96f4b 100644 (file)
@@ -14,7 +14,8 @@
                        "S8321414",
                        "LNDDYL",
                        "NigelSoft",
-                       "Macofe"
+                       "Macofe",
+                       "Reke"
                ]
        },
        "config-desc": "MediaWiki 安裝程式",
@@ -23,7 +24,7 @@
        "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-localsettings-badkey": "你提供的升級金鑰不正確。",
        "config-upgrade-key-missing": "已偵測到先前安裝的 MediaWiki。\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\n$1",
index 9a5a3ff..5a0dd36 100644 (file)
@@ -60,8 +60,8 @@ class Interwiki {
                $this->mURL = $url;
                $this->mAPI = $api;
                $this->mWikiID = $wikiId;
-               $this->mLocal = $local;
-               $this->mTrans = $trans;
+               $this->mLocal = (bool)$local;
+               $this->mTrans = (bool)$trans;
        }
 
        /**
@@ -115,7 +115,16 @@ class Interwiki {
        }
 
        /**
-        * Purge the cache for an interwiki prefix
+        * Resets locally cached Interwiki objects. This is intended for use during testing only.
+        * This does not invalidate entries in the persistent cache, as invalidateCache() does.
+        * @since 1.27
+        */
+       public static function resetLocalCache() {
+               static::$smCache = [];
+       }
+
+       /**
+        * Purge the cache (local and persistent) for an interwiki prefix.
         * @param string $prefix
         * @since 1.26
         */
@@ -123,6 +132,7 @@ class Interwiki {
                $cache = ObjectCache::getMainWANInstance();
                $key = wfMemcKey( 'interwiki', $prefix );
                $cache->delete( $key );
+               unset( static::$smCache[$prefix] );
        }
 
        /**
@@ -141,7 +151,7 @@ class Interwiki {
                        // Split values
                        list( $local, $url ) = explode( ' ', $value, 2 );
                        $s->mURL = $url;
-                       $s->mLocal = (int)$local;
+                       $s->mLocal = (bool)$local;
                } else {
                        $s = false;
                }
@@ -161,7 +171,6 @@ class Interwiki {
                global $wgInterwikiScopes, $wgInterwikiFallbackSite;
                static $site;
 
-               wfDebug( __METHOD__ . "( $prefix )\n" );
                $value = false;
                try {
                        // Resolve site name
@@ -262,8 +271,8 @@ class Interwiki {
                if ( isset( $mc['iw_url'] ) ) {
                        $iw = new Interwiki();
                        $iw->mURL = $mc['iw_url'];
-                       $iw->mLocal = isset( $mc['iw_local'] ) ? $mc['iw_local'] : 0;
-                       $iw->mTrans = isset( $mc['iw_trans'] ) ? $mc['iw_trans'] : 0;
+                       $iw->mLocal = isset( $mc['iw_local'] ) ? (bool)$mc['iw_local'] : false;
+                       $iw->mTrans = isset( $mc['iw_trans'] ) ? (bool)$mc['iw_trans'] : false;
                        $iw->mAPI = isset( $mc['iw_api'] ) ? $mc['iw_api'] : '';
                        $iw->mWikiID = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : '';
 
@@ -453,7 +462,7 @@ class Interwiki {
        public function getName() {
                $msg = wfMessage( 'interwiki-name-' . $this->mPrefix )->inContentLanguage();
 
-               return !$msg->exists() ? '' : $msg;
+               return !$msg->exists() ? '' : $msg->text();
        }
 
        /**
@@ -464,7 +473,7 @@ class Interwiki {
        public function getDescription() {
                $msg = wfMessage( 'interwiki-desc-' . $this->mPrefix )->inContentLanguage();
 
-               return !$msg->exists() ? '' : $msg;
+               return !$msg->exists() ? '' : $msg->text();
        }
 
        /**
index 2dd0615..a4b3241 100644 (file)
@@ -407,7 +407,7 @@ class JobQueueGroup {
 
                                        return [ 'v' => $wgConf->getConfig( $wiki, $name ) ];
                                },
-                               [ 'pcTTL' => 30 ]
+                               [ 'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
                        );
 
                        return $value['v'];
index 22afead..fbc1572 100644 (file)
@@ -70,7 +70,7 @@ class RecentChangesUpdateJob extends Job {
        }
 
        protected function purgeExpiredRows() {
-               global $wgRCMaxAge;
+               global $wgRCMaxAge, $wgUpdateRowsPerQuery;
 
                $lockKey = wfWikiID() . ':recentchanges-prune';
 
@@ -81,14 +81,13 @@ class RecentChangesUpdateJob extends Job {
                        return; // already in progress
                }
 
-               $batchSize = 100; // avoid slave lag
                $cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
                do {
                        $rcIds = $dbw->selectFieldValues( 'recentchanges',
                                'rc_id',
                                [ 'rc_timestamp < ' . $dbw->addQuotes( $cutoff ) ],
                                __METHOD__,
-                               [ 'LIMIT' => $batchSize ]
+                               [ 'LIMIT' => $wgUpdateRowsPerQuery ]
                        );
                        if ( $rcIds ) {
                                $dbw->delete( 'recentchanges', [ 'rc_id' => $rcIds ], __METHOD__ );
@@ -96,7 +95,7 @@ class RecentChangesUpdateJob extends Job {
                        // Commit in chunks to avoid slave lag
                        $dbw->commit( __METHOD__, 'flush' );
 
-                       if ( count( $rcIds ) === $batchSize ) {
+                       if ( count( $rcIds ) === $wgUpdateRowsPerQuery ) {
                                // There might be more, so try waiting for slaves
                                try {
                                        wfGetLBFactory()->waitForReplication( [ 'timeout' => 3 ] );
index 15ee980..b7653be 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup JobQueue
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Job to update link tables for pages
@@ -149,9 +150,18 @@ class RefreshLinksJob extends Job {
                        $revision = Revision::newFromTitle( $title, false, Revision::READ_LATEST );
                }
 
+               $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+
                if ( !$revision ) {
+                       $stats->increment( 'refreshlinks.rev_not_found' );
                        $this->setLastError( "Revision not found for {$title->getPrefixedDBkey()}" );
                        return false; // just deleted?
+               } elseif ( !$revision->isCurrent() ) {
+                       // If the revision isn't current, there's no point in doing a bunch
+                       // of work just to fail at the lockAndGetLatest() check later.
+                       $stats->increment( 'refreshlinks.rev_not_current' );
+                       $this->setLastError( "Revision {$revision->getId()} is not current" );
+                       return false;
                }
 
                $content = $revision->getContent( Revision::RAW );
@@ -181,21 +191,27 @@ class RefreshLinksJob extends Job {
 
                        if ( $page->getLinksTimestamp() > $skewedTimestamp ) {
                                // Something already updated the backlinks since this job was made
+                               $stats->increment( 'refreshlinks.update_skipped' );
                                return true;
                        }
 
-                       if ( $page->getTouched() >= $skewedTimestamp || $opportunistic ) {
-                               // Something bumped page_touched since this job was made
-                               // or the cache is otherwise suspected to be up-to-date
+                       if ( $page->getTouched() >= $this->params['rootJobTimestamp'] || $opportunistic ) {
+                               // Cache is suspected to be up-to-date. As long as the cache rev ID matches
+                               // and it reflects the job's triggering change, then it is usable.
                                $parserOutput = ParserCache::singleton()->getDirty( $page, $parserOptions );
-                               if ( $parserOutput && $parserOutput->getCacheTime() < $skewedTimestamp ) {
+                               if ( !$parserOutput
+                                       || $parserOutput->getCacheRevisionId() != $revision->getId()
+                                       || $parserOutput->getCacheTime() < $skewedTimestamp
+                               ) {
                                        $parserOutput = false; // too stale
                                }
                        }
                }
 
                // Fetch the current revision and parse it if necessary...
-               if ( $parserOutput == false ) {
+               if ( $parserOutput ) {
+                       $stats->increment( 'refreshlinks.parser_cached' );
+               } else {
                        $start = microtime( true );
                        // Revision ID must be passed to the parser output to get revision variables correct
                        $parserOutput = $content->getParserOutput(
@@ -213,6 +229,7 @@ class RefreshLinksJob extends Job {
                                        $parserOutput, $page, $parserOptions, $ctime, $revision->getId()
                                );
                        }
+                       $stats->increment( 'refreshlinks.parser_uncached' );
                }
 
                $updates = $content->getSecondaryDataUpdates(
@@ -246,6 +263,7 @@ class RefreshLinksJob extends Job {
                        // serialized, it would be OK to update links based on older revisions since it
                        // would eventually get to the latest. Since that is not the case (by design),
                        // only update the link tables to a state matching the current revision's output.
+                       $stats->increment( 'refreshlinks.rev_cas_failure' );
                        $this->setLastError( "page_latest changed from {$revision->getId()} to $latestNow" );
                        return false;
                }
index 2f2faed..6e40f4c 100644 (file)
@@ -172,7 +172,7 @@ class CSSMin {
        }
 
        /**
-        * @param $file string
+        * @param string $file
         * @return bool|string
         */
        public static function getMimeType( $file ) {
index f28a4c0..b0cd413 100644 (file)
@@ -54,10 +54,6 @@ abstract class EventRelayer implements LoggerAwareInterface {
                return $this->doNotify( $channel, $events );
        }
 
-       /**
-        * Set logger instance.
-        * @param LoggerInterface $logger
-        */
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
        }
index 8e3c0a5..bf46ce1 100644 (file)
@@ -285,8 +285,12 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10 ) {
                do {
                        $this->clearLastError();
+                       $reportDupes = $this->reportDupes;
+                       $this->reportDupes = false;
                        $casToken = null; // passed by reference
                        $currentValue = $this->getWithToken( $key, $casToken, self::READ_LATEST );
+                       $this->reportDupes = $reportDupes;
+
                        if ( $this->getLastError() ) {
                                return false; // don't spam retries (retry only on races)
                        }
@@ -342,7 +346,11 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                }
 
                $this->clearLastError();
+               $reportDupes = $this->reportDupes;
+               $this->reportDupes = false;
                $currentValue = $this->get( $key, self::READ_LATEST );
+               $this->reportDupes = $reportDupes;
+
                if ( $this->getLastError() ) {
                        $success = false;
                } else {
index fa465c7..91e7934 100644 (file)
@@ -29,7 +29,6 @@
  * @since 1.27
  */
 interface IExpiringStore {
-
        // Constants for TTL values, in seconds
        const TTL_MINUTE = 60;
        const TTL_HOUR = 3600;
@@ -38,5 +37,9 @@ interface IExpiringStore {
        const TTL_MONTH = 2592000; // 30 * 24 * 3600
        const TTL_YEAR = 31536000; // 365 * 24 * 3600
 
+       // Shorthand process cache TTLs (useful for web requests and CLI mode)
+       const TTL_PROC_SHORT = 3; // reasonably strict cache time that last the life of quick requests
+       const TTL_PROC_LONG = 30; // loose cache time that can survive slow web requests
+
        const TTL_INDEFINITE = 0;
 }
index 59322b6..668135d 100644 (file)
@@ -487,7 +487,7 @@ class MemcachedClient {
         */
        public function get_multi( $keys ) {
                if ( !$this->_active ) {
-                       return false;
+                       return array();
                }
 
                if ( isset( $this->stats['get_multi'] ) ) {
index dd2e0d5..18cc10e 100644 (file)
@@ -69,10 +69,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        protected $cache;
        /** @var HashBagOStuff Script instance PHP cache */
        protected $procCache;
-       /** @var string Cache pool name */
-       protected $pool;
+       /** @var string Purge channel name */
+       protected $purgeChannel;
        /** @var EventRelayer Bus that handles purge broadcasts */
-       protected $relayer;
+       protected $purgeRelayer;
        /** @var LoggerInterface */
        protected $logger;
 
@@ -134,25 +134,27 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
        const MAX_PC_KEYS = 1000; // max keys to keep in process cache
 
+       const DEFAULT_PURGE_CHANNEL = 'wancache-purge';
+
        /**
         * @param array $params
-        *   - cache   : BagOStuff object
-        *   - pool    : pool name
-        *   - relayer : EventRelayer object
-        *   - logger  : LoggerInterface object
+        *   - cache    : BagOStuff object for a persistent cache
+        *   - channels : Map of (action => channel string). Actions include "purge".
+        *   - relayers : Map of (action => EventRelayer object). Actions include "purge".
+        *   - logger   : LoggerInterface object
         */
        public function __construct( array $params ) {
                $this->cache = $params['cache'];
-               $this->pool = $params['pool'];
-               $this->relayer = $params['relayer'];
                $this->procCache = new HashBagOStuff( [ 'maxKeys' => self::MAX_PC_KEYS ] );
+               $this->purgeChannel = isset( $params['channels']['purge'] )
+                       ? $params['channels']['purge']
+                       : self::DEFAULT_PURGE_CHANNEL;
+               $this->purgeRelayer = isset( $params['relayers']['purge'] )
+                       ? $params['relayers']['purge']
+                       : new EventRelayerNull( [] );
                $this->setLogger( isset( $params['logger'] ) ? $params['logger'] : new NullLogger() );
        }
 
-       /**
-        * Set logger instance.
-        * @param LoggerInterface $logger
-        */
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
        }
@@ -673,12 +675,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *
         *             return CatConfig::newFromRow( $dbr->selectRow( ... ) );
         *         },
-        *         array(
+        *         [
         *             // Calling touchCheckKey() on this key invalidates the cache
-        *             'checkKeys' => array( $cache->makeKey( 'site-cat-config' ) ),
+        *             'checkKeys' => [ $cache->makeKey( 'site-cat-config' ) ],
         *             // Try to only let one datacenter thread manage cache updates at a time
         *             'lockTSE' => 30
-        *         )
+        *         ]
         *     );
         * @endcode
         *
@@ -698,15 +700,15 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *
         *             return CatState::newFromResults( $dbr->select( ... ) );
         *         },
-        *         array(
+        *         [
         *              // The "check" keys that represent things the value depends on;
         *              // Calling touchCheckKey() on any of them invalidates the cache
-        *             'checkKeys' => array(
+        *             'checkKeys' => [
         *                 $cache->makeKey( 'sustenance-bowls', $cat->getRoomId() ),
         *                 $cache->makeKey( 'people-present', $cat->getHouseId() ),
         *                 $cache->makeKey( 'cat-laws', $cat->getCityId() ),
-        *             )
-        *         )
+        *             ]
+        *         ]
         *     );
         * @endcode
         *
@@ -724,7 +726,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *             $setOpts += Database::getCacheSetOptions( $dbr );
         *
         *             // Start off with the last cached list
-        *             $list = $oldValue ?: array();
+        *             $list = $oldValue ?: [];
         *             // Fetch the last 100 relevant rows in descending order;
         *             // only fetch rows newer than $list[0] to reduce scanning
         *             $rows = iterator_to_array( $dbr->select( ... ) );
@@ -732,7 +734,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *             return array_slice( array_merge( $new, $list ), 0, 100 );
         *        },
         *        // Try to only let one datacenter thread manage cache updates at a time
-        *        array( 'lockTSE' => 30 )
+        *        [ 'lockTSE' => 30 ]
         *     );
         * @endcode
         *
@@ -950,7 +952,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        'sbt' => true, // substitute $UNIXTIME$ with actual microtime
                ] );
 
-               $ok = $this->relayer->notify( "{$this->pool}:purge", $event );
+               $ok = $this->purgeRelayer->notify( $this->purgeChannel, $event );
                if ( !$ok ) {
                        $this->lastRelayError = self::ERR_RELAY;
                }
@@ -970,7 +972,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        'key' => $key,
                ] );
 
-               $ok = $this->relayer->notify( "{$this->pool}:purge", $event );
+               $ok = $this->purgeRelayer->notify( $this->purgeChannel, $event );
                if ( !$ok ) {
                        $this->lastRelayError = self::ERR_RELAY;
                }
index 2764f46..da48e00 100644 (file)
@@ -33,6 +33,14 @@ interface LinkTarget {
         */
        public function getNamespace();
 
+       /**
+        * Convenience function to test if it is in the namespace
+        *
+        * @param int $ns
+        * @return bool
+        */
+       public function inNamespace( $ns );
+
        /**
         * Get the link fragment (i.e. the bit after the #) in text form.
         *
@@ -73,4 +81,18 @@ interface LinkTarget {
         * @return LinkTarget
         */
        public function createFragmentTarget( $fragment );
+
+       /**
+        * Whether this LinkTarget has an interwiki component
+        *
+        * @return bool
+        */
+       public function isExternal();
+
+       /**
+        * The interwiki component of this LinkTarget
+        *
+        * @return string
+        */
+       public function getInterwiki();
 }
index 664c111..1d0bdf6 100644 (file)
@@ -25,6 +25,8 @@
  */
 use MediaWiki\Linker\LinkTarget;
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * This module processes the email notifications when the current page is
  * changed. It looks up the table watchlist to find out which users are watching
@@ -92,7 +94,7 @@ class EmailNotification {
                if ( !$config->get( 'EnotifWatchlist' ) && !$config->get( 'ShowUpdatedMarker' ) ) {
                        return [];
                }
-               return WatchedItemStore::getDefaultInstance()->updateNotificationTimestamp(
+               return MediaWikiServices::getInstance()->getWatchedItemStore()->updateNotificationTimestamp(
                        $editor,
                        $linkTarget,
                        $timestamp
@@ -125,7 +127,7 @@ class EmailNotification {
                $config = RequestContext::getMain()->getConfig();
                $watchers = [];
                if ( $config->get( 'EnotifWatchlist' ) || $config->get( 'ShowUpdatedMarker' ) ) {
-                       $watchers = WatchedItemStore::getDefaultInstance()->updateNotificationTimestamp(
+                       $watchers = MediaWikiServices::getInstance()->getWatchedItemStore()->updateNotificationTimestamp(
                                $editor,
                                $title,
                                $timestamp
index 4da41c8..ccd345c 100644 (file)
@@ -104,6 +104,25 @@ class BitmapHandler extends TransformationalImageHandler {
                return true;
        }
 
+       /**
+        * Get ImageMagick subsampling factors for the target JPEG pixel format.
+        *
+        * @param string $pixelFormat one of 'yuv444', 'yuv422', 'yuv420'
+        * @return array of string keys
+        */
+       protected function imageMagickSubsampling( $pixelFormat ) {
+               switch ( $pixelFormat ) {
+               case 'yuv444':
+                       return [ '1x1', '1x1', '1x1' ];
+               case 'yuv422':
+                       return [ '2x1', '1x1', '1x1' ];
+               case 'yuv420':
+                       return [ '2x2', '1x1', '1x1' ];
+               default:
+                       throw new MWException( 'Invalid pixel format for JPEG output' );
+               }
+       }
+
        /**
         * Transform an image using ImageMagick
         *
@@ -115,7 +134,7 @@ class BitmapHandler extends TransformationalImageHandler {
        protected function transformImageMagick( $image, $params ) {
                # use ImageMagick
                global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
-                       $wgImageMagickTempDir, $wgImageMagickConvertCommand;
+                       $wgImageMagickTempDir, $wgImageMagickConvertCommand, $wgJpegPixelFormat;
 
                $quality = [];
                $sharpen = [];
@@ -123,6 +142,7 @@ class BitmapHandler extends TransformationalImageHandler {
                $animation_pre = [];
                $animation_post = [];
                $decoderHint = [];
+               $subsampling = [];
 
                if ( $params['mimeType'] == 'image/jpeg' ) {
                        $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
@@ -141,6 +161,10 @@ class BitmapHandler extends TransformationalImageHandler {
                                // JPEG decoder hint to reduce memory, available since IM 6.5.6-2
                                $decoderHint = [ '-define', "jpeg:size={$params['physicalDimensions']}" ];
                        }
+                       if ( $wgJpegPixelFormat ) {
+                               $factors = $this->imageMagickSubsampling( $wgJpegPixelFormat );
+                               $subsampling = [ '-sampling-factor', implode( ',', $factors ) ];
+                       }
                } elseif ( $params['mimeType'] == 'image/png' ) {
                        $quality = [ '-quality', '95' ]; // zlib 9, adaptive filtering
                        if ( $params['interlace'] ) {
@@ -225,6 +249,7 @@ class BitmapHandler extends TransformationalImageHandler {
                        [ '-depth', 8 ],
                        $sharpen,
                        [ '-rotate', "-$rotation" ],
+                       $subsampling,
                        $animation_post,
                        [ $this->escapeMagickOutput( $params['dstPath'] ) ] ) );
 
@@ -251,7 +276,7 @@ class BitmapHandler extends TransformationalImageHandler {
         */
        protected function transformImageMagickExt( $image, $params ) {
                global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
-                       $wgMaxInterlacingAreas;
+                       $wgMaxInterlacingAreas, $wgJpegPixelFormat;
 
                try {
                        $im = new Imagick();
@@ -272,6 +297,10 @@ class BitmapHandler extends TransformationalImageHandler {
                                if ( $params['interlace'] ) {
                                        $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
                                }
+                               if ( $wgJpegPixelFormat ) {
+                                       $factors = $this->imageMagickSubsampling( $wgJpegPixelFormat );
+                                       $im->setSamplingFactors( $factors );
+                               }
                        } elseif ( $params['mimeType'] == 'image/png' ) {
                                $im->setCompressionQuality( 95 );
                                if ( $params['interlace'] ) {
index 8ec7298..5f23855 100644 (file)
@@ -193,7 +193,7 @@ class GIFHandler extends BitmapHandler {
         *
         * Shown in the &query=imageinfo&iiprop=size api query.
         *
-        * @param $file File
+        * @param File $file
         * @return float The duration of the file.
         */
        public function getLength( $file ) {
index f9af101..8a3e001 100644 (file)
@@ -180,7 +180,7 @@ class PNGHandler extends BitmapHandler {
         *
         * Shown in the &query=imageinfo&iiprop=size api query.
         *
-        * @param $file File
+        * @param File $file
         * @return float The duration of the file.
         */
        public function getLength( $file ) {
index f1f2161..3287fac 100644 (file)
@@ -288,9 +288,9 @@ abstract class TransformationalImageHandler extends ImageHandler {
        /**
         * Get the source file for the transform
         *
-        * @param $file File
-        * @param $params Array
-        * @return Array Array with keys  width, height and path.
+        * @param File $file
+        * @param array $params
+        * @return array Array with keys  width, height and path.
         */
        protected function getThumbnailSource( $file, $params ) {
                return $file->getThumbnailSource( $params );
index 1ef4d26..b4f515a 100644 (file)
@@ -184,3 +184,5 @@ chemical/x-mdl-sdfile sdf
 chemical/x-mdl-rxnfile rxn
 chemical/x-mdl-rdfile rd
 chemical/x-mdl-rgfile rg
+application/x-amf amf
+application/sla stl
index bf152b6..24846e6 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Functions to get cache objects
@@ -298,8 +299,11 @@ class ObjectCache {
                }
 
                $params = $wgWANObjectCaches[$id];
-               $class = $params['relayerConfig']['class'];
-               $params['relayer'] = new $class( $params['relayerConfig'] );
+               foreach ( $params['channels'] as $action => $channel ) {
+                       $params['relayers'][$action] = MediaWikiServices::getInstance()->getEventRelayerGroup()
+                               ->getRelayer( $channel );
+                       $params['channels'][$action] = $channel;
+               }
                $params['cache'] = self::newFromId( $params['cacheId'] );
                if ( isset( $params['loggroup'] ) ) {
                        $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] );
index 61e6926..90508da 100644 (file)
@@ -310,7 +310,8 @@ class RedisBagOStuff extends BagOStuff {
         * @return mixed
         */
        protected function unserialize( $data ) {
-               return ctype_digit( $data ) ? intval( $data ) : unserialize( $data );
+               $int = intval( $data );
+               return $data === (string)$int ? $int : unserialize( $data );
        }
 
        /**
index a6b9915..0dc28bd 100644 (file)
  * @ingroup Media
  */
 class WikiFilePage extends WikiPage {
-       /**
-        * @var File
-        */
+       /** @var File */
        protected $mFile = false;
+       /** @var LocalRepo */
        protected $mRepo = null;
+       /** @var bool */
        protected $mFileLoaded = false;
+       /** @var array */
        protected $mDupes = null;
 
        public function __construct( $title ) {
@@ -170,7 +171,6 @@ class WikiFilePage extends WikiPage {
                if ( $this->mFile->exists() ) {
                        wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
                        DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
-                       $this->mFile->upgradeRow();
                        $this->mFile->purgeCache( [ 'forThumbRefresh' => true ] );
                } else {
                        wfDebug( 'ImagePage::doPurge no image for '
index 06785b7..040a6f3 100644 (file)
@@ -2115,7 +2115,13 @@ class WikiPage implements Page, IDBAccessObject {
                        : '';
                $edit->pst = $edit->pstContent ? $edit->pstContent->serialize( $serialFormat ) : '';
 
+               if ( $edit->output ) {
+                       $edit->output->setCacheTime( wfTimestampNow() );
+               }
+
+               // Process cache the result
                $this->mPreparedEdit = $edit;
+
                return $edit;
        }
 
diff --git a/includes/parser/BlockLevelPass.php b/includes/parser/BlockLevelPass.php
new file mode 100644 (file)
index 0000000..cbacd34
--- /dev/null
@@ -0,0 +1,535 @@
+<?php
+
+/**
+ * This is the part of the wikitext parser which handles automatic paragraphs
+ * and conversion of start-of-line prefixes to HTML lists.
+ *
+ * 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 Parser
+ */
+class BlockLevelPass {
+       private $DTopen = false;
+       private $inPre = false;
+       private $lastSection = '';
+       private $linestart;
+       private $text;
+
+       # State constants for the definition list colon extraction
+       const COLON_STATE_TEXT = 0;
+       const COLON_STATE_TAG = 1;
+       const COLON_STATE_TAGSTART = 2;
+       const COLON_STATE_CLOSETAG = 3;
+       const COLON_STATE_TAGSLASH = 4;
+       const COLON_STATE_COMMENT = 5;
+       const COLON_STATE_COMMENTDASH = 6;
+       const COLON_STATE_COMMENTDASHDASH = 7;
+
+       /**
+        * Make lists from lines starting with ':', '*', '#', etc.
+        *
+        * @param string $text
+        * @param bool $lineStart Whether or not this is at the start of a line.
+        * @return string The lists rendered as HTML
+        */
+       public static function doBlockLevels( $text, $lineStart ) {
+               $pass = new self( $text, $lineStart );
+               return $pass->execute();
+       }
+
+       /**
+        * Private constructor
+        */
+       private function __construct( $text, $lineStart ) {
+               $this->text = $text;
+               $this->lineStart = $lineStart;
+       }
+
+       /**
+        * If a pre or p is open, return the corresponding close tag and update
+        * the state. If no tag is open, return an empty string.
+        * @return string
+        */
+       private function closeParagraph() {
+               $result = '';
+               if ( $this->lastSection !== '' ) {
+                       $result = '</' . $this->lastSection . ">\n";
+               }
+               $this->inPre = false;
+               $this->lastSection = '';
+               return $result;
+       }
+
+       /**
+        * getCommon() returns the length of the longest common substring
+        * of both arguments, starting at the beginning of both.
+        *
+        * @param string $st1
+        * @param string $st2
+        *
+        * @return int
+        */
+       private function getCommon( $st1, $st2 ) {
+               $shorter = min( strlen( $st1 ), strlen( $st2 ) );
+
+               for ( $i = 0; $i < $shorter; ++$i ) {
+                       if ( $st1[$i] !== $st2[$i] ) {
+                               break;
+                       }
+               }
+               return $i;
+       }
+
+       /**
+        * Open the list item element identified by the prefix character.
+        *
+        * @param string $char
+        *
+        * @return string
+        */
+       private function openList( $char ) {
+               $result = $this->closeParagraph();
+
+               if ( '*' === $char ) {
+                       $result .= "<ul><li>";
+               } elseif ( '#' === $char ) {
+                       $result .= "<ol><li>";
+               } elseif ( ':' === $char ) {
+                       $result .= "<dl><dd>";
+               } elseif ( ';' === $char ) {
+                       $result .= "<dl><dt>";
+                       $this->DTopen = true;
+               } else {
+                       $result = '<!-- ERR 1 -->';
+               }
+
+               return $result;
+       }
+
+       /**
+        * Close the current list item and open the next one.
+        * @param string $char
+        *
+        * @return string
+        */
+       private function nextItem( $char ) {
+               if ( '*' === $char || '#' === $char ) {
+                       return "</li>\n<li>";
+               } elseif ( ':' === $char || ';' === $char ) {
+                       $close = "</dd>\n";
+                       if ( $this->DTopen ) {
+                               $close = "</dt>\n";
+                       }
+                       if ( ';' === $char ) {
+                               $this->DTopen = true;
+                               return $close . '<dt>';
+                       } else {
+                               $this->DTopen = false;
+                               return $close . '<dd>';
+                       }
+               }
+               return '<!-- ERR 2 -->';
+       }
+
+       /**
+        * Close the current list item identified by the prefix character.
+        * @param string $char
+        *
+        * @return string
+        */
+       private function closeList( $char ) {
+               if ( '*' === $char ) {
+                       $text = "</li></ul>";
+               } elseif ( '#' === $char ) {
+                       $text = "</li></ol>";
+               } elseif ( ':' === $char ) {
+                       if ( $this->DTopen ) {
+                               $this->DTopen = false;
+                               $text = "</dt></dl>";
+                       } else {
+                               $text = "</dd></dl>";
+                       }
+               } else {
+                       return '<!-- ERR 3 -->';
+               }
+               return $text;
+       }
+
+       /**
+        * Execute the pass.
+        * @return string
+        */
+       private function execute() {
+               $text = $this->text;
+               # Parsing through the text line by line.  The main thing
+               # happening here is handling of block-level elements p, pre,
+               # and making lists from lines starting with * # : etc.
+               $textLines = StringUtils::explode( "\n", $text );
+
+               $lastPrefix = $output = '';
+               $this->DTopen = $inBlockElem = false;
+               $prefixLength = 0;
+               $pendingPTag = false;
+               $inBlockquote = false;
+
+               foreach ( $textLines as $inputLine ) {
+                       # Fix up $lineStart
+                       if ( !$this->lineStart ) {
+                               $output .= $inputLine;
+                               $this->lineStart = true;
+                               continue;
+                       }
+                       # * = ul
+                       # # = ol
+                       # ; = dt
+                       # : = dd
+
+                       $lastPrefixLength = strlen( $lastPrefix );
+                       $preCloseMatch = preg_match( '/<\\/pre/i', $inputLine );
+                       $preOpenMatch = preg_match( '/<pre/i', $inputLine );
+                       # If not in a <pre> element, scan for and figure out what prefixes are there.
+                       if ( !$this->inPre ) {
+                               # Multiple prefixes may abut each other for nested lists.
+                               $prefixLength = strspn( $inputLine, '*#:;' );
+                               $prefix = substr( $inputLine, 0, $prefixLength );
+
+                               # eh?
+                               # ; and : are both from definition-lists, so they're equivalent
+                               #  for the purposes of determining whether or not we need to open/close
+                               #  elements.
+                               $prefix2 = str_replace( ';', ':', $prefix );
+                               $t = substr( $inputLine, $prefixLength );
+                               $this->inPre = (bool)$preOpenMatch;
+                       } else {
+                               # Don't interpret any other prefixes in preformatted text
+                               $prefixLength = 0;
+                               $prefix = $prefix2 = '';
+                               $t = $inputLine;
+                       }
+
+                       # List generation
+                       if ( $prefixLength && $lastPrefix === $prefix2 ) {
+                               # Same as the last item, so no need to deal with nesting or opening stuff
+                               $output .= $this->nextItem( substr( $prefix, -1 ) );
+                               $pendingPTag = false;
+
+                               if ( substr( $prefix, -1 ) === ';' ) {
+                                       # The one nasty exception: definition lists work like this:
+                                       # ; title : definition text
+                                       # So we check for : in the remainder text to split up the
+                                       # title and definition, without b0rking links.
+                                       $term = $t2 = '';
+                                       if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
+                                               $t = $t2;
+                                               $output .= $term . $this->nextItem( ':' );
+                                       }
+                               }
+                       } elseif ( $prefixLength || $lastPrefixLength ) {
+                               # We need to open or close prefixes, or both.
+
+                               # Either open or close a level...
+                               $commonPrefixLength = $this->getCommon( $prefix, $lastPrefix );
+                               $pendingPTag = false;
+
+                               # Close all the prefixes which aren't shared.
+                               while ( $commonPrefixLength < $lastPrefixLength ) {
+                                       $output .= $this->closeList( $lastPrefix[$lastPrefixLength - 1] );
+                                       --$lastPrefixLength;
+                               }
+
+                               # Continue the current prefix if appropriate.
+                               if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
+                                       $output .= $this->nextItem( $prefix[$commonPrefixLength - 1] );
+                               }
+
+                               # Open prefixes where appropriate.
+                               if ( $lastPrefix && $prefixLength > $commonPrefixLength ) {
+                                       $output .= "\n";
+                               }
+                               while ( $prefixLength > $commonPrefixLength ) {
+                                       $char = substr( $prefix, $commonPrefixLength, 1 );
+                                       $output .= $this->openList( $char );
+
+                                       if ( ';' === $char ) {
+                                               # @todo FIXME: This is dupe of code above
+                                               if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
+                                                       $t = $t2;
+                                                       $output .= $term . $this->nextItem( ':' );
+                                               }
+                                       }
+                                       ++$commonPrefixLength;
+                               }
+                               if ( !$prefixLength && $lastPrefix ) {
+                                       $output .= "\n";
+                               }
+                               $lastPrefix = $prefix2;
+                       }
+
+                       # If we have no prefixes, go to paragraph mode.
+                       if ( 0 == $prefixLength ) {
+                               # No prefix (not in list)--go to paragraph mode
+                               # @todo consider using a stack for nestable elements like span, table and div
+                               $openMatch = preg_match(
+                                       '/(?:<table|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|'
+                                               . '<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS',
+                                       $t
+                               );
+                               $closeMatch = preg_match(
+                                       '/(?:<\\/table|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'
+                                               . '<td|<th|<\\/?blockquote|<\\/?div|<hr|<\\/pre|<\\/p|<\\/mw:|'
+                                               . Parser::MARKER_PREFIX
+                                               . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS',
+                                       $t
+                               );
+
+                               if ( $openMatch || $closeMatch ) {
+                                       $pendingPTag = false;
+                                       # @todo bug 5718: paragraph closed
+                                       $output .= $this->closeParagraph();
+                                       if ( $preOpenMatch && !$preCloseMatch ) {
+                                               $this->inPre = true;
+                                       }
+                                       $bqOffset = 0;
+                                       while ( preg_match( '/<(\\/?)blockquote[\s>]/i', $t,
+                                               $bqMatch, PREG_OFFSET_CAPTURE, $bqOffset )
+                                       ) {
+                                               $inBlockquote = !$bqMatch[1][0]; // is this a close tag?
+                                               $bqOffset = $bqMatch[0][1] + strlen( $bqMatch[0][0] );
+                                       }
+                                       $inBlockElem = !$closeMatch;
+                               } elseif ( !$inBlockElem && !$this->inPre ) {
+                                       if ( ' ' == substr( $t, 0, 1 )
+                                               && ( $this->lastSection === 'pre' || trim( $t ) != '' )
+                                               && !$inBlockquote
+                                       ) {
+                                               # pre
+                                               if ( $this->lastSection !== 'pre' ) {
+                                                       $pendingPTag = false;
+                                                       $output .= $this->closeParagraph() . '<pre>';
+                                                       $this->lastSection = 'pre';
+                                               }
+                                               $t = substr( $t, 1 );
+                                       } else {
+                                               # paragraph
+                                               if ( trim( $t ) === '' ) {
+                                                       if ( $pendingPTag ) {
+                                                               $output .= $pendingPTag . '<br />';
+                                                               $pendingPTag = false;
+                                                               $this->lastSection = 'p';
+                                                       } else {
+                                                               if ( $this->lastSection !== 'p' ) {
+                                                                       $output .= $this->closeParagraph();
+                                                                       $this->lastSection = '';
+                                                                       $pendingPTag = '<p>';
+                                                               } else {
+                                                                       $pendingPTag = '</p><p>';
+                                                               }
+                                                       }
+                                               } else {
+                                                       if ( $pendingPTag ) {
+                                                               $output .= $pendingPTag;
+                                                               $pendingPTag = false;
+                                                               $this->lastSection = 'p';
+                                                       } elseif ( $this->lastSection !== 'p' ) {
+                                                               $output .= $this->closeParagraph() . '<p>';
+                                                               $this->lastSection = 'p';
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       # somewhere above we forget to get out of pre block (bug 785)
+                       if ( $preCloseMatch && $this->inPre ) {
+                               $this->inPre = false;
+                       }
+                       if ( $pendingPTag === false ) {
+                               $output .= $t;
+                               if ( $prefixLength === 0 ) {
+                                       $output .= "\n";
+                               }
+                       }
+               }
+               while ( $prefixLength ) {
+                       $output .= $this->closeList( $prefix2[$prefixLength - 1] );
+                       --$prefixLength;
+                       if ( !$prefixLength ) {
+                               $output .= "\n";
+                       }
+               }
+               if ( $this->lastSection !== '' ) {
+                       $output .= '</' . $this->lastSection . '>';
+                       $this->lastSection = '';
+               }
+
+               return $output;
+       }
+
+       /**
+        * Split up a string on ':', ignoring any occurrences inside tags
+        * to prevent illegal overlapping.
+        *
+        * @param string $str The string to split
+        * @param string &$before Set to everything before the ':'
+        * @param string &$after Set to everything after the ':'
+        * @throws MWException
+        * @return string The position of the ':', or false if none found
+        */
+       private function findColonNoLinks( $str, &$before, &$after ) {
+               $colonPos = strpos( $str, ':' );
+               if ( $colonPos === false ) {
+                       # Nothing to find!
+                       return false;
+               }
+
+               $ltPos = strpos( $str, '<' );
+               if ( $ltPos === false || $ltPos > $colonPos ) {
+                       # Easy; no tag nesting to worry about
+                       $before = substr( $str, 0, $colonPos );
+                       $after = substr( $str, $colonPos + 1 );
+                       return $colonPos;
+               }
+
+               # Ugly state machine to walk through avoiding tags.
+               $state = self::COLON_STATE_TEXT;
+               $level = 0;
+               $len = strlen( $str );
+               for ( $i = 0; $i < $len; $i++ ) {
+                       $c = $str[$i];
+
+                       switch ( $state ) {
+                       case self::COLON_STATE_TEXT:
+                               switch ( $c ) {
+                               case "<":
+                                       # Could be either a <start> tag or an </end> tag
+                                       $state = self::COLON_STATE_TAGSTART;
+                                       break;
+                               case ":":
+                                       if ( $level === 0 ) {
+                                               # We found it!
+                                               $before = substr( $str, 0, $i );
+                                               $after = substr( $str, $i + 1 );
+                                               return $i;
+                                       }
+                                       # Embedded in a tag; don't break it.
+                                       break;
+                               default:
+                                       # Skip ahead looking for something interesting
+                                       $colonPos = strpos( $str, ':', $i );
+                                       if ( $colonPos === false ) {
+                                               # Nothing else interesting
+                                               return false;
+                                       }
+                                       $ltPos = strpos( $str, '<', $i );
+                                       if ( $level === 0 ) {
+                                               if ( $ltPos === false || $colonPos < $ltPos ) {
+                                                       # We found it!
+                                                       $before = substr( $str, 0, $colonPos );
+                                                       $after = substr( $str, $colonPos + 1 );
+                                                       return $i;
+                                               }
+                                       }
+                                       if ( $ltPos === false ) {
+                                               # Nothing else interesting to find; abort!
+                                               # We're nested, but there's no close tags left. Abort!
+                                               break 2;
+                                       }
+                                       # Skip ahead to next tag start
+                                       $i = $ltPos;
+                                       $state = self::COLON_STATE_TAGSTART;
+                               }
+                               break;
+                       case self::COLON_STATE_TAG:
+                               # In a <tag>
+                               switch ( $c ) {
+                               case ">":
+                                       $level++;
+                                       $state = self::COLON_STATE_TEXT;
+                                       break;
+                               case "/":
+                                       # Slash may be followed by >?
+                                       $state = self::COLON_STATE_TAGSLASH;
+                                       break;
+                               default:
+                                       # ignore
+                               }
+                               break;
+                       case self::COLON_STATE_TAGSTART:
+                               switch ( $c ) {
+                               case "/":
+                                       $state = self::COLON_STATE_CLOSETAG;
+                                       break;
+                               case "!":
+                                       $state = self::COLON_STATE_COMMENT;
+                                       break;
+                               case ">":
+                                       # Illegal early close? This shouldn't happen D:
+                                       $state = self::COLON_STATE_TEXT;
+                                       break;
+                               default:
+                                       $state = self::COLON_STATE_TAG;
+                               }
+                               break;
+                       case self::COLON_STATE_CLOSETAG:
+                               # In a </tag>
+                               if ( $c === ">" ) {
+                                       $level--;
+                                       if ( $level < 0 ) {
+                                               wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
+                                               return false;
+                                       }
+                                       $state = self::COLON_STATE_TEXT;
+                               }
+                               break;
+                       case self::COLON_STATE_TAGSLASH:
+                               if ( $c === ">" ) {
+                                       # Yes, a self-closed tag <blah/>
+                                       $state = self::COLON_STATE_TEXT;
+                               } else {
+                                       # Probably we're jumping the gun, and this is an attribute
+                                       $state = self::COLON_STATE_TAG;
+                               }
+                               break;
+                       case self::COLON_STATE_COMMENT:
+                               if ( $c === "-" ) {
+                                       $state = self::COLON_STATE_COMMENTDASH;
+                               }
+                               break;
+                       case self::COLON_STATE_COMMENTDASH:
+                               if ( $c === "-" ) {
+                                       $state = self::COLON_STATE_COMMENTDASHDASH;
+                               } else {
+                                       $state = self::COLON_STATE_COMMENT;
+                               }
+                               break;
+                       case self::COLON_STATE_COMMENTDASHDASH:
+                               if ( $c === ">" ) {
+                                       $state = self::COLON_STATE_TEXT;
+                               } else {
+                                       $state = self::COLON_STATE_COMMENT;
+                               }
+                               break;
+                       default:
+                               throw new MWException( "State machine error in " . __METHOD__ );
+                       }
+               }
+               if ( $level > 0 ) {
+                       wfDebug( __METHOD__ . ": Invalid input; not enough close tags (level $level, state $state)\n" );
+                       return false;
+               }
+               return false;
+       }
+}
index a1d62e5..96674be 100644 (file)
@@ -99,16 +99,6 @@ class Parser {
        # Regular expression for a non-newline space
        const SPACE_NOT_NL = '(?:\t|&nbsp;|&\#0*160;|&\#[Xx]0*[Aa]0;|\p{Zs})';
 
-       # State constants for the definition list colon extraction
-       const COLON_STATE_TEXT = 0;
-       const COLON_STATE_TAG = 1;
-       const COLON_STATE_TAGSTART = 2;
-       const COLON_STATE_CLOSETAG = 3;
-       const COLON_STATE_TAGSLASH = 4;
-       const COLON_STATE_COMMENT = 5;
-       const COLON_STATE_COMMENTDASH = 6;
-       const COLON_STATE_COMMENTDASHDASH = 7;
-
        # Flags for preprocessToDom
        const PTD_FOR_INCLUSION = 1;
 
@@ -176,14 +166,14 @@ class Parser {
         * @var ParserOutput
         */
        public $mOutput;
-       public $mAutonumber, $mDTopen;
+       public $mAutonumber;
 
        /**
         * @var StripState
         */
        public $mStripState;
 
-       public $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
+       public $mIncludeCount;
        /**
         * @var LinkHolderArray
         */
@@ -342,11 +332,7 @@ class Parser {
                $this->mOutput = new ParserOutput;
                $this->mOptions->registerWatcher( [ $this->mOutput, 'recordOption' ] );
                $this->mAutonumber = 0;
-               $this->mLastSection = '';
-               $this->mDTopen = false;
                $this->mIncludeCount = [];
-               $this->mArgStack = false;
-               $this->mInPre = false;
                $this->mLinkHolders = new LinkHolderArray( $this );
                $this->mLinkID = 0;
                $this->mRevisionObject = $this->mRevisionTimestamp =
@@ -2401,127 +2387,6 @@ class Parser {
                return Linker::normalizeSubpageLink( $this->mTitle, $target, $text );
        }
 
-       /**#@+
-        * Used by doBlockLevels()
-        * @private
-        *
-        * @return string
-        */
-       public function closeParagraph() {
-               $result = '';
-               if ( $this->mLastSection != '' ) {
-                       $result = '</' . $this->mLastSection . ">\n";
-               }
-               $this->mInPre = false;
-               $this->mLastSection = '';
-               return $result;
-       }
-
-       /**
-        * getCommon() returns the length of the longest common substring
-        * of both arguments, starting at the beginning of both.
-        * @private
-        *
-        * @param string $st1
-        * @param string $st2
-        *
-        * @return int
-        */
-       public function getCommon( $st1, $st2 ) {
-               $fl = strlen( $st1 );
-               $shorter = strlen( $st2 );
-               if ( $fl < $shorter ) {
-                       $shorter = $fl;
-               }
-
-               for ( $i = 0; $i < $shorter; ++$i ) {
-                       if ( $st1[$i] != $st2[$i] ) {
-                               break;
-                       }
-               }
-               return $i;
-       }
-
-       /**
-        * These next three functions open, continue, and close the list
-        * element appropriate to the prefix character passed into them.
-        * @private
-        *
-        * @param string $char
-        *
-        * @return string
-        */
-       public function openList( $char ) {
-               $result = $this->closeParagraph();
-
-               if ( '*' === $char ) {
-                       $result .= "<ul><li>";
-               } elseif ( '#' === $char ) {
-                       $result .= "<ol><li>";
-               } elseif ( ':' === $char ) {
-                       $result .= "<dl><dd>";
-               } elseif ( ';' === $char ) {
-                       $result .= "<dl><dt>";
-                       $this->mDTopen = true;
-               } else {
-                       $result = '<!-- ERR 1 -->';
-               }
-
-               return $result;
-       }
-
-       /**
-        * TODO: document
-        * @param string $char
-        * @private
-        *
-        * @return string
-        */
-       public function nextItem( $char ) {
-               if ( '*' === $char || '#' === $char ) {
-                       return "</li>\n<li>";
-               } elseif ( ':' === $char || ';' === $char ) {
-                       $close = "</dd>\n";
-                       if ( $this->mDTopen ) {
-                               $close = "</dt>\n";
-                       }
-                       if ( ';' === $char ) {
-                               $this->mDTopen = true;
-                               return $close . '<dt>';
-                       } else {
-                               $this->mDTopen = false;
-                               return $close . '<dd>';
-                       }
-               }
-               return '<!-- ERR 2 -->';
-       }
-
-       /**
-        * @todo Document
-        * @param string $char
-        * @private
-        *
-        * @return string
-        */
-       public function closeList( $char ) {
-               if ( '*' === $char ) {
-                       $text = "</li></ul>";
-               } elseif ( '#' === $char ) {
-                       $text = "</li></ol>";
-               } elseif ( ':' === $char ) {
-                       if ( $this->mDTopen ) {
-                               $this->mDTopen = false;
-                               $text = "</dt></dl>";
-                       } else {
-                               $text = "</dd></dl>";
-                       }
-               } else {
-                       return '<!-- ERR 3 -->';
-               }
-               return $text;
-       }
-       /**#@-*/
-
        /**
         * Make lists from lines starting with ':', '*', '#', etc. (DBL)
         *
@@ -2531,365 +2396,7 @@ class Parser {
         * @return string The lists rendered as HTML
         */
        public function doBlockLevels( $text, $linestart ) {
-
-               # Parsing through the text line by line.  The main thing
-               # happening here is handling of block-level elements p, pre,
-               # and making lists from lines starting with * # : etc.
-               $textLines = StringUtils::explode( "\n", $text );
-
-               $lastPrefix = $output = '';
-               $this->mDTopen = $inBlockElem = false;
-               $prefixLength = 0;
-               $paragraphStack = false;
-               $inBlockquote = false;
-
-               foreach ( $textLines as $oLine ) {
-                       # Fix up $linestart
-                       if ( !$linestart ) {
-                               $output .= $oLine;
-                               $linestart = true;
-                               continue;
-                       }
-                       # * = ul
-                       # # = ol
-                       # ; = dt
-                       # : = dd
-
-                       $lastPrefixLength = strlen( $lastPrefix );
-                       $preCloseMatch = preg_match( '/<\\/pre/i', $oLine );
-                       $preOpenMatch = preg_match( '/<pre/i', $oLine );
-                       # If not in a <pre> element, scan for and figure out what prefixes are there.
-                       if ( !$this->mInPre ) {
-                               # Multiple prefixes may abut each other for nested lists.
-                               $prefixLength = strspn( $oLine, '*#:;' );
-                               $prefix = substr( $oLine, 0, $prefixLength );
-
-                               # eh?
-                               # ; and : are both from definition-lists, so they're equivalent
-                               #  for the purposes of determining whether or not we need to open/close
-                               #  elements.
-                               $prefix2 = str_replace( ';', ':', $prefix );
-                               $t = substr( $oLine, $prefixLength );
-                               $this->mInPre = (bool)$preOpenMatch;
-                       } else {
-                               # Don't interpret any other prefixes in preformatted text
-                               $prefixLength = 0;
-                               $prefix = $prefix2 = '';
-                               $t = $oLine;
-                       }
-
-                       # List generation
-                       if ( $prefixLength && $lastPrefix === $prefix2 ) {
-                               # Same as the last item, so no need to deal with nesting or opening stuff
-                               $output .= $this->nextItem( substr( $prefix, -1 ) );
-                               $paragraphStack = false;
-
-                               if ( substr( $prefix, -1 ) === ';' ) {
-                                       # The one nasty exception: definition lists work like this:
-                                       # ; title : definition text
-                                       # So we check for : in the remainder text to split up the
-                                       # title and definition, without b0rking links.
-                                       $term = $t2 = '';
-                                       if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
-                                               $t = $t2;
-                                               $output .= $term . $this->nextItem( ':' );
-                                       }
-                               }
-                       } elseif ( $prefixLength || $lastPrefixLength ) {
-                               # We need to open or close prefixes, or both.
-
-                               # Either open or close a level...
-                               $commonPrefixLength = $this->getCommon( $prefix, $lastPrefix );
-                               $paragraphStack = false;
-
-                               # Close all the prefixes which aren't shared.
-                               while ( $commonPrefixLength < $lastPrefixLength ) {
-                                       $output .= $this->closeList( $lastPrefix[$lastPrefixLength - 1] );
-                                       --$lastPrefixLength;
-                               }
-
-                               # Continue the current prefix if appropriate.
-                               if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
-                                       $output .= $this->nextItem( $prefix[$commonPrefixLength - 1] );
-                               }
-
-                               # Open prefixes where appropriate.
-                               if ( $lastPrefix && $prefixLength > $commonPrefixLength ) {
-                                       $output .= "\n";
-                               }
-                               while ( $prefixLength > $commonPrefixLength ) {
-                                       $char = substr( $prefix, $commonPrefixLength, 1 );
-                                       $output .= $this->openList( $char );
-
-                                       if ( ';' === $char ) {
-                                               # @todo FIXME: This is dupe of code above
-                                               if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
-                                                       $t = $t2;
-                                                       $output .= $term . $this->nextItem( ':' );
-                                               }
-                                       }
-                                       ++$commonPrefixLength;
-                               }
-                               if ( !$prefixLength && $lastPrefix ) {
-                                       $output .= "\n";
-                               }
-                               $lastPrefix = $prefix2;
-                       }
-
-                       # If we have no prefixes, go to paragraph mode.
-                       if ( 0 == $prefixLength ) {
-                               # No prefix (not in list)--go to paragraph mode
-                               # XXX: use a stack for nestable elements like span, table and div
-                               $openmatch = preg_match(
-                                       '/(?:<table|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|'
-                                               . '<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS',
-                                       $t
-                               );
-                               $closematch = preg_match(
-                                       '/(?:<\\/table|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'
-                                               . '<td|<th|<\\/?blockquote|<\\/?div|<hr|<\\/pre|<\\/p|<\\/mw:|'
-                                               . self::MARKER_PREFIX
-                                               . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS',
-                                       $t
-                               );
-
-                               if ( $openmatch || $closematch ) {
-                                       $paragraphStack = false;
-                                       # @todo bug 5718: paragraph closed
-                                       $output .= $this->closeParagraph();
-                                       if ( $preOpenMatch && !$preCloseMatch ) {
-                                               $this->mInPre = true;
-                                       }
-                                       $bqOffset = 0;
-                                       while ( preg_match( '/<(\\/?)blockquote[\s>]/i', $t,
-                                               $bqMatch, PREG_OFFSET_CAPTURE, $bqOffset )
-                                       ) {
-                                               $inBlockquote = !$bqMatch[1][0]; // is this a close tag?
-                                               $bqOffset = $bqMatch[0][1] + strlen( $bqMatch[0][0] );
-                                       }
-                                       $inBlockElem = !$closematch;
-                               } elseif ( !$inBlockElem && !$this->mInPre ) {
-                                       if ( ' ' == substr( $t, 0, 1 )
-                                               && ( $this->mLastSection === 'pre' || trim( $t ) != '' )
-                                               && !$inBlockquote
-                                       ) {
-                                               # pre
-                                               if ( $this->mLastSection !== 'pre' ) {
-                                                       $paragraphStack = false;
-                                                       $output .= $this->closeParagraph() . '<pre>';
-                                                       $this->mLastSection = 'pre';
-                                               }
-                                               $t = substr( $t, 1 );
-                                       } else {
-                                               # paragraph
-                                               if ( trim( $t ) === '' ) {
-                                                       if ( $paragraphStack ) {
-                                                               $output .= $paragraphStack . '<br />';
-                                                               $paragraphStack = false;
-                                                               $this->mLastSection = 'p';
-                                                       } else {
-                                                               if ( $this->mLastSection !== 'p' ) {
-                                                                       $output .= $this->closeParagraph();
-                                                                       $this->mLastSection = '';
-                                                                       $paragraphStack = '<p>';
-                                                               } else {
-                                                                       $paragraphStack = '</p><p>';
-                                                               }
-                                                       }
-                                               } else {
-                                                       if ( $paragraphStack ) {
-                                                               $output .= $paragraphStack;
-                                                               $paragraphStack = false;
-                                                               $this->mLastSection = 'p';
-                                                       } elseif ( $this->mLastSection !== 'p' ) {
-                                                               $output .= $this->closeParagraph() . '<p>';
-                                                               $this->mLastSection = 'p';
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       # somewhere above we forget to get out of pre block (bug 785)
-                       if ( $preCloseMatch && $this->mInPre ) {
-                               $this->mInPre = false;
-                       }
-                       if ( $paragraphStack === false ) {
-                               $output .= $t;
-                               if ( $prefixLength === 0 ) {
-                                       $output .= "\n";
-                               }
-                       }
-               }
-               while ( $prefixLength ) {
-                       $output .= $this->closeList( $prefix2[$prefixLength - 1] );
-                       --$prefixLength;
-                       if ( !$prefixLength ) {
-                               $output .= "\n";
-                       }
-               }
-               if ( $this->mLastSection != '' ) {
-                       $output .= '</' . $this->mLastSection . '>';
-                       $this->mLastSection = '';
-               }
-
-               return $output;
-       }
-
-       /**
-        * Split up a string on ':', ignoring any occurrences inside tags
-        * to prevent illegal overlapping.
-        *
-        * @param string $str The string to split
-        * @param string &$before Set to everything before the ':'
-        * @param string &$after Set to everything after the ':'
-        * @throws MWException
-        * @return string The position of the ':', or false if none found
-        */
-       public function findColonNoLinks( $str, &$before, &$after ) {
-
-               $pos = strpos( $str, ':' );
-               if ( $pos === false ) {
-                       # Nothing to find!
-                       return false;
-               }
-
-               $lt = strpos( $str, '<' );
-               if ( $lt === false || $lt > $pos ) {
-                       # Easy; no tag nesting to worry about
-                       $before = substr( $str, 0, $pos );
-                       $after = substr( $str, $pos + 1 );
-                       return $pos;
-               }
-
-               # Ugly state machine to walk through avoiding tags.
-               $state = self::COLON_STATE_TEXT;
-               $stack = 0;
-               $len = strlen( $str );
-               for ( $i = 0; $i < $len; $i++ ) {
-                       $c = $str[$i];
-
-                       switch ( $state ) {
-                       # (Using the number is a performance hack for common cases)
-                       case 0: # self::COLON_STATE_TEXT:
-                               switch ( $c ) {
-                               case "<":
-                                       # Could be either a <start> tag or an </end> tag
-                                       $state = self::COLON_STATE_TAGSTART;
-                                       break;
-                               case ":":
-                                       if ( $stack == 0 ) {
-                                               # We found it!
-                                               $before = substr( $str, 0, $i );
-                                               $after = substr( $str, $i + 1 );
-                                               return $i;
-                                       }
-                                       # Embedded in a tag; don't break it.
-                                       break;
-                               default:
-                                       # Skip ahead looking for something interesting
-                                       $colon = strpos( $str, ':', $i );
-                                       if ( $colon === false ) {
-                                               # Nothing else interesting
-                                               return false;
-                                       }
-                                       $lt = strpos( $str, '<', $i );
-                                       if ( $stack === 0 ) {
-                                               if ( $lt === false || $colon < $lt ) {
-                                                       # We found it!
-                                                       $before = substr( $str, 0, $colon );
-                                                       $after = substr( $str, $colon + 1 );
-                                                       return $i;
-                                               }
-                                       }
-                                       if ( $lt === false ) {
-                                               # Nothing else interesting to find; abort!
-                                               # We're nested, but there's no close tags left. Abort!
-                                               break 2;
-                                       }
-                                       # Skip ahead to next tag start
-                                       $i = $lt;
-                                       $state = self::COLON_STATE_TAGSTART;
-                               }
-                               break;
-                       case 1: # self::COLON_STATE_TAG:
-                               # In a <tag>
-                               switch ( $c ) {
-                               case ">":
-                                       $stack++;
-                                       $state = self::COLON_STATE_TEXT;
-                                       break;
-                               case "/":
-                                       # Slash may be followed by >?
-                                       $state = self::COLON_STATE_TAGSLASH;
-                                       break;
-                               default:
-                                       # ignore
-                               }
-                               break;
-                       case 2: # self::COLON_STATE_TAGSTART:
-                               switch ( $c ) {
-                               case "/":
-                                       $state = self::COLON_STATE_CLOSETAG;
-                                       break;
-                               case "!":
-                                       $state = self::COLON_STATE_COMMENT;
-                                       break;
-                               case ">":
-                                       # Illegal early close? This shouldn't happen D:
-                                       $state = self::COLON_STATE_TEXT;
-                                       break;
-                               default:
-                                       $state = self::COLON_STATE_TAG;
-                               }
-                               break;
-                       case 3: # self::COLON_STATE_CLOSETAG:
-                               # In a </tag>
-                               if ( $c === ">" ) {
-                                       $stack--;
-                                       if ( $stack < 0 ) {
-                                               wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
-                                               return false;
-                                       }
-                                       $state = self::COLON_STATE_TEXT;
-                               }
-                               break;
-                       case self::COLON_STATE_TAGSLASH:
-                               if ( $c === ">" ) {
-                                       # Yes, a self-closed tag <blah/>
-                                       $state = self::COLON_STATE_TEXT;
-                               } else {
-                                       # Probably we're jumping the gun, and this is an attribute
-                                       $state = self::COLON_STATE_TAG;
-                               }
-                               break;
-                       case 5: # self::COLON_STATE_COMMENT:
-                               if ( $c === "-" ) {
-                                       $state = self::COLON_STATE_COMMENTDASH;
-                               }
-                               break;
-                       case self::COLON_STATE_COMMENTDASH:
-                               if ( $c === "-" ) {
-                                       $state = self::COLON_STATE_COMMENTDASHDASH;
-                               } else {
-                                       $state = self::COLON_STATE_COMMENT;
-                               }
-                               break;
-                       case self::COLON_STATE_COMMENTDASHDASH:
-                               if ( $c === ">" ) {
-                                       $state = self::COLON_STATE_TEXT;
-                               } else {
-                                       $state = self::COLON_STATE_COMMENT;
-                               }
-                               break;
-                       default:
-                               throw new MWException( "State machine error in " . __METHOD__ );
-                       }
-               }
-               if ( $stack > 0 ) {
-                       wfDebug( __METHOD__ . ": Invalid input; not enough close tags (stack $stack, state $state)\n" );
-                       return false;
-               }
-               return false;
+               return BlockLevelPass::doBlockLevels( $text, $linestart );
        }
 
        /**
index 916cfc2..c6265a7 100644 (file)
@@ -146,14 +146,17 @@ class ParserCache {
                        if ( !$useOutdated && $optionsKey->expired( $article->getTouched() ) ) {
                                wfIncrStats( "pcache.miss.expired" );
                                $cacheTime = $optionsKey->getCacheTime();
-                               wfDebug( "Parser options key expired, touched " . $article->getTouched()
+                               wfDebugLog( "ParserCache",
+                                       "Parser options key expired, touched " . $article->getTouched()
                                        . ", epoch $wgCacheEpoch, cached $cacheTime\n" );
                                return false;
-                       } elseif ( $optionsKey->isDifferentRevision( $article->getLatest() ) ) {
+                       } elseif ( !$useOutdated && $optionsKey->isDifferentRevision( $article->getLatest() ) ) {
                                wfIncrStats( "pcache.miss.revid" );
                                $revId = $article->getLatest();
                                $cachedRevId = $optionsKey->getCacheRevisionId();
-                               wfDebug( "ParserOutput key is for an old revision, latest $revId, cached $cachedRevId\n" );
+                               wfDebugLog( "ParserCache",
+                                       "ParserOutput key is for an old revision, latest $revId, cached $cachedRevId\n"
+                               );
                                return false;
                        }
 
@@ -201,6 +204,7 @@ class ParserCache {
                }
 
                $casToken = null;
+               /** @var ParserOutput $value */
                $value = $this->mMemc->get( $parserOutputKey, $casToken, BagOStuff::READ_VERIFIED );
                if ( !$value ) {
                        wfDebug( "ParserOutput cache miss.\n" );
@@ -222,14 +226,15 @@ class ParserCache {
                if ( !$useOutdated && $value->expired( $touched ) ) {
                        wfIncrStats( "pcache.miss.expired" );
                        $cacheTime = $value->getCacheTime();
-                       wfDebug( "ParserOutput key expired, touched $touched, "
+                       wfDebugLog( "ParserCache",
+                               "ParserOutput key expired, touched $touched, "
                                . "epoch $wgCacheEpoch, cached $cacheTime\n" );
                        $value = false;
-               } elseif ( $value->isDifferentRevision( $article->getLatest() ) ) {
+               } elseif ( !$useOutdated && $value->isDifferentRevision( $article->getLatest() ) ) {
                        wfIncrStats( "pcache.miss.revid" );
                        $revId = $article->getLatest();
                        $cachedRevId = $value->getCacheRevisionId();
-                       wfDebug(
+                       wfDebugLog( "ParserCache",
                                "ParserOutput key is for an old revision, latest $revId, cached $cachedRevId\n"
                        );
                        $value = false;
@@ -237,7 +242,7 @@ class ParserCache {
                        Hooks::run( 'RejectParserCacheValue', [ $value, $wikiPage, $popts ] ) === false
                ) {
                        wfIncrStats( 'pcache.miss.rejected' );
-                       wfDebug(
+                       wfDebugLog( "ParserCache",
                                "ParserOutput key valid, but rejected by RejectParserCacheValue hook handler.\n"
                        );
                        $value = false;
@@ -257,7 +262,7 @@ class ParserCache {
         */
        public function save( $parserOutput, $page, $popts, $cacheTime = null, $revId = null ) {
                $expire = $parserOutput->getCacheExpiry();
-               if ( $expire > 0 ) {
+               if ( $expire > 0 && !$this->mMemc instanceof EmptyBagOStuff ) {
                        $cacheTime = $cacheTime ?: wfTimestampNow();
                        if ( !$revId ) {
                                $revision = $page->getRevision();
@@ -297,7 +302,7 @@ class ParserCache {
                                'ParserCacheSaveComplete',
                                [ $this, $parserOutput, $page->getTitle(), $popts, $revId ]
                        );
-               } else {
+               } elseif ( $expire <= 0 ) {
                        wfDebug( "Parser output was marked as uncacheable and has not been saved.\n" );
                }
        }
index 40c67dd..6c7ad4e 100644 (file)
@@ -381,6 +381,9 @@ class ParserOutput extends CacheTime {
                return $this->mTOCHTML;
        }
 
+       /**
+        * @return string|null TS_MW timestamp of the revision content
+        */
        public function getTimestamp() {
                return $this->mTimestamp;
        }
index 7ea87c3..d7aee5b 100644 (file)
@@ -117,11 +117,11 @@ class PasswordPolicyChecks {
        /**
         * Ensure that password isn't in top X most popular passwords
         *
-        * @param $policyVal int Cut off to use. Will automatically shrink to the max
+        * @param int $policyVal 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
+        * @param User $user
+        * @param string $password
         * @since 1.27
         * @return Status
         */
index acdbd81..bd7072a 100644 (file)
@@ -81,7 +81,7 @@ abstract class PoolCounter {
 
        /**
         * @param array $conf
-        * @param string $type
+        * @param string $type The class of actions to limit concurrency for (task type)
         * @param string $key
         */
        protected function __construct( $conf, $type, $key ) {
@@ -93,8 +93,9 @@ abstract class PoolCounter {
                }
 
                if ( $this->slots ) {
-                       $key = $this->hashKeyIntoSlots( $key, $this->slots );
+                       $key = $this->hashKeyIntoSlots( $type, $key, $this->slots );
                }
+
                $this->key = $key;
                $this->isMightWaitKey = !preg_match( '/^nowait:/', $this->key );
        }
@@ -102,7 +103,7 @@ abstract class PoolCounter {
        /**
         * Create a Pool counter. This should only be called from the PoolWorks.
         *
-        * @param string $type
+        * @param string $type The class of actions to limit concurrency for (task type)
         * @param string $key
         *
         * @return PoolCounter
@@ -192,18 +193,19 @@ abstract class PoolCounter {
        }
 
        /**
-        * Given a key (any string) and the number of lots, returns a slot number (an integer from
-        * the [0..($slots-1)] range). This is used for a global limit on the number of instances of
-        * a given type that can acquire a lock. The hashing is deterministic so that
+        * Given a key (any string) and the number of lots, returns a slot key (a prefix with a suffix
+        * integer from the [0..($slots-1)] range). This is used for a global limit on the number of
+        * instances of a given type that can acquire a lock. The hashing is deterministic so that
         * PoolCounter::$workers is always an upper limit of how many instances with the same key
         * can acquire a lock.
         *
+        * @param string $type The class of actions to limit concurrency for (task type)
         * @param string $key PoolCounter instance key (any string)
         * @param int $slots The number of slots (max allowed value is 65536)
-        * @return int
+        * @return string Slot key with the type and slot number
         */
-       protected function hashKeyIntoSlots( $key, $slots ) {
-               return hexdec( substr( sha1( $key ), 0, 4 ) ) % $slots;
+       protected function hashKeyIntoSlots( $type, $key, $slots ) {
+               return $type . ':' . ( hexdec( substr( sha1( $key ), 0, 4 ) ) % $slots );
        }
 }
 
index e61b65a..a570d78 100644 (file)
@@ -31,7 +31,7 @@ abstract class PoolCounterWork {
        protected $cacheable = false; // does this override getCachedWork() ?
 
        /**
-        * @param string $type The type of PoolCounter to use
+        * @param string $type The class of actions to limit concurrency for (task type)
         * @param string $key Key that identifies the queue this work is placed on
         */
        public function __construct( $type, $key ) {
index 85a7cef..834b8b1 100644 (file)
@@ -44,7 +44,7 @@ class PoolCounterWorkViaCallback extends PoolCounterWork {
         * If a 'doCachedWork' callback is provided, then execute() may wait for any prior
         * process in the pool to finish and reuse its cached result.
         *
-        * @param string $type
+        * @param string $type The class of actions to limit concurrency for
         * @param string $key
         * @param array $callbacks Map of callbacks
         * @throws MWException
index 7ddedb9..29016a8 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 class PoolWorkArticleView extends PoolCounterWork {
-       /** @var Page */
+       /** @var WikiPage */
        private $page;
 
        /** @var string */
@@ -44,7 +44,7 @@ class PoolWorkArticleView extends PoolCounterWork {
        private $error = false;
 
        /**
-        * @param Page $page
+        * @param WikiPage $page
         * @param ParserOptions $parserOptions ParserOptions to use for the parse
         * @param int $revid ID of the revision being parsed.
         * @param bool $useParserCache Whether to use the parser cache.
@@ -52,7 +52,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param Content|string $content Content to parse or null to load it; may
         *   also be given as a wikitext string, for BC.
         */
-       public function __construct( Page $page, ParserOptions $parserOptions,
+       public function __construct( WikiPage $page, ParserOptions $parserOptions,
                $revid, $useParserCache, $content = null
        ) {
                if ( is_string( $content ) ) { // BC: old style call
index f977124..415e664 100644 (file)
@@ -209,8 +209,12 @@ class ExtensionProcessor implements Processor {
        protected function extractHooks( array $info ) {
                if ( isset( $info['Hooks'] ) ) {
                        foreach ( $info['Hooks'] as $name => $value ) {
-                               foreach ( (array)$value as $callback ) {
-                                       $this->globals['wgHooks'][$name][] = $callback;
+                               if ( is_array( $value ) ) {
+                                       foreach ( $value as $callback ) {
+                                               $this->globals['wgHooks'][$name][] = $callback;
+                                       }
+                               } else {
+                                       $this->globals['wgHooks'][$name][] = $value;
                                }
                        }
                }
index 8e0239a..85fc53d 100644 (file)
@@ -227,15 +227,17 @@ class ResourceLoaderContext {
         * Get the possibly-cached User object for the specified username
         *
         * @since 1.25
-        * @return User|bool false if a valid object cannot be created
+        * @return User
         */
        public function getUserObj() {
                if ( $this->userObj === null ) {
                        $username = $this->getUser();
                        if ( $username ) {
-                               $this->userObj = User::newFromName( $username );
+                               // Use provided username if valid, fallback to anonymous user
+                               $this->userObj = User::newFromName( $username ) ?: new User;
                        } else {
-                               $this->userObj = new User; // Anonymous user
+                               // Anonymous user
+                               $this->userObj = new User;
                        }
                }
 
index 13f13e6..121a6c9 100644 (file)
@@ -114,16 +114,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                return $this->origin;
        }
 
-       /**
-        * Set this module's origin. This is called by ResourceLoader::register()
-        * when registering the module. Other code should not call this.
-        *
-        * @param int $origin Origin
-        */
-       public function setOrigin( $origin ) {
-               $this->origin = $origin;
-       }
-
        /**
         * @param ResourceLoaderContext $context
         * @return bool
index 490a4ab..91e63e7 100644 (file)
@@ -26,7 +26,7 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
        /* Methods */
 
        /**
-        * @param $context ResourceLoaderContext
+        * @param ResourceLoaderContext $context
         * @return array
         */
        public function getStyles( ResourceLoaderContext $context ) {
@@ -68,7 +68,7 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
        }
 
        /**
-        * @param $context ResourceLoaderContext
+        * @param ResourceLoaderContext $context
         * @return bool
         */
        public function isKnownEmpty( ResourceLoaderContext $context ) {
@@ -78,7 +78,7 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
        }
 
        /**
-        * @param $context ResourceLoaderContext
+        * @param ResourceLoaderContext $context
         * @return string: Hash
         */
        public function getModifiedHash( ResourceLoaderContext $context ) {
index e2a8e41..b225185 100644 (file)
@@ -40,7 +40,7 @@ class ResourceLoaderUserGroupsModule extends ResourceLoaderWikiModule {
                }
 
                $user = $context->getUserObj();
-               if ( !$user || $user->isAnon() ) {
+               if ( $user->isAnon() ) {
                        return [];
                }
 
index d584165..c38f8d8 100644 (file)
@@ -43,7 +43,7 @@ class ResourceLoaderUserModule extends ResourceLoaderWikiModule {
                }
 
                $user = $context->getUserObj();
-               if ( !$user || $user->isAnon() ) {
+               if ( $user->isAnon() ) {
                        return [];
                }
 
index 796dc20..a3f8825 100644 (file)
@@ -75,6 +75,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                case 'styles':
                                case 'scripts':
                                case 'group':
+                               case 'targets':
                                        $this->{$member} = $option;
                                        break;
                        }
index 26e4b17..b555592 100644 (file)
@@ -103,7 +103,7 @@ abstract class RevDelList extends RevisionListBase {
         * @return Status
         * @since 1.23 Added 'perItemStatus' param
         */
-       public function setVisibility( $params ) {
+       public function setVisibility( array $params ) {
                $bitPars = $params['value'];
                $comment = $params['comment'];
                $perItemStatus = isset( $params['perItemStatus'] ) ? $params['perItemStatus'] : false;
index b263fb3..dcef95c 100644 (file)
  * @defgroup Search Search
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Contain a class for special pages
  * @ingroup Search
  */
-class SearchEngine {
+abstract class SearchEngine {
        /** @var string */
        public $prefix = '';
 
@@ -124,155 +126,56 @@ class SearchEngine {
         * @param string $term
         * @return string
         */
-       function transformSearchTerm( $term ) {
+       public function transformSearchTerm( $term ) {
                return $term;
        }
 
+       /**
+        * Get service class to finding near matches.
+        * @param Config $config Configuration to use for the matcher.
+        * @return SearchNearMatcher
+        */
+       public function getNearMatcher( Config $config ) {
+               global $wgContLang;
+               return new SearchNearMatcher( $config, $wgContLang );
+       }
+
+       /**
+        * Get near matcher for default SearchEngine.
+        * @return SearchNearMatcher
+        */
+       protected static function defaultNearMatcher() {
+               $config = MediaWikiServices::getInstance()->getMainConfig();
+               return MediaWikiServices::getInstance()->newSearchEngine()->getNearMatcher( $config );
+       }
+
        /**
         * If an exact title match can be found, or a very slightly close match,
         * return the title. If no match, returns NULL.
-        *
+        * @deprecated since 1.27; Use SearchEngine::getNearMatcher()
         * @param string $searchterm
         * @return Title
         */
        public static function getNearMatch( $searchterm ) {
-               $title = self::getNearMatchInternal( $searchterm );
-
-               Hooks::run( 'SearchGetNearMatchComplete', [ $searchterm, &$title ] );
-               return $title;
+               return static::defaultNearMatcher()->getNearMatch( $searchterm );
        }
 
        /**
         * Do a near match (see SearchEngine::getNearMatch) and wrap it into a
         * SearchResultSet.
-        *
+        * @deprecated since 1.27; Use SearchEngine::getNearMatcher()
         * @param string $searchterm
         * @return SearchResultSet
         */
        public static function getNearMatchResultSet( $searchterm ) {
-               return new SearchNearMatchResultSet( self::getNearMatch( $searchterm ) );
+               return static::defaultNearMatcher()->getNearMatchResultSet( $searchterm );
        }
 
        /**
-        * Really find the title match.
-        * @param string $searchterm
-        * @return null|Title
+        * Get chars legal for search.
+        * NOTE: usage as static is deprecated and preserved only as BC measure
+        * @return string
         */
-       private static function getNearMatchInternal( $searchterm ) {
-               global $wgContLang, $wgEnableSearchContributorsByIP;
-
-               $allSearchTerms = [ $searchterm ];
-
-               if ( $wgContLang->hasVariants() ) {
-                       $allSearchTerms = array_unique( array_merge(
-                               $allSearchTerms,
-                               $wgContLang->autoConvertToAllVariants( $searchterm )
-                       ) );
-               }
-
-               $titleResult = null;
-               if ( !Hooks::run( 'SearchGetNearMatchBefore', [ $allSearchTerms, &$titleResult ] ) ) {
-                       return $titleResult;
-               }
-
-               foreach ( $allSearchTerms as $term ) {
-
-                       # Exact match? No need to look further.
-                       $title = Title::newFromText( $term );
-                       if ( is_null( $title ) ) {
-                               return null;
-                       }
-
-                       # Try files if searching in the Media: namespace
-                       if ( $title->getNamespace() == NS_MEDIA ) {
-                               $title = Title::makeTitle( NS_FILE, $title->getText() );
-                       }
-
-                       if ( $title->isSpecialPage() || $title->isExternal() || $title->exists() ) {
-                               return $title;
-                       }
-
-                       # See if it still otherwise has content is some sane sense
-                       $page = WikiPage::factory( $title );
-                       if ( $page->hasViewableContent() ) {
-                               return $title;
-                       }
-
-                       if ( !Hooks::run( 'SearchAfterNoDirectMatch', [ $term, &$title ] ) ) {
-                               return $title;
-                       }
-
-                       # Now try all lower case (i.e. first letter capitalized)
-                       $title = Title::newFromText( $wgContLang->lc( $term ) );
-                       if ( $title && $title->exists() ) {
-                               return $title;
-                       }
-
-                       # Now try capitalized string
-                       $title = Title::newFromText( $wgContLang->ucwords( $term ) );
-                       if ( $title && $title->exists() ) {
-                               return $title;
-                       }
-
-                       # Now try all upper case
-                       $title = Title::newFromText( $wgContLang->uc( $term ) );
-                       if ( $title && $title->exists() ) {
-                               return $title;
-                       }
-
-                       # Now try Word-Caps-Breaking-At-Word-Breaks, for hyphenated names etc
-                       $title = Title::newFromText( $wgContLang->ucwordbreaks( $term ) );
-                       if ( $title && $title->exists() ) {
-                               return $title;
-                       }
-
-                       // Give hooks a chance at better match variants
-                       $title = null;
-                       if ( !Hooks::run( 'SearchGetNearMatch', [ $term, &$title ] ) ) {
-                               return $title;
-                       }
-               }
-
-               $title = Title::newFromText( $searchterm );
-
-               # Entering an IP address goes to the contributions page
-               if ( $wgEnableSearchContributorsByIP ) {
-                       if ( ( $title->getNamespace() == NS_USER && User::isIP( $title->getText() ) )
-                               || User::isIP( trim( $searchterm ) ) ) {
-                               return SpecialPage::getTitleFor( 'Contributions', $title->getDBkey() );
-                       }
-               }
-
-               # Entering a user goes to the user page whether it's there or not
-               if ( $title->getNamespace() == NS_USER ) {
-                       return $title;
-               }
-
-               # Go to images that exist even if there's no local page.
-               # There may have been a funny upload, or it may be on a shared
-               # file repository such as Wikimedia Commons.
-               if ( $title->getNamespace() == NS_FILE ) {
-                       $image = wfFindFile( $title );
-                       if ( $image ) {
-                               return $title;
-                       }
-               }
-
-               # MediaWiki namespace? Page may be "implied" if not customized.
-               # Just return it, with caps forced as the message system likes it.
-               if ( $title->getNamespace() == NS_MEDIAWIKI ) {
-                       return Title::makeTitle( NS_MEDIAWIKI, $wgContLang->ucfirst( $title->getText() ) );
-               }
-
-               # Quoted term? Try without the quotes...
-               $matches = [];
-               if ( preg_match( '/^"([^"]+)"$/', $searchterm, $matches ) ) {
-                       return SearchEngine::getNearMatch( $matches[1] );
-               }
-
-               return null;
-       }
-
        public static function legalSearchChars() {
                return "A-Za-z_'.0-9\\x80-\\xFF\\-";
        }
@@ -390,44 +293,8 @@ class SearchEngine {
                return $parsed;
        }
 
-       /**
-        * Make a list of searchable namespaces and their canonical names.
-        * @return array
-        */
-       public static function searchableNamespaces() {
-               global $wgContLang;
-               $arr = [];
-               foreach ( $wgContLang->getNamespaces() as $ns => $name ) {
-                       if ( $ns >= NS_MAIN ) {
-                               $arr[$ns] = $name;
-                       }
-               }
-
-               Hooks::run( 'SearchableNamespaces', [ &$arr ] );
-               return $arr;
-       }
-
-       /**
-        * Extract default namespaces to search from the given user's
-        * settings, returning a list of index numbers.
-        *
-        * @param user $user
-        * @return array
-        */
-       public static function userNamespaces( $user ) {
-               $arr = [];
-               foreach ( SearchEngine::searchableNamespaces() as $ns => $name ) {
-                       if ( $user->getOption( 'searchNs' . $ns ) ) {
-                               $arr[] = $ns;
-                       }
-               }
-
-               return $arr;
-       }
-
        /**
         * Find snippet highlight settings for all users
-        *
         * @return array Contextlines, contextchars
         */
        public static function userHighlightPrefs() {
@@ -436,77 +303,6 @@ class SearchEngine {
                return [ $contextlines, $contextchars ];
        }
 
-       /**
-        * An array of namespaces indexes to be searched by default
-        *
-        * @return array
-        */
-       public static function defaultNamespaces() {
-               global $wgNamespacesToBeSearchedDefault;
-
-               return array_keys( $wgNamespacesToBeSearchedDefault, true );
-       }
-
-       /**
-        * Get a list of namespace names useful for showing in tooltips
-        * and preferences
-        *
-        * @param array $namespaces
-        * @return array
-        */
-       public static function namespacesAsText( $namespaces ) {
-               global $wgContLang;
-
-               $formatted = array_map( [ $wgContLang, 'getFormattedNsText' ], $namespaces );
-               foreach ( $formatted as $key => $ns ) {
-                       if ( empty( $ns ) ) {
-                               $formatted[$key] = wfMessage( 'blanknamespace' )->text();
-                       }
-               }
-               return $formatted;
-       }
-
-       /**
-        * Load up the appropriate search engine class for the currently
-        * active database backend, and return a configured instance.
-        *
-        * @param string $type Type of search backend, if not the default
-        * @return SearchEngine
-        */
-       public static function create( $type = null ) {
-               global $wgSearchType;
-               $dbr = null;
-
-               $alternatives = self::getSearchTypes();
-
-               if ( $type && in_array( $type, $alternatives ) ) {
-                       $class = $type;
-               } elseif ( $wgSearchType !== null ) {
-                       $class = $wgSearchType;
-               } else {
-                       $dbr = wfGetDB( DB_SLAVE );
-                       $class = $dbr->getSearchEngine();
-               }
-
-               $search = new $class( $dbr );
-               return $search;
-       }
-
-       /**
-        * Return the search engines we support. If only $wgSearchType
-        * is set, it'll be an array of just that one item.
-        *
-        * @return array
-        */
-       public static function getSearchTypes() {
-               global $wgSearchType, $wgSearchTypeAlternatives;
-
-               $alternatives = $wgSearchTypeAlternatives ?: [];
-               array_unshift( $alternatives, $wgSearchType );
-
-               return $alternatives;
-       }
-
        /**
         * Create or update the search index record for the given page.
         * Title and text should be pre-processed.
@@ -584,7 +380,7 @@ class SearchEngine {
         * Makes search simple string if it was namespaced.
         * Sets namespaces of the search to namespaces extracted from string.
         * @param string $search
-        * @return $string Simplified search string
+        * @return string Simplified search string
         */
        protected function normalizeNamespaces( $search ) {
                // Find a Title which is not an interwiki and is in NS_MAIN
@@ -774,6 +570,67 @@ class SearchEngine {
                return $backend->defaultSearchBackend( $this->namespaces, $search, $this->limit, $this->offset );
        }
 
+       /**
+        * Make a list of searchable namespaces and their canonical names.
+        * @deprecated since 1.27; use SearchEngineConfig::searchableNamespaces()
+        * @return array
+        */
+       public static function searchableNamespaces() {
+               return MediaWikiServices::getInstance()->getSearchEngineConfig()->searchableNamespaces();
+       }
+
+       /**
+        * Extract default namespaces to search from the given user's
+        * settings, returning a list of index numbers.
+        * @deprecated since 1.27; use SearchEngineConfig::userNamespaces()
+        * @param user $user
+        * @return array
+        */
+       public static function userNamespaces( $user ) {
+               return MediaWikiServices::getInstance()->getSearchEngineConfig()->userNamespaces( $user );
+       }
+
+       /**
+        * An array of namespaces indexes to be searched by default
+        * @deprecated since 1.27; use SearchEngineConfig::defaultNamespaces()
+        * @return array
+        */
+       public static function defaultNamespaces() {
+               return MediaWikiServices::getInstance()->getSearchEngineConfig()->defaultNamespaces();
+       }
+
+       /**
+        * Get a list of namespace names useful for showing in tooltips
+        * and preferences
+        * @deprecated since 1.27; use SearchEngineConfig::namespacesAsText()
+        * @param array $namespaces
+        * @return array
+        */
+       public static function namespacesAsText( $namespaces ) {
+               return MediaWikiServices::getInstance()->getSearchEngineConfig()->namespacesAsText( $namespaces );
+       }
+
+       /**
+        * Load up the appropriate search engine class for the currently
+        * active database backend, and return a configured instance.
+        * @deprecated since 1.27; Use SearchEngineFactory::create
+        * @param string $type Type of search backend, if not the default
+        * @return SearchEngine
+        */
+       public static function create( $type = null ) {
+               return MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
+       }
+
+       /**
+        * Return the search engines we support. If only $wgSearchType
+        * is set, it'll be an array of just that one item.
+        * @deprecated since 1.27; use SearchEngineConfig::getSearchTypes()
+        * @return array
+        */
+       public static function getSearchTypes() {
+               return MediaWikiServices::getInstance()->getSearchEngineConfig()->getSearchTypes();
+       }
+
 }
 
 /**
diff --git a/includes/search/SearchEngineConfig.php b/includes/search/SearchEngineConfig.php
new file mode 100644 (file)
index 0000000..90f85c3
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * Configuration handling class for SearchEngine.
+ * Provides added service over plain configuration.
+ *
+ * @since 1.27
+ */
+class SearchEngineConfig {
+
+       /**
+        * Config object from which the settings will be derived.
+        * @var Config
+        */
+       private $config;
+
+       /**
+        * Current language
+        * @var Language
+        */
+       private $language;
+
+       public function __construct( Config $config, Language $lang ) {
+               $this->config = $config;
+               $this->language = $lang;
+       }
+
+       /**
+        * Retrieve original config.
+        * @return Config
+        */
+       public function getConfig() {
+               return $this->config;
+       }
+
+       /**
+        * Make a list of searchable namespaces and their canonical names.
+        * @return array Namespace ID => name
+        */
+       public function searchableNamespaces() {
+               $arr = [];
+               foreach ( $this->language->getNamespaces() as $ns => $name ) {
+                       if ( $ns >= NS_MAIN ) {
+                               $arr[$ns] = $name;
+                       }
+               }
+
+               Hooks::run( 'SearchableNamespaces', [ &$arr ] );
+               return $arr;
+       }
+
+       /**
+        * Extract default namespaces to search from the given user's
+        * settings, returning a list of index numbers.
+        *
+        * @param user $user
+        * @return int[]
+        */
+       public function userNamespaces( $user ) {
+               $arr = [];
+               foreach ( $this->searchableNamespaces() as $ns => $name ) {
+                       if ( $user->getOption( 'searchNs' . $ns ) ) {
+                               $arr[] = $ns;
+                       }
+               }
+
+               return $arr;
+       }
+
+       /**
+        * An array of namespaces indexes to be searched by default
+        *
+        * @return int[] Namespace IDs
+        */
+       public function defaultNamespaces() {
+               return array_keys( $this->config->get( 'NamespacesToBeSearchedDefault' ), true );
+       }
+
+       /**
+        * Return the search engines we support. If only $wgSearchType
+        * is set, it'll be an array of just that one item.
+        *
+        * @return array
+        */
+       public function getSearchTypes() {
+               $alternatives = $this->config->get( 'SearchTypeAlternatives' ) ?: [];
+               array_unshift( $alternatives, $this->config->get( 'SearchType' ) );
+
+               return $alternatives;
+       }
+
+       /**
+        * Return the search engine configured in $wgSearchType, etc.
+        *
+        * @return string|null
+        */
+       public function getSearchType() {
+               return $this->config->get( 'SearchType' );
+       }
+
+       /**
+        * Get a list of namespace names useful for showing in tooltips
+        * and preferences.
+        *
+        * @param int[] $namespaces
+        * @return string[] List of names
+        */
+       public function namespacesAsText( $namespaces ) {
+               $formatted = array_map( [ $this->language, 'getFormattedNsText' ], $namespaces );
+               foreach ( $formatted as $key => $ns ) {
+                       if ( empty( $ns ) ) {
+                               $formatted[$key] = wfMessage( 'blanknamespace' )->text();
+                       }
+               }
+               return $formatted;
+       }
+}
diff --git a/includes/search/SearchEngineFactory.php b/includes/search/SearchEngineFactory.php
new file mode 100644 (file)
index 0000000..67f500c
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Factory class for SearchEngine.
+ * Allows to create engine of the specific type.
+ */
+class SearchEngineFactory {
+
+       /**
+        * Configuration for SearchEngine classes.
+        * @var SearchEngineConfig
+        */
+       private $config;
+
+       public function __construct( SearchEngineConfig $config ) {
+               $this->config = $config;
+       }
+
+       /**
+        * Create SearchEngine of the given type.
+        * @param string $type
+        * @return SearchEngine
+        */
+       public function create( $type = null ) {
+               $dbr = null;
+
+               $configType = $this->config->getSearchType();
+               $alternatives = $this->config->getSearchTypes();
+
+               if ( $type && in_array( $type, $alternatives ) ) {
+                       $class = $type;
+               } elseif ( $configType !== null ) {
+                       $class = $configType;
+               } else {
+                       $dbr = wfGetDB( DB_SLAVE );
+                       $class = $dbr->getSearchEngine();
+               }
+
+               $search = new $class( $dbr );
+               return $search;
+       }
+}
index 510726b..6d66707 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * A SearchResultSet wrapper for SearchEngine::getNearMatch
+ * A SearchResultSet wrapper for SearchNearMatcher
  */
 class SearchNearMatchResultSet extends SearchResultSet {
        private $fetched = false;
diff --git a/includes/search/SearchNearMatcher.php b/includes/search/SearchNearMatcher.php
new file mode 100644 (file)
index 0000000..0400021
--- /dev/null
@@ -0,0 +1,169 @@
+<?php
+
+/**
+ * Implementation of near match title search.
+ * TODO: split into service/implementation.
+ */
+class SearchNearMatcher {
+       /**
+        * Configuration object.
+        * @param Config $config
+        */
+       protected $config;
+
+       /**
+        * Current language
+        * @var Language
+        */
+       private $language;
+
+       public function __construct( Config $config, Language $lang ) {
+               $this->config = $config;
+               $this->language = $lang;
+       }
+
+       /**
+        * If an exact title match can be found, or a very slightly close match,
+        * return the title. If no match, returns NULL.
+        *
+        * @param string $searchterm
+        * @return Title
+        */
+       public function getNearMatch( $searchterm ) {
+               $title = $this->getNearMatchInternal( $searchterm );
+
+               Hooks::run( 'SearchGetNearMatchComplete', [ $searchterm, &$title ] );
+               return $title;
+       }
+
+       /**
+        * Do a near match (see SearchEngine::getNearMatch) and wrap it into a
+        * SearchResultSet.
+        *
+        * @param string $searchterm
+        * @return SearchResultSet
+        */
+       public function getNearMatchResultSet( $searchterm ) {
+               return new SearchNearMatchResultSet( $this->getNearMatch( $searchterm ) );
+       }
+
+       /**
+        * Really find the title match.
+        * @param string $searchterm
+        * @return null|Title
+        */
+       protected function getNearMatchInternal( $searchterm ) {
+               $lang = $this->language;
+
+               $allSearchTerms = [ $searchterm ];
+
+               if ( $lang->hasVariants() ) {
+                       $allSearchTerms = array_unique( array_merge(
+                               $allSearchTerms,
+                               $lang->autoConvertToAllVariants( $searchterm )
+                       ) );
+               }
+
+               $titleResult = null;
+               if ( !Hooks::run( 'SearchGetNearMatchBefore', [ $allSearchTerms, &$titleResult ] ) ) {
+                       return $titleResult;
+               }
+
+               foreach ( $allSearchTerms as $term ) {
+
+                       # Exact match? No need to look further.
+                       $title = Title::newFromText( $term );
+                       if ( is_null( $title ) ) {
+                               return null;
+                       }
+
+                       # Try files if searching in the Media: namespace
+                       if ( $title->getNamespace() == NS_MEDIA ) {
+                               $title = Title::makeTitle( NS_FILE, $title->getText() );
+                       }
+
+                       if ( $title->isSpecialPage() || $title->isExternal() || $title->exists() ) {
+                               return $title;
+                       }
+
+                       # See if it still otherwise has content is some sane sense
+                       $page = WikiPage::factory( $title );
+                       if ( $page->hasViewableContent() ) {
+                               return $title;
+                       }
+
+                       if ( !Hooks::run( 'SearchAfterNoDirectMatch', [ $term, &$title ] ) ) {
+                               return $title;
+                       }
+
+                       # Now try all lower case (i.e. first letter capitalized)
+                       $title = Title::newFromText( $lang->lc( $term ) );
+                       if ( $title && $title->exists() ) {
+                               return $title;
+                       }
+
+                       # Now try capitalized string
+                       $title = Title::newFromText( $lang->ucwords( $term ) );
+                       if ( $title && $title->exists() ) {
+                               return $title;
+                       }
+
+                       # Now try all upper case
+                       $title = Title::newFromText( $lang->uc( $term ) );
+                       if ( $title && $title->exists() ) {
+                               return $title;
+                       }
+
+                       # Now try Word-Caps-Breaking-At-Word-Breaks, for hyphenated names etc
+                       $title = Title::newFromText( $lang->ucwordbreaks( $term ) );
+                       if ( $title && $title->exists() ) {
+                               return $title;
+                       }
+
+                       // Give hooks a chance at better match variants
+                       $title = null;
+                       if ( !Hooks::run( 'SearchGetNearMatch', [ $term, &$title ] ) ) {
+                               return $title;
+                       }
+               }
+
+               $title = Title::newFromText( $searchterm );
+
+               # Entering an IP address goes to the contributions page
+               if ( $this->config->get( 'EnableSearchContributorsByIP' ) ) {
+                       if ( ( $title->getNamespace() == NS_USER && User::isIP( $title->getText() ) )
+                               || User::isIP( trim( $searchterm ) ) ) {
+                               return SpecialPage::getTitleFor( 'Contributions', $title->getDBkey() );
+                       }
+               }
+
+               # Entering a user goes to the user page whether it's there or not
+               if ( $title->getNamespace() == NS_USER ) {
+                       return $title;
+               }
+
+               # Go to images that exist even if there's no local page.
+               # There may have been a funny upload, or it may be on a shared
+               # file repository such as Wikimedia Commons.
+               if ( $title->getNamespace() == NS_FILE ) {
+                       $image = wfFindFile( $title );
+                       if ( $image ) {
+                               return $title;
+                       }
+               }
+
+               # MediaWiki namespace? Page may be "implied" if not customized.
+               # Just return it, with caps forced as the message system likes it.
+               if ( $title->getNamespace() == NS_MEDIAWIKI ) {
+                       return Title::makeTitle( NS_MEDIAWIKI, $lang->ucfirst( $title->getText() ) );
+               }
+
+               # Quoted term? Try without the quotes...
+               $matches = [];
+               if ( preg_match( '/^"([^"]+)"$/', $searchterm, $matches ) ) {
+                       return self::getNearMatch( $matches[1] );
+               }
+
+               return null;
+       }
+}
index 6c406e7..21effbb 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Search
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @todo FIXME: This class is horribly factored. It would probably be better to
  * have a useful base class to which you pass some standard information, then
@@ -49,6 +51,11 @@ class SearchResult {
         */
        protected $mText;
 
+       /**
+        * @var SearchEngine
+        */
+       protected $searchEngine;
+
        /**
         * Return a new SearchResult and initializes it with a title.
         *
@@ -56,7 +63,7 @@ class SearchResult {
         * @return SearchResult
         */
        public static function newFromTitle( $title ) {
-               $result = new self();
+               $result = new static();
                $result->initFromTitle( $title );
                return $result;
        }
@@ -78,6 +85,7 @@ class SearchResult {
                                $this->mImage = wfFindFile( $this->mTitle );
                        }
                }
+               $this->searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
        }
 
        /**
@@ -119,8 +127,8 @@ class SearchResult {
        protected function initText() {
                if ( !isset( $this->mText ) ) {
                        if ( $this->mRevision != null ) {
-                               $this->mText = SearchEngine::create()
-                                       ->getTextFromContent( $this->mTitle, $this->mRevision->getContent() );
+                               $this->mText = $this->searchEngine->getTextFromContent(
+                                               $this->mTitle, $this->mRevision->getContent() );
                        } else { // TODO: can we fetch raw wikitext for commons images?
                                $this->mText = '';
                        }
@@ -136,7 +144,7 @@ class SearchResult {
                $this->initText();
 
                // TODO: make highliter take a content object. Make ContentHandler a factory for SearchHighliter.
-               list( $contextlines, $contextchars ) = SearchEngine::userHighlightPrefs();
+               list( $contextlines, $contextchars ) = $this->searchEngine->userHighlightPrefs();
 
                $h = new SearchHighlighter();
                if ( count( $terms ) > 0 ) {
index 4188f4f..29878d4 100644 (file)
@@ -379,6 +379,156 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
                $this->remove( 'wsTokenSecrets' );
        }
 
+       /**
+        * Fetch the secret keys for self::setSecret() and self::getSecret().
+        * @return string[] Encryption key, HMAC key
+        */
+       private function getSecretKeys() {
+               global $wgSessionSecret, $wgSecretKey;
+
+               $wikiSecret = $wgSessionSecret ?: $wgSecretKey;
+               $userSecret = $this->get( 'wsSessionSecret', null );
+               if ( $userSecret === null ) {
+                       $userSecret = \MWCryptRand::generateHex( 32 );
+                       $this->set( 'wsSessionSecret', $userSecret );
+               }
+
+               $keymats = hash_pbkdf2( 'sha256', $wikiSecret, $userSecret, 10001, 64, true );
+               return [
+                       substr( $keymats, 0, 32 ),
+                       substr( $keymats, 32, 32 ),
+               ];
+       }
+
+       /**
+        * Set a value in the session, encrypted
+        *
+        * This relies on the secrecy of $wgSecretKey (by default), or $wgSessionSecret.
+        *
+        * @param string|int $key
+        * @param mixed $value
+        */
+       public function setSecret( $key, $value ) {
+               global $wgSessionInsecureSecrets;
+
+               list( $encKey, $hmacKey ) = $this->getSecretKeys();
+               $serialized = serialize( $value );
+
+               // The code for encryption (with OpenSSL) and sealing is taken from
+               // Chris Steipp's OATHAuthUtils class in Extension::OATHAuth.
+
+               // Encrypt
+               // @todo: import a pure-PHP library for AES instead of doing $wgSessionInsecureSecrets
+               $iv = \MWCryptRand::generate( 16, true );
+               if ( function_exists( 'openssl_encrypt' ) ) {
+                       $ciphertext = openssl_encrypt( $serialized, 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, $iv );
+                       if ( $ciphertext === false ) {
+                               throw new UnexpectedValueException( 'Encryption failed: ' . openssl_error_string() );
+                       }
+               } elseif ( function_exists( 'mcrypt_encrypt' ) ) {
+                       $ciphertext = mcrypt_encrypt( 'rijndael-128', $encKey, $serialized, 'ctr', $iv );
+                       if ( $ciphertext === false ) {
+                               throw new UnexpectedValueException( 'Encryption failed' );
+                       }
+               } elseif ( $wgSessionInsecureSecrets ) {
+                       $ex = new \Exception( 'No encryption is available, storing data as plain text' );
+                       $this->logger->warning( $ex->getMessage(), [ 'exception' => $ex ] );
+                       $ciphertext = $serialized;
+               } else {
+                       throw new \BadMethodCallException(
+                               'Encryption is not available. You really should install the PHP OpenSSL extension, ' .
+                               'or failing that the mcrypt extension. But if you really can\'t and you\'re willing ' .
+                               'to accept insecure storage of sensitive session data, set ' .
+                               '$wgSessionInsecureSecrets = true in LocalSettings.php to make this exception go away.'
+                       );
+               }
+
+               // Seal
+               $sealed = base64_encode( $iv ) . '.' . base64_encode( $ciphertext );
+               $hmac = hash_hmac( 'sha256', $sealed, $hmacKey, true );
+               $encrypted = base64_encode( $hmac ) . '.' . $sealed;
+
+               // Store
+               $this->set( $key, $encrypted );
+       }
+
+       /**
+        * Fetch a value from the session that was set with self::setSecret()
+        * @param string|int $key
+        * @param mixed $default Returned if $this->exists( $key ) would be false or decryption fails
+        * @return mixed
+        */
+       public function getSecret( $key, $default = null ) {
+               global $wgSessionInsecureSecrets;
+
+               // Fetch
+               $encrypted = $this->get( $key, null );
+               if ( $encrypted === null ) {
+                       return $default;
+               }
+
+               // The code for unsealing, checking, and decrypting (with OpenSSL) is
+               // taken from Chris Steipp's OATHAuthUtils class in
+               // Extension::OATHAuth.
+
+               // Unseal and check
+               $pieces = explode( '.', $encrypted );
+               if ( count( $pieces ) !== 3 ) {
+                       $ex = new \Exception( 'Invalid sealed-secret format' );
+                       $this->logger->warning( $ex->getMessage(), [ 'exception' => $ex ] );
+                       return $default;
+               }
+               list( $hmac, $iv, $ciphertext ) = $pieces;
+               list( $encKey, $hmacKey ) = $this->getSecretKeys();
+               $integCalc = hash_hmac( 'sha256', $iv . '.' . $ciphertext, $hmacKey, true );
+               if ( !hash_equals( $integCalc, base64_decode( $hmac ) ) ) {
+                       $ex = new \Exception( 'Sealed secret has been tampered with, aborting.' );
+                       $this->logger->warning( $ex->getMessage(), [ 'exception' => $ex ] );
+                       return $default;
+               }
+
+               // Decrypt
+               // @todo: import a pure-PHP library for AES instead of doing $wgSessionInsecureSecrets
+               if ( function_exists( 'openssl_decrypt' ) ) {
+                       $serialized = openssl_decrypt(
+                               base64_decode( $ciphertext ), 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, base64_decode( $iv )
+                       );
+                       if ( $serialized === false ) {
+                               $ex = new \Exception( 'Decyption failed: ' . openssl_error_string() );
+                               $this->logger->debug( $ex->getMessage(), [ 'exception' => $ex ] );
+                               return $default;
+                       }
+               } elseif ( function_exists( 'mcrypt_decrypt' ) ) {
+                       $serialized = mcrypt_decrypt(
+                               'rijndael-128', $encKey, base64_decode( $ciphertext ), 'ctr', base64_decode( $iv )
+                       );
+                       if ( $serialized === false ) {
+                               $ex = new \Exception( 'Decyption failed' );
+                               $this->logger->debug( $ex->getMessage(), [ 'exception' => $ex ] );
+                               return $default;
+                       }
+               } elseif ( $wgSessionInsecureSecrets ) {
+                       $ex = new \Exception(
+                               'No encryption is available, retrieving data that was stored as plain text'
+                       );
+                       $this->logger->warning( $ex->getMessage(), [ 'exception' => $ex ] );
+                       $serialized = base64_decode( $ciphertext );
+               } else {
+                       throw new \BadMethodCallException(
+                               'Encryption is not available. You really should install the PHP OpenSSL extension, ' .
+                               'or failing that the mcrypt extension. But if you really can\'t and you\'re willing ' .
+                               'to accept insecure storage of sensitive session data, set ' .
+                               '$wgSessionInsecureSecrets = true in LocalSettings.php to make this exception go away.'
+                       );
+               }
+
+               $value = unserialize( $serialized );
+               if ( $value === false && $serialized !== serialize( false ) ) {
+                       $value = $default;
+               }
+               return $value;
+       }
+
        /**
         * Delay automatic saving while multiple updates are being made
         *
index 1b5a834..c235861 100644 (file)
@@ -54,6 +54,7 @@ class SessionInfo {
        private $remembered = false;
        private $forceHTTPS = false;
        private $idIsSafe = false;
+       private $forceUse = false;
 
        /** @var array|null */
        private $providerMetadata = null;
@@ -76,6 +77,10 @@ class SessionInfo {
         *  - idIsSafe: (bool) Set true if the 'id' did not come from the user.
         *    Generally you'll use this from SessionProvider::newEmptySession(),
         *    and not from any other method.
+        *  - forceUse: (bool) Set true if the 'id' is from
+        *    SessionProvider::hashToSessionId() to delete conflicting session
+        *    store data instead of discarding this SessionInfo. Ignored unless
+        *    both 'provider' and 'id' are given.
         *  - copyFrom: (SessionInfo) SessionInfo to copy other data items from.
         */
        public function __construct( $priority, array $data ) {
@@ -97,6 +102,7 @@ class SessionInfo {
                                'forceHTTPS' => $from->forceHTTPS,
                                'metadata' => $from->providerMetadata,
                                'idIsSafe' => $from->idIsSafe,
+                               'forceUse' => $from->forceUse,
                                // @codeCoverageIgnoreStart
                        ];
                        // @codeCoverageIgnoreEnd
@@ -110,6 +116,7 @@ class SessionInfo {
                                'forceHTTPS' => false,
                                'metadata' => null,
                                'idIsSafe' => false,
+                               'forceUse' => false,
                                // @codeCoverageIgnoreStart
                        ];
                        // @codeCoverageIgnoreEnd
@@ -137,9 +144,11 @@ class SessionInfo {
                if ( $data['id'] !== null ) {
                        $this->id = $data['id'];
                        $this->idIsSafe = $data['idIsSafe'];
+                       $this->forceUse = $data['forceUse'] && $this->provider;
                } else {
                        $this->id = $this->provider->getManager()->generateSessionId();
                        $this->idIsSafe = true;
+                       $this->forceUse = false;
                }
                $this->priority = (int)$priority;
                $this->userInfo = $data['userInfo'];
@@ -185,6 +194,20 @@ class SessionInfo {
                return $this->idIsSafe;
        }
 
+       /**
+        * Force use of this SessionInfo if validation fails
+        *
+        * The normal behavior is to discard the SessionInfo if validation against
+        * the data stored in the session store fails. If this returns true,
+        * SessionManager will instead delete the session store data so this
+        * SessionInfo may still be used.
+        *
+        * @return bool
+        */
+       final public function forceUse() {
+               return $this->forceUse;
+       }
+
        /**
         * Return the priority
         * @return int
index a364045..777d3d6 100644 (file)
@@ -301,6 +301,19 @@ final class SessionManager implements SessionManagerInterface {
                return $this->getSessionFromInfo( $infos[0], $request );
        }
 
+       public function invalidateSessionsForUser( User $user ) {
+               global $wgAuth;
+
+               $user->setToken();
+               $user->saveSettings();
+
+               $wgAuth->getUserInstance( $user )->resetAuthToken();
+
+               foreach ( $this->getProviders() as $provider ) {
+                       $provider->invalidateSessionsForUser( $user );
+               }
+       }
+
        public function getVaryHeaders() {
                // @codeCoverageIgnoreStart
                if ( defined( 'MW_NO_SESSION' ) && MW_NO_SESSION !== 'warn' ) {
@@ -704,6 +717,20 @@ final class SessionManager implements SessionManagerInterface {
                $key = wfMemcKey( 'MWSession', $info->getId() );
                $blob = $this->store->get( $key );
 
+               // If we got data from the store and the SessionInfo says to force use,
+               // "fail" means to delete the data from the store and retry. Otherwise,
+               // "fail" is just return false.
+               if ( $info->forceUse() && $blob !== false ) {
+                       $failHandler = function () use ( $key, &$info, $request ) {
+                               $this->store->delete( $key );
+                               return $this->loadSessionInfoFromStore( $info, $request );
+                       };
+               } else {
+                       $failHandler = function () {
+                               return false;
+                       };
+               }
+
                $newParams = [];
 
                if ( $blob !== false ) {
@@ -713,7 +740,7 @@ final class SessionManager implements SessionManagerInterface {
                                        'session' => $info,
                                ] );
                                $this->store->delete( $key );
-                               return false;
+                               return $failHandler();
                        }
 
                        // Sanity check: blob has data and metadata arrays
@@ -724,7 +751,7 @@ final class SessionManager implements SessionManagerInterface {
                                        'session' => $info,
                                ] );
                                $this->store->delete( $key );
-                               return false;
+                               return $failHandler();
                        }
 
                        $data = $blob['data'];
@@ -741,7 +768,7 @@ final class SessionManager implements SessionManagerInterface {
                                        'session' => $info,
                                ] );
                                $this->store->delete( $key );
-                               return false;
+                               return $failHandler();
                        }
 
                        // First, load the provider from metadata, or validate it against the metadata.
@@ -756,7 +783,7 @@ final class SessionManager implements SessionManagerInterface {
                                                ]
                                        );
                                        $this->store->delete( $key );
-                                       return false;
+                                       return $failHandler();
                                }
                        } elseif ( $metadata['provider'] !== (string)$provider ) {
                                $this->logger->warning( 'Session "{session}": Wrong provider ' .
@@ -764,7 +791,7 @@ final class SessionManager implements SessionManagerInterface {
                                        [
                                                'session' => $info,
                                ] );
-                               return false;
+                               return $failHandler();
                        }
 
                        // Load provider metadata from metadata, or validate it against the metadata
@@ -788,7 +815,7 @@ final class SessionManager implements SessionManagerInterface {
                                                                'exception' => $ex,
                                                        ] + $ex->getContext()
                                                );
-                                               return false;
+                                               return $failHandler();
                                        }
                                }
                        }
@@ -810,7 +837,7 @@ final class SessionManager implements SessionManagerInterface {
                                                'session' => $info,
                                                'exception' => $ex,
                                        ] );
-                                       return false;
+                                       return $failHandler();
                                }
                                $newParams['userInfo'] = $userInfo;
                        } else {
@@ -825,7 +852,7 @@ final class SessionManager implements SessionManagerInterface {
                                                                'uid_a' => $metadata['userId'],
                                                                'uid_b' => $userInfo->getId(),
                                                ] );
-                                               return false;
+                                               return $failHandler();
                                        }
 
                                        // If the user was renamed, probably best to fail here.
@@ -839,7 +866,7 @@ final class SessionManager implements SessionManagerInterface {
                                                                'uname_a' => $metadata['userName'],
                                                                'uname_b' => $userInfo->getName(),
                                                ] );
-                                               return false;
+                                               return $failHandler();
                                        }
 
                                } elseif ( $metadata['userName'] !== null ) { // Shouldn't happen, but just in case
@@ -851,7 +878,7 @@ final class SessionManager implements SessionManagerInterface {
                                                                'uname_a' => $metadata['userName'],
                                                                'uname_b' => $userInfo->getName(),
                                                ] );
-                                               return false;
+                                               return $failHandler();
                                        }
                                } elseif ( !$userInfo->isAnon() ) {
                                        // Metadata specifies an anonymous user, but the passed-in
@@ -861,7 +888,7 @@ final class SessionManager implements SessionManagerInterface {
                                                [
                                                        'session' => $info,
                                        ] );
-                                       return false;
+                                       return $failHandler();
                                }
                        }
 
@@ -872,7 +899,7 @@ final class SessionManager implements SessionManagerInterface {
                                $this->logger->warning( 'Session "{session}": User token mismatch', [
                                        'session' => $info,
                                ] );
-                               return false;
+                               return $failHandler();
                        }
                        if ( !$userInfo->isVerified() ) {
                                $newParams['userInfo'] = $userInfo->verified();
@@ -899,7 +926,7 @@ final class SessionManager implements SessionManagerInterface {
                                        [
                                                'session' => $info,
                                ] );
-                               return false;
+                               return $failHandler();
                        }
 
                        // If no user was provided and no metadata, it must be anon.
@@ -912,7 +939,7 @@ final class SessionManager implements SessionManagerInterface {
                                                [
                                                        'session' => $info,
                                        ] );
-                                       return false;
+                                       return $failHandler();
                                }
                        } elseif ( !$info->getUserInfo()->isVerified() ) {
                                $this->logger->warning(
@@ -920,7 +947,7 @@ final class SessionManager implements SessionManagerInterface {
                                        [
                                                'session' => $info,
                                ] );
-                               return false;
+                               return $failHandler();
                        }
 
                        $data = false;
@@ -942,7 +969,7 @@ final class SessionManager implements SessionManagerInterface {
                // Allow the provider to check the loaded SessionInfo
                $providerMetadata = $info->getProviderMetadata();
                if ( !$info->getProvider()->refreshSessionInfo( $info, $request, $providerMetadata ) ) {
-                       return false;
+                       return $failHandler();
                }
                if ( $providerMetadata !== $info->getProviderMetadata() ) {
                        $info = new SessionInfo( $info->getPriority(), [
@@ -962,7 +989,7 @@ final class SessionManager implements SessionManagerInterface {
                        $this->logger->warning( 'Session "{session}": ' . $reason, [
                                'session' => $info,
                        ] );
-                       return false;
+                       return $failHandler();
                }
 
                return true;
@@ -1074,7 +1101,7 @@ final class SessionManager implements SessionManagerInterface {
         */
        public function generateSessionId() {
                do {
-                       $id = wfBaseConvert( \MWCryptRand::generateHex( 40 ), 16, 32, 32 );
+                       $id = \Wikimedia\base_convert( \MWCryptRand::generateHex( 40 ), 16, 32, 32 );
                        $key = wfMemcKey( 'MWSession', $id );
                } while ( isset( $this->allSessionIds[$id] ) || is_array( $this->store->get( $key ) ) );
                return $id;
index b3e28fe..d4e52c7 100644 (file)
@@ -24,6 +24,7 @@
 namespace MediaWiki\Session;
 
 use Psr\Log\LoggerAwareInterface;
+use User;
 use WebRequest;
 
 /**
@@ -72,6 +73,17 @@ interface SessionManagerInterface extends LoggerAwareInterface {
         */
        public function getEmptySession( WebRequest $request = null );
 
+       /**
+        * Invalidate sessions for a user
+        *
+        * After calling this, existing sessions should be invalid. For mutable
+        * session providers, this generally means the user has to log in again;
+        * for immutable providers, it generally means the loss of session data.
+        *
+        * @param User $user
+        */
+       public function invalidateSessionsForUser( User $user );
+
        /**
         * Return the HTTP headers that need varying on.
         *
index 8ee1272..ed113b7 100644 (file)
@@ -27,6 +27,7 @@ use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Config;
 use Language;
+use User;
 use WebRequest;
 
 /**
@@ -358,6 +359,19 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI
                }
        }
 
+       /**
+        * Invalidate existing sessions for a user
+        *
+        * If the provider has its own equivalent of CookieSessionProvider's Token
+        * cookie (and doesn't use User::getToken() to implement it), it should
+        * reset whatever token it does use here.
+        *
+        * @protected For use by \MediaWiki\Session\SessionManager only
+        * @param User $user;
+        */
+       public function invalidateSessionsForUser( User $user ) {
+       }
+
        /**
         * Return the HTTP headers that need varying on.
         *
@@ -458,7 +472,9 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI
         *
         * Generally this will only be used when self::persistsSessionId() is false and
         * the provider has to base the session ID on the verified user's identity
-        * or other static data.
+        * or other static data. The SessionInfo should then typically have the
+        * 'forceUse' flag set to avoid persistent session failure if validation of
+        * the stored data fails.
         *
         * @param string $data
         * @param string|null $key Defaults to $this->config->get( 'SecretKey' )
@@ -484,7 +500,7 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI
                        // @codeCoverageIgnoreEnd
                }
                if ( strlen( $hash ) >= 40 ) {
-                       $hash = wfBaseConvert( $hash, 16, 32, 32 );
+                       $hash = \Wikimedia\base_convert( $hash, 16, 32, 32 );
                }
                return substr( $hash, -32 );
        }
index 97fffda..d70a6b9 100644 (file)
@@ -1589,8 +1589,8 @@ abstract class Skin extends ContextSource {
        public function linkKnown(
                $target,
                $html = null,
-               $customAttribs = [ ],
-               $query = [ ],
+               $customAttribs = [],
+               $query = [],
                $options = [ 'known', 'noclasses' ]
        ) {
                wfDeprecated( __METHOD__, '1.21' );
index 366862d..cc993aa 100644 (file)
@@ -21,6 +21,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Factory class to create Skin objects
  *
@@ -42,16 +44,11 @@ class SkinFactory {
        private $displayNames = [];
 
        /**
-        * @var SkinFactory
+        * @deprecated in 1.27
+        * @return SkinFactory
         */
-       private static $self;
-
        public static function getDefaultInstance() {
-               if ( !self::$self ) {
-                       self::$self = new self;
-               }
-
-               return self::$self;
+               return MediaWikiServices::getInstance()->getSkinFactory();
        }
 
        /**
index 2523810..1beac43 100644 (file)
@@ -513,8 +513,8 @@ abstract class QueryPage extends SpecialPage {
         * What is limit to fetch from DB
         *
         * Used to make it appear the DB stores less results then it actually does
-        * @param $uiLimit int Limit from UI
-        * @param $uiOffset int Offset from UI
+        * @param int $uiLimit Limit from UI
+        * @param int $uiOffset Offset from UI
         * @return int Limit to use for DB (not including extra row to see if at end)
         */
        protected function getDBLimit( $uiLimit, $uiOffset ) {
index fb153fc..b274017 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * Parent class for all special pages.
  *
@@ -59,6 +61,9 @@ class SpecialPage {
        /**
         * Get a localised Title object for a specified special page name
         *
+        * @since 1.9
+        * @since 1.21 $fragment parameter added
+        *
         * @param string $name
         * @param string|bool $subpage Subpage string, or false to not use a subpage
         * @param string $fragment The link fragment (after the "#")
@@ -342,7 +347,7 @@ class SpecialPage {
                        return [];
                }
 
-               $searchEngine = SearchEngine::create();
+               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
                $searchEngine->setLimitOffset( $limit, $offset );
                $searchEngine->setNamespaces( [] );
                $result = $searchEngine->defaultPrefixSearch( $search );
@@ -628,6 +633,7 @@ class SpecialPage {
        /**
         * Wrapper around wfMessage that sets the current context.
         *
+        * @since 1.16
         * @return Message
         * @see wfMessage
         */
index 725c4fc..4c869f9 100644 (file)
@@ -86,6 +86,7 @@ class SpecialPageFactory {
                'CreateAccount' => 'SpecialCreateAccount',
 
                // Users and rights
+               'Activeusers' => 'SpecialActiveUsers',
                'Block' => 'SpecialBlock',
                'Unblock' => 'SpecialUnblock',
                'BlockList' => 'SpecialBlockList',
@@ -254,8 +255,6 @@ class SpecialPageFactory {
                                self::$list['ChangeContentModel'] = 'SpecialChangeContentModel';
                        }
 
-                       self::$list['Activeusers'] = 'SpecialActiveUsers';
-
                        // Add extension special pages
                        self::$list = array_merge( self::$list, $wgSpecialPages );
 
@@ -539,6 +538,7 @@ class SpecialPageFactory {
                        $trxProfiler = Profiler::instance()->getTransactionProfiler();
                        if ( $context->getRequest()->wasPosted() && !$page->doesWrites() ) {
                                $trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
+                               $context->getRequest()->markAsSafeRequest();
                        }
                }
 
index d6d4500..c697ca7 100644 (file)
@@ -24,6 +24,8 @@
  */
 
 /**
+ * Implements Special:Activeusers
+ *
  * @ingroup SpecialPage
  */
 class SpecialActiveUsers extends SpecialPage {
@@ -41,16 +43,25 @@ class SpecialActiveUsers extends SpecialPage {
         * @param string $par Parameter passed to the page or null
         */
        public function execute( $par ) {
-               $days = $this->getConfig()->get( 'ActiveUserDays' );
+               $out = $this->getOutput();
 
                $this->setHeaders();
                $this->outputHeader();
 
-               $out = $this->getOutput();
-               $out->wrapWikiMsg( "<div class='mw-activeusers-intro'>\n$1\n</div>",
-                       [ 'activeusers-intro', $this->getLanguage()->formatNum( $days ) ] );
+               $opts = new FormOptions();
+
+               $opts->add( 'username', '' );
+               $opts->add( 'hidebots', false, FormOptions::BOOL );
+               $opts->add( 'hidesysops', false, FormOptions::BOOL );
+
+               $opts->fetchValuesFromRequest( $this->getRequest() );
+
+               if ( $par !== null ) {
+                       $opts->setValue( 'username', $par );
+               }
 
                // Mention the level of cache staleness...
+               $cacheText = '';
                $dbr = wfGetDB( DB_SLAVE, 'recentchanges' );
                $rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
                if ( $rcMax ) {
@@ -66,22 +77,51 @@ class SpecialActiveUsers extends SpecialPage {
                                $secondsOld = time() - wfTimestamp( TS_UNIX, $rcMin );
                        }
                        if ( $secondsOld > 0 ) {
-                               $out->addWikiMsg( 'cachedspecial-viewing-cached-ttl',
-                               $this->getLanguage()->formatDuration( $secondsOld ) );
+                               $cacheTxt = '<br>' . $this->msg( 'cachedspecial-viewing-cached-ttl' )
+                                       ->durationParams( $secondsOld );
                        }
                }
 
-               $up = new ActiveUsersPager( $this->getContext(), null, $par );
+               $pager = new ActiveUsersPager( $this->getContext(), $opts );
+               $usersBody = $pager->getBody();
+
+               $days = $this->getConfig()->get( 'ActiveUserDays' );
+
+               $formDescriptor = [
+                       'username' => [
+                               'type' => 'user',
+                               'name' => 'username',
+                               'label-message' => 'activeusers-from',
+                       ],
+
+                       'hidebots' => [
+                               'type' => 'check',
+                               'name' => 'hidebots',
+                               'label-message' => 'activeusers-hidebots',
+                               'default' => false,
+                       ],
+
+                       'hidesysops' => [
+                               'type' => 'check',
+                               'name' => 'hidesysops',
+                               'label-message' => 'activeusers-hidesysops',
+                               'default' => false,
+                       ],
+               ];
 
-               # getBody() first to check, if empty
-               $usersbody = $up->getBody();
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->setIntro( $this->msg( 'activeusers-intro' )->numParams( $days ) . $cacheText )
+                       ->setWrapperLegendMsg( 'activeusers' )
+                       ->setSubmitTextMsg( 'activeusers-submit' )
+                       ->setMethod( 'get' )
+                       ->prepareForm()
+                       ->displayForm( false );
 
-               $out->addHTML( $up->getPageHeader() );
-               if ( $usersbody ) {
+               if ( $usersBody ) {
                        $out->addHTML(
-                               $up->getNavigationBar() .
-                               Html::rawElement( 'ul', [], $usersbody ) .
-                               $up->getNavigationBar()
+                               $pager->getNavigationBar() .
+                               Html::rawElement( 'ul', [], $usersBody ) .
+                               $pager->getNavigationBar()
                        );
                } else {
                        $out->addWikiMsg( 'activeusers-noresult' );
index 625e4aa..fcadede 100644 (file)
@@ -28,7 +28,7 @@
  * @ingroup SpecialPage
  */
 class SpecialBlock extends FormSpecialPage {
-       /** @var User User to be blocked, as passed either by parameter (url?wpTarget=Foo)
+       /** @var User|string|null User to be blocked, as passed either by parameter (url?wpTarget=Foo)
         * or as subpage (Special:Block/Foo) */
        protected $target;
 
@@ -330,8 +330,12 @@ class SpecialBlock extends FormSpecialPage {
 
                $otherBlockMessages = [];
                if ( $this->target !== null ) {
+                       $targetName = $this->target;
+                       if ( $this->target instanceof User ) {
+                               $targetName = $this->target->getName();
+                       }
                        # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
-                       Hooks::run( 'OtherBlockLogLink', [ &$otherBlockMessages, $this->target ] );
+                       Hooks::run( 'OtherBlockLogLink', [ &$otherBlockMessages, $targetName ] );
 
                        if ( count( $otherBlockMessages ) ) {
                                $s = Html::rawElement(
index fe90a4f..11faa28 100644 (file)
@@ -32,7 +32,7 @@ class SpecialBookSources extends SpecialPage {
        /**
         * ISBN passed to the page, if any
         */
-       private $isbn = '';
+       protected $isbn = '';
 
        public function __construct() {
                parent::__construct( 'Booksources' );
@@ -44,17 +44,23 @@ class SpecialBookSources extends SpecialPage {
         * @param string $isbn ISBN passed as a subpage parameter
         */
        public function execute( $isbn ) {
+               $out = $this->getOutput();
+
                $this->setHeaders();
                $this->outputHeader();
+
                $this->isbn = self::cleanIsbn( $isbn ?: $this->getRequest()->getText( 'isbn' ) );
-               $this->getOutput()->addHTML( $this->makeForm() );
+
+               $this->buildForm();
+
                if ( $this->isbn !== '' ) {
                        if ( !self::isValidISBN( $this->isbn ) ) {
-                               $this->getOutput()->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div class=\"error\">\n$1\n</div>",
                                        'booksources-invalid-isbn'
                                );
                        }
+
                        $this->showList();
                }
        }
@@ -115,36 +121,25 @@ class SpecialBookSources extends SpecialPage {
 
        /**
         * Generate a form to allow users to enter an ISBN
-        *
-        * @return string
         */
-       private function makeForm() {
-               $form = Html::openElement( 'fieldset' ) . "\n";
-               $form .= Html::element(
-                       'legend',
-                       [],
-                       $this->msg( 'booksources-search-legend' )->text()
-               ) . "\n";
-               $form .= Html::openElement( 'form', [ 'method' => 'get', 'action' => wfScript() ] ) . "\n";
-               $form .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) . "\n";
-               $form .= '<p>' . Xml::inputLabel(
-                       $this->msg( 'booksources-isbn' )->text(),
-                       'isbn',
-                       'isbn',
-                       20,
-                       $this->isbn,
-                       [ 'autofocus' => '', 'class' => 'mw-ui-input-inline' ]
-               );
-
-               $form .= '&#160;' . Html::submitButton(
-                       $this->msg( 'booksources-search' )->text(),
-                       [], [ 'mw-ui-progressive' ]
-               ) . "</p>\n";
-
-               $form .= Html::closeElement( 'form' ) . "\n";
-               $form .= Html::closeElement( 'fieldset' ) . "\n";
-
-               return $form;
+       private function buildForm() {
+               $formDescriptor = [
+                       'isbn' => [
+                               'type' => 'text',
+                               'name' => 'isbn',
+                               'label-message' => 'booksources-isbn',
+                               'default' => $this->isbn,
+                               'autofocus' => true,
+                               'required' => true,
+                       ],
+               ];
+
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->setWrapperLegendMsg( 'booksources-search-legend' )
+                       ->setSubmitTextMsg( 'booksources-search' )
+                       ->setMethod( 'get' )
+                       ->prepareForm()
+                       ->displayForm( false );
        }
 
        /**
@@ -155,11 +150,13 @@ class SpecialBookSources extends SpecialPage {
         * @return bool
         */
        private function showList() {
+               $out = $this->getOutput();
+
                global $wgContLang;
 
                # Hook to allow extensions to insert additional HTML,
                # e.g. for API-interacting plugins and so on
-               Hooks::run( 'BookInformation', [ $this->isbn, $this->getOutput() ] );
+               Hooks::run( 'BookInformation', [ $this->isbn, $out ] );
 
                # Check for a local page such as Project:Book_sources and use that if available
                $page = $this->msg( 'booksources' )->inContentLanguage()->text();
@@ -172,7 +169,7 @@ class SpecialBookSources extends SpecialPage {
                                // XXX: in the future, this could be stored as structured data, defining a list of book sources
 
                                $text = $content->getNativeData();
-                               $this->getOutput()->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $text ) );
+                               $out->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $text ) );
 
                                return true;
                        } else {
@@ -181,13 +178,13 @@ class SpecialBookSources extends SpecialPage {
                }
 
                # Fall back to the defaults given in the language file
-               $this->getOutput()->addWikiMsg( 'booksources-text' );
-               $this->getOutput()->addHTML( '<ul>' );
+               $out->addWikiMsg( 'booksources-text' );
+               $out->addHTML( '<ul>' );
                $items = $wgContLang->getBookstoreList();
                foreach ( $items as $label => $url ) {
-                       $this->getOutput()->addHTML( $this->makeListItem( $label, $url ) );
+                       $out->addHTML( $this->makeListItem( $label, $url ) );
                }
-               $this->getOutput()->addHTML( '</ul>' );
+               $out->addHTML( '</ul>' );
 
                return true;
        }
index ee9f665..c7a650c 100644 (file)
@@ -84,12 +84,20 @@ class SpecialChangeContentModel extends FormSpecialPage {
                        ],
                ];
                if ( $this->title ) {
+                       $options = $this->getOptionsForTitle( $this->title );
+                       if ( empty( $options ) ) {
+                               throw new ErrorPageError(
+                                       'changecontentmodel-emptymodels-title',
+                                       'changecontentmodel-emptymodels-text',
+                                       $this->title->getPrefixedText()
+                               );
+                       }
                        $fields['pagetitle']['readonly'] = true;
                        $fields += [
                                'model' => [
                                        'type' => 'select',
                                        'name' => 'model',
-                                       'options' => $this->getOptionsForTitle( $this->title ),
+                                       'options' => $options,
                                        'label-message' => 'changecontentmodel-model-label'
                                ],
                                'reason' => [
index f2fa921..627dd2c 100644 (file)
@@ -27,6 +27,8 @@ use MediaWiki\Linker\LinkTarget;
  * @ingroup Watchlist
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Provides the UI through which users can perform editing
  * operations on their watchlist
@@ -325,7 +327,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
        private function getWatchlist() {
                $list = [];
 
-               $watchedItems = WatchedItemStore::getDefaultInstance()->getWatchedItemsForUser(
+               $watchedItems = MediaWikiServices::getInstance()->getWatchedItemStore()->getWatchedItemsForUser(
                        $this->getUser(),
                        [ 'forWrite' => $this->getRequest()->wasPosted() ]
                );
@@ -366,7 +368,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
        protected function getWatchlistInfo() {
                $titles = [];
 
-               $watchedItems = WatchedItemStore::getDefaultInstance()
+               $watchedItems = MediaWikiServices::getInstance()->getWatchedItemStore()
                        ->getWatchedItemsForUser( $this->getUser(), [ 'sort' => WatchedItemStore::SORT_ASC ] );
 
                $lb = new LinkBatch();
@@ -421,7 +423,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $user = $this->getUser();
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
 
                foreach ( $this->badItems as $row ) {
                        list( $title, $namespace, $dbKey ) = $row;
@@ -472,7 +474,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        $expandedTargets[] = new TitleValue( MWNamespace::getTalk( $ns ), $dbKey );
                }
 
-               WatchedItemStore::getDefaultInstance()->addWatchBatchForUser(
+               MediaWikiServices::getInstance()->getWatchedItemStore()->addWatchBatchForUser(
                        $this->getUser(),
                        $expandedTargets
                );
@@ -487,7 +489,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         * @param array $titles Array of strings, or Title objects
         */
        private function unwatchTitles( $titles ) {
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
 
                foreach ( $titles as $title ) {
                        if ( !$title instanceof Title ) {
index bb82d03..6de127d 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * Implements Special:FileDuplicateSearch
  *
@@ -244,7 +246,7 @@ class FileDuplicateSearchPage extends QueryPage {
                        // No prefix suggestion outside of file namespace
                        return [];
                }
-               $searchEngine = SearchEngine::create();
+               $searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
                $searchEngine->setLimitOffset( $limit, $offset );
                // Autocomplete subpage the same as a normal search, but just for files
                $searchEngine->setNamespaces( [ NS_FILE ] );
index a229fa3..2d087ca 100644 (file)
@@ -34,7 +34,7 @@ class SpecialLockdb extends FormSpecialPage {
        }
 
        public function doesWrites() {
-               return true;
+               return false;
        }
 
        public function requiresWrite() {
@@ -47,6 +47,9 @@ class SpecialLockdb extends FormSpecialPage {
                if ( !is_writable( dirname( $this->getConfig()->get( 'ReadOnlyFile' ) ) ) ) {
                        throw new ErrorPageError( 'lockdb', 'lockfilenotwritable' );
                }
+               if ( file_exists( $this->getConfig()->get( 'ReadOnlyFile' ) ) ) {
+                       throw new ErrorPageError( 'lockdb', 'databaselocked' );
+               }
        }
 
        protected function getFormFields() {
@@ -65,9 +68,9 @@ class SpecialLockdb extends FormSpecialPage {
        }
 
        protected function alterForm( HTMLForm $form ) {
-               $form->setWrapperLegend( false );
-               $form->setHeaderText( $this->msg( 'lockdbtext' )->parseAsBlock() );
-               $form->setSubmitTextMsg( 'lockbtn' );
+               $form->setWrapperLegend( false )
+                       ->setHeaderText( $this->msg( 'lockdbtext' )->parseAsBlock() )
+                       ->setSubmitTextMsg( 'lockbtn' );
        }
 
        public function onSubmit( array $data ) {
@@ -105,6 +108,10 @@ class SpecialLockdb extends FormSpecialPage {
                $out->addWikiMsg( 'lockdbsuccesstext' );
        }
 
+       protected function getDisplayFormat() {
+               return 'ooui';
+       }
+
        protected function getGroupName() {
                return 'wiki';
        }
index defca7d..e3be225 100644 (file)
@@ -106,21 +106,26 @@ class MIMEsearchPage extends QueryPage {
        }
 
        /**
-        * Return HTML to put just before the results.
+        * Generate and output the form
         */
        function getPageHeader() {
-               return Xml::openElement(
-                               'form',
-                               [ 'id' => 'specialmimesearch', 'method' => 'get', 'action' => wfScript() ]
-                       ) .
-                       Xml::openElement( 'fieldset' ) .
-                       Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
-                       Xml::element( 'legend', null, $this->msg( 'mimesearch' )->text() ) .
-                       Xml::inputLabel( $this->msg( 'mimetype' )->text(), 'mime', 'mime', 20, $this->mime ) .
-                       ' ' .
-                       Xml::submitButton( $this->msg( 'ilsubmit' )->text() ) .
-                                       Xml::closeElement( 'fieldset' ) .
-                                       Xml::closeElement( 'form' );
+               $formDescriptor = [
+                       'mime' => [
+                               'type' => 'text',
+                               'name' => 'mime',
+                               'label-message' => 'mimetype',
+                               'required' => true,
+                               'default' => $this->mime,
+                       ],
+               ];
+
+               $form = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->setWrapperLegendMsg( 'mimesearch' )
+                       ->setSubmitTextMsg( 'ilsubmit' )
+                       ->setAction( $this->getPageTitle()->getLocalURL() )
+                       ->setMethod( 'get' )
+                       ->prepareForm()
+                       ->displayForm( false );
        }
 
        public function execute( $par ) {
@@ -133,7 +138,7 @@ class MIMEsearchPage extends QueryPage {
                ) {
                        $this->setHeaders();
                        $this->outputHeader();
-                       $this->getOutput()->addHTML( $this->getPageHeader() );
+                       $this->getPageHeader();
                        return;
                }
 
index 8ba90a6..e51e8b5 100644 (file)
@@ -109,12 +109,12 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * Output the results of the query.
         *
-        * @param $out OutputPage
-        * @param $skin Skin (deprecated presumably)
-        * @param $dbr IDatabase
-        * @param $res ResultWrapper Results from query
-        * @param $num integer Number of results
-        * @param $offset integer Paging offset (Should always be 0 in our case)
+        * @param OutputPage $out
+        * @param Skin $skin (deprecated presumably)
+        * @param IDatabase $dbr
+        * @param ResultWrapper $res Results from query
+        * @param int $num Number of results
+        * @param int $offset Paging offset (Should always be 0 in our case)
         */
        protected function outputResults( $out, $skin, $dbr, $res, $num, $offset ) {
                $prevMediaType = null;
@@ -168,9 +168,9 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * Output a row of the stats table
         *
-        * @param $mime String mime type (e.g. image/jpeg)
-        * @param $count integer Number of images of this type
-        * @param $totalBytes integer Total space for images of this type
+        * @param string $mime mime type (e.g. image/jpeg)
+        * @param int $count Number of images of this type
+        * @param int $totalBytes Total space for images of this type
         */
        protected function outputTableRow( $mime, $count, $bytes ) {
                $mimeSearch = SpecialPage::getTitleFor( 'MIMEsearch', $mime );
@@ -230,8 +230,8 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * Given a mime type, return a comma separated list of allowed extensions.
         *
-        * @param $mime String mime type
-        * @return String Comma separated list of allowed extensions (e.g. ".ogg, .oga")
+        * @param string $mime mime type
+        * @return string Comma separated list of allowed extensions (e.g. ".ogg, .oga")
         */
        private function getExtensionList( $mime ) {
                $exts = MimeMagic::singleton()->getExtensionsForType( $mime );
@@ -291,7 +291,7 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * Output a header for a new media type section
         *
-        * @param $mediaType string A media type (e.g. from the MEDIATYPE_xxx constants)
+        * @param string $mediaType A media type (e.g. from the MEDIATYPE_xxx constants)
         */
        protected function outputMediaType( $mediaType ) {
                $this->getOutput()->addHTML(
@@ -318,8 +318,8 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * parse the fake title format that this special page abuses querycache with.
         *
-        * @param $fakeTitle String A string formatted as <media type>;<mime type>;<count>;<bytes>
-        * @return Array The constituant parts of $fakeTitle
+        * @param string $fakeTitle A string formatted as <media type>;<mime type>;<count>;<bytes>
+        * @return array The constituant parts of $fakeTitle
         */
        private function splitFakeTitle( $fakeTitle ) {
                return explode( ';', $fakeTitle, 4 );
@@ -337,8 +337,8 @@ class MediaStatisticsPage extends QueryPage {
         * This method isn't used, since we override outputResults, but
         * we need to implement since abstract in parent class.
         *
-        * @param $skin Skin
-        * @param $result stdObject Result row
+        * @param Skin $skin
+        * @param stdObject $result Result row
         * @return bool|string|void
         * @throws MWException
         */
@@ -349,8 +349,8 @@ class MediaStatisticsPage extends QueryPage {
        /**
         * Initialize total values so we can figure out percentages later.
         *
-        * @param $dbr IDatabase
-        * @param $res ResultWrapper
+        * @param IDatabase $dbr
+        * @param ResultWrapper $res
         */
        public function preprocessResults( $dbr, $res ) {
                $this->totalCount = $this->totalBytes = 0;
index b916c1f..162ef60 100644 (file)
  * @ingroup SpecialPage
  */
 class SpecialMergeHistory extends SpecialPage {
-       /** @var string */
-       protected $mAction;
+       /** @var FormOptions */
+       protected $mOpts;
 
-       /** @var string */
-       protected $mTarget;
+       /** @var Status */
+       protected $mStatus;
 
-       /** @var string */
-       protected $mDest;
-
-       /** @var string */
-       protected $mTimestamp;
-
-       /** @var int */
-       protected $mTargetID;
-
-       /** @var int */
-       protected $mDestID;
-
-       /** @var string */
-       protected $mComment;
-
-       /** @var bool Was posted? */
-       protected $mMerge;
-
-       /** @var bool Was submitted? */
-       protected $mSubmitted;
-
-       /** @var Title */
-       protected $mTargetObj;
-
-       /** @var Title */
-       protected $mDestObj;
+       /** @var Title|null */
+       protected $mTargetObj, $mDestObj;
 
        /** @var int[] */
        public $prevId;
@@ -72,124 +48,107 @@ class SpecialMergeHistory extends SpecialPage {
                return true;
        }
 
-       /**
-        * @return void
-        */
-       private function loadRequestParams() {
-               $request = $this->getRequest();
-               $this->mAction = $request->getVal( 'action' );
-               $this->mTarget = $request->getVal( 'target' );
-               $this->mDest = $request->getVal( 'dest' );
-               $this->mSubmitted = $request->getBool( 'submitted' );
-
-               $this->mTargetID = intval( $request->getVal( 'targetID' ) );
-               $this->mDestID = intval( $request->getVal( 'destID' ) );
-               $this->mTimestamp = $request->getVal( 'mergepoint' );
-               if ( !preg_match( '/[0-9]{14}/', $this->mTimestamp ) ) {
-                       $this->mTimestamp = '';
-               }
-               $this->mComment = $request->getText( 'wpComment' );
-
-               $this->mMerge = $request->wasPosted()
-                       && $this->getUser()->matchEditToken( $request->getVal( 'wpEditToken' ) );
-
-               // target page
-               if ( $this->mSubmitted ) {
-                       $this->mTargetObj = Title::newFromText( $this->mTarget );
-                       $this->mDestObj = Title::newFromText( $this->mDest );
-               } else {
-                       $this->mTargetObj = null;
-                       $this->mDestObj = null;
-               }
-       }
-
        public function execute( $par ) {
                $this->useTransactionalTimeLimit();
 
                $this->checkPermissions();
                $this->checkReadOnly();
 
-               $this->loadRequestParams();
-
                $this->setHeaders();
                $this->outputHeader();
 
-               if ( $this->mTargetID && $this->mDestID && $this->mAction == 'submit' && $this->mMerge ) {
+               $this->addHelpLink( 'Help:Merge history' );
+
+               $opts = new FormOptions();
+
+               $opts->add( 'target', '' );
+               $opts->add( 'dest', '' );
+               $opts->add( 'target', '' );
+               $opts->add( 'mergepoint', '' );
+               $opts->add( 'reason', '' );
+               $opts->add( 'merge', false );
+
+               $opts->fetchValuesFromRequest( $this->getRequest() );
+
+               $target = $opts->getValue( 'target' );
+               $dest = $opts->getValue( 'dest' );
+               $targetObj = Title::newFromText( $target );
+               $destObj = Title::newFromText( $dest );
+               $status = Status::newGood();
+
+               $this->mOpts = $opts;
+               $this->mTargetObj = $targetObj;
+               $this->mDestObj = $destObj;
+
+               if ( $opts->getValue( 'merge' ) && $targetObj &&
+                       $destObj && $opts->getValue( 'mergepoint' ) !== '' ) {
                        $this->merge();
 
                        return;
                }
 
-               if ( !$this->mSubmitted ) {
+               if ( $target === '' && $dest === '' ) {
                        $this->showMergeForm();
 
                        return;
                }
 
-               $errors = [];
-               if ( !$this->mTargetObj instanceof Title ) {
-                       $errors[] = $this->msg( 'mergehistory-invalid-source' )->parseAsBlock();
-               } elseif ( !$this->mTargetObj->exists() ) {
-                       $errors[] = $this->msg( 'mergehistory-no-source',
-                               wfEscapeWikiText( $this->mTargetObj->getPrefixedText() )
-                       )->parseAsBlock();
+               if ( !$targetObj instanceof Title ) {
+                       $status->merge( Status::newFatal( 'mergehistory-invalid-source' ) );
+               } elseif ( !$targetObj->exists() ) {
+                       $status->merge( Status::newFatal( 'mergehistory-no-source',
+                               wfEscapeWikiText( $targetObj->getPrefixedText() )
+                       ) );
                }
 
-               if ( !$this->mDestObj instanceof Title ) {
-                       $errors[] = $this->msg( 'mergehistory-invalid-destination' )->parseAsBlock();
-               } elseif ( !$this->mDestObj->exists() ) {
-                       $errors[] = $this->msg( 'mergehistory-no-destination',
-                               wfEscapeWikiText( $this->mDestObj->getPrefixedText() )
-                       )->parseAsBlock();
+               if ( !$destObj instanceof Title ) {
+                       $status->merge( Status::newFatal( 'mergehistory-invalid-destination' ) );
+               } elseif ( !$destObj->exists() ) {
+                       $status->merge( Status::newFatal( 'mergehistory-no-destination',
+                               wfEscapeWikiText( $destObj->getPrefixedText() )
+                       ) );
                }
 
-               if ( $this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals( $this->mDestObj ) ) {
-                       $errors[] = $this->msg( 'mergehistory-same-destination' )->parseAsBlock();
+               if ( $targetObj && $destObj && $targetObj->equals( $destObj ) ) {
+                       $status->merge( Status::newFatal( 'mergehistory-same-destination' ) );
                }
 
-               if ( count( $errors ) ) {
-                       $this->showMergeForm();
-                       $this->getOutput()->addHTML( implode( "\n", $errors ) );
-               } else {
+               $this->mStatus = $status;
+
+               $this->showMergeForm();
+
+               if ( $status->isOK() ) {
                        $this->showHistory();
                }
        }
 
        function showMergeForm() {
-               $out = $this->getOutput();
-               $out->addWikiMsg( 'mergehistory-header' );
-
-               $out->addHTML(
-                       Xml::openElement( 'form', [
-                               'method' => 'get',
-                               'action' => wfScript() ] ) .
-                               '<fieldset>' .
-                               Xml::element( 'legend', [],
-                                       $this->msg( 'mergehistory-box' )->text() ) .
-                               Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) .
-                               Html::hidden( 'submitted', '1' ) .
-                               Html::hidden( 'mergepoint', $this->mTimestamp ) .
-                               Xml::openElement( 'table' ) .
-                               '<tr>
-                               <td>' . Xml::label( $this->msg( 'mergehistory-from' )->text(), 'target' ) . '</td>
-                               <td>' . Xml::input( 'target', 30, $this->mTarget, [ 'id' => 'target' ] ) . '</td>
-                       </tr><tr>
-                               <td>' . Xml::label( $this->msg( 'mergehistory-into' )->text(), 'dest' ) . '</td>
-                               <td>' . Xml::input( 'dest', 30, $this->mDest, [ 'id' => 'dest' ] ) . '</td>
-                       </tr><tr><td>' .
-                               Xml::submitButton( $this->msg( 'mergehistory-go' )->text() ) .
-                               '</td></tr>' .
-                               Xml::closeElement( 'table' ) .
-                               '</fieldset>' .
-                               '</form>'
-               );
-
-               $this->addHelpLink( 'Help:Merge history' );
+               $formDescriptor = [
+                       'target' => [
+                               'type' => 'title',
+                               'name' => 'target',
+                               'label-message' => 'mergehistory-from',
+                               'required' => true,
+                       ],
+
+                       'dest' => [
+                               'type' => 'title',
+                               'name' => 'dest',
+                               'label-message' => 'mergehistory-into',
+                               'required' => true,
+                       ],
+               ];
+
+               $form = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->setIntro( $this->msg( 'mergehistory-header' ) )
+                       ->setWrapperLegendMsg( 'mergehistory-box' )
+                       ->setSubmitTextMsg( 'mergehistory-go' )
+                       ->setMethod( 'post' )
+                       ->prepareForm()
+                       ->displayForm( $this->mStatus );
        }
 
        private function showHistory() {
-               $this->showMergeForm();
-
                # List all stored revisions
                $revisions = new MergeHistoryPager(
                        $this, [], $this->mTargetObj, $this->mDestObj
@@ -197,62 +156,46 @@ class SpecialMergeHistory extends SpecialPage {
                $haveRevisions = $revisions && $revisions->getNumRows() > 0;
 
                $out = $this->getOutput();
-               $titleObj = $this->getPageTitle();
-               $action = $titleObj->getLocalURL( [ 'action' => 'submit' ] );
-               # Start the form here
-               $top = Xml::openElement(
-                       'form',
-                       [
-                               'method' => 'post',
-                               'action' => $action,
-                               'id' => 'merge'
-                       ]
-               );
-               $out->addHTML( $top );
-
-               if ( $haveRevisions ) {
-                       # Format the user-visible controls (comment field, submission button)
-                       # in a nice little table
-                       $table =
-                               Xml::openElement( 'fieldset' ) .
-                                       $this->msg( 'mergehistory-merge', $this->mTargetObj->getPrefixedText(),
-                                               $this->mDestObj->getPrefixedText() )->parse() .
-                                       Xml::openElement( 'table', [ 'id' => 'mw-mergehistory-table' ] ) .
-                                       '<tr>
-                                               <td class="mw-label">' .
-                                       Xml::label( $this->msg( 'mergehistory-reason' )->text(), 'wpComment' ) .
-                                       '</td>
-                                       <td class="mw-input">' .
-                                       Xml::input( 'wpComment', 50, $this->mComment, [ 'id' => 'wpComment' ] ) .
-                                       '</td>
-                                       </tr>
-                                       <tr>
-                                               <td>&#160;</td>
-                                               <td class="mw-submit">' .
-                                       Xml::submitButton(
-                                               $this->msg( 'mergehistory-submit' )->text(),
-                                               [ 'name' => 'merge', 'id' => 'mw-merge-submit' ]
-                                       ) .
-                                       '</td>
-                                       </tr>' .
-                                       Xml::closeElement( 'table' ) .
-                                       Xml::closeElement( 'fieldset' );
-
-                       $out->addHTML( $table );
-               }
-
-               $out->addHTML(
-                       '<h2 id="mw-mergehistory">' .
-                               $this->msg( 'mergehistory-list' )->escaped() . "</h2>\n"
-               );
+               $header = '<h2 id="mw-mergehistory">' .
+                       $this->msg( 'mergehistory-list' )->escaped() . "</h2>\n";
 
                if ( $haveRevisions ) {
-                       $out->addHTML( $revisions->getNavigationBar() );
-                       $out->addHTML( '<ul>' );
-                       $out->addHTML( $revisions->getBody() );
-                       $out->addHTML( '</ul>' );
-                       $out->addHTML( $revisions->getNavigationBar() );
+                       $hiddenFields = [
+                               'merge' => true,
+                               'target' => $this->mOpts->getValue( 'target' ),
+                               'dest' => $this->mOpts->getValue( 'dest' ),
+                       ];
+
+                       $formDescriptor = [
+                               'reason' => [
+                                       'type' => 'text',
+                                       'name' => 'reason',
+                                       'label-message' => 'mergehistory-reason',
+                               ],
+                       ];
+
+                       $mergeText = $this->msg( 'mergehistory-merge',
+                               $this->mTargetObj->getPrefixedText(),
+                               $this->mDestObj->getPrefixedText()
+                       )->parse();
+
+                       $history = $header .
+                               $revisions->getNavigationBar() .
+                               '<ul>' .
+                               $revisions->getBody() .
+                               '</ul>' .
+                               $revisions->getNavigationBar();
+
+                       $form = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                               ->addHiddenFields( $hiddenFields )
+                               ->setPreText( $mergeText )
+                               ->setFooterText( $history )
+                               ->setSubmitTextMsg( 'mergehistory-submit' )
+                               ->setMethod( 'post' )
+                               ->prepareForm()
+                               ->displayForm( false );
                } else {
+                       $out->addHTML( $header );
                        $out->addWikiMsg( 'mergehistory-empty' );
                }
 
@@ -260,18 +203,6 @@ class SpecialMergeHistory extends SpecialPage {
                $mergeLogPage = new LogPage( 'merge' );
                $out->addHTML( '<h2>' . $mergeLogPage->getName()->escaped() . "</h2>\n" );
                LogEventsList::showLogExtract( $out, 'merge', $this->mTargetObj );
-
-               # When we submit, go by page ID to avoid some nasty but unlikely collisions.
-               # Such would happen if a page was renamed after the form loaded, but before submit
-               $misc = Html::hidden( 'targetID', $this->mTargetObj->getArticleID() );
-               $misc .= Html::hidden( 'destID', $this->mDestObj->getArticleID() );
-               $misc .= Html::hidden( 'target', $this->mTarget );
-               $misc .= Html::hidden( 'dest', $this->mDest );
-               $misc .= Html::hidden( 'wpEditToken', $this->getUser()->getEditToken() );
-               $misc .= Xml::closeElement( 'form' );
-               $out->addHTML( $misc );
-
-               return true;
        }
 
        function formatRevisionRow( $row ) {
@@ -281,7 +212,7 @@ class SpecialMergeHistory extends SpecialPage {
                $last = $this->msg( 'last' )->escaped();
 
                $ts = wfTimestamp( TS_MW, $row->rev_timestamp );
-               $checkBox = Xml::radio( 'mergepoint', $ts, ( $this->mTimestamp === $ts ) );
+               $checkBox = Xml::radio( 'mergepoint', $ts, ( $this->mOpts->getValue( 'mergepoint' ) === $ts ) );
 
                $user = $this->getUser();
 
@@ -336,23 +267,24 @@ class SpecialMergeHistory extends SpecialPage {
         * @return bool Success
         */
        function merge() {
+               $opts = $this->mOpts;
+
                # Get the titles directly from the IDs, in case the target page params
                # were spoofed. The queries are done based on the IDs, so it's best to
                # keep it consistent...
-               $targetTitle = Title::newFromID( $this->mTargetID );
-               $destTitle = Title::newFromID( $this->mDestID );
-               if ( is_null( $targetTitle ) || is_null( $destTitle ) ) {
-                       return false; // validate these
-               }
-               if ( $targetTitle->getArticleID() == $destTitle->getArticleID() ) {
+               $targetObj = $this->mTargetObj;
+               $destObj = $this->mDestObj;
+
+               if ( is_null( $targetObj ) || is_null( $destObj ) ||
+                       $targetObj->getArticleID() == $destObj->getArticleID() ) {
                        return false;
                }
 
                // MergeHistory object
-               $mh = new MergeHistory( $targetTitle, $destTitle, $this->mTimestamp );
+               $mh = new MergeHistory( $targetObj, $destObj, $opts->getValue( 'mergepoint' ) );
 
                // Merge!
-               $mergeStatus = $mh->merge( $this->getUser(), $this->mComment );
+               $mergeStatus = $mh->merge( $this->getUser(), $opts->getValue( 'reason' ) );
                if ( !$mergeStatus->isOK() ) {
                        // Failed merge
                        $this->getOutput()->addWikiMsg( $mergeStatus->getMessage() );
@@ -360,7 +292,7 @@ class SpecialMergeHistory extends SpecialPage {
                }
 
                $targetLink = Linker::link(
-                       $targetTitle,
+                       $targetObj,
                        null,
                        [],
                        [ 'redirect' => 'no' ]
@@ -368,7 +300,7 @@ class SpecialMergeHistory extends SpecialPage {
 
                $this->getOutput()->addWikiMsg( $this->msg( 'mergehistory-done' )
                        ->rawParams( $targetLink )
-                       ->params( $destTitle->getPrefixedText() )
+                       ->params( $destObj->getPrefixedText() )
                        ->numParams( $mh->getMergedRevisionCount() )
                );
 
index b93fb4e..b6398cb 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * A special page that lists last changes made to the wiki
  *
@@ -355,7 +357,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        if ( $showWatcherCount && $obj->rc_namespace >= 0 ) {
                                if ( !isset( $watcherCache[$obj->rc_namespace][$obj->rc_title] ) ) {
                                        $watcherCache[$obj->rc_namespace][$obj->rc_title] =
-                                               WatchedItemStore::getDefaultInstance()->countWatchers(
+                                               MediaWikiServices::getInstance()->getWatchedItemStore()->countWatchers(
                                                        new TitleValue( (int)$obj->rc_namespace, $obj->rc_title )
                                                );
                                }
index 2bf8385..d474ba5 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * implements Special:Search - Run text & title search and display the output
  * @ingroup SpecialPage
@@ -79,10 +81,17 @@ class SpecialSearch extends SpecialPage {
         */
        protected $customCaptions;
 
+       /**
+        * Search engine configurations.
+        * @var SearchEngineConfig
+        */
+       protected $searchConfig;
+
        const NAMESPACES_CURRENT = 'sense';
 
        public function __construct() {
                parent::__construct( 'Search' );
+               $this->searchConfig = MediaWikiServices::getInstance()->getSearchEngineConfig();
        }
 
        /**
@@ -150,7 +159,7 @@ class SpecialSearch extends SpecialPage {
                $nslist = $this->powerSearch( $request );
                if ( !count( $nslist ) ) {
                        # Fallback to user preference
-                       $nslist = SearchEngine::userNamespaces( $user );
+                       $nslist = $this->searchConfig->userNamespaces( $user );
                }
 
                $profile = null;
@@ -202,7 +211,8 @@ class SpecialSearch extends SpecialPage {
                        return;
                }
                # If there's an exact or very near match, jump right there.
-               $title = SearchEngine::getNearMatch( $term );
+               $title = $this->getSearchEngine()
+                       ->getNearMatcher( $this->getConfig() )->getNearMatch( $term );
 
                if ( !is_null( $title ) &&
                        Hooks::run( 'SpecialSearchGoResult', [ $term, $title, &$url ] )
@@ -620,7 +630,7 @@ class SpecialSearch extends SpecialPage {
         */
        protected function powerSearch( &$request ) {
                $arr = [];
-               foreach ( SearchEngine::searchableNamespaces() as $ns => $name ) {
+               foreach ( $this->searchConfig->searchableNamespaces() as $ns => $name ) {
                        if ( $request->getCheck( 'ns' . $ns ) ) {
                                $arr[] = $ns;
                        }
@@ -674,7 +684,10 @@ class SpecialSearch extends SpecialPage {
                                $user->setOption( 'searchNs' . $n, true );
                        }
 
-                       $user->saveSettings();
+                       DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                               $user->saveSettings();
+                       } );
+
                        return true;
                }
 
@@ -1021,7 +1034,7 @@ class SpecialSearch extends SpecialPage {
 
                // Groups namespaces into rows according to subject
                $rows = [];
-               foreach ( SearchEngine::searchableNamespaces() as $namespace => $name ) {
+               foreach ( $this->searchConfig->searchableNamespaces() as $namespace => $name ) {
                        $subject = MWNamespace::getSubject( $namespace );
                        if ( !array_key_exists( $subject, $rows ) ) {
                                $rows[$subject] = "";
@@ -1104,15 +1117,15 @@ class SpecialSearch extends SpecialPage {
         */
        protected function getSearchProfiles() {
                // Builds list of Search Types (profiles)
-               $nsAllSet = array_keys( SearchEngine::searchableNamespaces() );
-
+               $nsAllSet = array_keys( $this->searchConfig->searchableNamespaces() );
+               $defaultNs = $this->searchConfig->defaultNamespaces();
                $profiles = [
                        'default' => [
                                'message' => 'searchprofile-articles',
                                'tooltip' => 'searchprofile-articles-tooltip',
-                               'namespaces' => SearchEngine::defaultNamespaces(),
-                               'namespace-messages' => SearchEngine::namespacesAsText(
-                                       SearchEngine::defaultNamespaces()
+                               'namespaces' => $defaultNs,
+                               'namespace-messages' => $this->searchConfig->namespacesAsText(
+                                       $defaultNs
                                ),
                        ],
                        'images' => [
@@ -1225,6 +1238,7 @@ class SpecialSearch extends SpecialPage {
                        'name' => 'search',
                        'autofocus' => trim( $term ) === '',
                        'value' => $term,
+                       'dataLocation' => 'content',
                ] );
 
                $out =
@@ -1328,7 +1342,8 @@ class SpecialSearch extends SpecialPage {
        public function getSearchEngine() {
                if ( $this->searchEngine === null ) {
                        $this->searchEngine = $this->searchEngineType ?
-                               SearchEngine::create( $this->searchEngineType ) : SearchEngine::create();
+                               MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $this->searchEngineType ) :
+                               MediaWikiServices::getInstance()->newSearchEngine();
                }
 
                return $this->searchEngine;
index 9214c23..8cd86ce 100644 (file)
@@ -33,7 +33,7 @@ class SpecialUnlockdb extends FormSpecialPage {
        }
 
        public function doesWrites() {
-               return true;
+               return false;
        }
 
        public function requiresWrite() {
@@ -58,9 +58,9 @@ class SpecialUnlockdb extends FormSpecialPage {
        }
 
        protected function alterForm( HTMLForm $form ) {
-               $form->setWrapperLegend( false );
-               $form->setHeaderText( $this->msg( 'unlockdbtext' )->parseAsBlock() );
-               $form->setSubmitTextMsg( 'unlockbtn' );
+               $form->setWrapperLegend( false )
+                       ->setHeaderText( $this->msg( 'unlockdbtext' )->parseAsBlock() )
+                       ->setSubmitTextMsg( 'unlockbtn' );
        }
 
        public function onSubmit( array $data ) {
@@ -86,6 +86,10 @@ class SpecialUnlockdb extends FormSpecialPage {
                $out->addWikiMsg( 'unlockdbsuccesstext' );
        }
 
+       protected function getDisplayFormat() {
+               return 'ooui';
+       }
+
        protected function getGroupName() {
                return 'wiki';
        }
index 82e07fd..09111f6 100644 (file)
@@ -180,6 +180,11 @@ class SpecialUpload extends SpecialPage {
                        throw new UserBlockedError( $user->getBlock() );
                }
 
+               // Global blocks
+               if ( $user->isBlockedGlobally() ) {
+                       throw new UserBlockedError( $user->getGlobalBlock() );
+               }
+
                # Check whether we actually want to allow changing stuff
                $this->checkReadOnly();
 
@@ -362,8 +367,11 @@ class SpecialUpload extends SpecialPage {
 
                $sessionKey = $this->mUpload->stashSession();
 
+               // Add styles for the warning, reused from the live preview
+               $this->getOutput()->addModuleStyles( 'mediawiki.special.upload' );
+
                $warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
-                       . '<div class="warningbox"><ul>';
+                       . '<div class="mw-destfile-warning"><ul>';
                foreach ( $warnings as $warning => $args ) {
                        if ( $warning == 'badfilename' ) {
                                $this->mDesiredDestName = Title::makeTitle( NS_FILE, $args )->getText();
index a77c79e..45315a7 100644 (file)
@@ -699,7 +699,7 @@ class LoginForm extends SpecialPage {
 
                $u->setEmail( $this->mEmail );
                $u->setRealName( $this->mRealName );
-               $u->setToken();
+               SessionManager::singleton()->invalidateSessionsForUser( $u );
 
                Hooks::run( 'LocalUserCreated', [ $u, $autocreate ] );
                $oldUser = $u;
index 15691f2..58cde7e 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * A special page that lists last changes made to the wiki,
  * limited to user-defined list of titles.
@@ -365,7 +367,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                if ( $this->getConfig()->get( 'RCShowWatchingUsers' )
                        && $user->getOption( 'shownumberswatching' )
                ) {
-                       $watchedItemStore = WatchedItemStore::getDefaultInstance();
+                       $watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore();
                }
 
                $s = $list->beginRecentChangesList();
@@ -646,7 +648,8 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         * @return int
         */
        protected function countItems() {
-               $count = WatchedItemStore::getDefaultInstance()->countWatchedItems( $this->getUser() );
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+               $count = $store->countWatchedItems( $this->getUser() );
                return floor( $count / 2 );
        }
 }
index baa55f0..b4ea732 100644 (file)
@@ -75,7 +75,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                $this->target = Title::newFromText( $opts->getValue( 'target' ) );
                if ( !$this->target ) {
                        if ( !$this->including() ) {
-                               $out->addHTML( $this->whatlinkshereForm() );
+                               $this->buildForm();
                        }
 
                        return;
@@ -200,12 +200,8 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                ) {
                        if ( 0 == $level ) {
                                if ( !$this->including() ) {
-                                       $out->addHTML( $this->whatlinkshereForm() );
+                                       $this->buildForm();
 
-                                       // Show filters only if there are links
-                                       if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
-                                               $out->addHTML( $this->getFilterPanel() );
-                                       }
                                        $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
                                        $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() );
                                        $out->setStatusCode( 404 );
@@ -269,8 +265,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
 
                if ( $level == 0 ) {
                        if ( !$this->including() ) {
-                               $out->addHTML( $this->whatlinkshereForm() );
-                               $out->addHTML( $this->getFilterPanel() );
+                               $this->buildForm();
                                $out->addWikiMsg( 'linkshere', $this->target->getPrefixedText() );
 
                                $prevnext = $this->getPrevNext( $prevId, $nextId );
@@ -444,7 +439,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                return $this->msg( 'viewprevnext' )->rawParams( $prev, $next, $nums )->escaped();
        }
 
-       function whatlinkshereForm() {
+       protected function buildForm() {
                // We get nicer value from the title object
                $this->opts->consumeValue( 'target' );
                // Reset these for new requests
@@ -455,88 +450,57 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                $nsinvert = $this->opts->consumeValue( 'invert' );
 
                # Build up the form
-               $f = Xml::openElement( 'form', [ 'action' => wfScript() ] );
 
-               # Values that should not be forgotten
-               $f .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
-               foreach ( $this->opts->getUnconsumedValues() as $name => $value ) {
-                       $f .= Html::hidden( $name, $value );
-               }
-
-               $f .= Xml::fieldset( $this->msg( 'whatlinkshere' )->text() );
-
-               # Target input (.mw-searchInput enables suggestions)
-               $f .= Xml::inputLabel( $this->msg( 'whatlinkshere-page' )->text(), 'target',
-                       'mw-whatlinkshere-target', 40, $target, [ 'class' => 'mw-searchInput' ] );
+               $hiddenFields = [
+                       'title' => $this->getPageTitle()->getPrefixedDBkey(),
+               ];
 
-               $f .= ' ';
+               $formDescriptor = [
+                       'target' => [
+                               'type' => 'title',
+                               'name' => 'target',
+                               'label-message' => 'whatlinkshere-page',
+                               'default' => $this->opts->getValue( 'target' ),
+                       ],
 
-               # Namespace selector
-               $f .= Html::namespaceSelector(
-                       [
-                               'selected' => $namespace,
-                               'all' => '',
-                               'label' => $this->msg( 'namespace' )->text()
-                       ], [
+                       'namespace' => [
+                               'type' => 'namespaceselect',
                                'name' => 'namespace',
-                               'id' => 'namespace',
-                               'class' => 'namespaceselector',
-                       ]
-               );
-
-               $f .= '&#160;' .
-                       Xml::checkLabel(
-                               $this->msg( 'invert' )->text(),
-                               'invert',
-                               'nsinvert',
-                               $nsinvert,
-                               [ 'title' => $this->msg( 'tooltip-whatlinkshere-invert' )->text() ]
-                       );
-
-               $f .= ' ';
-
-               # Submit
-               $f .= Xml::submitButton( $this->msg( 'whatlinkshere-submit' )->text() );
-
-               # Close
-               $f .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' ) . "\n";
-
-               return $f;
-       }
-
-       /**
-        * Create filter panel
-        *
-        * @return string HTML fieldset and filter panel with the show/hide links
-        */
-       function getFilterPanel() {
-               $show = $this->msg( 'show' )->escaped();
-               $hide = $this->msg( 'hide' )->escaped();
-
-               $changed = $this->opts->getChangedValues();
-               unset( $changed['target'] ); // Already in the request title
+                               'label-message' => 'namespace',
+                               'all' => '',
+                       ],
+
+                       'invert' => [
+                               'type' => 'check',
+                               'name' => 'invert',
+                               'label-message' => 'invert',
+                               'default' => false,
+                       ],
+               ];
 
-               $links = [];
-               $types = [ 'hidetrans', 'hidelinks', 'hideredirs' ];
-               if ( $this->target->getNamespace() == NS_FILE ) {
-                       $types[] = 'hideimages';
+               $filters = [ 'hidetrans', 'hidelinks', 'hideredirs' ];
+               if ( $this->target instanceof Title &&
+                       $this->target->getNamespace() == NS_FILE ) {
+                       $filters[] = 'hideimages';
                }
 
-               // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans',
-               // 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages'
-               // To be sure they will be found by grep
-               foreach ( $types as $type ) {
-                       $chosen = $this->opts->getValue( $type );
-                       $msg = $chosen ? $show : $hide;
-                       $overrides = [ $type => !$chosen ];
-                       $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
-                               $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
+               foreach ( $filters as $filter ) {
+                       $formDescriptor[$filter] = [
+                               'type' => 'check',
+                               'name' => $filter,
+                               'label' => $this->msg( 'whatlinkshere-' . $filter ),
+                               'value' => false,
+                       ];
                }
 
-               return Xml::fieldset(
-                       $this->msg( 'whatlinkshere-filters' )->text(),
-                       $this->getLanguage()->pipeList( $links )
-               );
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->addHiddenFields( $hiddenFields )
+                       ->setWrapperLegendMsg( 'whatlinkshere' )
+                       ->setSubmitTextMsg( 'whatlinkshere-submit' )
+                       ->setAction( $this->getPageTitle()->getLocalURL() )
+                       ->setMethod( 'get' )
+                       ->prepareForm()
+                       ->displayForm( false );
        }
 
        /**
index 0d3bc9a..73ab0ad 100644 (file)
@@ -52,15 +52,15 @@ class ActiveUsersPager extends UsersPager {
 
        /**
         * @param IContextSource $context
-        * @param null $group Unused
-        * @param string $par Parameter passed to the page
+        * @param FormOptions $opts
         */
-       function __construct( IContextSource $context = null, $group = null, $par = null ) {
+       function __construct( IContextSource $context = null, FormOptions $opts ) {
                parent::__construct( $context );
 
                $this->RCMaxAge = $this->getConfig()->get( 'ActiveUserDays' );
-               $un = $this->getRequest()->getText( 'username', $par );
                $this->requestedUser = '';
+
+               $un = $opts->getValue( 'username' );
                if ( $un != '' ) {
                        $username = Title::makeTitleSafe( NS_USER, $un );
                        if ( !is_null( $username ) ) {
@@ -68,21 +68,10 @@ class ActiveUsersPager extends UsersPager {
                        }
                }
 
-               $this->setupOptions();
-       }
-
-       public function setupOptions() {
-               $this->opts = new FormOptions();
-
-               $this->opts->add( 'hidebots', false, FormOptions::BOOL );
-               $this->opts->add( 'hidesysops', false, FormOptions::BOOL );
-
-               $this->opts->fetchValuesFromRequest( $this->getRequest() );
-
-               if ( $this->opts->getValue( 'hidebots' ) == 1 ) {
+               if ( $opts->getValue( 'hidebots' ) == 1 ) {
                        $this->hideRights[] = 'bot';
                }
-               if ( $this->opts->getValue( 'hidesysops' ) == 1 ) {
+               if ( $opts->getValue( 'hidesysops' ) == 1 ) {
                        $this->hideGroups[] = 'sysop';
                }
        }
@@ -203,52 +192,4 @@ class ActiveUsersPager extends UsersPager {
                return Html::rawElement( 'li', [], "{$item} [{$count}]{$blocked}" );
        }
 
-       function getPageHeader() {
-               $self = $this->getTitle();
-               $limit = $this->mLimit ? Html::hidden( 'limit', $this->mLimit ) : '';
-
-               # Form tag
-               $out = Xml::openElement( 'form', [ 'method' => 'get', 'action' => wfScript() ] );
-               $out .= Xml::fieldset( $this->msg( 'activeusers' )->text() ) . "\n";
-               $out .= Html::hidden( 'title', $self->getPrefixedDBkey() ) . $limit . "\n";
-
-               # Username field (with autocompletion support)
-               $this->getOutput()->addModules( 'mediawiki.userSuggest' );
-               $out .= Xml::inputLabel(
-                               $this->msg( 'activeusers-from' )->text(),
-                               'username',
-                               'offset',
-                               20,
-                               $this->requestedUser,
-                               [
-                                       'class' => 'mw-ui-input-inline mw-autocomplete-user',
-                                       'tabindex' => 1,
-                               ] + (
-                                       // Set autofocus on blank input
-                               $this->requestedUser === '' ? [ 'autofocus' => '' ] : []
-                               )
-                       ) . '<br />';
-
-               $out .= Xml::checkLabel( $this->msg( 'activeusers-hidebots' )->text(),
-                       'hidebots', 'hidebots', $this->opts->getValue( 'hidebots' ), [ 'tabindex' => 2 ] );
-
-               $out .= Xml::checkLabel(
-                               $this->msg( 'activeusers-hidesysops' )->text(),
-                               'hidesysops',
-                               'hidesysops',
-                               $this->opts->getValue( 'hidesysops' ),
-                               [ 'tabindex' => 3 ]
-                       ) . '<br />';
-
-               # Submit button and form bottom
-               $out .= Xml::submitButton(
-                               $this->msg( 'activeusers-submit' )->text(),
-                               [ 'tabindex' => 4 ]
-                       ) . "\n";
-               $out .= Xml::closeElement( 'fieldset' );
-               $out .= Xml::closeElement( 'form' );
-
-               return $out;
-       }
-
 }
index 7c08be4..5c504f3 100644 (file)
@@ -98,11 +98,12 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         * @param string $text The page title. Should be valid. Only minimal normalization is applied.
         *        Underscores will be replaced.
         * @param string $fragment The fragment name (may be empty).
+        * @param string $interwiki The interwiki name (may be empty).
         *
         * @throws InvalidArgumentException If the namespace is invalid
         * @return string
         */
-       public function formatTitle( $namespace, $text, $fragment = '' ) {
+       public function formatTitle( $namespace, $text, $fragment = '', $interwiki = '' ) {
                if ( $namespace !== false ) {
                        $namespace = $this->getNamespaceName( $namespace, $text );
 
@@ -115,6 +116,10 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                        $text = $text . '#' . $fragment;
                }
 
+               if ( $interwiki !== '' ) {
+                       $text = $interwiki . ':' . $text;
+               }
+
                $text = str_replace( '_', ' ', $text );
 
                return $text;
@@ -136,17 +141,17 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                // be refactored to avoid this.
                $parts = $this->splitTitleString( $text, $defaultNamespace );
 
-               // Interwiki links are not supported by TitleValue
-               if ( $parts['interwiki'] !== '' ) {
-                       throw new MalformedTitleException( 'title-invalid-interwiki', $text );
-               }
-
                // Relative fragment links are not supported by TitleValue
                if ( $parts['dbkey'] === '' ) {
                        throw new MalformedTitleException( 'title-invalid-empty', $text );
                }
 
-               return new TitleValue( $parts['namespace'], $parts['dbkey'], $parts['fragment'] );
+               return new TitleValue(
+                       $parts['namespace'],
+                       $parts['dbkey'],
+                       $parts['fragment'],
+                       $parts['interwiki']
+               );
        }
 
        /**
@@ -168,7 +173,37 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         * @return string
         */
        public function getPrefixedText( LinkTarget $title ) {
-               return $this->formatTitle( $title->getNamespace(), $title->getText(), '' );
+               return $this->formatTitle(
+                       $title->getNamespace(),
+                       $title->getText(),
+                       '',
+                       $title->getInterwiki()
+               );
+       }
+
+       /**
+        * @since 1.27
+        * @see TitleFormatter::getPrefixedDBkey()
+        * @param LinkTarget $target
+        * @return string
+        */
+       public function getPrefixedDBkey( LinkTarget $target ) {
+               $key = '';
+               if ( $target->isExternal() ) {
+                       $key .= $target->getInterwiki() . ':';
+               }
+               $nsName = $this->getNamespaceName(
+                       $target->getNamespace(),
+                       $target->getText()
+               );
+
+               if ( $nsName !== '' ) {
+                       $key .= $nsName . ':';
+               }
+
+               $key .= $target->getText();
+
+               return strtr( $key, ' ', '_' );
        }
 
        /**
@@ -179,7 +214,12 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
         * @return string
         */
        public function getFullText( LinkTarget $title ) {
-               return $this->formatTitle( $title->getNamespace(), $title->getText(), $title->getFragment() );
+               return $this->formatTitle(
+                       $title->getNamespace(),
+                       $title->getText(),
+                       $title->getFragment(),
+                       $title->getInterwiki()
+               );
        }
 
        /**
index 96f396c..5177606 100644 (file)
@@ -42,10 +42,11 @@ interface TitleFormatter {
         * @param int|bool $namespace The namespace ID (or false, if the namespace should be ignored)
         * @param string $text The page title
         * @param string $fragment The fragment name (may be empty).
+        * @param string $interwiki The interwiki prefix (may be empty).
         *
         * @return string
         */
-       public function formatTitle( $namespace, $text, $fragment = '' );
+       public function formatTitle( $namespace, $text, $fragment = '', $interwiki = '' );
 
        /**
         * Returns the title text formatted for display, without namespace of fragment.
@@ -67,6 +68,18 @@ interface TitleFormatter {
         */
        public function getPrefixedText( LinkTarget $title );
 
+       /**
+        * Return the title in prefixed database key form, with interwiki
+        * and namespace.
+        *
+        * @since 1.27
+        *
+        * @param LinkTarget $target
+        *
+        * @return string
+        */
+       public function getPrefixedDBkey( LinkTarget $target );
+
        /**
         * Returns the title formatted for display, with namespace and fragment.
         *
index c23d698..597bf2f 100644 (file)
@@ -30,9 +30,6 @@ use Wikimedia\Assert\Assert;
  * @note In contrast to Title, this is designed to be a plain value object. That is,
  * it is immutable, does not use global state, and causes no side effects.
  *
- * @note TitleValue represents the title of a local page (or fragment of a page).
- * It does not represent a link, and does not support interwiki prefixes etc.
- *
  * @see https://www.mediawiki.org/wiki/Requests_for_comment/TitleValue
  * @since 1.23
  */
@@ -52,6 +49,11 @@ class TitleValue implements LinkTarget {
         */
        protected $fragment;
 
+       /**
+        * @var string
+        */
+       protected $interwiki;
+
        /**
         * Constructs a TitleValue.
         *
@@ -65,13 +67,15 @@ class TitleValue implements LinkTarget {
         * @param string $dbkey The page title in valid DBkey form. No normalization is applied.
         * @param string $fragment The fragment title. Use '' to represent the whole page.
         *   No validation or normalization is applied.
+        * @param string $interwiki The interwiki component
         *
         * @throws InvalidArgumentException
         */
-       public function __construct( $namespace, $dbkey, $fragment = '' ) {
+       public function __construct( $namespace, $dbkey, $fragment = '', $interwiki = '' ) {
                Assert::parameterType( 'integer', $namespace, '$namespace' );
                Assert::parameterType( 'string', $dbkey, '$dbkey' );
                Assert::parameterType( 'string', $fragment, '$fragment' );
+               Assert::parameterType( 'string', $interwiki, '$interwiki' );
 
                // Sanity check, no full validation or normalization applied here!
                Assert::parameter( !preg_match( '/^_|[ \r\n\t]|_$/', $dbkey ), '$dbkey', 'invalid DB key' );
@@ -80,6 +84,7 @@ class TitleValue implements LinkTarget {
                $this->namespace = $namespace;
                $this->dbkey = $dbkey;
                $this->fragment = $fragment;
+               $this->interwiki = $interwiki;
        }
 
        /**
@@ -89,6 +94,15 @@ class TitleValue implements LinkTarget {
                return $this->namespace;
        }
 
+       /**
+        * @since 1.27
+        * @param int $ns
+        * @return bool
+        */
+       public function inNamespace( $ns ) {
+               return $this->namespace == $ns;
+       }
+
        /**
         * @return string
         */
@@ -138,7 +152,32 @@ class TitleValue implements LinkTarget {
         * @return TitleValue
         */
        public function createFragmentTarget( $fragment ) {
-               return new TitleValue( $this->namespace, $this->dbkey, $fragment );
+               return new TitleValue(
+                       $this->namespace,
+                       $this->dbkey,
+                       $fragment,
+                       $this->interwiki
+               );
+       }
+
+       /**
+        * Whether it has an interwiki part
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function isExternal() {
+               return $this->interwiki !== '';
+       }
+
+       /**
+        * Returns the interwiki part
+        *
+        * @since 1.27
+        * @return string
+        */
+       public function getInterwiki() {
+               return $this->interwiki;
        }
 
        /**
@@ -155,6 +194,10 @@ class TitleValue implements LinkTarget {
                        $name .= '#' . $this->fragment;
                }
 
+               if ( $this->interwiki !== '' ) {
+                       $name = $this->interwiki . ':' . $name;
+               }
+
                return $name;
        }
 }
index c1e096b..3d7d71c 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Session\SessionManager;
 use MediaWiki\Session\Token;
 
@@ -275,8 +276,8 @@ class User implements IDBAccessObject {
        protected $mImplicitGroups;
        /** @var array */
        protected $mFormerGroups;
-       /** @var bool */
-       protected $mBlockedGlobally;
+       /** @var Block */
+       protected $mGlobalBlock;
        /** @var bool */
        protected $mLocked;
        /** @var bool */
@@ -474,7 +475,7 @@ class User implements IDBAccessObject {
         */
        protected static function getInProcessCache() {
                if ( !self::$inProcessCache ) {
-                       self::$inProcessCache = new HashBagOStuff( ['maxKeys' => 10] );
+                       self::$inProcessCache = new HashBagOStuff( [ 'maxKeys' => 10 ] );
                }
                return self::$inProcessCache;
        }
@@ -1534,7 +1535,8 @@ class User implements IDBAccessObject {
                foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
                        $defOpt[$langCode == $wgContLang->getCode() ? 'variant' : "variant-$langCode"] = $langCode;
                }
-               foreach ( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
+               $namespaces = MediaWikiServices::getInstance()->getSearchEngineConfig()->searchableNamespaces();
+               foreach ( $namespaces as $nsnum => $nsname ) {
                        $defOpt['searchNs' . $nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
                }
                $defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
@@ -1992,8 +1994,22 @@ class User implements IDBAccessObject {
         * @return bool True if blocked, false otherwise
         */
        public function isBlockedGlobally( $ip = '' ) {
-               if ( $this->mBlockedGlobally !== null ) {
-                       return $this->mBlockedGlobally;
+               return $this->getGlobalBlock( $ip ) instanceof Block;
+       }
+
+       /**
+        * 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 Block|null Block object if blocked, null otherwise
+        * @throws FatalError
+        * @throws MWException
+        */
+       public function getGlobalBlock( $ip = '' ) {
+               if ( $this->mGlobalBlock !== null ) {
+                       return $this->mGlobalBlock ?: null;
                }
                // User is already an IP?
                if ( IP::isIPAddress( $this->getName() ) ) {
@@ -2002,9 +2018,17 @@ class User implements IDBAccessObject {
                        $ip = $this->getRequest()->getIP();
                }
                $blocked = false;
-               Hooks::run( 'UserIsBlockedGlobally', [ &$this, $ip, &$blocked ] );
-               $this->mBlockedGlobally = (bool)$blocked;
-               return $this->mBlockedGlobally;
+               $block = null;
+               Hooks::run( 'UserIsBlockedGlobally', [ &$this, $ip, &$blocked, &$block ] );
+
+               if ( $blocked && $block === null ) {
+                       // back-compat: UserIsBlockedGlobally didn't have $block param first
+                       $block = new Block;
+                       $block->setTarget( $ip );
+               }
+
+               $this->mGlobalBlock = $blocked ? $block : false;
+               return $this->mGlobalBlock ?: null;
        }
 
        /**
@@ -2465,9 +2489,9 @@ class User implements IDBAccessObject {
                        throw new PasswordError( wfMessage( 'externaldberror' )->text() );
                }
 
-               $this->setToken();
                $this->setOption( 'watchlisttoken', false );
                $this->setPasswordInternal( $str );
+               SessionManager::singleton()->invalidateSessionsForUser( $this );
 
                return true;
        }
@@ -2484,9 +2508,9 @@ class User implements IDBAccessObject {
                global $wgAuth;
 
                if ( $wgAuth->allowSetLocalPassword() ) {
-                       $this->setToken();
                        $this->setOption( 'watchlisttoken', false );
                        $this->setPasswordInternal( $str );
+                       SessionManager::singleton()->invalidateSessionsForUser( $this );
                }
        }
 
@@ -3374,6 +3398,19 @@ class User implements IDBAccessObject {
                return !$this->isLoggedIn();
        }
 
+       /**
+        * @return bool Whether this user is flagged as being a bot role account
+        * @since 1.28
+        */
+       public function isBot() {
+               $isBot = false;
+               if ( !Hooks::run( "UserIsBot", [ $this, &$isBot ] ) ) {
+                       return $isBot;
+               }
+
+               return ( $isBot || in_array( 'bot', $this->getGroups() ) );
+       }
+
        /**
         * Check if user is allowed to access a feature / make an action
         *
@@ -3476,7 +3513,7 @@ class User implements IDBAccessObject {
         */
        public function isWatched( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( $title->isWatchable() && ( !$checkRights || $this->isAllowed( 'viewmywatchlist' ) ) ) {
-                       return WatchedItemStore::getDefaultInstance()->isWatched( $this, $title );
+                       return MediaWikiServices::getInstance()->getWatchedItemStore()->isWatched( $this, $title );
                }
                return false;
        }
@@ -3490,7 +3527,7 @@ class User implements IDBAccessObject {
         */
        public function addWatch( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( !$checkRights || $this->isAllowed( 'editmywatchlist' ) ) {
-                       WatchedItemStore::getDefaultInstance()->addWatchBatchForUser(
+                       MediaWikiServices::getInstance()->getWatchedItemStore()->addWatchBatchForUser(
                                $this,
                                [ $title->getSubjectPage(), $title->getTalkPage() ]
                        );
@@ -3507,8 +3544,9 @@ class User implements IDBAccessObject {
         */
        public function removeWatch( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( !$checkRights || $this->isAllowed( 'editmywatchlist' ) ) {
-                       WatchedItemStore::getDefaultInstance()->removeWatch( $this, $title->getSubjectPage() );
-                       WatchedItemStore::getDefaultInstance()->removeWatch( $this, $title->getTalkPage() );
+                       $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+                       $store->removeWatch( $this, $title->getSubjectPage() );
+                       $store->removeWatch( $this, $title->getTalkPage() );
                }
                $this->invalidateCache();
        }
@@ -3577,7 +3615,7 @@ class User implements IDBAccessObject {
                        $force = 'force';
                }
 
-               WatchedItemStore::getDefaultInstance()
+               MediaWikiServices::getInstance()->getWatchedItemStore()
                        ->resetNotificationTimestamp( $this, $title, $force, $oldid );
        }
 
old mode 100644 (file)
new mode 100755 (executable)
index 5ff411d..6baaff0
@@ -16,6 +16,7 @@ class SearchInputWidget extends TitleInputWidget {
        protected $performSearchOnClick = true;
        protected $validateTitle = false;
        protected $highlightFirst = false;
+       protected $dataLocation = 'header';
 
        /**
         * @param array $config Configuration options
@@ -24,6 +25,8 @@ class SearchInputWidget extends TitleInputWidget {
         * @param boolean|null $config['performSearchOnClick'] If true, the script will start a search
         *  whenever a user hits a suggestion. If false, the text of the suggestion is inserted into the
         *  text field only (default: true)
+        * @param string $config['dataLocation'] Where the search input field will be
+        *  used (header or content, default: header)
         */
        public function __construct( array $config = [] ) {
                $config = array_merge( [
@@ -31,7 +34,6 @@ class SearchInputWidget extends TitleInputWidget {
                        'maxLength' => null,
                        'type' => 'search',
                        'icon' => 'search',
-                       'dataLocation' => 'content',
                ], $config );
 
                // Parent constructor
index 190f2bf..e7643b1 100644 (file)
@@ -942,14 +942,14 @@ class Language {
         * @param string $key
         * @return string
         */
-       function getMonthAbbreviation( $key ) {
+       public function getMonthAbbreviation( $key ) {
                return $this->getMessageFromDB( self::$mMonthAbbrevMsgs[$key - 1] );
        }
 
        /**
         * @return array
         */
-       function getMonthAbbreviationsArray() {
+       public function getMonthAbbreviationsArray() {
                $monthNames = [ '' ];
                for ( $i = 1; $i < 13; $i++ ) {
                        $monthNames[] = $this->getMonthAbbreviation( $i );
@@ -961,7 +961,7 @@ class Language {
         * @param string $key
         * @return string
         */
-       function getWeekdayName( $key ) {
+       public function getWeekdayName( $key ) {
                return $this->getMessageFromDB( self::$mWeekdayMsgs[$key - 1] );
        }
 
@@ -1089,7 +1089,7 @@ class Language {
         * @throws MWException
         * @return string
         */
-       function sprintfDate( $format, $ts, DateTimeZone $zone = null, &$ttl = null ) {
+       public function sprintfDate( $format, $ts, DateTimeZone $zone = null, &$ttl = null ) {
                $s = '';
                $raw = false;
                $roman = false;
@@ -2067,7 +2067,7 @@ class Language {
         *   get user timecorrection setting)
         * @return int
         */
-       function userAdjust( $ts, $tz = false ) {
+       public function userAdjust( $ts, $tz = false ) {
                global $wgUser, $wgLocalTZoffset;
 
                if ( $tz === false ) {
@@ -2214,7 +2214,7 @@ class Language {
         *   validateTimeZone() in Special:Preferences
         * @return string
         */
-       function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
+       public function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
                $ts = wfTimestamp( TS_MW, $ts );
                if ( $adj ) {
                        $ts = $this->userAdjust( $ts, $timecorrection );
@@ -2233,7 +2233,7 @@ class Language {
         *   validateTimeZone() in Special:Preferences
         * @return string
         */
-       function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
+       public function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
                $ts = wfTimestamp( TS_MW, $ts );
                if ( $adj ) {
                        $ts = $this->userAdjust( $ts, $timecorrection );
@@ -2253,7 +2253,7 @@ class Language {
         *   validateTimeZone() in Special:Preferences
         * @return string
         */
-       function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false ) {
+       public function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false ) {
                $ts = wfTimestamp( TS_MW, $ts );
                if ( $adj ) {
                        $ts = $this->userAdjust( $ts, $timecorrection );
@@ -2559,7 +2559,7 @@ class Language {
         * @param string $key
         * @return array|null
         */
-       function getMessage( $key ) {
+       public function getMessage( $key ) {
                return self::$dataCache->getSubitem( $this->mCode, 'messages', $key );
        }
 
@@ -2576,7 +2576,7 @@ class Language {
         * @param string $string
         * @return string
         */
-       function iconv( $in, $out, $string ) {
+       public function iconv( $in, $out, $string ) {
                # This is a wrapper for iconv in all languages except esperanto,
                # which does some nasty x-conversions beforehand
 
@@ -2623,7 +2623,7 @@ class Language {
         *
         * @return string
         */
-       function ucfirst( $str ) {
+       public function ucfirst( $str ) {
                $o = ord( $str );
                if ( $o < 96 ) { // if already uppercase...
                        return $str;
@@ -2643,7 +2643,7 @@ class Language {
         *
         * @return string
         */
-       function uc( $str, $first = false ) {
+       public function uc( $str, $first = false ) {
                if ( $first ) {
                        if ( $this->isMultibyte( $str ) ) {
                                return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
index f9ebdec..b413ef9 100644 (file)
@@ -32,7 +32,7 @@ class LanguageAz extends Language {
         * @param string $string
         * @return mixed|string
         */
-       function ucfirst( $string ) {
+       public function ucfirst( $string ) {
                if ( $string[0] == 'i' ) {
                        return 'İ' . substr( $string, 1 );
                }
index 697fc93..3fec5fc 100644 (file)
@@ -59,7 +59,7 @@ class LanguageEo extends Language {
         * @param string $string Text to be converted
         * @return string
         */
-       function iconv( $in, $out, $string ) {
+       public function iconv( $in, $out, $string ) {
                if ( strcasecmp( $in, 'x' ) == 0 && strcasecmp( $out, 'utf-8' ) == 0 ) {
                        return preg_replace_callback(
                                '/([cghjsu]x?)((?:xx)*)(?!x)/i',
index 0cd0c0d..30abe25 100644 (file)
@@ -54,7 +54,7 @@ class LanguageKaa extends Language {
         *
         * @return string
         */
-       function ucfirst( $string ) {
+       public function ucfirst( $string ) {
                if ( substr( $string, 0, 1 ) === 'i' ) {
                        return 'İ' . substr( $string, 1 );
                }
index 9c6ad44..548c9a0 100644 (file)
@@ -415,7 +415,7 @@ class LanguageKk extends LanguageKk_cyrl {
         *
         * @return string
         */
-       function ucfirst( $string ) {
+       public function ucfirst( $string ) {
                if ( $string[0] == 'i' ) {
                        $variant = $this->getPreferredVariant();
                        if ( $variant == 'kk-latn' || $variant == 'kk-tr' ) {
index 353b59a..5204fb5 100644 (file)
@@ -35,7 +35,7 @@ class LanguageQqx extends Language {
         * @param string $key
         * @return string
         */
-       function getMessage( $key ) {
+       public function getMessage( $key ) {
                return "($key$*)";
        }
 }
index a4f05f8..c947341 100644 (file)
@@ -37,7 +37,7 @@ class LanguageTr extends Language {
         * @param string $string
         * @return string
         */
-       function ucfirst( $string ) {
+       public function ucfirst( $string ) {
                if ( strlen( $string ) && $string[0] == 'i' ) {
                        return 'İ' . substr( $string, 1 );
                }
index 3520298..078b068 100644 (file)
@@ -42,7 +42,7 @@ class LanguageWa extends Language {
         * @param bool $tc
         * @return string
         */
-       function date( $ts, $adj = false, $format = true, $tc = false ) {
+       public function date( $ts, $adj = false, $format = true, $tc = false ) {
                $ts = wfTimestamp( TS_MW, $ts );
                if ( $adj ) {
                        $ts = $this->userAdjust( $ts, $tc );
@@ -89,7 +89,7 @@ class LanguageWa extends Language {
         * @param bool $tc
         * @return string
         */
-       function timeanddate( $ts, $adj = false, $format = true, $tc = false ) {
+       public function timeanddate( $ts, $adj = false, $format = true, $tc = false ) {
                if ( $adj ) {
                        $ts = $this->userAdjust( $ts, $tc );
                }
index 08a40b8..e4998fc 100644 (file)
@@ -3220,6 +3220,7 @@ public static $zh2Hant = [
 '不采声' => '不采聲',
 '不采聲' => '不采聲',
 '不锈钢' => '不鏽鋼',
+'不食乾腊' => '不食乾腊',
 '不食干腊' => '不食乾腊',
 '不斗' => '不鬥',
 '丑三' => '丑三',
@@ -3273,6 +3274,7 @@ public static $zh2Hant = [
 '丰容' => '丰容',
 '丰情' => '丰情',
 '丰标' => '丰標',
+'丰標' => '丰標',
 '丰标不凡' => '丰標不凡',
 '丰標不凡' => '丰標不凡',
 '丰神' => '丰神',
@@ -3299,6 +3301,7 @@ public static $zh2Hant = [
 '么爷' => '么爺',
 '么雞' => '么雞',
 '么么小丑' => '么麼小丑',
+'么麼小丑' => '么麼小丑',
 '之一只' => '之一只',
 '之二只' => '之二只',
 '之八九只' => '之八九只',
@@ -3497,6 +3500,7 @@ public static $zh2Hant = [
 '于仁泰' => '于仁泰',
 '于仲文' => '于仲文',
 '于佳卉' => '于佳卉',
+'于來山' => '于來山',
 '于来山' => '于來山',
 '于伟国' => '于偉國',
 '于偉國' => '于偉國',
@@ -3509,17 +3513,20 @@ public static $zh2Hant = [
 '于再清' => '于再清',
 '于冕' => '于冕',
 '于冠华' => '于冠華',
+'于冠華' => '于冠華',
 '于凌奎' => '于凌奎',
 '于凌辰' => '于凌辰',
 '于勒' => '于勒',
 '于化虎' => '于化虎',
 '于占元' => '于占元',
 '于友泽' => '于友澤',
+'于友澤' => '于友澤',
 '于台烟' => '于台煙',
 '于台煙' => '于台煙',
 '于右任' => '于右任',
 '于吉' => '于吉',
 '于和伟' => '于和偉',
+'于和偉' => '于和偉',
 '于品海' => '于品海',
 '于国桢' => '于國楨',
 '于國楨' => '于國楨',
@@ -3530,6 +3537,7 @@ public static $zh2Hant = [
 '于大宝' => '于大寶',
 '于大寶' => '于大寶',
 '于天仁' => '于天仁',
+'于天龍' => '于天龍',
 '于天龙' => '于天龍',
 '于奇库杜克' => '于奇庫杜克',
 '于奇庫杜克' => '于奇庫杜克',
@@ -3543,6 +3551,7 @@ public static $zh2Hant = [
 '于家堡' => '于家堡',
 '于寘' => '于寘',
 '于宝轩' => '于寶軒',
+'于寶軒' => '于寶軒',
 '于小伟' => '于小偉',
 '于小偉' => '于小偉',
 '于小彤' => '于小彤',
@@ -3565,6 +3574,7 @@ public static $zh2Hant = [
 '于志宁' => '于志寧',
 '于志寧' => '于志寧',
 '于忠肃集' => '于忠肅集',
+'于忠肅集' => '于忠肅集',
 '于思' => '于思',
 '于慎行' => '于慎行',
 '于慧' => '于慧',
@@ -3593,6 +3603,7 @@ public static $zh2Hant = [
 '于格' => '于格',
 '于枫' => '于楓',
 '于楓' => '于楓',
+'于榮光' => '于榮光',
 '于荣光' => '于榮光',
 '于樂' => '于樂',
 '于树洁' => '于樹潔',
@@ -3644,6 +3655,7 @@ public static $zh2Hant = [
 '于西翰' => '于西翰',
 '于謙' => '于謙',
 '于谦' => '于謙',
+'于謹' => '于謹',
 '于谨' => '于謹',
 '于貝爾' => '于貝爾',
 '于贝尔' => '于貝爾',
@@ -3662,6 +3674,7 @@ public static $zh2Hant = [
 '于双戈' => '于雙戈',
 '于雙戈' => '于雙戈',
 '于云鹤' => '于雲鶴',
+'于雲鶴' => '于雲鶴',
 '于震' => '于震',
 '于震寰' => '于震寰',
 '于震环' => '于震環',
@@ -3754,9 +3767,11 @@ public static $zh2Hant = [
 '伊斯兰历' => '伊斯蘭曆',
 '伊斯兰历史' => '伊斯蘭歷史',
 '伊东怜' => '伊東怜',
+'伊東怜' => '伊東怜',
 '伊尔汗历表' => '伊爾汗曆表',
 '伊达里子' => '伊達里子',
 '伊适杰' => '伊適杰',
+'伊適杰' => '伊適杰',
 '伊里布' => '伊里布',
 '伊郁' => '伊鬱',
 '伏几' => '伏几',
@@ -3780,6 +3795,7 @@ public static $zh2Hant = [
 '余光中' => '余光中',
 '余光生' => '余光生',
 '余力为' => '余力為',
+'余力為' => '余力為',
 '余威德' => '余威德',
 '余子明' => '余子明',
 '余思敏' => '余思敏',
@@ -3804,7 +3820,6 @@ public static $zh2Hant = [
 '并吞' => '併吞',
 '并拢' => '併攏',
 '并案' => '併案',
-'并流' => '併流',
 '并火' => '併火',
 '并为一家' => '併為一家',
 '并为一体' => '併為一體',
@@ -3909,6 +3924,7 @@ public static $zh2Hant = [
 '俭仆' => '儉僕',
 '俭朴' => '儉樸',
 '俭确之教' => '儉确之教',
+'儉确之教' => '儉确之教',
 '儒略改革历' => '儒略改革曆',
 '儒略改革历史' => '儒略改革歷史',
 '儒略历' => '儒略曆',
@@ -3957,7 +3973,9 @@ public static $zh2Hant = [
 '党姓' => '党姓',
 '党家' => '党家',
 '党怀英' => '党懷英',
+'党懷英' => '党懷英',
 '党进' => '党進',
+'党進' => '党進',
 '党項' => '党項',
 '党项' => '党項',
 '内脏' => '內臟',
@@ -3990,6 +4008,8 @@ public static $zh2Hant = [
 '公仔面' => '公仔麵',
 '公仆' => '公僕',
 '公孙丑' => '公孫丑',
+'公寓里' => '公寓裡',
+'公寓里弄' => '公寓里弄',
 '公干' => '公幹',
 '公历' => '公曆',
 '公历史' => '公歷史',
@@ -4001,6 +4021,7 @@ public static $zh2Hant = [
 '六天后' => '六天後',
 '六年' => '六年',
 '六楼后座' => '六樓后座',
+'六樓后座' => '六樓后座',
 '六谷' => '六穀',
 '六扎' => '六紮',
 '六冲' => '六衝',
@@ -4042,6 +4063,7 @@ public static $zh2Hant = [
 '几椅' => '几椅',
 '几榻' => '几榻',
 '几净窗明' => '几淨窗明',
+'几淨窗明' => '几淨窗明',
 '几筵' => '几筵',
 '几面上' => '几面上',
 '凶征' => '凶徵',
@@ -4063,11 +4085,13 @@ public static $zh2Hant = [
 '分钟里' => '分鐘裡',
 '刑余' => '刑餘',
 '划一桨' => '划一槳',
+'划一槳' => '划一槳',
 '划上' => '划上',
 '划下' => '划下',
 '划不來' => '划不來',
 '划不来' => '划不來',
 '划了一会' => '划了一會',
+'划了一會' => '划了一會',
 '划來划去' => '划來划去',
 '划来划去' => '划來划去',
 '划具' => '划具',
@@ -4084,6 +4108,7 @@ public static $zh2Hant = [
 '划槳' => '划槳',
 '划水' => '划水',
 '划着独木舟' => '划着獨木舟',
+'划着獨木舟' => '划着獨木舟',
 '划着竹筏' => '划着竹筏',
 '划着船' => '划着船',
 '划算' => '划算',
@@ -4145,6 +4170,7 @@ public static $zh2Hant = [
 '刘佳怜' => '劉佳怜',
 '劉佳怜' => '劉佳怜',
 '刘芸后' => '劉芸后',
+'劉芸后' => '劉芸后',
 '力拼' => '力拚',
 '力拼众敌' => '力拼眾敵',
 '力争上游' => '力爭上遊',
@@ -4332,6 +4358,7 @@ public static $zh2Hant = [
 '叶恭弘' => '叶恭弘',
 '叶音' => '叶音',
 '叶韵' => '叶韻',
+'叶韻' => '叶韻',
 '吃板刀面' => '吃板刀麵',
 '吃碗面' => '吃碗麵',
 '吃姜' => '吃薑',
@@ -4443,8 +4470,10 @@ public static $zh2Hant = [
 '启发式' => '啟發式',
 '啷当' => '啷噹',
 '喂了一声' => '喂了一聲',
+'喂了一聲' => '喂了一聲',
 '喂喂' => '喂喂',
 '喂哟' => '喂喲',
+'喂喲' => '喂喲',
 '喂!' => '喂!',
 '喂,' => '喂,',
 '善于' => '善於',
@@ -4480,6 +4509,7 @@ public static $zh2Hant = [
 '向慕' => '嚮慕',
 '向迩' => '嚮邇',
 '严云农' => '嚴云農',
+'嚴云農' => '嚴云農',
 '严于' => '嚴於',
 '嚼谷' => '嚼穀',
 '啰啰苏苏' => '囉囉囌囌',
@@ -4552,6 +4582,7 @@ public static $zh2Hant = [
 '地志' => '地誌',
 '地丑德齐' => '地醜德齊',
 '坏于' => '坏於',
+'坏於' => '坏於',
 '坐如钟' => '坐如鐘',
 '坐台' => '坐檯',
 '坐钟' => '坐鐘',
@@ -4607,6 +4638,7 @@ public static $zh2Hant = [
 '夏游' => '夏遊',
 '外强中干' => '外強中乾',
 '外制' => '外製',
+'外面包' => '外面包',
 '多半只' => '多半只',
 '多只包括' => '多只包括',
 '多只可' => '多只可',
@@ -4825,6 +4857,7 @@ public static $zh2Hant = [
 '寺钟' => '寺鐘',
 '封后' => '封后',
 '封为后' => '封為后',
+'封為后' => '封為后',
 '封面里' => '封面裡',
 '射雕' => '射鵰',
 '专向往' => '專向往',
@@ -4838,6 +4871,7 @@ public static $zh2Hant = [
 '对准钟' => '對準鐘',
 '对准钟表' => '對準鐘錶',
 '对着干' => '對着幹',
+'對着幹' => '對着幹',
 '对华发' => '對華發',
 '对表中' => '對表中',
 '对表扬' => '對表揚',
@@ -4875,13 +4909,16 @@ public static $zh2Hant = [
 '尸子' => '尸子',
 '尸居余气' => '尸居餘氣',
 '尸弃佛' => '尸棄佛',
+'尸棄佛' => '尸棄佛',
 '尸祝' => '尸祝',
+'尸祿' => '尸祿',
 '尸禄' => '尸祿',
 '尸罗精舍' => '尸羅精舍',
 '尸羅精舍' => '尸羅精舍',
 '尸臣' => '尸臣',
 '尸谏' => '尸諫',
 '尸魂界' => '尸魂界',
+'尸鳩' => '尸鳩',
 '尸鸠' => '尸鳩',
 '局促不安' => '局促不安',
 '局里' => '局裡',
@@ -4956,6 +4993,7 @@ public static $zh2Hant = [
 '帘子' => '帘子',
 '帘布' => '帘布',
 '帝后台' => '帝后臺',
+'帝后臺' => '帝后臺',
 '师范' => '師範',
 '席卷' => '席捲',
 '带征' => '帶徵',
@@ -5117,6 +5155,7 @@ public static $zh2Hant = [
 '張杰' => '張杰',
 '张柏芝' => '張栢芝',
 '张乐于张徐' => '張樂于張徐',
+'張樂于張徐' => '張樂于張徐',
 '强制' => '強制',
 '强制作用' => '強制作用',
 '强奸' => '強姦',
@@ -5226,6 +5265,7 @@ public static $zh2Hant = [
 '心系世' => '心繫世',
 '心系中' => '心繫中',
 '心系乔' => '心繫乔',
+'心繫乔' => '心繫乔',
 '心系五' => '心繫五',
 '心系京' => '心繫京',
 '心系人' => '心繫人',
@@ -5238,6 +5278,7 @@ public static $zh2Hant = [
 '心系全' => '心繫全',
 '心系两' => '心繫兩',
 '心系农' => '心繫农',
+'心繫农' => '心繫农',
 '心系功' => '心繫功',
 '心系动' => '心繫動',
 '心系募' => '心繫募',
@@ -5420,6 +5461,7 @@ public static $zh2Hant = [
 '欲障' => '慾障',
 '忧郁' => '憂鬱',
 '凭几' => '憑几',
+'憑几' => '憑几',
 '凭吊' => '憑弔',
 '凭折' => '憑摺',
 '凭准' => '憑準',
@@ -5462,6 +5504,7 @@ public static $zh2Hant = [
 '所占卜' => '所占卜',
 '所占星' => '所占星',
 '所占算' => '所占算',
+'所有只' => '所有只',
 '所托' => '所託',
 '扁拟谷盗虫' => '扁擬穀盜蟲',
 '手塚治虫' => '手塚治虫',
@@ -5497,6 +5540,7 @@ public static $zh2Hant = [
 '扑作教刑' => '扑作教刑',
 '扑打' => '扑打',
 '扑挞' => '扑撻',
+'扑撻' => '扑撻',
 '打干哕' => '打乾噦',
 '打出吊入' => '打出弔入',
 '打卡钟' => '打卡鐘',
@@ -5757,6 +5801,7 @@ public static $zh2Hant = [
 '搏斗' => '搏鬥',
 '捣鬼吊白' => '搗鬼弔白',
 '扼肮' => '搤肮',
+'搤肮' => '搤肮',
 '扼肮拊背' => '搤肮拊背',
 '搬斗' => '搬鬥',
 '搭干铺' => '搭乾鋪',
@@ -5792,6 +5837,7 @@ public static $zh2Hant = [
 '扑咚咚' => '撲鼕鼕',
 '擀面' => '擀麵',
 '击扑' => '擊扑',
+'擊扑' => '擊扑',
 '击钟' => '擊鐘',
 '操作钟' => '操作鐘',
 '担仔面' => '擔仔麵',
@@ -5852,7 +5898,6 @@ public static $zh2Hant = [
 '数字钟' => '數字鐘',
 '数字钟表' => '數字鐘錶',
 '数罪并罚' => '數罪併罰',
-'数与虏确' => '數與虜确',
 '数只' => '數隻',
 '文丑' => '文丑',
 '文学志' => '文學誌',
@@ -5889,6 +5934,7 @@ public static $zh2Hant = [
 '旁注' => '旁註',
 '旅游' => '旅遊',
 '旋回' => '旋迴',
+'旋松' => '旋鬆',
 '族里' => '族裡',
 '日心历表' => '日心曆表',
 '日历' => '日曆',
@@ -6191,6 +6237,7 @@ public static $zh2Hant = [
 '武后' => '武后',
 '武斗' => '武鬥',
 '岁聿云暮' => '歲聿云暮',
+'歲聿云暮' => '歲聿云暮',
 '历史里' => '歷史裡',
 '归并' => '歸併',
 '归于' => '歸於',
@@ -6224,9 +6271,11 @@ public static $zh2Hant = [
 '气冲斗牛' => '氣沖斗牛',
 '气郁' => '氣鬱',
 '氤郁' => '氤鬱',
+'水并流' => '水併流',
 '水来汤里去' => '水來湯裡去',
 '水准' => '水準',
 '水无怜奈' => '水無怜奈',
+'水無怜奈' => '水無怜奈',
 '水表示' => '水表示',
 '水表面' => '水表面',
 '水里' => '水裡',
@@ -6242,9 +6291,11 @@ public static $zh2Hant = [
 '永志不忘' => '永誌不忘',
 '求知欲' => '求知慾',
 '求签' => '求籤',
+'江并流' => '江併流',
 '池里' => '池裡',
 '污蔑' => '污衊',
 '汤卤' => '汤滷',
+'汤滷' => '汤滷',
 '汲于' => '汲於',
 '决斗' => '決鬥',
 '沈淀' => '沈澱',
@@ -6290,6 +6341,7 @@ public static $zh2Hant = [
 '洒洒' => '洒洒',
 '洒淅' => '洒淅',
 '洒涤' => '洒滌',
+'洒滌' => '洒滌',
 '洒濯' => '洒濯',
 '洒然' => '洒然',
 '洒脱' => '洒脫',
@@ -6334,6 +6386,7 @@ public static $zh2Hant = [
 '涂敏恒' => '涂敏恆',
 '涂泽民' => '涂澤民',
 '涂澤民' => '涂澤民',
+'涂紹煃' => '涂紹煃',
 '涂绍煃' => '涂紹煃',
 '涂羽卿' => '涂羽卿',
 '涂謹申' => '涂謹申',
@@ -6526,6 +6579,7 @@ public static $zh2Hant = [
 '漓湘' => '灕湘',
 '漓然' => '灕然',
 '滩涂' => '灘涂',
+'灘涂' => '灘涂',
 '滩席' => '灘蓆',
 '火并非' => '火並非',
 '火并' => '火併',
@@ -6562,9 +6616,11 @@ public static $zh2Hant = [
 '照入签' => '照入籤',
 '照相干片' => '照相乾片',
 '煨干' => '煨乾',
+'煮制' => '煮製',
 '煮面' => '煮麵',
 '熊杰' => '熊杰',
 '荧郁' => '熒鬱',
+'炖制' => '燉製',
 '燎发' => '燎髮',
 '烧干' => '燒乾',
 '燕几' => '燕几',
@@ -6608,6 +6664,7 @@ public static $zh2Hant = [
 '特制' => '特製',
 '牵一发' => '牽一髮',
 '牵系' => '牽繫',
+'犖确' => '犖确',
 '荦确' => '犖确',
 '狂并潮' => '狂併潮',
 '狃于' => '狃於',
@@ -6622,6 +6679,7 @@ public static $zh2Hant = [
 '狱里' => '獄裡',
 '奖杯' => '獎盃',
 '独裁制' => '獨裁制',
+'獨裁制' => '獨裁制',
 '独辟蹊径' => '獨闢蹊徑',
 '获匪其丑' => '獲匪其醜',
 '兽欲' => '獸慾',
@@ -6814,6 +6872,7 @@ public static $zh2Hant = [
 '眼睛里' => '眼睛裡',
 '眼里' => '眼裡',
 '着眼于' => '着眼於',
+'着眼於' => '着眼於',
 '困乏' => '睏乏',
 '困了' => '睏了',
 '困倦' => '睏倦',
@@ -6863,8 +6922,10 @@ public static $zh2Hant = [
 '磨蝎' => '磨蝎',
 '磨制' => '磨製',
 '磨炼' => '磨鍊',
+'磨面' => '磨麵',
 '磬钟' => '磬鐘',
 '硗确' => '磽确',
+'磽确' => '磽确',
 '砻谷' => '礱穀',
 '示范' => '示範',
 '社里' => '社裡',
@@ -6901,7 +6962,9 @@ public static $zh2Hant = [
 '秋游' => '秋遊',
 '种丹妮' => '种丹妮',
 '种师中' => '种師中',
+'种師中' => '种師中',
 '种师道' => '种師道',
+'种師道' => '种師道',
 '种放' => '种放',
 '科尼亚克期' => '科尼亞克期',
 '科斗' => '科斗',
@@ -7068,7 +7131,6 @@ public static $zh2Hant = [
 '精准' => '精準',
 '精致' => '精緻',
 '精制' => '精製',
-'精炼' => '精鍊',
 '精辟' => '精闢',
 '精松' => '精鬆',
 '糊里糊涂' => '糊裡糊塗',
@@ -7079,6 +7141,7 @@ public static $zh2Hant = [
 '系里' => '系裡',
 '纪历' => '紀曆',
 '纪历史' => '紀歷史',
+'紅后假說' => '紅后假說',
 '红后假说' => '紅后假說',
 '红绳系足' => '紅繩繫足',
 '红钟' => '紅鐘',
@@ -7138,6 +7201,7 @@ public static $zh2Hant = [
 '经有云' => '經有云',
 '综合征' => '綜合徵',
 '绿发' => '綠髮',
+'维系统' => '維系統',
 '维系' => '維繫',
 '绾发' => '綰髮',
 '纲鉴' => '綱鑑',
@@ -7176,6 +7240,7 @@ public static $zh2Hant = [
 '总数只' => '總數只',
 '总数里' => '總數裡',
 '总裁制' => '總裁制',
+'總裁制' => '總裁制',
 '繁复' => '繁複',
 '繁钟' => '繁鐘',
 '绷扒吊拷' => '繃扒弔拷',
@@ -7200,6 +7265,7 @@ public static $zh2Hant = [
 '系于' => '繫於',
 '系于一发' => '繫於一髮',
 '系着' => '繫着',
+'繫着' => '繫着',
 '系结' => '繫結',
 '系紧' => '繫緊',
 '系绳' => '繫繩',
@@ -7262,6 +7328,7 @@ public static $zh2Hant = [
 '聊斋志异' => '聊齋志異',
 '圣人历' => '聖人曆',
 '圣后' => '聖后',
+'聖后' => '聖后',
 '圣马尔谷日' => '聖馬爾谷日',
 '聖馬爾谷日' => '聖馬爾谷日',
 '聘雇' => '聘僱',
@@ -7288,6 +7355,7 @@ public static $zh2Hant = [
 '背地里' => '背地裡',
 '胎发' => '胎髮',
 '胜肽' => '胜肽',
+'胜鍵' => '胜鍵',
 '胜键' => '胜鍵',
 '胡云' => '胡云',
 '胡子婴' => '胡子嬰',
@@ -7312,11 +7380,11 @@ public static $zh2Hant = [
 '脱发' => '脫髮',
 '脺脏' => '脺臟',
 '脾脏' => '脾臟',
-'腊之以为饵' => '腊之以為餌',
 '腊味' => '腊味',
 '腊毒' => '腊毒',
 '腊笔' => '腊筆',
 '腌臜' => '腌臢',
+'腌臢' => '腌臢',
 '肾脏' => '腎臟',
 '腐干' => '腐乾',
 '腐余' => '腐餘',
@@ -7325,7 +7393,6 @@ public static $zh2Hant = [
 '脑干' => '腦幹',
 '腰里' => '腰裡',
 '脚注' => '腳註',
-'脚炼' => '腳鍊',
 '肠脏' => '腸臟',
 '胶卷' => '膠捲',
 '膨松' => '膨鬆',
@@ -7435,6 +7502,7 @@ public static $zh2Hant = [
 '草席' => '草蓆',
 '荐居' => '荐居',
 '荐臻' => '荐臻',
+'荐饑' => '荐饑',
 '荐饥' => '荐饑',
 '荷花淀' => '荷花澱',
 '庄里' => '莊裡',
@@ -7466,7 +7534,9 @@ public static $zh2Hant = [
 '落腮胡' => '落腮鬍',
 '落发' => '落髮',
 '叶叶琴' => '葉叶琴',
+'葉叶琴' => '葉叶琴',
 '叶叶琹' => '葉叶琹',
+'葉叶琹' => '葉叶琹',
 '叶阳后' => '葉陽后',
 '葉陽后' => '葉陽后',
 '葡萄干' => '葡萄乾',
@@ -7630,6 +7700,7 @@ public static $zh2Hant = [
 '冲然' => '衝然',
 '冲盹' => '衝盹',
 '冲着' => '衝着',
+'衝着' => '衝着',
 '冲破' => '衝破',
 '冲程' => '衝程',
 '冲突' => '衝突',
@@ -7804,14 +7875,12 @@ public static $zh2Hant = [
 '言云' => '言云',
 '言大而夸' => '言大而夸',
 '言里' => '言裡',
-'言辩而确' => '言辯而确',
 '订制' => '訂製',
 '计划' => '計劃',
 '计时表' => '計時錶',
 '托了' => '託了',
 '托事' => '託事',
 '托交' => '託交',
-'托人' => '託人',
 '托付' => '託付',
 '托克逊' => '託克遜',
 '托儿' => '託兒',
@@ -7836,6 +7905,7 @@ public static $zh2Hant = [
 '托过' => '託過',
 '托里县' => '託里縣',
 '托附' => '託附',
+'許愿起經' => '許愿起經',
 '许愿起经' => '許愿起經',
 '許聖杰' => '許聖杰',
 '注上' => '註上',
@@ -7944,6 +8014,7 @@ public static $zh2Hant = [
 '谋干' => '謀幹',
 '謝杰' => '謝杰',
 '谢杰' => '謝杰',
+'謝華后' => '謝華后',
 '谢华后' => '謝華后',
 '谬采虚声' => '謬採虛聲',
 '谬赞' => '謬讚',
@@ -7994,6 +8065,7 @@ public static $zh2Hant = [
 '豔后' => '豔后',
 '象征' => '象徵',
 '贪欲' => '貪慾',
+'貴价' => '貴价',
 '贵价' => '貴价',
 '貴子里' => '貴子里',
 '贵干' => '貴幹',
@@ -8014,6 +8086,7 @@ public static $zh2Hant = [
 '赋范' => '賦范',
 '质数里' => '質數裡',
 '质朴' => '質樸',
+'賭后' => '賭后',
 '赌后' => '賭后',
 '赌台' => '賭檯',
 '赌斗' => '賭鬥',
@@ -8029,7 +8102,9 @@ public static $zh2Hant = [
 '赶制' => '趕製',
 '赶面棍' => '趕麵棍',
 '赵威后' => '趙威后',
+'趙威后' => '趙威后',
 '赵惠后' => '趙惠后',
+'趙惠后' => '趙惠后',
 '赵治勋' => '趙治勳',
 '趱干' => '趲幹',
 '足于' => '足於',
@@ -8536,6 +8611,7 @@ public static $zh2Hant = [
 '鉴识' => '鑑識',
 '鉴赏' => '鑑賞',
 '鉴于' => '鑒於',
+'長几' => '長几',
 '长几' => '長几',
 '长于' => '長於',
 '长历' => '長曆',
@@ -8569,7 +8645,6 @@ public static $zh2Hant = [
 '闯荡' => '闖蕩',
 '闯炼' => '闖鍊',
 '关系' => '關係',
-'关弓与我确' => '關弓與我确',
 '关于' => '關於',
 '辟佛' => '闢佛',
 '辟作' => '闢作',
@@ -8617,6 +8692,7 @@ public static $zh2Hant = [
 '随于' => '隨於',
 '隐占' => '隱佔',
 '隐几' => '隱几',
+'隱几' => '隱几',
 '隐于' => '隱於',
 '只字' => '隻字',
 '只影' => '隻影',
@@ -8635,6 +8711,7 @@ public static $zh2Hant = [
 '双折射' => '雙折射',
 '双折' => '雙摺',
 '双胜类' => '雙胜類',
+'雙胜類' => '雙胜類',
 '双雕' => '雙鵰',
 '杂合面儿' => '雜合麵兒',
 '杂志' => '雜誌',
@@ -8652,6 +8729,7 @@ public static $zh2Hant = [
 '难于' => '難於',
 '雨蒙蒙' => '雨濛濛',
 '雪窗萤几' => '雪窗螢几',
+'雪窗螢几' => '雪窗螢几',
 '雪里' => '雪裡',
 '雪里红' => '雪裡紅',
 '雪里蕻' => '雪裡蕻',
@@ -8767,6 +8845,7 @@ public static $zh2Hant = [
 '显示钟' => '顯示鐘',
 '显示钟表' => '顯示鐘錶',
 '风干' => '風乾',
+'風后' => '風后',
 '风后' => '風后',
 '风土志' => '風土誌',
 '风后,' => '風後,',
@@ -9006,6 +9085,7 @@ public static $zh2Hant = [
 '发胶' => '髮膠',
 '发菜' => '髮菜',
 '发蜡' => '髮蠟',
+'髮踊沖冠' => '髮踊沖冠',
 '发踊冲冠' => '髮踴沖冠',
 '发辫' => '髮辮',
 '发钗' => '髮釵',
@@ -9079,7 +9159,6 @@ public static $zh2Hant = [
 '斗劲' => '鬥勁',
 '斗勇' => '鬥勇',
 '斗胜' => '鬥勝',
-'斗口' => '鬥口',
 '斗合' => '鬥合',
 '斗嘴' => '鬥嘴',
 '斗地主' => '鬥地主',
@@ -9206,6 +9285,7 @@ public static $zh2Hant = [
 '鲜于' => '鮮于',
 '鲸须' => '鯨鬚',
 '鳥栖' => '鳥栖',
+'鳥栖市' => '鳥栖市',
 '鸟栖市' => '鳥栖市',
 '凤梨干' => '鳳梨乾',
 '鸣钟' => '鳴鐘',
@@ -9221,6 +9301,7 @@ public static $zh2Hant = [
 '鹤发' => '鶴髮',
 '鸾鉴' => '鸞鑑',
 '鹰雕' => '鹰鵰',
+'鹰鵰' => '鹰鵰',
 '咸、甜' => '鹹、甜',
 '咸味' => '鹹味',
 '咸嘴淡舌' => '鹹嘴淡舌',
@@ -9267,6 +9348,7 @@ public static $zh2Hant = [
 '麹霉' => '麴黴',
 '面人儿' => '麵人兒',
 '面包' => '麵包',
+'面团' => '麵團',
 '面坊' => '麵坊',
 '面坯儿' => '麵坯兒',
 '面塑' => '麵塑',
@@ -9283,7 +9365,6 @@ public static $zh2Hant = [
 '面筋' => '麵筋',
 '面粉' => '麵粉',
 '面糊' => '麵糊',
-'面团' => '麵糰',
 '面缸' => '麵缸',
 '面茶' => '麵茶',
 '面制品' => '麵製品',
@@ -13189,7 +13270,9 @@ public static $zh2Hans = [
 '乾上乾下' => '乾上乾下',
 '乾东' => '乾东',
 '乾東' => '乾东',
+'乾为天' => '乾为天',
 '乾為天' => '乾为天',
+'乾为阳' => '乾为阳',
 '乾為陽' => '乾为阳',
 '乾九' => '乾九',
 '乾乾' => '乾乾',
@@ -13379,6 +13462,7 @@ public static $zh2Hans = [
 '藉詞' => '借词',
 '傒倖' => '傒倖',
 '先名後姓' => '先名后姓',
+'兒宽' => '兒宽',
 '兒寬' => '兒宽',
 '六么' => '六幺',
 '蘭質薰心' => '兰质薰心',
@@ -13422,6 +13506,7 @@ public static $zh2Hans = [
 '同陞和' => '同升和',
 '名著' => '名著',
 '吳克羣' => '吴克羣',
+'吴克羣' => '吴克羣',
 '周易乾' => '周易乾',
 '諠譁' => '喧哗',
 '回覆' => '回复',
@@ -13453,6 +13538,7 @@ public static $zh2Hans = [
 '跼促' => '局促',
 '侷限' => '局限',
 '跼限' => '局限',
+'山崎闇斋' => '山崎闇斋',
 '山崎闇齋' => '山崎闇斋',
 '岳託' => '岳讬',
 '巨著' => '巨著',
@@ -13490,6 +13576,7 @@ public static $zh2Hans = [
 '么謙' => '幺谦',
 '么麼' => '幺麽',
 '么麽' => '幺麽',
+'幺麽' => '幺麽',
 '么麽小丑' => '幺麽小丑',
 '慶餘' => '庆馀',
 '康乾' => '康乾',
@@ -13556,12 +13643,14 @@ public static $zh2Hans = [
 '於崇文' => '於崇文',
 '於志賀' => '於志贺',
 '於志贺' => '於志贺',
+'於戏' => '於戏',
 '於戲' => '於戏',
 '於梨华' => '於梨华',
 '於梨華' => '於梨华',
 '於氏' => '於氏',
 '於潜' => '於潜',
 '於潛縣' => '於潜县',
+'於潜县' => '於潜县',
 '於祥玉' => '於祥玉',
 '於菟' => '於菟',
 '於賢德' => '於贤德',
@@ -13718,6 +13807,7 @@ public static $zh2Hans = [
 '論著' => '论著',
 '譯著' => '译著',
 '謝肇淛' => '谢肇淛',
+'谢肇淛' => '谢肇淛',
 '象乾' => '象乾',
 '躊躇滿志' => '踌躇滿志',
 '較著' => '较著',
@@ -14545,6 +14635,8 @@ public static $zh2TW = [
 '电线杆' => '電線桿',
 '电脑程序' => '電腦程式',
 '计算机程序' => '電腦程式',
+'电脑网络' => '電腦網路',
+'電腦網絡' => '電腦網路',
 '荷尔斯泰因' => '霍爾斯坦',
 '荷爾斯泰因' => '霍爾斯坦',
 '面包着' => '面包著',
@@ -15016,6 +15108,7 @@ public static $zh2HK = [
 '克羅埃西亞' => '克羅地亞',
 '奈洛比' => '內羅畢',
 '公布' => '公佈',
+'公寓里' => '公寓裏',
 '冒著' => '冒着',
 '冒著作' => '冒著作',
 '冒著名' => '冒著名',
@@ -18277,6 +18370,7 @@ public static $zh2CN = [
 '都卜勒' => '多普勒',
 '多明尼加' => '多米尼加',
 '大姊' => '大姐',
+'大姊姊' => '大姐姐',
 '天份' => '天分',
 '夾著' => '夹着',
 '夾著書' => '夹著书',
@@ -19315,7 +19409,6 @@ public static $zh2CN = [
 '著處' => '着处',
 '著她' => '着她',
 '著妳' => '着妳',
-'著姓' => '着姓',
 '著它' => '着它',
 '著定' => '着定',
 '著實' => '着实',
index 5ef02ce..1ae670f 100644 (file)
        "upload-form-label-infoform-description": "Beskrywing",
        "upload-form-label-usage-title": "Gebruik",
        "upload-form-label-usage-filename": "Lêernaam",
-       "foreign-structured-upload-form-label-own-work": "Dit is my eie werk",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorieë",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work": "Dit is my eie werk",
+       "upload-form-label-infoform-categories": "Kategorieë",
+       "upload-form-label-infoform-date": "Datum",
        "backend-fail-stream": "Kon nie die lêer $1 uitstroom nie.",
        "backend-fail-backup": "Kon nie 'n rugsteunkopie van die lêer $1 maak nie.",
        "backend-fail-notexists": "Die lêer $1 bestaan nie.",
index 882a694..0f46528 100644 (file)
@@ -59,7 +59,8 @@
                        "BAB ZAA",
                        "ASammour",
                        "Maroen1990",
-                       "Sonic N800"
+                       "Sonic N800",
+                       "Jdforrester"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "minoredit": "هذا تعديل طفيف",
        "watchthis": "راقب هذه الصفحة",
        "savearticle": "احفظ الصفحة",
+       "publishpage": "نشر الصفحة",
        "preview": "عرض مسبق",
        "showpreview": "أظهر معاينة",
        "showdiff": "عرض التغييرات",
        "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": "الصفحة خالية. يمكنك [[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>، لكنك لست مخولاً لإنشاء هذه الصفحة.",
        "missing-revision": "المراجعة #$1 من الصفحة المسماة \"{{FULLPAGENAME}}\" غير موجودة.\n\nهذا يحدث عادة عن طريق اتباع وصلة تاريخ قديمة لصفحة تم حذفها.\nالتفاصيل يمكن إيجادها في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
        "userpage-userdoesnotexist": "حساب المستخدم \"<nowiki>$1</nowiki>\" غير مسجل.\nمن فضلك تأكد أنك تريد إنشاء/تعديل هذه الصفحة.",
        "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": "التاريخ",
+       "upload-form-label-own-work": "هذا عملي الخاص",
+       "upload-form-label-infoform-categories": "تصنيفات",
+       "upload-form-label-infoform-date": "التاريخ",
        "backend-fail-stream": "لا يمكن عرض الملف $1.",
        "backend-fail-backup": "لا يمكن صنع نسخة أحتياطية للملف $1.",
        "backend-fail-notexists": "الملف $1 غير موجود.",
        "watchlistedit-raw-done": "قائمة مراقبتك تم تحديثها.",
        "watchlistedit-raw-added": "تمت إضافة {{PLURAL:$1||عنوان واحد|عنوانين|$1 عناوين|$1 عنوانا|$1 عنوان}}:",
        "watchlistedit-raw-removed": "تمت إزالة {{PLURAL:$1||عنوان واحد|عنوانين|$1 عناوين|$1 عنوانا|$1 عنوان}}:",
-       "watchlistedit-clear-title": "قائمة مراقبة ممسوحة",
+       "watchlistedit-clear-title": "امسح قائمة المراقبة",
        "watchlistedit-clear-legend": "امسح قائمة المراقبة",
        "watchlistedit-clear-explain": "ستحذف جميع الصفحات من قائمة مراقبتك",
        "watchlistedit-clear-titles": "العناوين:",
index c5f50c6..10feac9 100644 (file)
@@ -29,6 +29,7 @@
        "tog-watchdefault": "Amestar les páxines y ficheros qu'edite a la mio llista de siguimientu",
        "tog-watchmoves": "Amestar les páxines y ficheros que tresllade a la mio llista de siguimientu",
        "tog-watchdeletion": "Amestar les páxines y ficheros que desanicie a la mio llista de siguimientu",
+       "tog-watchuploads": "Amestar los nuevos ficheros que xuba a la mio llista de siguimientu",
        "tog-watchrollback": "Amestar les páxines onde fici una reversión a la mio llista de siguimientu",
        "tog-minordefault": "Marcar toles ediciones como menores de mou predetermináu",
        "tog-previewontop": "Amosar previsualización enantes del cuadru d'edición",
@@ -53,7 +54,7 @@
        "tog-ccmeonemails": "Mandame copies de los correos qu'unvio a otros usuarios",
        "tog-diffonly": "Nun amosar el conteníu de la páxina embaxo de les diferencies",
        "tog-showhiddencats": "Amosar categoríes anubríes",
-       "tog-norollbackdiff": "Desaniciar les diferencies depués de facer una restauración",
+       "tog-norollbackdiff": "Nun amosar diferencies depués de facer una restauración",
        "tog-useeditwarning": "Avisame cuando salga d'una páxina d'edición con cambios ensin guardar",
        "tog-prefershttps": "Usar siempre una conexón segura en aniciando sesión",
        "underline-always": "Siempre",
        "minoredit": "Esta ye una edición menor",
        "watchthis": "Vixilar esta páxina",
        "savearticle": "Guardar la páxina",
+       "publishpage": "Publicar la páxina",
        "preview": "Vista previa",
        "showpreview": "Amosar previsualización",
        "showdiff": "Amosar cambeos",
        "userpage-userdoesnotexist": "La cuenta d'usuariu «$1» nun ta rexistrada.\nPor favor comprueba si quies crear/editar esta páxina.",
        "userpage-userdoesnotexist-view": "La cuenta d'usuariu «$1» nun ta rexistrada.",
        "blocked-notice-logextract": "Anguaño esti usuariu ta bloquiáu.\nMás abaxo ufrese la entrada del rexistru de bloqueos pa referencia:",
-       "clearyourcache": "'''Nota:''' Llueu de guardar, seique tengas que llimpiar la caché del restolador pa ver los cambeos.\n*'''Firefox / Safari:''' Caltén ''Mayús'' mentes calques en ''Recargar'', o calca ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' nun Mac)\n* '''Google Chrome:''' Calca ''Ctrl-Mayús-R'' (''⌘-Mayús-R'' nun Mac)\n* '''Internet Explorer:''' Caltén ''Ctrl'' mentes calques ''Refrescar'', o calca ''Ctrl-F5''\n* '''Opera:''' llimpia la caché en ''Ferramientes → Preferencies''",
+       "clearyourcache": "'''Nota:''' Llueu de guardar, seique tengas que llimpiar la caché del restolador pa ver los cambeos.\n*'''Firefox / Safari:''' Caltén ''Mayús'' mentes calques en ''Recargar'', o calca ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' nun Mac)\n* '''Google Chrome:''' Calca ''Ctrl-Mayús-R'' (''⌘-Mayús-R'' nun Mac)\n* '''Internet Explorer:''' Caltén ''Ctrl'' mentes calques ''Refrescar'', o calca ''Ctrl-F5''\n* '''Opera:''' Entra'n Menú → Preferencies'' (''Opera → Preferencies'' nun Mac) y d'ehí en ''Intimidá y seguridá → Llimpiar datos de navegación → Imáxenes y ficheros en caché''.",
        "usercssyoucanpreview": "'''Conseyu:''' Usa'l botón \"{{int:showpreview}}\" pa probar el CSS nuevu enantes de guardalu.",
        "userjsyoucanpreview": "'''Conseyu:''' Usa'l botón \"{{int:showpreview}}\" pa probar el JavaScript nuevu enantes de guardalu.",
        "usercsspreview": "'''Recuerda que namái ye la vista previa del CSS d'usuariu.'''\n'''¡Inda nun ta guardáu!'''",
        "recentchangeslinked-page": "Nome de la páxina:",
        "recentchangeslinked-to": "Amosar los cambios de les páxines qu'enllacen en cuenta de los de la páxina dada",
        "recentchanges-page-added-to-category": "[[:$1]] amestóse a la categoría",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] y [[Special:WhatLinksHere/$1|{{PLURAL:$2|otra páxina|otres $2 páxines}}]] amestaes a la categoría",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] amestada a la categoría [[Special:WhatLinksHere/$1|esta páxina ta incluyida dientro d'otres páxines]]",
        "recentchanges-page-removed-from-category": "[[:$1]] desanicióse de la categoría",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] y [[Special:WhatLinksHere/$1|{{PLURAL:$2|otra páxina|otres $2 páxines}}]] desaniciaes de la categoría",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] desaniciada de la categoría [[Special:WhatLinksHere/$1|esta páxina ta incluyida dientro d'otres páxines]]",
        "autochange-username": "Cambiu automáticu de MediaWiki",
        "upload": "Xubir ficheru",
        "uploadbtn": "Xubir ficheru",
        "upload-form-label-infoform-description-tooltip": "Describe de mou curtiu cualquier cosa notable de la obra.\nPa una semeya, cuenta les principales coses qu'apaecen, la ocasión o'l sitiu.",
        "upload-form-label-usage-title": "Usu",
        "upload-form-label-usage-filename": "Nome del ficheru",
-       "foreign-structured-upload-form-label-own-work": "Esti ye'l mio propiu trabayu",
-       "foreign-structured-upload-form-label-infoform-categories": "Categoríes",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que xubo esti ficheru siguiendo les condiciones de serviciu y les polítiques de llicencies de {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Si nun puedes xubir esti ficheru baxo les polítiques de {{SITENAME}}, zarra esti diálogu y prueba otru métodu.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Quiciabes quieras probar tamién [[Special:Upload|la páxina predeterminada de xubíes]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Entiendo que toi xubiendo esti ficheru a un depósitu compartíu. Confirmo que toi faciéndolo cumpliendo les condiciones de serviciu y les polítiques de llicencies d'esi sitiu.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Si nun puedes xubir esti ficheru baxo les polítiques del depósitu compartíu, zarra esti diálogu y prueba otru métodu.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Tamién pué interesate usar [[Special:Upload|la páxina de carga de {{SITENAME}}]] si esti ficheru pué xubise allí baxo les sos polítiques.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Certifico que tengo los drechos d'autor d'esti ficheru, y aceuto irrevocablemente lliberalu a Wikimedia Commons baxo la llicencia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], y aceuto les [https://wikimediafoundation.org/wiki/Terms_of_Use Condiciones d'usu].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Si nun tienes los drechos d'autor d'esti ficheru, o quieres lliberalu baxo una llicencia diferente, considera usar el [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de carga en Commons Upload].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Tamién pué interesate usar [[Special:Upload|la páxina de carga de {{SITENAME}}]] si esti ficheru pué xubise allí baxo les sos polítiques.",
+       "upload-form-label-own-work": "Esti ye'l mio propiu trabayu",
+       "upload-form-label-infoform-categories": "Categoríes",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Confirmo que xubo esti ficheru siguiendo les condiciones de serviciu y les polítiques de llicencies de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Si nun puedes xubir esti ficheru baxo les polítiques de {{SITENAME}}, zarra esti diálogu y prueba otru métodu.",
+       "upload-form-label-not-own-work-local-local": "Quiciabes quieras probar tamién [[Special:Upload|la páxina predeterminada de xubíes]].",
+       "upload-form-label-own-work-message-default": "Entiendo que toi xubiendo esti ficheru a un depósitu compartíu. Confirmo que toi faciéndolo cumpliendo les condiciones de serviciu y les polítiques de llicencies d'esi sitiu.",
+       "upload-form-label-not-own-work-message-default": "Si nun puedes xubir esti ficheru baxo les polítiques del depósitu compartíu, zarra esti diálogu y prueba otru métodu.",
+       "upload-form-label-not-own-work-local-default": "Tamién pué interesate usar [[Special:Upload|la páxina de carga de {{SITENAME}}]] si esti ficheru pué xubise allí baxo les sos polítiques.",
+       "upload-form-label-own-work-message-shared": "Certifico que tengo los drechos d'autor d'esti ficheru, y aceuto irrevocablemente lliberalu a Wikimedia Commons baxo la llicencia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], y aceuto les [https://wikimediafoundation.org/wiki/Terms_of_Use Condiciones d'usu].",
+       "upload-form-label-not-own-work-message-shared": "Si nun tienes los drechos d'autor d'esti ficheru, o quieres lliberalu baxo una llicencia diferente, considera usar el [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de carga en Commons Upload].",
+       "upload-form-label-not-own-work-local-shared": "Tamién pué interesate usar [[Special:Upload|la páxina de carga de {{SITENAME}}]] si esti ficheru pué xubise allí baxo les sos polítiques.",
        "backend-fail-stream": "Nun se pudo tresmitir el ficheru $1.",
        "backend-fail-backup": "Nun se pudo facer copia de seguridá del ficheru $1.",
        "backend-fail-notexists": "El ficheru $1 nun esiste.",
        "tooltip-ca-nstab-category": "Ver la páxina de categoría",
        "tooltip-minoredit": "Marcar como una edición menor",
        "tooltip-save": "Guardar los cambios",
+       "tooltip-publish": "Publicar los cambeos",
        "tooltip-preview": "Vista previa de los cambios, ¡usa esto enantes de guardar!",
        "tooltip-diff": "Amuesa los cambios que fixisti nel testu.",
        "tooltip-compareselectedversions": "Ver les diferencies ente les dos revisiones seleicionaes d'esta páxina.",
        "confirmemail_body_set": "Dalguién, vusté posiblemente, dende la IP $1, configuró el corréu de\nla cuenta \"$2\" a esta direición de corréu en {{SITENAME}}.\n\nPa confirmar qu'esta cuenta ye suya daveres y activar les funciones\nde corréu en {{SITENAME}}, abra esti enllaz nel navegador:\n\n$3\n\nSi la cuenta *nun* ye de so, siga esti enllaz pa encaboxar\nla confirmación de les señes de corréu electrónicu:\n\n$5\n\nEsti códigu de confirmación caducará el $4.",
        "confirmemail_invalidated": "Confirmación de direición de corréu electrónicu encaboxada",
        "invalidateemail": "Encaboxar confirmación de corréu electrónicu",
+       "notificationemail_subject_changed": "Camudó la dirección de corréu electrónicu rexistrada de {{SITENAME}}",
+       "notificationemail_subject_removed": "Desanicióse la dirección de corréu electrónicu rexistrada de {{SITENAME}}",
        "scarytranscludedisabled": "[La tresclusión interwiki ta desactivada]",
        "scarytranscludefailed": "[Falló la recuperación de la plantía pa $1]",
        "scarytranscludefailed-httpstatus": "[Falló la recuperación de la plantía pa $1: HTTP $2]",
        "watchlistedit-raw-done": "Anovóse la to llista de siguimientu.",
        "watchlistedit-raw-added": "{{PLURAL:$1|Añadióse un títulu|Añadiéronse $1 títulos}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|Eliminóse ún títulu|Elimináronse $1 títulos}}:",
-       "watchlistedit-clear-title": "Llimpióse la llista de siguimientu",
+       "watchlistedit-clear-title": "Llimpiar la llista de siguimientu",
        "watchlistedit-clear-legend": "Llimpiar la llista de siguimientu",
        "watchlistedit-clear-explain": "Desaniciaránse tolos títulos de la to llista de siguimientu",
        "watchlistedit-clear-titles": "Títulos:",
index 5b1afd5..3e1f6e7 100644 (file)
        "upload-form-label-infoform-description": "İzah",
        "upload-form-label-usage-title": "İstifadə",
        "upload-form-label-usage-filename": "Fayl adı",
-       "foreign-structured-upload-form-label-own-work": "Bu mənim öz işimdir",
-       "foreign-structured-upload-form-label-infoform-categories": "Kateqoriyalar",
-       "foreign-structured-upload-form-label-infoform-date": "Tarix",
+       "upload-form-label-own-work": "Bu mənim öz işimdir",
+       "upload-form-label-infoform-categories": "Kateqoriyalar",
+       "upload-form-label-infoform-date": "Tarix",
        "backend-fail-notexists": "\"$1\" faylı mövcud deyil",
        "backend-fail-delete": "\"$1\" faylı sililmədi.",
        "backend-fail-copy": "\"$1\" faylı \"$2\" faylına kopyalanmır.",
index 0a74b0a..ad623cb 100644 (file)
@@ -18,7 +18,8 @@
                        "Sadiqr",
                        "Mjbmr",
                        "Alp Er Tunqa",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Ilğım"
                ]
        },
        "tog-underline": "باغلانتی‌لارین آلتینی خطله:",
        "tog-hidepatrolled": "سوْن دییشیکلیکلرده نظارتلنمیش دَییشیکلیکلری گیزلت",
        "tog-newpageshidepatrolled": "یوْخلانمیش صفحه‌لری یئنی صفحه‌لر لیستیندن گیزلت",
        "tog-extendwatchlist": "ایزله‌دیک‌لری، یالنیز یئنی‌لر اۆچون یوْخ، بۆتون دییشیک‌لیک‌لری گؤرستمک اۆچون، گنیشلندیر.",
-       "tog-usenewrc": "دَییشیک‌لیک‌لری سوْن دَییشیک‌لیک‌لر صفحه‌سینده ایزله‌دیک‌لر صفحه‌سینده گروپ‌لا (جاوااسکریپت گرک‌دیر)",
+       "tog-usenewrc": "دَییشیک‌لیک‌لری سوْن دَییشیک‌لیک‌لر صفحه‌سینده ایزله‌دیک‌لر صفحه‌سینده قروپ‌لا (جاوااسکریپت گرک‌دیر)",
        "tog-numberheadings": "باشلیق‌لاری اوْتوماتیک نۆمره‌له",
-       "tog-showtoolbar": "دَییشدیرمک آراج-چۇبوغونو گؤرست",
+       "tog-showtoolbar": "دَییشدیرمه آراج-چۇبوغونو گؤستر",
        "tog-editondblclick": "صفحه‌‌لری ایکی کیلیک‌ده دَییشدیر",
        "tog-editsectiononrightclick": "بؤلوم‌لرین دَییشدیرمه‌سینی، باشلیق‌لارین اۆستونده ساغ‌کلیک ائتمک‌‌له ایجازه وئر",
        "tog-watchcreations": "ياراتدیغیم صفحه‌‌لری و يۆکله‌دیگیم فايل‌لاری، ایزله‌دیک‌لریمه آرتیر",
        "tog-watchdefault": "دَییشدیردیگیم صفحه‌‌لری و فايل‌لاری، ایزله‌دیک‌لریمه آرتیر",
        "tog-watchmoves": "داشیدیغیم صفحه‌‌لری و فايللاری ایزله‌دیکلریمه آرتیر",
        "tog-watchdeletion": "سیلدیگیم صفحه‌‌لری و فايللاری ایزله‌دیکلریمه آرتیر",
-       "tog-watchrollback": "قایتاریلمیش صفحه لری ایزلدیکلریمه آرتیر",
-       "tog-minordefault": "دفالت اوْلاراق، بۆتون دَییشدیر‌مه‌لری کیچیک کیمی علامتله",
-       "tog-previewontop": "اؤÙ\86â\80\8cگؤسترÛ\8cØ´Û\8cØ\8c Ù\8aازÙ\85اÙ\82 Ù\82Û\87تÙ\88سÙ\88Ù\86داÙ\86 Ù\82اباÙ\82 Ú¯Ø¤Ø±Ø³Øª",
-       "tog-previewonfirst": "اÛ\8cÙ\84Ú© Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÙ\85Ù\87â\80\8cدÙ\87 Ø§Ø¤Ù\86â\80\8cگؤسترÛ\8cØ´Û\8c Ú¯Ø¤Ø±Ø³Øª",
-       "tog-enotifwatchlistpages": "اÛ\8cزÙ\84Ù\87â\80\8cدÛ\8cÚ©Ù\84رÛ\8cÙ\85â\80\8cدÙ\87 Ø§Ù\88Ù\84اÙ\86 Ø¨Û\8cر ØµÙ\81Ø­Ù\87 Û\8cا Ù\81اÛ\8cÙ\84 Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÛ\8cÙ\84Ù\86â\80\8cدÙ\87Ø\8c Ù\85Ù\86Ù\87 Ø§Û\8cÙ\85یل گؤندر",
-       "tog-enotifusertalkpages": "دانیشیق صحیفه‌‌م دَییشدیریلنده منه ایمیل گؤندر",
-       "tog-enotifminoredits": "صحیفه‌لرده و فایل‌لاردا کیچیک دَییشیکلیکلر اولسا دا منه ایمیل گؤندر",
-       "tog-enotifrevealaddr": "منیم ایمیل آدرسیمی بیلدیریش ایمیل‌لرینده گؤستر",
-       "tog-shownumberswatching": "گؤزله‌ین ایستیفاده‌چیلرین سایینی گؤستر",
+       "tog-watchrollback": "قایتاریلمیش صفحه‌لری ایزله‌دیکلریمه آرتیر",
+       "tog-minordefault": "دیفالت اوْلاراق، بۆتون دَییشدیر‌مه‌لری کیچیک کیمی علامتله",
+       "tog-previewontop": "اؤÙ\86â\80\8cگؤسترÛ\8cØ´Û\8cØ\8c Ù\8aازÙ\85اÙ\82 Ù\82Û\87تÙ\88سÙ\88Ù\86داÙ\86 Ù\82اباÙ\82 Ú¯Ø¤Ø³ØªØ±",
+       "tog-previewonfirst": "اÛ\8cÙ\84Ú© Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÙ\85Ù\87â\80\8cدÙ\87 Ø§Ø¤Ù\86â\80\8cگؤسترÛ\8cØ´Û\8c Ú¯Ø¤Ø³ØªØ±",
+       "tog-enotifwatchlistpages": "اÛ\8cزÙ\84Ù\87â\80\8cدÛ\8cÚ©Ù\84رÛ\8cÙ\85â\80\8cدÙ\87 Ø§Ù\88Ù\92Ù\84اÙ\86 Ø¨Û\8cر ØµÙ\81Ø­Ù\87 Ù\88 Û\8cا Ù\81اÛ\8cÙ\84 Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÛ\8cÙ\84Ù\86دÙ\87Ø\8c Ù\85Ù\86Ù\87 Ø§Û\8cÙ\85ئیل گؤندر",
+       "tog-enotifusertalkpages": "دانیشیق صفحه‌‌م دَییشدیریلنده منه ایمئیل گؤندر",
+       "tog-enotifminoredits": "صفحه‌لرده و فایل‌لاردا کیچیک دَییشیکلیکلر اوْلسا دا منه ایمئیل گؤندر",
+       "tog-enotifrevealaddr": "منیم ایمئیل آدرسیمی بیلدیریش ایمئیل‌لرینده گؤستر",
+       "tog-shownumberswatching": "گؤزله‌ین ایستیفاده‌چیلرین سایی‌سینی گؤستر",
        "tog-oldsig": "ایندی‌کی ایمضا:",
        "tog-fancysig": "ایمضانی ویکی-متن کیمی نظره آل (اوْتوماتیک باغلانتی‌سیز)",
        "tog-uselivepreview": "دیری اؤن‌گؤستریش ایشلت (تِست مرحله‌سینده)",
-       "tog-forceeditsummary": "دَییشیکلیک قیساسی بوْش قالاندا منه بیلیندیر",
+       "tog-forceeditsummary": "دَییشیکلیک قیساسی بوْش قالمیشسا منه بیلیندیر",
        "tog-watchlisthideown": "منیم دَییشیک‌لیک‌لریمی ایزله‌دیک‌لردن گیزلت",
        "tog-watchlisthidebots": "بوْت دَییشیک‌لیک‌لرینی ایزله‌دیک‌لردن گیزلت",
        "tog-watchlisthideminor": "کیچیک دَییشیک‌لیک‌لری ایزله‌دیک‌لردن گیزلت",
-       "tog-watchlisthideliu": "گیرمیش ایشلدن‌لرین دَییشیک‌لیک‌لرینی ایزله‌دیک‌لردن گیزلت",
+       "tog-watchlisthideliu": "گیریش ائتمیش ایشلدن‌لرین دَییشیک‌لیک‌لرینی ایزله‌دیک‌لردن گیزلت",
        "tog-watchlisthideanons": "تانینمامیش ایشلدن‌لرین دَییشیک‌لیک‌لرینی ایزله‌دیک‌لردن گیزلت",
        "tog-watchlisthidepatrolled": "نظارتلنمیش دَییشیکلیکلری گؤزله‌دیکلردن گیزلت",
-       "tog-ccmeonemails": "باشقا ایشلدن‌لره گؤندردیگیم ایمیل‌لرین کوْپی‌لرینی منه گؤندر",
-       "tog-diffonly": "مقایسه‌لر آلیتندا صفحه‌لرین ایچینده‌کی‌لرینی گؤرستمه",
-       "tog-showhiddencats": "Ú¯Û\8cزÙ\84Û\8c Ø¨Ø¤Ù\84Ù\85Ù\87â\80\8cÙ\84رÛ\8c Ú¯Ø¤Ø±Ø³Øª",
-       "tog-norollbackdiff": "Ù\82اÛ\8cتاراÙ\86داÙ\86 Ø³Ù\88Ù\92Ù\86را Ù\85Ù\82اÛ\8cسÙ\87 Ú¯Ø¤Ø±Ø³Øªمه",
-       "tog-useeditwarning": "دَییشدیرمه صفحه‌سیندن چیخاندا، ذخیره اولونمامیش دَییشدیرمه اوْلسا، منه تذکر وئر",
-       "tog-prefershttps": "هر زامان گیریش ائتمگه امن باغلانتی ایشلت",
+       "tog-ccmeonemails": "باشقا ایشلدن‌لره گؤندردیگیم ایمئیل‌لرین کوْپی‌لرینی منه گؤندر",
+       "tog-diffonly": "مۆقایسه‌لر آلتیندا صفحه‌نین ایچینده‌کیلرینی گؤسترمه",
+       "tog-showhiddencats": "Ú¯Û\8cزÙ\84Û\8c Ø¨Ø¤Ù\84Ù\85Ù\87â\80\8cÙ\84رÛ\8c Ú¯Ø¤Ø³ØªØ±",
+       "tog-norollbackdiff": "Ù\82اÛ\8cتاراÙ\86داÙ\86 Ø³Ù\88Ù\92Ù\86را Ù\81رÙ\82Û\8c Ú¯Ø¤Ø³ØªØ±مه",
+       "tog-useeditwarning": "دَییشدیرمه صفحه‌سیندن چیخاندا، قئید اوْلونمامیش دَییشدیرمه اوْلسا، منه بیلدیر",
+       "tog-prefershttps": "هر زامان گیریش ائتمه‌یه امنیتلی باغلانتی ایشلت",
        "underline-always": "هر زامان",
        "underline-never": "هئچ واخت",
        "underline-default": "وارساییلان قابیق یا براوزِر",
-       "editfont-style": "دَییشدیرمه قۇتوسونون فوْنتی:",
+       "editfont-style": "دَییشدیرمه قۇتوسونون فوْنتو:",
        "editfont-default": "براوزِر وارساییلانی",
        "editfont-monospace": "ثابیت آرالی فوْنت",
        "editfont-sansserif": "بۇجاق‌سیز فوْنت",
        "fri": "آینی‌گون (جۆمعه)",
        "sat": "يئل‌گونو (شنبه)",
        "january": "ژانویه",
-       "february": "فئوریه",
+       "february": "فوریه",
        "march": "مارس",
        "april": "آوریل",
        "may_long": "مئی",
        "june": "ژوئن",
-       "july": "ژولای",
+       "july": "جولای",
        "august": "آقوست",
        "september": "سپتامبر",
        "october": "اوْکتوبر",
        "november": "نوْوامبر",
-       "december": "دئساÙ\85بر",
+       "december": "دسامبر",
        "january-gen": "ژانویه",
-       "february-gen": "فئوریه",
+       "february-gen": "فوریه",
        "march-gen": "مارس",
        "april-gen": "آوریل",
        "may-gen": "مئی",
        "july-gen": "جولای",
        "august-gen": "آقوست",
        "september-gen": "سپتامبر",
-       "october-gen": "اوکتوبر",
-       "november-gen": "نووامبر",
-       "december-gen": "دئساÙ\85بر",
+       "october-gen": "اوْکتوبر",
+       "november-gen": "Ù\86Ù\88Ù\92Ù\88اÙ\85بر",
+       "december-gen": "دسامبر",
        "jan": "ژانویه",
-       "feb": "فئوریه",
+       "feb": "فوریه",
        "mar": "مارس",
        "apr": "آوریل",
        "may": "مئی",
        "jun": "ژوئن",
-       "jul": "ژولای",
+       "jul": "جولای",
        "aug": "آقوست",
        "sep": "سپتامبر",
        "oct": "اوْکتوبر",
        "nov": "نوْوامبر",
-       "dec": "دئساÙ\85بر",
+       "dec": "دسامبر",
        "january-date": "ژانویه‌نین $1-ی",
-       "february-date": "فئوریه‌نین $1-ی",
+       "february-date": "فوریه‌نین $1-ی",
        "march-date": "مارسین $1-ی",
        "april-date": "آوریلین $1-ی",
        "may-date": "مئیین $1-ی",
        "june-date": "ژوئنین $1-ی",
-       "july-date": "ژولایین $1-ی",
+       "july-date": "جولایین $1-ی",
        "august-date": "آقوستون $1-ی",
-       "september-date": "سئپتامبرین $1-ی",
+       "september-date": "سپتامبرین $1-ی",
        "october-date": "اوْکتوبرون $1-ی",
        "november-date": "نوْوامبرین $1-ی",
-       "december-date": "دئساÙ\85برÛ\8cÙ\86 $1-Û\8c",
+       "december-date": "دسامبرین $1-ی",
        "pagecategories": "{{PLURAL:$1|بؤلمه|بؤلمه‌لر}}",
        "category_header": "«$1» بؤلمه‌سینده صفحه‌لر",
        "subcategories": "آلت‌بؤلمه‌لر",
-       "category-media-header": "«$1» بؤلمه‌سین‌ده مئدیا",
-       "category-empty": "<em>بÙ\88 Ø¨Ø¤Ù\84Ù\85Ù\87â\80\8cدÙ\87 Ø§Û\8cÙ\86دÛ\8c Ù\81اÛ\8cÙ\84 Û\8cا Ù\85ئدیا یوْخدور.</em>",
+       "category-media-header": "«$1» بؤلمه‌سینده مدیا",
+       "category-empty": "<em>اÛ\8cÙ\86دÛ\8c Ø¨Û\87 Ø¨Ø¤Ù\84Ù\85Ù\87â\80\8cدÙ\87 Ù\81اÛ\8cÙ\84 Ù\88 Û\8cا Ù\85دیا یوْخدور.</em>",
        "hidden-categories": "{{PLURAL:$1|گیزلی بؤلمه|گیزلی بؤلمه‌لر}}",
        "hidden-category-category": "گیزلی بؤلمه‌لر",
        "category-subcat-count": "{{PLURAL:$2|بۇ بؤلمه‌ده تکجه آشاغیداکی آلت‌بؤلمه واردیر.|بۇ بؤلمه‌ده، جمعی $2-دن، آشاغیداکی {{PLURAL:$1|آلت‌بؤلمه|$1 آلت‌بؤلمه}} واردیر.}}",
        "viewhelppage": "یاردیم صحیفه‌سینه باخ",
        "categorypage": "بؤلمه صحیفه‌‌سینه باخ",
        "viewtalkpage": "دانیشیغا باخ",
-       "otherlanguages": "Ø¢Û\8cرÛ\8c دیل‌لرده",
+       "otherlanguages": "باشÙ\82ا دیل‌لرده",
        "redirectedfrom": "($1-دن يوْل‌لاندیریلمیش)",
        "redirectpagesub": "یوْللاندیرما صفحه‌سی",
        "redirectto": "مسیزپرین دَییشیب:",
        "currentevents": "ایندیکی حادیثه‌لر",
        "currentevents-url": "Project:ایندیکی اولایلار",
        "disclaimers": "یالانلامالار",
-       "disclaimerpage": "Project:گنل یالانلاما",
+       "disclaimerpage": "Project:گئنل یالانلاما",
        "edithelp": "ديَیشتیرمک یاردیمی",
        "helppage-top-gethelp": "کؤمک",
        "mainpage": "آنا صفحه",
        "noemail": "«$1» ایستیفاده‌چی‌یه ایمیل آدرسی قئید اولماییب‌دیر.",
        "noemailcreate": "دوزگون بیر ایمیل آدرسی وئرمه‌لیسینیز",
        "passwordsent": "«$1»-نا قئید اولونان ایمیل آدرسینه، یئنی بیر رمز گؤندریلدی.\nاونا آلان‌دان سونرا یئنی‌دن گیرین.",
-       "blocked-mailpassword": "سیزین آی‌پی آدرسینیز دَییشیک وئرمه‌یه باغلانیب و سوءاستفاده قاباغی آلماق اوچون، رمزی یئنی‌دن اله گتیرمک ایمکانینا ایجازه‌نیز یوخدور.",
+       "blocked-mailpassword": "سیزین آی‌پی آدرسینیزین دییشدیرمه ائده بیلمه‌سی باغلانمیشدیر. سوءایستیفاده قارشی‌سینی آلماق اۆچون، رمزی یئنی‌دن اله گتیرمک ایمکانینا ایجازه‌نیز یوْخدور.",
        "eauthentsent": "سیزین سئچیلمیش ایمیل آدرسینه، دوغرولاماق اوچون بیر ایمیل گؤندریلدی.\nهر یئنی بیر ایمیل گؤندرمک‌دن اؤنجه، بو حسابین دوغرودان سیزین اولدوغونو گؤسترمک اوچون، او ایمیل‌ده‌کی ایشلری گؤرمه‌لیسینیز.",
        "throttled-mailpassword": "سون {{PLURAL:$1|ساعات|$1 ساعات}}‌دا سیزه بیر رمز یئنیله‌مه ایمیلی گؤندریلیب‌دیر.\nسوءاستفاده قاباغین آلماق اوچون، هر {{PLURAL:$1|ساعات|$1 ساعات}}‌دا یالنیز بیر رمز یئنیله‌مه ایمیلی گؤندریلر.",
        "mailerror": "ایمیل گؤندرمه خطاسی: $1",
        "createaccount-title": "{{SITENAME}} اوچون حساب یارادیلماسی",
        "createaccount-text": "بیر کس، سیزین ایمیل آدرسینیزه {{SITENAME}} ($4) سایتیندا «$2» آدی و «$3» رمزی ایله بیر حساب آچیب‌دیر. سیز گرک گیریش ائدیب و رمزینیزی ایندی دَییشدیره‌سیز.\n\nبو حساب یانلیش دوزلیب‌سه، بو مئساژا محل قویمایابیلرسیز.",
        "login-throttled": "سیزین چوخ گیریش چالیشماغینیز اولوب‌دور.\nلوطفاً یئنی‌دن چالیشماق‌دان اؤنجه بیر آز $1 دؤزون.",
-       "login-abort-generic": "سÛ\8cزÛ\8cÙ\86 Ú¯Û\8cرÛ\8cØ´Û\8cÙ\86Û\8cز Ø¨Ø§Ø´Ø§Ø±Û\8câ\80\8cسÛ\8cز Ø§Ù\88لدو - دایاندیریلدی",
+       "login-abort-generic": "سÛ\8cزÛ\8cÙ\86 Ú¯Û\8cرÛ\8cØ´Û\8cÙ\86Û\8cز Ø¨Ø§Ø¬Ø§Ø±Û\8câ\80\8cسÛ\8cز Ø§Ù\88Ù\92لدو - دایاندیریلدی",
        "login-migrated-generic": "ایستفادچی حسابینیز آختاریلمیش دیر و آدینیز داها بو ویکی ده یوخدور",
        "loginlanguagelabel": "دیل: $1",
        "suspicious-userlogout": "سیزین چیخیش ایستگینیز رد اولوندو. بو، براوزرین یا پروکسی-کَشلمه‌سینین دوزگون ایشله‌مه‌مه‌سین‌دن قایناق‌لانیر.",
        "newpassword": "یئنی رمز",
        "retypenew": "یئنی رمزی یئنی‌دن یازین:",
        "resetpass_submit": "رمز یارادین و گیریش ائدین",
-       "changepassword-success": "رÙ\85زÛ\8cÙ\86Û\8cز Ø¨Ø§Ø´Ø§Ø±Û\8câ\80\8cÙ\84ا Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÙ\84دÛ\8c!",
+       "changepassword-success": "رÙ\85زÛ\8cÙ\86Û\8cز Ø¨Ø§Ø¬Ø§Ø±Û\8cÛ\8cÙ\84ا Ø¯Ù\8eÛ\8cÛ\8cشدÛ\8cرÙ\84دÛ\8c!",
        "changepassword-throttled": "سیزین چوخ گیریش چالیشماغینیز اولوب‌دور.\nلوطفاً یئنی‌دن چالیشماق‌دان اؤنجه $1 دؤزون.",
        "botpasswords-label-create": "یارات",
        "botpasswords-label-cancel": "وازگئچ",
        "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": "بیر کس (احتیمالاً سیز، $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-emailsentemail": "بÛ\8cر Ø±Ù\85ز Û\8cئÙ\86Û\8cÙ\84Ù\87â\80\8cÙ\85Ù\87 Ø§Û\8cÙ\85Û\8cÙ\84Û\8c Ú¯Ø¤Ù\86درÛ\8cÙ\84Û\8cبâ\80\8cدیر.",
+       "passwordreset-emailsentemail": "بÛ\87 Ø§Û\8cÙ\85ئÛ\8cÙ\84 Ø¢Ø¯Ø±Ø³Û\8c Ø­Ø³Ø§Ø¨Û\8cÙ\86Û\8cزا Ø«Ø¨Øª Ø§Ù\88Ù\92Ù\84Ù\88Ù\86Ù\85Ù\88شسا٬ Ø¨Û\8cر Ø±Ù\85ز Û\8cئÙ\86Û\8cÙ\84Ù\87â\80\8cÙ\85Ù\87 Ø§Û\8cÙ\85ئÛ\8cÙ\84Û\8c Ú¯Ø¤Ù\86درÛ\8cÙ\84Ù\87â\80\8cجکدیر.",
        "passwordreset-emailsent-capture": "آشاغیدا گؤستریلن کیمی بیر رمز یئنیله‌مه ایمیلی گؤندریلیب‌دیر.",
        "passwordreset-emailerror-capture": "آشاغیدا گؤستریلن کیمی بیر رمز یئنیله‌مه ایمیلی یارادیلیب‌دیر، اما {{GENDER:$2ایستیفاده‌چی}}‌یه گؤندرمگی باشاریلی اولمادی: $1",
        "changeemail": "ایمیل آدرسینی دَییشدیر یا سیل",
        "previewnote": "'''بونون ساده‌جه بیر سیناق گؤستریشی اولدوغونو نظرده آلین.'''\nسیزین دییشیکلرینیز هله قئید اولونماییب!",
        "continue-editing": "دَییشدیرمه یئرینه گئت",
        "previewconflict": "بو سیناق گؤستریشی‌دیر و یادداشدا ساخلایاجاغینیز تق‌دیرده متنین دییشدیر صحیفه‌سی‌نین یوخاری حیسه‌سینده نتیجه‌نین نئجه اولاجاغینی گؤستریر.",
-       "session_fail_preview": "'''اÙ\88زر Ø§Û\8cستÛ\8cÛ\8cرÛ\8cÚ©! Ø³Û\8cزÛ\8cÙ\86 Ø¯Û\8cÛ\8cشتÛ\8cرÛ\8cÙ\86Û\8cزâ\80\8c Ø³Ø§Ø®Ù\84اÙ\86Û\8cÙ\84Ù\85ادÛ\8c. Ù\84Ø·Ù\81اÙ\8b Ø¨Û\8cر Ø¯Ø§Ù\87ا ØªÚ©Ø±Ø§Ø± Ø§Ø¦Ø¯Û\8cÙ\86. Ù¾Ø±Ù\88بÙ\84ئÙ\85 Ø­Ù\84 Ø§Ù\88Ù\84Ù\88Ù\86Ù\85اسا Ø­Ø³Ø§Ø¨Û\8cÙ\86Û\8cزداÙ\86 [[Special:UserLogout|Ú\86Û\8cØ®Û\8cÙ\86]]  Ù\88 Û\8cئÙ\86Û\8câ\80\8cدÙ\86 Ø¯Ø§Ø®Û\8cÙ\84 Ø§Ù\88لون.'''",
+       "session_fail_preview": "'''عÛ\86ذر Ø§Û\8cستÙ\87â\80\8cÛ\8cÛ\8cرÛ\8cÚ©! Ø³Û\8cزÛ\8cÙ\86 Ø¯Û\8cÛ\8cشدÛ\8cرÙ\85Ù\87â\80\8cÙ\86Û\8cز Û\8cازدÛ\8cرÛ\8cÙ\84Ù\85ادÛ\8c. \nسÛ\8cستÙ\85دÙ\86 Ú\86Û\8cØ®Ù\85Û\8cØ´ Ø§Ù\88Ù\92Ù\84دÙ\88غÙ\88Ù\86Ù\88ز Ù\85ؤحتÙ\85Ù\84â\80\8cدÛ\8cر. Ù\84Û\86Ø·Ù\81اÙ\8b Ø³Û\8cستÙ\85Ù\87 Ú¯Û\8cرÙ\85Û\8cØ´ Ø§Ù\88Ù\92Ù\84دÙ\88غÙ\88Ù\86Ù\88زداÙ\86 Ø¢Ø±Ø®Ø§Û\8cÛ\8cÙ\86 Ø§Ù\88Ù\92Ù\84Ù\88ب Ø¨Û\8cر Ø¯Ø§Ù\87ا ØªÚ©Ø±Ø§Ø± Ø§Ø¦Ø¯Û\8cÙ\86. \nÙ\85Û\86Ø´Ú©Ù\88Ù\84 Ø­Ù\84 Ø§Ù\88Ù\92Ù\84Ù\88Ù\86Ù\85اسا Ø­Ø³Ø§Ø¨Û\8cÙ\86Û\8cزداÙ\86 [[Special:UserLogout|Ú\86Û\8cØ®Û\8cب]] Û\8cئÙ\86Û\8câ\80\8cدÙ\86 Ú¯Û\8cرÛ\8cØ´ Ø§Ø¦Ø¯Û\8cÙ\86Ù¬ Ø¨Ø±Ø§Ù\88زرÛ\8cÙ\86Û\8cزÛ\8cÙ\86 Ø¨Û\87 Ø³Ø§Û\8cتا Ú©Ù\88Ú©Û\8c Ù\88ئرÙ\85Ù\87 Ø§Û\8cجازÙ\87â\80\8cسÛ\8cÙ\86Û\8c Ù\88ئردÛ\8cÚ¯Û\8cÙ\86دÙ\86 Ø¯Ù\87 Ø¢Ø±Ø®Ø§Û\8cÛ\8cÙ\86 Ø§Ù\88Ù\92لون.'''",
        "session_fail_preview_html": "'''اوزر ایستییریک! داخیل وئری‌سی‌نین ایتمه‌سین‌دن گؤره تنظیملمه‌نیزی اعمال کئچیره بیلمیجیی.' '\n\n' چونکی {{SITENAME}} سایتیندا raw هتمل تأثیرین‌دیر،تا جاوااسکریپت هوجوم‌لارینا تدبیر اولا‌راق گیزلنمیش‌دیر.'\n\n' 'گر بو حاق‌لی بیر تنظیملمه گیریش میسئ، لطفاً یئنی‌دن جهد ائدین. اگر هله چالیشمازسا، [[Special:UserLogout|خارج شوید]] یئنی‌دن ایجلاس آچماغی یوخلایین.' '",
        "token_suffix_mismatch": "'' ' ديَیشیکلیگی‌نین گئری چئوریلدی، چونکی آلیجی‌نین تنزیمله‌مه کوتوجوغونداکی دورغو ایشاره‌لرینی پوزدو. \nديَیشیکلیگی‌نین، صحیفه‌‌ متنینده پوزولماغی اؤنله‌مک اوچون گئری چئوریلدی. \nاگر پروبلئملی بیر wئب-باسئد آنونیم پروکسی خیدمتی ایستیفاده بو حادثه‌‌ بضا رئاللاشا بیلر.'' '",
        "edit_form_incomplete": "'''دییشیک‌لیک فورماسی اوچون بعضی سئروئرلره ایشلمه‌دی؛ ائتدیگینیز دییشیک‌لیک‌لر بوزولمامیشتیر، نظردن کئچیریب یئنی‌دن سینایین.'",
        "uploadstash-summary": "بو صحیفه‌‌ يوکلنمیش(و يا يوکلنمکده دیر) آمما هله ویکیده نشر اولونمامیش فايللارا چاتماغی تعمین ائدر. بو فايللار يالنیز يوکله‌يه‌نی طرفیندن گؤروله بیلر.",
        "uploadstash-clear": "مووققتی فايللاری تمیزله",
        "uploadstash-nofiles": "سیزین هئچ آمبار اولموش فایلینیز یوخدور.",
-       "uploadstash-badtoken": "Ú\86اÙ\84Û\8cØ´Ù\85اÙ\86Û\8cÙ\86 Ø­Û\8cاتا Ú©Ø¦Ú\86Û\8cرÛ\8cÙ\84Ù\85Ù\87â\80\8cسÛ\8c Ø¨Ø§Ø´Ø§Ø±Û\8cسÛ\8cز Ø§Ù\88Ù\84دÙ\88Ø\8c Ø§Ø­ØªÛ\8cÙ\85اÙ\84Ù\84ا ØªÙ\86زیمله‌مه قايدالاری زامان آشیمینا معروض قالدی. يئنیدن چالیشین.",
+       "uploadstash-badtoken": "Ú\86اÙ\84Û\8cØ´Ù\85اÙ\86Û\8cÙ\86 Ø­Û\8cاتا Ú©Ø¦Ú\86Û\8cرÛ\8cÙ\84Ù\85Ù\87â\80\8cسÛ\8c Ø¨Ø§Ø´Ø§Ø±Û\8cسÛ\8cز Ø§Ù\88Ù\84دÙ\88Ø\8c Ø§Ø­ØªÛ\8cÙ\85اÙ\84Ù\84ا ØªÙ\86ظیمله‌مه قايدالاری زامان آشیمینا معروض قالدی. يئنیدن چالیشین.",
        "uploadstash-errclear": "فايللارین سیلینمه‌سی باشاریسیز اولدو.",
        "uploadstash-refresh": "فايل سیياهیسینی يئنیله",
        "invalid-chunk-offset": "اعتبارسیز یئربه‌یئر",
        "unblock": "ایستیفاده‌چی‌نین باغلانماسین گؤتور",
        "blockip": " {{GENDER:$1|ایشلدن}}ی باغلا",
        "blockip-legend": "ایستیفادچی نی باغلا",
-       "blockiptext": "آشاغی‌داکی فورمو ایستیفاده ائده‌رک مویین بیر ایپنین و یا قئیدیات‌دان کئچمیش ایستیفاده‌چی‌نین دییشیک‌لیک ائتمه‌سینی مانعه تؤره‌ده بیلرسینیز. بو یالنیز واندالیزمی قارشی‌سینی آلماق اوچون و [[{{MediaWiki:Policy-url}}|قایدا‌لارا]] اویغون اولا‌راق ائدیلمه‌لی. آشاغییا موتلق قاداغا ایله علاقه‌دار بیر شرح یازین. (نومونه:-بو-صحیفه‌لرده واندالیزم ائتمیش‌دیر).",
+       "blockiptext": "آشاغی‌داکی فورمو ایستیفاده ائده‌رک مۆعیّن بیر آی‌پی‌نین و یا قئیدیات‌دان کئچمیش ایستیفاده‌چی‌نین دییشیک‌لیک ائتمه‌سینی مانعه تؤره‌ده بیلرسینیز. بۇ یالنیز واندالیزمین قارشی‌سینی آلماق اۆچون و [[{{MediaWiki:Policy-url}}|قایدا‌لارا]] اۇیغون اوْلا‌راق ائدیلمه‌لی. آشاغی‌یا مۆطلق قاداغا ایله علاقه‌دار بیر شرح یازین. (اؤرنک:-بۇ-صفحه‌لرده واندالیزم ائتمیشدیر).",
        "ipaddressorusername": "آی-پی عونوانی و یا ایستیفاده‌چی آدی",
        "ipbexpiry": "بیتمه مدتی:",
        "ipbreason": "ندن:",
        "unblock-hideuser": "ایستیفاده‌چی آدی گیزلی اولدوغو اوچون، بی باغلامانی گؤتوره بیلمزسینیز.",
        "ipb_cant_unblock": "ختا: باغلاما آی دی سی $1 تاپیلمادی. باغلامانین گؤتورولمه‌سی مومکون‌دور.",
        "ipb_blocked_as_range": "خطا: $1 ای پی عنوانی بیرباشا مانعه و مانعه تؤرتمه آزالدیلماسینا یول وئریلمیر.\nآنجاق، بو عنوان $2 آرا‌لیغینین پارچاسی اولا‌راق مانعه تؤردیلمیش، دئکابر مانعه تؤرتمه‌سینی قال‌دیرا.",
-       "ip_range_invalid": "یانلیش ای پی",
+       "ip_range_invalid": "گئچرسیز آی‌پی آرالیغی.",
        "ip_range_toolarge": "/ $1 بلوک‌دان داها بؤیوک بازه باغلانمالارینا ایجازه وئریلمیر.",
        "proxyblocker": "پروکسی باغلییان",
        "proxyblockreason": "ای پی آدرئسینیز آچیق بیر پروکسی اولدوغو اوچون مانعه تؤردیلدی.\nخاهیش ائدیریک اینتئرنئت سئویش تعمین ایله یا دا تئکنیکی دستک ایله علاقه قورون و بو جدی تهلوکه‌سیزلیک پروبلئمین‌دن خبردار ائدین.",
        "tooltip-pt-preferences": "{{GENDER:|سیزین}} ترجیحلرینیز",
        "tooltip-pt-watchlist": "دییشمکلرینی ایزله‌دیگینیز صفحه‌لرین سیاهی‌سی",
        "tooltip-pt-mycontris": "{{GENDER:|سیزین}} چالیشمالارینیزین لیستی",
-       "tooltip-pt-login": "گیریش ائتمه‌یینیز توصیه اولونور؛ اما گرکلی دئییل",
+       "tooltip-pt-login": "گیریش ائتمه‌نیز تؤوصیه اوْلونور؛ آنجاق گرکلی دئییلدیر",
        "tooltip-pt-logout": "چیخیش",
-       "tooltip-pt-createaccount": "سیزدن دعوت اولونور ایشلدن حسابی آچیب و گیریش ائده‌سیز؛ آنجاق حساب یاراتماق ایستگه باغلی‌دیر",
+       "tooltip-pt-createaccount": "سیزی ایشلدن حسابی آچیب گیریش ائتمه‌یه چاغیریریق؛ آنجاق حساب یاراتماق ایستگینیزه باغلی‌دیر",
        "tooltip-ca-talk": "ایچینده‌کیلره گؤره دانیشیق",
        "tooltip-ca-edit": "بۇ صفحه‌‌نی دَییشدیر",
        "tooltip-ca-addsection": "یئنی بؤلوم یارات",
        "tooltip-ca-unwatch": "بو صفحه‌نی ایزله‌دیگینیز صفحه‌لردن قالدیرین",
        "tooltip-search": "{{SITENAME}}-دا آختار",
        "tooltip-search-go": "اولورسا بو آددا بیر صفحه‌یه گئت",
-       "tooltip-search-fulltext": "بو یازی اولان صفحه‌لری آختار",
+       "tooltip-search-fulltext": "بو یازینی صفحه‌لرده آختار",
        "tooltip-p-logo": "آنا صفحه‌یه باخ",
        "tooltip-n-mainpage": "آنا صفحه‌‌یه باخین",
        "tooltip-n-mainpage-description": "آنا صفحه‌یه باخ",
-       "tooltip-n-portal": "پروژه‌ یه گؤره، سیز نه ایش گوره بیلرسیز، هاردا نه‌لری تاپا بیلرسیز",
-       "tooltip-n-currentevents": "اÛ\8cÙ\86دÛ\8cÚ©Û\8c Ø§Ù\88Ù\84اÛ\8câ\80\8cÙ\84ارا Ø§Û\8cÙ\84Ú¯Û\8cÙ\84Û\8c Ø¨Û\8cÙ\84Ú¯Û\8câ\80\8cÙ\84ر ØªØ§Ù¾",
-       "tooltip-n-recentchanges": "بÙ\88 Ù\88Û\8cÚ©Û\8câ\80\8cدÙ\87 Ø³Ù\88Ù\86 Ø¯Ù\8eÛ\8cÛ\8cØ´Û\8cÚ©لرین لیستی",
+       "tooltip-n-portal": "پروژه‌‌یه گؤره، سیز نه ایش گؤره بیلرسینیز، هاردا نه‌لری تاپا بیلرسینیز",
+       "tooltip-n-currentevents": "اÛ\8cÙ\86دÛ\8cÚ©Û\8c Ø§Ù\88Ù\92Ù\84اÛ\8cÙ\84ارا Ø§Û\8cÙ\84Ú¯Û\8cÙ\84Û\8c Ø¨Û\8cÙ\84Ú¯Û\8cÙ\84ر ØªØ§Ù¾",
+       "tooltip-n-recentchanges": "بÙ\88 Ù\88Û\8cÚ©Û\8câ\80\8cدÙ\87 Ø³Ù\88Ù\92Ù\86 Ø¯Ù\8eÛ\8cÛ\8cØ´Û\8cÚ©â\80\8cÙ\84Û\8cÚ©â\80\8cلرین لیستی",
        "tooltip-n-randompage": "بیر تصادوفی صفحه گتیر",
        "tooltip-n-help": "آنلاماق یئری",
-       "tooltip-t-whatlinkshere": "بورایا باغلانان بوتون ویکی صفحه‌لرین لیستی",
-       "tooltip-t-recentchangeslinked": "بو صفحه‌دن باغلانان صفحه‌لرین سون دَییشیکلیک‌لری",
+       "tooltip-t-whatlinkshere": "بۇرا باغلانان بۆتون ویکی صفحه‌لرین لیستی",
+       "tooltip-t-recentchangeslinked": "بۇ صفحه اوْنلارا باغلانان صفحه‌لرین سوْن دَییشیکلیک‌لری",
        "tooltip-feed-rss": "بو صحیفه‌‌ اوچون آراس‌اس يايیمی",
        "tooltip-feed-atom": "بو صحیفه‌‌ اوچون آتوم يايیمی",
        "tooltip-t-contributions": "{{GENDER:$1|بۇ ایشلدنین}} وئردیگی دییشیکلر لیستی",
index 9c4fdb0..1cb4117 100644 (file)
        "parser-unstrip-loop-warning": "Ябылмаған pre табылды",
        "parser-unstrip-recursion-limit": "($1) рекурсия сиге үтеп кителгән",
        "converter-manual-rule-error": "Тел әйлендереү ҡағиҙәһендә хата табылды",
-       "undo-success": "Был үҙгәртеүҙе кире алып була. Зинһар, улар һеҙҙе ҡыҙыҡһындырған үҙгәртеүҙәр булыуынан шикләнмәҫ өсөн версияларҙы сағыштырыуҙы ҡарағыҙ һәм үҙгәртеүҙәрҙе ғәмәлғә керетер өсөн «Битте һаҡларға» төймәһенә баҫығыҙ.",
+       "undo-success": "Был үҙгәртеүҙе кире алып була. Үҙгәртеүҙәр нәҡ һеҙ теләгәнсә булһа, версияларҙы сағыштырып ҡарағыҙ, ғәмәлгә индерер өсөн, «Битте һаҡларға» төймәһенә баҫығыҙ.",
        "undo-failure": "Ара үҙгәртеүҙәр тура килмәү сәбәпле төҙәтеүҙе кире алып булмай.",
        "undo-norev": "Үҙгәртеүҙе кире алып булмай, сөнки юҡ йәки юйылған.",
        "undo-nochange": "Төҙәтеү кире ҡайтарылған.",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) ҡарарға",
        "searchmenu-exists": "'''Был вики-проектта «[[:$1]]» бите бар'''",
        "searchmenu-new": "{{PLURAL:$2|}}<strong>Был википроектта \"[[:$1]]\" бите булдырырға.</strong>",
-       "searchprofile-articles": "ЭÑ\81Ñ\82Ó\99лек Ð±Ð¸Ñ\82Ñ\82Ó\99Ñ\80е",
+       "searchprofile-articles": "Төп Ð±Ð¸Ñ\82Ñ\82Ó\99Ñ\80",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything": "Барыһы",
        "searchprofile-advanced": "Киңәйтелгән",
        "grant-blockusers": "Иҫәп яҙмаларын блоклау һәм блоклауҙы асыу",
        "grant-createaccount": "Иҫәп яҙмаһын булдырырға",
        "grant-createeditmovepage": "Биттәрҙе булдырыу,мөхәррирләү һәм исемен үҙгәртеү",
-       "grant-delete": "Журналдағы биттәрҙе юйыу,төҙәтеү",
+       "grant-delete": "Журналдағы биттәрҙе, яҙмаларҙы юйыу һәм төҙәтеү",
        "grant-editinterface": "MediaWiki исеме арауығында төҙәтеү һәм ҡулланыусы CSS/JavaScript",
        "grant-editmycssjs": "CSS/JavaScript ҡулланыусы кодын төҙәтеү",
        "grant-editmyoptions": "Һеҙҙең ҡулланыусы көйләүҙәрен мөхәррирләү",
        "upload-form-label-infoform-description-tooltip": "Был әҫәр тураһында ҡыҫҡаса тасуирлама бирегеҙ. Фото өсөн - фотола нимә иң мөһиме, төшөрөлгән урынды яҙығыҙ.",
        "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": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог теҙерәһен ябығыҙ ҙа тейәү өсөн башҡа ысулды һайлағыҙ.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "{{SITENAME}} талаптарына ярашлы файлы тейәп булһа,  [[Special:Upload|тейәү битен]] ҡарағыҙ.",
-       "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/ҡулланыу шарттары] менән килешәм.",
-       "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": "{{SITENAME}} талаптарына ярашлы файлы тейәп булһа,  [[Special:Upload|тейәү битен]] ҡарағыҙ.",
+       "upload-form-label-own-work": "Был минең эш",
+       "upload-form-label-infoform-categories": "Категориялар",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Тейәлгән файл  {{SITENAME}} лицензия сәйәсәтенә ярашлы икәнен раҫлайым.",
+       "upload-form-label-not-own-work-message-local": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог теҙерәһен ябығыҙ ҙа тейәү !с!н башҡа ысулды һайлағыҙ.",
+       "upload-form-label-not-own-work-local-local": "Ошонда эшләп ҡарағыҙ[[Special:Upload|килешеү буйынса тейәү бите]].",
+       "upload-form-label-own-work-message-default": "Был файлды дөйөм репозиторийға күсереүемде аңлайым. Быны ҡулланыусы килешеүе һәм лицензия сәйәсәтенә ярашлы эшләүемде раҫлайым.",
+       "upload-form-label-not-own-work-message-default": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог теҙерәһен ябығыҙ ҙа тейәү өсөн башҡа ысулды һайлағыҙ.",
+       "upload-form-label-not-own-work-local-default": "{{SITENAME}} талаптарына ярашлы файлы тейәп булһа,  [[Special:Upload|тейәү битен]] ҡарағыҙ.",
+       "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/ҡулланыу шарттары] менән килешәм.",
+       "upload-form-label-not-own-work-message-shared": "Әгәр ошо файлдың авторы түгелһегеҙ һәм уны икенсе лицензия аҫтында сығарырға теләйһегеҙ икән,  [https://commons.wikimedia.org/wiki/Special:UploadWizard Викискладҡа күсереү оҫталары] мөмкинлеген файҙаланығыҙ.",
+       "upload-form-label-not-own-work-local-shared": "{{SITENAME}} талаптарына ярашлы файлы тейәп булһа,  [[Special:Upload|тейәү битен]] ҡарағыҙ.",
        "backend-fail-stream": "$1 файлын трансляциялап булмай.",
        "backend-fail-backup": "$1 файлының резерв күсермәһен эшләп булмай.",
        "backend-fail-notexists": "$1 файлы юҡ.",
        "ipaddressorusername": "Ҡатнашыусының IP-адресы йәки исеме:",
        "ipbexpiry": "Тамамлана:",
        "ipbreason": "Сәбәп:",
-       "ipbreason-dropdown": "*Ғәҙәттәге бикләү сәбәптәре \n** Ялған мәғлүмәт өҫтәү\n** Биттәрҙең эстәлеген юйыу\n** Тышҡы сайттарға һылтанмалар спамлау\n** Биттәргә мәғәнәһеҙ яҙмалар (ҡый) өҫтәү \n** Ҡатнашыусыларға янау (эҙәрлекләү)\n** Бер нисә иҫәп яҙмаларын артығы менән булдырыу\n** Килешһеҙ иҫәп яҙмаһы",
+       "ipbreason-dropdown": "*Ғәҙәттәге бикләү сәбәптәре \n** Ялған мәғлүмәт өҫтәү\n** Биттәрҙең эстәлеген юйыу\n** Тышҡы сайттарға спам-һылтанмалар \n** Биттәргә мәғәнәһеҙ яҙмалар өҫтәү \n** Ҡатнашыусыларға янау (эҙәрлекләү)\n** Бер нисә иҫәп яҙмаһын булдырыу\n** Килешһеҙ иҫәп яҙмаһы",
        "ipb-hardblock": "Был IP-адрестан танылған ҡулланыусыларға мөхәррирләүҙе тыйырға",
        "ipbcreateaccount": "Яңы иҫәп яҙыуҙарын булдырыуҙы тыйыу",
        "ipbemailban": "Электрон почтаға хат ебәреүҙе тыйыу",
        "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",
+       "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": "Төҫтәрҙең тәрәнлеге",
index ae502cd..c132dca 100644 (file)
@@ -58,7 +58,7 @@
        "tog-ccmeonemails": "Адпраўляць мне копіі лістоў, якія я дасылаю іншым удзельнікам",
        "tog-diffonly": "Не паказваць зьмест старонкі пад параўнаньнем зьменаў",
        "tog-showhiddencats": "Паказваць схаваныя катэгорыі",
-       "tog-norollbackdiff": "Не паказваць зьмены пасьля выкарыстаньня функцыі адкату",
+       "tog-norollbackdiff": "Не паказваць зьмены пасьля выкананьня адкату",
        "tog-useeditwarning": "Папярэджваць мяне, калі я буду пакідаць старонку рэдагаваньня зь незахаванымі зьменамі",
        "tog-prefershttps": "Заўсёды карыстацца бясьпечным злучэньнем па ўваходзе ў сыстэму",
        "underline-always": "Заўсёды",
        "minoredit": "Гэта дробная праўка",
        "watchthis": "Назіраць за гэтай старонкай",
        "savearticle": "Захаваць старонку",
+       "publishpage": "Апублікаваць старонку",
        "preview": "Папярэдні прагляд",
        "showpreview": "Праглядзець",
        "showdiff": "Паказаць зьмены",
        "userpage-userdoesnotexist": "Рахунак удзельніка «<nowiki>$1</nowiki>» не зарэгістраваны. Калі ласка, удакладніце, ці жадаеце Вы стварыць/рэдагаваць гэтую старонку.",
        "userpage-userdoesnotexist-view": "Рахунак «$1» ня створаны.",
        "blocked-notice-logextract": "Гэты ўдзельнік у дадзены момант заблякаваны.\nАпошні запіс з журналу блякаваньняў пададзены ніжэй для даведкі:",
-       "clearyourcache": "'''Заўвага:''' Каб пабачыць зьмены пасьля захаваньня, Вам можа спатрэбіцца ачысьціць кэш Вашага браўзэра. \n* '''Firefox / Safari:''' Трымайце ''Shift'' і націсьніце ''Reload'', ці націсьніце ''Ctrl-F5'' ці ''Ctrl-R'' (''⌘-R'' на Mac)\n* '''Google Chrome:''' Націсьніце ''Ctrl-Shift-R'' (''⌘-Shift-R'' на Mac)\n* '''Internet Explorer:''' Трымайце ''Ctrl'' і націсьніце ''Refresh'', ці націсьніце ''Ctrl-F5''\n* '''Opera:''' Ачысьціце кэш праз ''Tools → Preferences''",
+       "clearyourcache": "<strong>Заўвага:</strong> каб пабачыць зьмены пасьля захаваньня, Вам можа спатрэбіцца ачысьціць кэш Вашага браўзэра. \n* <strong>Firefox / Safari:</strong> трымайце <em>Shift</em> і націсьніце <em>Reload</em>, ці націсьніце <em>Ctrl-F5</em> ці <em>Ctrl-R</em> (<em>⌘-R</em> на Mac)\n* <strong>Google Chrome:</strong> націсьніце <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Mac)\n* <strong>Internet Explorer:</strong> трымайце <em>Ctrl</em> і націсьніце <em>Refresh</em>, ці націсьніце <em>Ctrl-F5</em>\n* <strong>Opera:</strong> перайдзіце ў <em>Menu → Settings</em> (<em>Opera → Preferences</em> на Mac), а потым у <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''Падказка:''' выкарыстоўвайце кнопку «{{int:showpreview}}», каб паспрабаваць новы код CSS перад тым як яго запісаць.",
        "userjsyoucanpreview": "'''Падказка:''' выкарыстоўвайце кнопку «{{int:showpreview}}», каб паспрабаваць новы код JavaScript перад тым, як яго запісаць.",
        "usercsspreview": "'''Памятайце, што гэта толькі папярэдні прагляд Вашага CSS. Ён яшчэ не запісаны!'''",
        "upload-form-label-infoform-description-tooltip": "Коратка апішыце ўсё значнае пра гэтую працу.\nДля фота, узгадайце пра асноўныя аб’екты, выпадак ці месца.",
        "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": "Я пацьвярджаю, што загружаю гэты файл згодна з правіламі і ліцэнзійнай палітыкай {{GRAMMAR:родны|{{SITENAME}}}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Калі вы ня можаце загрузіць файл у адпаведнасьці з правіламі {{GRAMMAR:родны|{{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|старонкай загрузкі {{GRAMMAR:родны|{{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|старонкай загрузкі {{GRAMMAR:родны|{{SITENAME}}}}]], калі правілы сайту дазваляюць загрузку такога файлу.",
+       "upload-form-label-own-work": "Гэта мая ўласная праца",
+       "upload-form-label-infoform-categories": "Катэгорыі",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Я пацьвярджаю, што загружаю гэты файл згодна з правіламі і ліцэнзійнай палітыкай {{GRAMMAR:родны|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "Калі вы ня можаце загрузіць файл у адпаведнасьці з правіламі {{GRAMMAR:родны|{{SITENAME}}}}, калі ласка, закрыйце гэтае акно і паспрабуйце іншы мэтад.",
+       "upload-form-label-not-own-work-local-local": "Вы таксама можаце паспрабаваць [[Special:Upload|старонку загрузкі па змоўчаньні]].",
+       "upload-form-label-own-work-message-default": "Я разумею, што загружаю гэты файл у агульнае сховішча. Я пацьвярджаю, што раблю гэта ў адпаведнасьці з умовамі выкарыстаньня і ліцэнзійнай палітыкай.",
+       "upload-form-label-not-own-work-message-default": "Калі вы ня можаце загрузіць гэты файл паводле правілаў агульнага сховішча, калі ласка, закрыйце гэты дыялёг і паспрабуйце іншы мэтад.",
+       "upload-form-label-not-own-work-local-default": "Вы можаце паспрабаваць скарыстацца [[Special:Upload|старонкай загрузкі {{GRAMMAR:родны|{{SITENAME}}}}]], калі гэты файл можна туды загрузіць згодна з правіламі.",
+       "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 умовамі выкарыстаньня].",
+       "upload-form-label-not-own-work-message-shared": "Калі вы не зьяўляецеся ўласьнікам аўтарскіх правоў на гэты файл, або вы жадаеце распаўсюджваць яго пад іншай ліцэнзіяй, можаце скарыстацца [https://commons.wikimedia.org/wiki/Special:UploadWizard Майстарам загрузкі ў Вікісховішча].",
+       "upload-form-label-not-own-work-local-shared": "Вы таксама можаце скарыстацца [[Special:Upload|старонкай загрузкі {{GRAMMAR:родны|{{SITENAME}}}}]], калі правілы сайту дазваляюць загрузку такога файлу.",
        "backend-fail-stream": "Немагчыма накіраваць файл $1.",
        "backend-fail-backup": "Немагчыма зрабіць рэзэрвовую копію файла $1.",
        "backend-fail-notexists": "Файл $1 не існуе.",
        "apisandbox-dynamic-parameters-add-placeholder": "Назва парамэтру",
        "apisandbox-dynamic-error-exists": "Парамэтар з назвай «$1» ужо існуе.",
        "apisandbox-deprecated-parameters": "Састарэлыя парамэтры",
+       "apisandbox-fetch-token": "Аўтазапаўненьне токену",
        "apisandbox-submit-invalid-fields-title": "Некаторыя палі няслушныя",
        "apisandbox-submit-invalid-fields-message": "Калі ласка, выпраўце пазначаныя палі і паспрабуйце яшчэ раз.",
        "apisandbox-results": "Вынікі",
        "apisandbox-sending-request": "Адпраўка API-запыту…",
+       "apisandbox-loading-results": "Атрымліваем API-вынікі…",
+       "apisandbox-results-error": "Адбылася памылка пры загрузцы адказу на API-запыт: $1.",
        "apisandbox-request-url-label": "URL-адрас запыту:",
        "apisandbox-request-time": "Час запыту: {{PLURAL:$1|$1 мс}}",
+       "apisandbox-results-fixtoken": "Выпраўце токен і паўтарыце адпраўку",
+       "apisandbox-results-fixtoken-fail": "Памылка пры атрыманьні токену «$1».",
+       "apisandbox-alert-page": "Палі на гэтай старонцы няслушныя.",
+       "apisandbox-alert-field": "Значэньне гэтага поля зьяўляецца няслушным.",
        "booksources": "Крыніцы кніг",
        "booksources-search-legend": "Пошук кніг",
        "booksources-isbn": "ISBN:",
        "listgrouprights-namespaceprotection-header": "Абмежаваньні прасторы назваў",
        "listgrouprights-namespaceprotection-namespace": "Прастора назваў",
        "listgrouprights-namespaceprotection-restrictedto": "Правы, якія дазваляюць удзельніку рэдагаваць",
+       "listgrants": "Дазволы",
+       "listgrants-grant": "Дазвол",
+       "listgrants-rights": "Правы",
        "trackingcategories": "Катэгорыі, якія патрабуюць увагі",
        "trackingcategories-summary": "На гэтай старонцы пералічаныя катэгорыя, які патрабуюць увагі і якія аўтаматычна запаўняюцца праграмным забесьяпчэньнем MediaWiki. Іх назвы могуць быць зьмененыя рэдагаваньнем сыстэмных паведамленьняў у прасторы назваў {{ns:8}}.",
        "trackingcategories-msg": "Катэгорыя, якая патрабуе ўвагі",
        "whatlinkshere-prev": "{{PLURAL:$1|папярэдняя|папярэднія}} $1",
        "whatlinkshere-next": "{{PLURAL:$1|наступная|наступныя}} $1",
        "whatlinkshere-links": "← спасылкі",
-       "whatlinkshere-hideredirs": "$1 перанакіраваньні",
+       "whatlinkshere-hideredirs": "Схаваць перанакіраваньні",
        "whatlinkshere-hidetrans": "$1 уключэньні",
        "whatlinkshere-hidelinks": "$1 спасылкі",
        "whatlinkshere-hideimages": "$1 спасылкі на выявы",
index a2fbb19..f018af4 100644 (file)
        "upload-form-label-infoform-description-tooltip": "Коратка апішыце ўсё значнае пра гэту працу.\nДля фатаграфіі ўкажыце галоўныя аб'екты, нагоду або месца.",
        "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": "Я пацвярджаю, што ўкладваю гэты файл згодна з правіламі і ліцэнзійнай палітыкай {{GRAMMAR:родны|{{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}}]], калі гэты файл можна укладваць туды згодна з іх палітыкай.",
+       "upload-form-label-own-work": "Гэта мая ўласная праца",
+       "upload-form-label-infoform-categories": "Катэгорыі",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Я пацвярджаю, што ўкладваю гэты файл згодна з правіламі і ліцэнзійнай палітыкай {{GRAMMAR:родны|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "Калі вы не можаце ўкладваць гэты файл згодна з правіламі пляцоўкі {{SITENAME}}, калі ласка, закрыйце гэта акно і паспрабуйце іншы метад.",
+       "upload-form-label-not-own-work-local-local": "Вы таксама можаце паспрабаваць [[Special:Upload|прадвызначаную старонку ўкладвання]].",
+       "upload-form-label-own-work-message-default": "Я разумею, што ўкладваю гэты файл у агульнае сховішча. Я пацвярджаю, што раблю гэта ў адпаведнасці з умовамі выкарыстання і ліцэнзійнай палітыкай.",
+       "upload-form-label-not-own-work-message-default": "Калі вы не можаце ўкладваць гэты файл згодна з правіламі агульнага сховішча, калі ласка, закрыйце гэта акно і паспрабуйце іншы метад.",
+       "upload-form-label-not-own-work-local-default": "Вы таксама можаце паспрабаваць скарыстацца [[Special:Upload|старонкай укладанняў пляцоўкі {{SITENAME}}]], калі гэты файл можна укладваць туды згодна з іх палітыкай.",
        "backend-fail-stream": "Не атрымалася трансляваць файл $1.",
        "backend-fail-backup": "Немагчыма зрабіць рэзервную копію $1.",
        "backend-fail-notexists": "Файл $1 не існуе.",
        "tags-edit-chosen-no-results": "Не знойдзена бірак, якія б адпавядалі запыту",
        "tags-edit-reason": "Прычына:",
        "tags-edit-nooldid-title": "Недапушчальная мэтавая версія",
+       "tags-edit-nooldid-text": "Вы або не пазначылі мэтавую версію для выканання гэтай функцыі, або пазначаная версія не існуе.",
+       "tags-edit-none-selected": "Калі ласка, выберыце прынамсі адну бірку для дадання ці выдалення.",
        "comparepages": "Параўнанне старонак",
        "compare-page1": "Старонка 1",
        "compare-page2": "Старонка 2",
        "compare-revision-not-exists": "Паказанай вамі версіі не існуе.",
        "dberr-problems": "Прабачце, на пляцоўцы здарыліся тэхнічныя цяжкасці.",
        "dberr-again": "Паспрабуйце перачытаць праз некалькі хвілін.",
-       "dberr-info": "(Немагчыма звязацца з серверам баз даных: $1)",
-       "dberr-info-hidden": "(Немагчыма звязацца з серверам базы звестак)",
+       "dberr-info": "(Немагчыма звязацца з базай даных: $1)",
+       "dberr-info-hidden": "(Немагчыма звязацца з базай звестак)",
        "dberr-usegoogle": "Тымчасам можна паспрабаваць пошук праз Гугл.",
        "dberr-outofdate": "Заўважце, што тамтэйшыя індэксы тутэйшага зместу могуць быць састарэлымі.",
        "dberr-cachederror": "Гэта копія старонкі, узятая з кэшу, і, магчыма, састарэлая.",
        "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> не існуе.",
        "sqlite-has-fts": "$1 з падтрымкай поўна-тэкставага пошуку",
index b6c5cf0..828033c 100644 (file)
@@ -33,7 +33,8 @@
                        "Matma Rex",
                        "Xð",
                        "Miroslav35232",
-                       "Ket"
+                       "Ket",
+                       "Ricordo.tenerissimo"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "minoredit": "Това е малка промяна",
        "watchthis": "Наблюдаване на страницата",
        "savearticle": "Съхраняване",
+       "publishpage": "Публикуване на страницата",
        "preview": "Предварителен преглед",
        "showpreview": "Предварителен преглед",
        "showdiff": "Показване на промените",
        "newarticle": "(нова)",
        "newarticletext": "Последвахте препратка към страница, която все още не съществува.\nЗа да я създадете, просто започнете да пишете в долната текстова кутия\n(вижте [$1 помощната страница] за повече информация).",
        "anontalkpagetext": "----''Това е дискусионната страница на анонимен потребител, който все още няма регистрирана сметка или не я използва, затова се налага да използваме IP-адрес, за да го идентифицираме. Такъв адрес може да се споделя от няколко потребители.''\n\n''Ако сте анонимен потребител и мислите, че тези неуместни коментари са отправени към вас, [[Special:UserLogin/signup|регистрирайте се]] или [[Special:UserLogin|влезте в системата]], за да избегнете евентуално бъдещо объркване с други анонимни потребители.''",
-       "noarticletext": "Тази Ñ\81Ñ\82Ñ\80аниÑ\86а Ð²Ñ\81е Ð¾Ñ\89е Ð½Ðµ Ñ\81Ñ\8aÑ\89еÑ\81Ñ\82вÑ\83ва. Ð\9cожеÑ\82е Ð´Ð° [[Special:Search/{{PAGENAME}}|поÑ\82Ñ\8aÑ\80Ñ\81иÑ\82е Ð·Ð° Ð·Ð°Ð³Ð»Ð°Ð²Ð¸ÐµÑ\82о Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а]] Ð² Ð´Ñ\80Ñ\83ги Ñ\81Ñ\82Ñ\80аниÑ\86и, Ð´Ð° <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Ð¿Ð¾Ñ\82Ñ\8aÑ\80Ñ\81иÑ\82е Ð² Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\86иÑ\82е] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} да я създадете]</span>.",
+       "noarticletext": "Ð\9fонаÑ\81Ñ\82оÑ\8fÑ\89ем Ð½Ñ\8fма Ñ\82екÑ\81Ñ\82 Ð½Ð° Ñ\82ази Ñ\81Ñ\82Ñ\80аниÑ\86а. Ð\9cожеÑ\82е Ð´Ð° [[Special:Search/{{PAGENAME}}|поÑ\82Ñ\8aÑ\80Ñ\81иÑ\82е Ð·Ð° Ð·Ð°Ð³Ð»Ð°Ð²Ð¸ÐµÑ\82о Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а]] Ð² Ð´Ñ\80Ñ\83ги Ñ\81Ñ\82Ñ\80аниÑ\86и, Ð´Ð° <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Ð¿Ð¾Ñ\82Ñ\8aÑ\80Ñ\81иÑ\82е Ð² Ñ\81Ñ\8aоÑ\82веÑ\82ниÑ\82е Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\86и] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} да я създадете]</span>.",
        "noarticletext-nopermission": "Текущо в тази страница няма текст.\nМожете да [[Special:Search/{{PAGENAME}}|потърсите заглавието на тази страница ]] в други страници или да <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} потърсите в съответните дневници]</span>, но нямате права да създадете тази страница.",
        "missing-revision": "Версия #$1 на страницата „{{FULLPAGENAME}}“ не съществува.\n\nТова обикновено се дължи на препратка от историята на страницата, която е била изтрита.\nПодробности могат да бъдат открити в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дневника на изтриванията].",
        "userpage-userdoesnotexist": "Няма регистрирана потребителска сметка за „<nowiki>$1</nowiki>“. Изисква се потвърждение, че желаете да създадете/редактирате тази страница?",
        "revdelete-show-file-submit": "Да",
        "revdelete-selected-text": "{{PLURAL:$1|Избрана версия|Избрани версии}} от [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Избрано събитие|Избрани събития}}:",
+       "revdelete-text-text": "Изтритите редакции ще продължат да се виждат в историята на страницата, но части от съдържанието ще бъдат публично недостъпни.",
+       "revdelete-text-others": "Другите администратори ще продължат да имат достъп до скритото съдържание и могат да го възстановят, освен ако не бъдат наложени допълнителни ограничения.",
        "revdelete-confirm": "Необходимо е да потвърдите, че желаете да извършите действието, разбирате последствията и го правите според [[{{MediaWiki:Policy-url}}|политиката]].",
        "revdelete-suppress-text": "Премахването трябва да се използва '''само''' при следните случаи:\n* Потенциално уязвима в правно отношение информация\n* Неподходяща лична информация\n*: ''домашни адреси и телефонни номера, номера за социално осигуряване и др.''",
        "revdelete-legend": "Задаване на ограничения:",
        "upload-form-label-infoform-description-tooltip": "Накратко опишете всичко, което си струва да се каже за тази творба.\nНапример, ако е снимка, опишете основните неща, които са снимани, повода, местоположението и т.н.",
        "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}}, моля, затворете този прозорец и опитайте друг метод.",
+       "upload-form-label-own-work": "Това е моя собствена творба",
+       "upload-form-label-infoform-categories": "Категории",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Потвърждавам, че качвам този файл в съответствие с правилата и лицензионната политика на сайта {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Ако не можете да заредите този файл в съответствие с правилата на сайта {{SITENAME}}, моля, затворете този прозорец и опитайте друг метод.",
        "backend-fail-notexists": "Файлът $1 не съществува.",
        "backend-fail-delete": "Файлът $1 не може да бъде изтрит.",
        "backend-fail-alreadyexists": "Файлът $1 вече съществува.",
        "suppress": "Премахване от публичния архив",
        "querypage-disabled": "Тази специална страница е изключена, защото затруднява производителността на уикито.",
        "apihelp-no-such-module": "Модул \"$1\" не беше намерен.",
+       "apisandbox-fullscreen": "Разшири полето",
        "apisandbox-reset": "Изчистване",
        "apisandbox-examples": "Пример",
-       "apisandbox-results": "Резултат",
+       "apisandbox-dynamic-parameters-add-placeholder": "Име на параметъра",
+       "apisandbox-results": "Резултати",
        "booksources": "Източници на книги",
        "booksources-search-legend": "Търсене на информация за книга",
        "booksources-search": "Търсене",
        "logempty": "Дневникът не съдържа записи, отговарящи на избрания критерий.",
        "log-title-wildcard": "Търсене на заглавия, започващи със",
        "showhideselectedlogentries": "Промяна на видимостта на избраните записи",
-       "checkbox-all": "Всички",
-       "checkbox-none": "Никои",
+       "checkbox-select": "Избери: $1",
+       "checkbox-all": "всички",
+       "checkbox-none": "никои",
+       "checkbox-invert": "обърни избора",
        "allpages": "Всички страници",
        "nextpage": "Следваща страница ($1)",
        "prevpage": "Предходна страница ($1)",
        "protect-othertime": "Друг срок:",
        "protect-othertime-op": "друг срок",
        "protect-existing-expiry": "Оставащо време: $2, $3",
+       "protect-existing-expiry-infinity": "Existing expiration time: безсрочно",
        "protect-otherreason": "Друга/допълнителна причина:",
        "protect-otherreason-op": "Друга причина",
        "protect-dropdown": "* Стандартни причини за защита на страници\n** Чест обект на вандализъм\n** Чест обект на спам\n** Редакторска война\n** Страница, изискваща много сървърни ресурси",
        "delete_and_move_text": "== Наложително изтриване ==\n\nЦелевата страница „[[:$1]]“ вече съществува. Искате ли да я изтриете, за да освободите място за преместването?",
        "delete_and_move_confirm": "Да, искам да изтрия тази страница.",
        "delete_and_move_reason": "Изтрита, за да се освободи място за преместване от „[[$1]]“",
-       "selfmove": "Страницата не може да бъде преместена, тъй като целевото име съвпада с първоначалното й заглавие.",
+       "selfmove": "Страницата не може да бъде преместена, тъй като целевото име съвпада с първоначалното ѝ заглавие.",
        "immobile-source-namespace": "Не могат да се местят страници в именно пространство „$1“",
        "immobile-target-namespace": "Не е възможно преместването на страници в именното пространство „$1“",
        "immobile-target-namespace-iw": "Страницата не може да бъде преместена под заглавие, оформено като междууики препратка.",
        "sqlite-no-fts": "$1 без поддръжка на пълнотекстово търсене",
        "logentry-delete-delete": "$1 {{GENDER:$2|изтри}} страницата $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|възстанови}} страницата $3",
+       "logentry-delete-revision": "$1 {{GENDER:$2|промени}} видимостта на {{PLURAL:$5|една редакция|$5 редакции}} в страница $3: $4",
+       "logentry-delete-event-legacy": "$1 {{GENDER:$2|промени}} видимостта на събитията от дневниците за страница $3",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|промени}} видимостта на версиите на страница $3",
        "logentry-suppress-revision": "$1 тайно {{GENDER:$2|промени}} видимостта на {{PLURAL:$5|една версия|$5 версии}} на страницата $3: $4",
        "logentry-suppress-revision-legacy": "$1 тайно {{GENDER:$2|промени}} видимостта на версиите на страница $3",
index 2863646..3846953 100644 (file)
        "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}} تا.",
+       "upload-form-label-own-work": "ائ ني جیندئ کار اینت",
+       "upload-form-label-infoform-categories": "تهرئان",
+       "upload-form-label-infoform-date": "تاریخ",
+       "upload-form-label-own-work-message-local": "من ایشیرا قبولا کنین که من ائ فایلا بُرزا کنین گۆ استفاده ئی شرایطان شه  جوازئ شینک  بوتینا و خدماتئ سیاستان به {{SITENAME}} تا.",
        "backend-fail-stream": "نه توانن $1 ئی فایلا دیم دهین.",
        "backend-fail-backup": "نتنوانن پُشتوانی نخسه یی په $1 فایلا جۆڑ کنن.",
        "backend-fail-notexists": " $1 ئی فایل وجود نداریت.",
        "listgrouprights-rights": "حقوق",
        "listgrouprights-helppage": "Help:گروپانئ حقوق",
        "listgrouprights-members": "(اعضائانی لڑلیست)",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
        "listgrouprights-addgroup": "توانیت ای {{PLURAL:$2|گروپ|گروپ ئان}} ئا اضافه بکینت: $1",
        "listgrouprights-removegroup": "توانیت ای {{PLURAL:$2|گروپ|گروپ ئان}} ئه پاک بکنیت: $1",
        "listgrouprights-addgroup-all": "توانیت موچین گروپانا اضافه بکنیت",
        "bydate": "شه تاریخی رُوگا",
        "sp-newimages-showfrom": "نشان‌داتین نۆکین اکسانی شه $2، $1 بئ بعد",
        "seconds": "{{PLURAL:$1|$1ثانیه| $1  ثانیه}}",
-       "minutes": "{{PLURAL:$1|دقیقه|دقیقه}}",
+       "minutes": "{{PLURAL:$1|$1 دقیقه|$1 دقیقه}}",
        "hours": "{{PLURAL:$1|ساعت|ساعت}}",
        "days": "{{PLURAL:$1|روچ|روچ}}",
        "weeks": "{{PLURAL:$1|$1 هپتگ|$1 هپتگ ئان}}",
index 55e4cf2..00e296a 100644 (file)
@@ -45,6 +45,7 @@
        "tog-watchdefault": "আমার সম্পাদিত পাতা এবং ফাইলগুলো আমার নজরতালিকায় যোগ করা হোক",
        "tog-watchmoves": "আমার স্থানান্তরিত পাতা এবং ফাইলগুলো আমার নজরতালিকায় যোগ করা হোক",
        "tog-watchdeletion": "আমার অপসারিত পাতা এবং ফাইলগুলো আমার নজর তালিকায় যোগ করা হোক",
+       "tog-watchuploads": "আমার নজরতালিকায় আমার আপলোড করা নতুন ফাইল যোগ কর",
        "tog-watchrollback": "আমার দ্বারা রোলব্যাক করা পাতা আমার নজরতালিকায় যোগ করা হোক",
        "tog-minordefault": "শুরুতেই সব সম্পাদনাকে অনুল্লেখ্য বলে চিহ্নিত করা হোক",
        "tog-previewontop": "সম্পাদনা বাক্সের আগে প্রাকদর্শন দেখানো হোক",
        "minoredit": "এটি একটি অনুল্লেখ্য সম্পাদনা",
        "watchthis": "এই পাতাটি নজরে রাখুন",
        "savearticle": "সংরক্ষণ",
+       "publishpage": "পাতা প্রকাশ করুন",
        "preview": "প্রাকদর্শন",
        "showpreview": "প্রাকদর্শন",
        "showdiff": "পরিবর্তনসমূহ",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" নামের কোন ব্যবহারকারী অ্যাকাউন্ট নিবন্ধিত হয়নি। অনুগ্রহ করে পরীক্ষা করে দেখুন আপনি এই পাতাটি সৃষ্টি/সম্পাদনা করতে চান কি না।",
        "userpage-userdoesnotexist-view": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
        "blocked-notice-logextract": "এই ব্যবহারকারী বর্তমানে ব্লক রয়েছে।\nরেফারেন্সের জন্য সাম্প্রতিক ব্লক লগ ভুক্তি নিচে দেওয়া হল:",
-       "clearyourcache": "<strong>লà¦\95à§\8dষà§\8dয à¦\95রà§\81ন:</strong> à¦¸à¦\82রà¦\95à§\8dষণà§\87র à¦ªà¦°, à¦ªà¦°à¦¿à¦¬à¦°à§\8dতনà¦\97à§\81লà§\8b à¦¦à§\87à¦\96তà§\87 à¦\86পনাà¦\95à§\87 à¦\86পনার à¦¬à§\8dরাà¦\89à¦\9cারà§\87র à¦\95à§\8dযাশà§\87 à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রার à¦ªà§\8dরয়à§\8bà¦\9cন à¦¹à¦¤à§\87 à¦ªà¦¾à¦°à§\87।\n* <strong>ফায়ারফà¦\95à§\8dস / à¦¸à¦¾à¦«à¦¾à¦°à¦¿:</strong> <em>Shift</em> à¦§à¦°à§\87 à¦°à¦¾à¦\96া à¦\85বসà§\8dথায়<em>পà§\81নà¦\83লà§\8bড à¦\95রà§\81ন</em>-à¦\8f à¦\95à§\8dলিà¦\95 à¦\95রà§\81ন, à¦\85থবা <em>Ctrl-F5</em> à¦¬à¦¾ <em>Ctrl-R</em> (মà§\8dযাà¦\95-à¦\8f <em>â\8c\98-R</em>) à¦\9aাপà§\81ন\n* <strong>à¦\97à§\81à¦\97ল à¦\95à§\8dরà§\8bম:</strong> <em>Ctrl-Shift-R</em> (মà§\8dযাà¦\95-à¦\8f <em>â\8c\98-Shift-R</em>) à¦\9aাপà§\81ন\n* <strong>à¦\87নà§\8dà¦\9fারনà§\87à¦\9f à¦\8fà¦\95à§\8dসপà§\8dলà§\8bরার:</strong> <em>Ctrl</em> à¦§à¦°à§\87 à¦°à¦¾à¦\96া à¦\85বসà§\8dথায় <em>Refresh</em>-à¦\8f à¦\95à§\8dলিà¦\95 à¦\95রà§\81ন, à¦\85থবা <em>Ctrl-F5</em> à¦\9aাপà§\81ন\n* <strong>à¦\85পà§\87রা:</strong> <em>সরà¦\9eà§\8dà¦\9cাম â\86\92 à¦ªà¦\9bনà§\8dদসমà§\82হ</em>-à¦\8f à¦\97িয়à§\87 à¦\95à§\8dযাশà§\87 à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রà§\87 à¦¨à¦¿à¦¨",
+       "clearyourcache": "<strong>লà¦\95à§\8dষà§\8dয à¦\95রà§\81ন:</strong> à¦¸à¦\82রà¦\95à§\8dষণà§\87র à¦ªà¦°, à¦ªà¦°à¦¿à¦¬à¦°à§\8dতনà¦\97à§\81লà§\8b à¦¦à§\87à¦\96তà§\87 à¦\86পনাà¦\95à§\87 à¦\86পনার à¦¬à§\8dরাà¦\89à¦\9cারà§\87র à¦\95à§\8dযাশà§\87 à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রার à¦ªà§\8dরয়à§\8bà¦\9cন à¦¹à¦¤à§\87 à¦ªà¦¾à¦°à§\87।\n* <strong>ফায়ারফà¦\95à§\8dস / à¦¸à¦¾à¦«à¦¾à¦°à¦¿:</strong> <em>Shift</em> à¦§à¦°à§\87 à¦°à¦¾à¦\96া à¦\85বসà§\8dথায়<em>পà§\81নà¦\83লà§\8bড à¦\95রà§\81ন</em>-à¦\8f à¦\95à§\8dলিà¦\95 à¦\95রà§\81ন, à¦\85থবা <em>Ctrl-F5</em> à¦¬à¦¾ <em>Ctrl-R</em> (মà§\8dযাà¦\95-à¦\8f <em>â\8c\98-R</em>) à¦\9aাপà§\81ন\n* <strong>à¦\97à§\81à¦\97ল à¦\95à§\8dরà§\8bম:</strong> <em>Ctrl-Shift-R</em> (মà§\8dযাà¦\95-à¦\8f <em>â\8c\98-Shift-R</em>) à¦\9aাপà§\81ন\n* <strong>à¦\87নà§\8dà¦\9fারনà§\87à¦\9f à¦\8fà¦\95à§\8dসপà§\8dলà§\8bরার:</strong> <em>Ctrl</em> à¦§à¦°à§\87 à¦°à¦¾à¦\96া à¦\85বসà§\8dথায় <em>Refresh</em>-à¦\8f à¦\95à§\8dলিà¦\95 à¦\95রà§\81ন, à¦\85থবা <em>Ctrl-F5</em> à¦\9aাপà§\81ন\n* <strong>à¦\85পà§\87রা:</strong> <em>মà§\87নà§\81 â\86\92 à¦¬à§\8dযবসà§\8dথাপনাসমà§\82হ</em>-à¦\8f à¦¯à¦¾à¦¨ (মà§\8dযাà¦\95à§\87 <em>à¦\85পà§\87রা â\86\92 à¦ªà¦\9bনà§\8dদসমà§\82হ</em>) à¦\8fবà¦\82 à¦\8fরপর <em>à¦\97à§\8bপনà§\80য়তা à¦\93 à¦¸à§\81রà¦\95à§\8dষা â\86\92 à¦¬à§\8dরাà¦\89à¦\9cিà¦\82-à¦\8fর à¦¤à¦¥à§\8dয à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রà§\81ন â\86\92 à¦\95à§\8dযাশà§\87 à¦\95রা à¦\9bবি à¦\93 à¦«à¦¾à¦\87লà¦\97à§\81লি</em>।",
        "usercssyoucanpreview": "'''পরামর্শ:''' \"{{int:showpreview}}\" বোতাম ব্যবহার করে সংরক্ষণের আগে আপনার নতুন CSS পরীক্ষা করুন।",
        "userjsyoucanpreview": "'''পরামর্শ:''' \"{{int:showpreview}}\" বোতাম ব্যবহার করে সংরক্ষণের আগে আপনার নতুন JavaScript পরীক্ষা করুন।",
        "usercsspreview": "'''মনে রাখবেন আপনি আপনার জন্য বরাদ্ধকৃত সিএসএস প্রাকদর্শন করছেন।\nএটা এখনও সংরক্ষণ করা হয়নি!'''",
        "continue-editing": "সম্পাদনা করুন",
        "previewconflict": "এই প্রাকদর্শনটি সম্পাদনা ক্ষেত্রের উপরের অংশটির টেক্সট সংরক্ষণ করলে যেরকম দেখাবে, তা দেখাচ্ছে।",
        "session_fail_preview": "দুঃখিত! সেশন ডাটা হারিয়ে যাওয়ার কারণে আপনার সম্পাদনাটি সংরক্ষণ করা সম্ভব হয়নি।\n\nআপনি সম্ভবত সংযোগ হারিয়েছন। <strong>দয়া করে যাচাই করুন যে আপনি এখনও প্রবেশরত রয়েছেন এবং আবার চেষ্টা করুন</strong>। যদি এটি এখনও কাজ না করে, তাহলে দয়া করে [[Special:UserLogout|অ্যাকাউন্ট থেকে প্রস্থান করুন]] এবং আবার অ্যাকাউন্টে প্রবেশ করে চেষ্টা করুন এবং এবং পরীক্ষা করুন যে আপনার ব্রাউজার এই সাইটে কুকি ব্যবহারের অনুমতি দেয়।",
-       "session_fail_preview_html": "'''দুঃখিত! সেশন উপাত্ত হারিয়ে যাওয়ার কারণে আমরা আপনার সম্পাদনাটি প্রক্রিয়া করতে পারিনি।'''\n\n''{{SITENAME}}-এ raw HTML সক্রিয় আছে বলে জাভাস্ক্রিপ্টভিত্তিক আক্রমণ থেকে প্রতিরক্ষার জন্য প্রাকদর্শনটি দেখানো হচ্ছে না।''\n\n'''যদি এটি সম্পাদনার একটি বৈধ প্রচেষ্টা হয়, তবে অনুগ্রহ করে আবার চেষ্টা করুন। যদি তারপরেও কাজ না হয়, তবে অ্যাকাউন্ট থেকে বেরিয়ে গিয়ে আবার প্রবেশ করে চেষ্টা করুন।'''",
+       "session_fail_preview_html": "দুঃখিত! সেশন উপাত্ত হারিয়ে যাওয়ার কারণে আমরা আপনার সম্পাদনাটি প্রক্রিয়া করতে পারিনি।\n\n<em>{{SITENAME}}-এ raw HTML সক্রিয় আছে বলে জাভাস্ক্রিপ্ট ভিত্তিক আক্রমণ থেকে প্রতিরক্ষার জন্য প্রাকদর্শনটি দেখানো হচ্ছে না।</em>\n\n<strong>যদি এটি সম্পাদনার একটি বৈধ প্রচেষ্টা হয়, তবে অনুগ্রহ করে আবার চেষ্টা করুন।</strong>\nযদি তারপরেও কাজ না হয়, তবে অ্যাকাউন্ট থেকে [[Special:UserLogout|বেরিয়ে গিয়ে]] আবার প্রবেশ করুন, এবং পরীক্ষা করে দেখুন যে আপনার ব্রাউজারে এই সাইট থেকে কুকি অনুমতি দেয়।",
        "token_suffix_mismatch": "'''আপনার সম্পাদনাটি প্রত্যাখ্যান করা হয়েছে, কারণ আপনার ক্লায়েন্ট প্রোগ্রামটি সম্পাদনা টেক্সটের বিরামচিহ্নগুলি গুলিয়ে ফেলেছে। পাতাটির টেক্সটে যাতে ক্ষতি না হয় সেজন্য সম্পাদনাটি প্রত্যাখ্যান করা হয়েছে। আপনি কোন ত্রুটিপূর্ণ ওয়েব-ভিত্তিক বেনামী প্রক্সি সেবা ব্যবহার করলে এরকম হতে পারে।'''",
        "edit_form_incomplete": "'''আপনার সম্পাদনার কিছু অংশ সার্ভারে পৌছায় নি; আপনার সম্পাদনা সম্পূর্ণরুপে আছে কিনা নিশ্চিত হয়ে আবার চেষ্টা করুন'''",
        "editing": "সম্পাদনা করছেন: $1",
        "undo-summary-username-hidden": "একজন লুকানো ব্যবহারকারী $1 সংশোধন পুনরায় ফিরিয়ে এনেছেন",
        "cantcreateaccounttitle": "অ্যাকাউন্ট তৈরি করা যাবে না",
        "cantcreateaccount-text": "[[User:$3|$3]] এই আইপি ঠিকানা('''$1''') থেকে অ্যাকাউন্ট সৃষ্টিতে বাধা দিয়েছেন।\n\n$3-এর দেয়া কারণ হল ''$2''",
-       "cantcreateaccount-range-text": "[[User:$3|$3]] কর্তৃক আইপি ঠিকানা <strong>$1</strong> ব্যাপ্তির মধ্য থেকে অ্যাকাউন্ট তৈরি করা অবরুদ্ধ করা হয়েছে। যাতে আপনার আইপি ঠিকানা (<strong>$4</strong>) রয়েছে। \n\n$3 কর্তৃক <em>$2</em> কারণ দেখানো হয়েছে।",
+       "cantcreateaccount-range-text": "[[User:$3|$3]] কর্তৃক আইপি ঠিকানার ব্যাপ্তি <strong>$1</strong>-এর মধ্যে অ্যাকাউন্ট তৈরি করা অবরুদ্ধ করা হয়েছে। যাতে আপনার আইপি ঠিকানাও (<strong>$4</strong>) রয়েছে। \n\n$3 কর্তৃক <em>$2</em> কারণ দেখানো হয়েছে।",
        "viewpagelogs": "এই পাতার জন্য লগগুলো দেখুন",
        "nohistory": "এই পাতার কোন সম্পাদনার ইতিহাস নেই।",
        "currentrev": "সর্বশেষ সংস্করণ",
        "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-not-own-work-local-local": "এছাড়াও আপনি [[Special:Upload|ডিফল্ট আপলোডের পাতা]] চেষ্টা করতে পারেন।",
-       "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/deed.bn ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন-শেয়ার অ্যালাইক ৪.০] লাইসেন্সের অধীনে এই ফাইলটি উইকিমিডিয়া কমন্সে অপরিবর্তনীয় প্রকাশে সম্মত হচ্ছি, এবং আমি [https://wikimediafoundation.org/wiki/Terms_of_Use ব্যবহারের শর্তাবলীর] সাথে সম্মত।",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "যদি আপনি এই ফাইলের স্বত্তাধিকারী না হন, বা আপনি একটি ভিন্ন লাইসেন্সের আওতায় প্রকাশ করতে ইচ্ছুক থাকেন, তাহলে [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=bn কমন্স আপলোড উইজার্ড] ব্যবহার করতে বিবেচনা করুন।",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি সাইটটি তাদের নীতিমালার অধীনে এই ফাইল আপলোড করার অনুমতি দেয়।",
+       "upload-form-label-own-work": "এটি আমার নিজের কাজ",
+       "upload-form-label-infoform-categories": "বিষয়শ্রেণীসমূহ",
+       "upload-form-label-infoform-date": "তারিখ",
+       "upload-form-label-not-own-work-local-local": "এছাড়াও আপনি [[Special:Upload|ডিফল্ট আপলোডের পাতা]] চেষ্টা করতে পারেন।",
+       "upload-form-label-not-own-work-local-default": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি এই ফাইলটি তাদের নীতিমালা অধীনে সেখানে আপলোড করা যায়।",
+       "upload-form-label-own-work-message-shared": "আমি প্রত্যয়ন করছি যে আমি এই ফাইলের স্বত্তাধিকারী, এবং [https://creativecommons.org/licenses/by-sa/4.0/deed.bn ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন-শেয়ার অ্যালাইক ৪.০] লাইসেন্সের অধীনে এই ফাইলটি উইকিমিডিয়া কমন্সে অপরিবর্তনীয় প্রকাশে সম্মত হচ্ছি, এবং আমি [https://wikimediafoundation.org/wiki/Terms_of_Use ব্যবহারের শর্তাবলীর] সাথে সম্মত।",
+       "upload-form-label-not-own-work-message-shared": "যদি আপনি এই ফাইলের স্বত্তাধিকারী না হন, বা আপনি একটি ভিন্ন লাইসেন্সের আওতায় প্রকাশ করতে ইচ্ছুক থাকেন, তাহলে [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=bn কমন্স আপলোড উইজার্ড] ব্যবহার করতে বিবেচনা করুন।",
+       "upload-form-label-not-own-work-local-shared": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি সাইটটি তাদের নীতিমালার অধীনে এই ফাইল আপলোড করার অনুমতি দেয়।",
        "backend-fail-stream": "\"$1\" ফাইলের স্ট্রিম দেখানো যাচ্ছে না।",
        "backend-fail-backup": "\"$1\" ফাইলের ব্যাকআপ তৈরী সম্ভব নয়।",
        "backend-fail-notexists": "\"$1\" নামের কোনো ফাইল নেই।",
        "lockdbsuccesstext": "ডাটাবেজ বন্ধ করা হয়েছে\n<br />আপনার রক্ষণাবেক্ষণ সম্পন্ন হবার পর [[Special:UnlockDB|ডাটাবেজ খুলে দিতে]] ভুলবেন না।",
        "unlockdbsuccesstext": "ডাটাবেজ খুলে দেওয়া হয়েছে।",
        "lockfilenotwritable": "ডাটাবেজ বন্ধ করার ফাইলটি লিখনযোগ্য নয়। ডাটাবেজ বন্ধ করতে বা খুলতে চাইলে ফাইলটিকে ওয়েব সার্ভার কর্তৃক লিখনযোগ্য হতে হবে।",
+       "databaselocked": "ডাটাবেসটি ইতিমধ্যেই তালাবদ্ধ।",
        "databasenotlocked": "ডাটাবেজ বন্ধ নয়।",
        "lockedbyandtime": "({{GENDER:$1|$1}} $2 এর $3 সময়ে)",
        "move-page": "$1 স্থানান্তর",
        "tooltip-ca-nstab-category": "বিষয়শ্রেণী পাতাটি দেখুন",
        "tooltip-minoredit": "এটিকে অনুল্লেখ্য সম্পাদনা হিসেবে চিহ্নিত করা হোক",
        "tooltip-save": "আপনার পরিবর্তনগুলি সংরক্ষিত হোক",
+       "tooltip-publish": "আপনার পরিবর্তন প্রকাশ করুন",
        "tooltip-preview": "অনুগ্রহ করে সংরক্ষণের আগে আপনার পরিবর্তনগুলি প্রাকদর্শন করুন!",
        "tooltip-diff": "আপনি টেক্সটে কী কী পরিবর্তন করেছেন, তা দেখানো হোক।",
        "tooltip-compareselectedversions": "এই পাতার দুইটি নির্বাচিত সংস্করণের মধ্যে তুলনা দেখুন।",
        "watchlistedit-raw-done": "আপনার নজর তালিকা হালনাগাদ করা হয়েছে।",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} যোগ করা হয়েছে:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} মুছে ফেলা হয়েছে:",
-       "watchlistedit-clear-title": "নà¦\9cরতালিà¦\95া à¦ªà¦°à¦¿à¦¸à§\8dà¦\95ার à¦\95রা à¦¹à¦¯à¦¼à§\87à¦\9bà§\87",
+       "watchlistedit-clear-title": "নà¦\9cরতালিà¦\95া à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রà§\81ন",
        "watchlistedit-clear-legend": "নজরতালিকা পরিস্কার",
        "watchlistedit-clear-explain": "সকল শিরোনামসমূহ আপনার নজরতালিকা থেকে সরিয়ে নেয়া হয়েছে।",
        "watchlistedit-clear-titles": "শিরোনামসমূহ:",
        "logentry-protect-protect-cascade": "$1 $3 {{GENDER:$2|সুরক্ষিত করেছেন}} $4 [প্রপাতাকার]",
        "logentry-protect-modify": "$1 $3-এর জন্য সুরক্ষা স্তর {{GENDER:$2|পরিবর্তন করেছেন}} $4",
        "logentry-protect-modify-cascade": "$1 $3-এর জন্য সুরক্ষা স্তর {{GENDER:$2|পরিবর্তন করেছেন}} $4 [প্রপাতাকার]",
-       "logentry-rights-rights": "$1 ব্যবহারকারী, $3 এর দলগত সদস্যপদ $4 থেকে $5 এ {{GENDER:$2|পরিবর্তন}} করেছেন",
+       "logentry-rights-rights": "$1 ব্যবহারকারী, {{GENDER:$6|$3}}-এর দলগত সদস্যপদ $4 থেকে $5 এ {{GENDER:$2|পরিবর্তন}} করেছেন",
        "logentry-rights-rights-legacy": "$1 দলের সদস্যপদ পরিবর্তন করেছেন {{GENDER:$2|changed}} এর জন্য $3",
        "logentry-rights-autopromote": "$1 স্বয়ংক্রিয়ভাবে $4 থেকে $5-এ {{GENDER:$2|উন্নীত}} হয়েছেন",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
        "randomrootpage": "অজানা মূল পাতা",
        "log-action-filter-block": "বাধাদানের ধরন:",
        "log-action-filter-delete": "অপসারণের ধরন:",
+       "log-action-filter-import": "আমদানির ধরন:",
        "log-action-filter-patrol": "টহলের ধরন:",
        "log-action-filter-protect": "সুরক্ষার ধরন:",
        "log-action-filter-upload": "আপলোডের ধরন:",
        "log-action-filter-protect-protect": "সুরক্ষা",
        "log-action-filter-protect-modify": "সুরক্ষা পরিমার্জন",
        "log-action-filter-protect-unprotect": "অসুরক্ষা",
+       "log-action-filter-rights-autopromote": "স্বয়ংক্রিয় পরিবর্তন",
        "log-action-filter-upload-upload": "নতুন আপলোড",
        "log-action-filter-upload-overwrite": "পুনঃআপলোড"
 }
index 03a0f88..4a459fa 100644 (file)
@@ -24,6 +24,7 @@
        "tog-hideminor": "Kuzhat ar c'hemmoù nevez dister",
        "tog-hidepatrolled": "Kuzhat ar c'hemmoù evezhiet e-touez ar c'hemmoù diwezhañ",
        "tog-newpageshidepatrolled": "Kuzhat ar pajennoù evezhiet diouzh roll ar pajennoù nevez",
+       "tog-hidecategorization": "Kuzhat rummatadur ar pajennoù",
        "tog-extendwatchlist": "Astenn ar roll evezhiañ a-benn diskouez an holl gemmoù ha neket ar re ziwezhañ hepken.",
        "tog-usenewrc": "Diskouez ar c'hemmoù nevez en ur feson kempennoc'h",
        "tog-numberheadings": "Niverenniñ emgefre an titloù",
        "rows": "Linennoù :",
        "columns": "Bannoù",
        "searchresultshead": "Klask",
-       "stub-threshold": "Bevenn uhelañ evit al <a href=\"#\" class=\"stub\">liammoù war-du an danvez pennadoù</a> (okted) :",
+       "stub-threshold": "Bevenn uhelañ evit al liammoù war-du an danvez pennadoù ($1) :",
        "stub-threshold-disabled": "Diweredekaet",
        "recentchangesdays": "Niver a zevezhioù da ziskouez er c'hemmoù diwezhañ :",
        "recentchangesdays-max": "D'ar muiañ $1 {{PLURAL:$1|deiz|deiz}}",
        "prefs-emailconfirm-label": "Kadarnaat ar postel :",
        "youremail": "Postel :",
        "username": "{{GENDER:$1|Anv implijer|Anv implijerez}}:",
-       "prefs-memberingroups": "{{GENDER:$2|Ezel}} eus {{PLURAL:$1|ar strollad|ar strolladoù}} :",
+       "prefs-memberingroups": "{{GENDER:$2|Ezel}} eus {{PLURAL:$1|ar strollad|ar strolladoù}}:",
        "prefs-registration": "Deiziad enskrivañ :",
        "yourrealname": "Anv gwir*",
        "yourlanguage": "Yezh an etrefas&nbsp;",
        "upload-form-label-infoform-description": "Deskrivadur",
        "upload-form-label-usage-title": "Implij",
        "upload-form-label-usage-filename": "Anv ar restr",
-       "foreign-structured-upload-form-label-infoform-categories": "Rummadoù",
-       "foreign-structured-upload-form-label-infoform-date": "Deiziad",
+       "upload-form-label-infoform-categories": "Rummadoù",
+       "upload-form-label-infoform-date": "Deiziad",
        "backend-fail-stream": "Dibosupl eo lenn ar restr $1.",
        "backend-fail-backup": "Dibosupl enrollañ ar restr $1.",
        "backend-fail-notexists": "N'eus ket eus ar restr $1.",
        "delete-confirm": "Diverkañ \"$1\"",
        "delete-legend": "Diverkañ",
        "historywarning": "<strong>Diwallit :</strong> Emaoc'h war-nes diverkañ ur bajenn dezhi un istor gant {{PLURAL:$1|adweladenn}} :",
+       "historyaction-submit": "Diskouez",
        "confirmdeletetext": "War-nes diverkañ da viken ur bajenn pe ur skeudenn eus ar bank roadennoù emaoc'h. Diverket e vo ivez an holl stummoù kozh stag outi.\nKadarnait, mar plij, eo mat an dra-se hoc'h eus c'hoant da ober, e komprenit mat an heuliadoù, hag e rit se diouzh ar [[{{MediaWiki:Policy-url}}]].",
        "actioncomplete": "Diverkadenn kaset da benn",
        "actionfailed": "Ober c'hwitet",
index 7d3500a..9aefe5b 100644 (file)
        "upload-form-label-infoform-description": "Opis",
        "upload-form-label-usage-title": "Korištenje",
        "upload-form-label-usage-filename": "Ime datoteke",
-       "foreign-structured-upload-form-label-own-work": "Ovo je moje djelo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Potvrđujem da postavljam ovu datoteku u skladu s uslovima korištenja i pravilima o licenciranju na {{GRAMMAR:dativ|{{SITENAME}}}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Ako niste u stanju postaviti ovu datoteku pod pravilima {{GRAMMAR:genitiv|{{SITENAME}}}}, molimo zatvorite ovaj prozor i pokušajte drugom metodom.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Također možete pokušati [[Special:Upload|na standardnoj stranici za postavljanje]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Shvatam da postavljam ovu datoteku na zajedničko spremište. Potvrđujem da to činim u skladu s uslovima korištenja i ovdašnjim pravilima licenciranja.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Ako niste u stanju postaviti ovu datoteku pod pravilima zajedničkog skladišta, molimo zatvorite ovaj prozor i pokušajte drugom metodom.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Možete također pokušati koristeći  [[Special:Upload|stranicu za postavljanje na  {{GRAMMAR:dativ|{{SITENAME}}}}]], ako se ova datoteka može postaviti pod tamošnjim pravilima.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava za ovu datoteku i slažem se da ću je neopozivo postaviti na Wikimedia Commons pod licencom [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], te se slažem s [https://wikimediafoundation.org/wiki/Terms_of_Use uslovima korištenja].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku ili je želite postaviti pod drugom licencom, imajte na umu da možete koristiti [https://commons.wikimedia.org/wiki/Special:UploadWizard čarobnjak za postavljanje datoteka na Commonsu].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Također možete koristiti [[Special:Upload|stranicu za postavljanje datoteka na {{GRAMMAR:dativ|{{SITENAME}}}}]] ako pravila te stranice dozvoljavaju postavljanje ove datoteke.",
+       "upload-form-label-own-work": "Ovo je moje djelo",
+       "upload-form-label-infoform-categories": "Kategorije",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Potvrđujem da postavljam ovu datoteku u skladu s uslovima korištenja i pravilima o licenciranju na {{GRAMMAR:dativ|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "Ako niste u stanju postaviti ovu datoteku pod pravilima {{GRAMMAR:genitiv|{{SITENAME}}}}, molimo zatvorite ovaj prozor i pokušajte drugom metodom.",
+       "upload-form-label-not-own-work-local-local": "Također možete pokušati [[Special:Upload|na standardnoj stranici za postavljanje]].",
+       "upload-form-label-own-work-message-default": "Shvatam da postavljam ovu datoteku na zajedničko spremište. Potvrđujem da to činim u skladu s uslovima korištenja i ovdašnjim pravilima licenciranja.",
+       "upload-form-label-not-own-work-message-default": "Ako niste u stanju postaviti ovu datoteku pod pravilima zajedničkog skladišta, molimo zatvorite ovaj prozor i pokušajte drugom metodom.",
+       "upload-form-label-not-own-work-local-default": "Možete također pokušati koristeći  [[Special:Upload|stranicu za postavljanje na  {{GRAMMAR:dativ|{{SITENAME}}}}]], ako se ova datoteka može postaviti pod tamošnjim pravilima.",
+       "upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava za ovu datoteku i slažem se da ću je neopozivo postaviti na Wikimedia Commons pod licencom [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], te se slažem s [https://wikimediafoundation.org/wiki/Terms_of_Use uslovima korištenja].",
+       "upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku ili je želite postaviti pod drugom licencom, imajte na umu da možete koristiti [https://commons.wikimedia.org/wiki/Special:UploadWizard čarobnjak za postavljanje datoteka na Commonsu].",
+       "upload-form-label-not-own-work-local-shared": "Također možete koristiti [[Special:Upload|stranicu za postavljanje datoteka na {{GRAMMAR:dativ|{{SITENAME}}}}]] ako pravila te stranice dozvoljavaju postavljanje ove datoteke.",
        "backend-fail-stream": "Ne mogu emitirati datoteku $1.",
        "backend-fail-backup": "Ne može sigurnosno kopirati datoteku $1.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
index 754af74..cfe09b6 100644 (file)
@@ -72,6 +72,7 @@
        "tog-watchdefault": "Afegeix les pàgines que vagi editant a la llista de seguiment",
        "tog-watchmoves": "Afegeix les pàgines que reanomeni a la llista de seguiment",
        "tog-watchdeletion": "Afegeix les pàgines que elimini a la llista de seguiment",
+       "tog-watchuploads": "Afegeix els nous fitxers que pengi a la meva llista de seguiment",
        "tog-watchrollback": "Afegeix les pàgines on he realitzat una reversió a la llista de seguiment",
        "tog-minordefault": "Marca totes les contribucions com a edicions menors per defecte",
        "tog-previewontop": "Mostra una previsualització abans del quadre d'edició",
        "mypreferencesprotected": "No tens permís per editar les teves preferències.",
        "ns-specialprotected": "No es poden modificar les pàgines especials.",
        "titleprotected": "La creació d'aquesta pàgina està protegida per [[User:$1|$1]].\nEls seus motius han estat: <em>$2</em>.",
-       "filereadonlyerror": "No s'ha pogut modificar el fitxer «$1» perquè el repositori de fitxers \"$2\" està en mode només de lectura.\nL'administrador que l'ha bloquejat ha donat aquesta explicació: \"$3\".",
+       "filereadonlyerror": "No s'ha pogut modificar el fitxer «$1» perquè el repositori de fitxers «$2» està en mode només de lectura.\nL'administrador de sistema que l'ha bloquejat ha donat aquesta explicació: «$3».",
        "invalidtitle-knownnamespace": "El títol amb l'espai de noms «$2» i text «$3» no és vàlid",
        "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ó",
        "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.",
-       "blocked-mailpassword": "S'ha blocat la vostra adreça IP. Se us ha desactivat la funció de recuperació de contrasenya per a prevenir abusos.",
+       "blocked-mailpassword": "S'ha blocat la vostra adreça IP per a edicions. Per a prevenir abusos, s'ha desactivat la funció de recuperació de contrasenya des d'aquesta adreça IP.",
        "eauthentsent": "S'ha enviat un correu electrònic a la direcció especificada. Abans no s'enviï cap altre correu electrònic a aquesta adreça, cal verificar que és realment vostra. Per tant, cal que seguiu les instruccions presents en el correu electrònic que se us ha enviat.",
        "throttled-mailpassword": "Ja se us ha enviat un correu electrònic de reinicialització de contrasenya en {{PLURAL:$1|l'última hora|les últimes $1 hores}}.\nPer a prevenir abusos, només s'envia un correu electrònic de reinicialització de contrasenya cada {{PLURAL:$1|hora|$1 hores}}.",
        "mailerror": "S'ha produït un error en enviar el missatge: $1",
        "botpasswords-insert-failed": "No s'ha pogut afegir el nom del bot «$1». Ja hi estava afegit?",
        "botpasswords-update-failed": "No s'ha pogut actualitzar el nom del bot «$1». Hi estava suprimit?",
        "botpasswords-created-title": "S'ha creat la contrasenya del bot",
+       "botpasswords-created-body": "S'ha creat la contrasenya per al bot «$1» de l'usuari «$2».",
+       "botpasswords-updated-title": "Contrasenya de bot actualitzada",
        "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",
        "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.",
-       "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.'''",
+       "session_fail_preview": "Disculpes! No s'ha pogut processar la vostra modificació a causa d'una pèrdua de dades de la sessió.\n\nPot ser que s'hagi tancat la sessió. <strong>Comproveu si teniu la sessió iniciada i proveu-ho una altra vegada</strong>.\nSi continués sense funcionar, proveu de [[Special:UserLogout|finalitzar la sessió]] i torneu a iniciar-ne una. Comproveu que el vostre navegador permeti les galetes d'aquest lloc.",
+       "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<em>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.</em>\n\n<strong>Si es tracta d'una contribució legítima, si us plau, intenteu-ho una altra vegada.</strong> Si continua havent-hi problemes, [[Special:UserLogout|finalitzeu la sessió]] i torneu a iniciar-ne una. Comproveu que el vostre navegador permeti galetes d'aquest lloc.",
        "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.'''",
        "edit_form_incomplete": "'''Certes parts del formulari de modificació no han arribat al servidor, verifiqueu que les vostres modificacions estan intactes i proveu-ho de nou.'''",
        "editing": "Edició de la pàgina «$1»",
        "currentrev-asof": "Revisió de $1",
        "revisionasof": "Revisió del $1",
        "revision-info": "La revisió el $1 per {{GENDER:$6|$2}}$7",
-       "previousrevision": "←Versió més antiga",
-       "nextrevision": "Versió més nova→",
+       "previousrevision": "← Versió més antiga",
+       "nextrevision": "Versió més nova →",
        "currentrevisionlink": "Versió actual",
        "cur": "act",
        "next": "seg",
        "revdelete-submit": "Aplica a {{PLURAL:$1|la revisió seleccionada|les revisions seleccionades}}",
        "revdelete-success": "La visibilitat d'aquesta revisió s'ha actualitzat.",
        "revdelete-failure": "'''La visibilitat de la revisió no ha pogut actualitzar-se:'''\n$1",
-       "logdelete-success": "'''S'ha establert correctament la visibilitat d'aquest element.'''",
+       "logdelete-success": "S'ha establert la visibilitat del registre.",
        "logdelete-failure": "'''No s'ha pogut establir la visibilitat del registre:'''\n$1",
        "revdel-restore": "Canvia'n la visibilitat",
        "pagehist": "Historial",
        "recentchangeslinked-page": "Nom de la pàgina:",
        "recentchangeslinked-to": "Mostra els canvis de les pàgines enllaçades amb la pàgina donada",
        "recentchanges-page-added-to-category": "[[:$1]] afegida a la categoria",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] i [[Special:WhatLinksHere/$1|{{PLURAL:$2|una pàgina|$2 pàgines}}]] més afegides a la categoria",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] afegida a la categoria, [[Special:WhatLinksHere/$1|aquesta pàgina està inclosa en d'altres]]",
        "recentchanges-page-removed-from-category": "[[:$1]] treta de la categoria",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] i {{PLURAL:$2|una pàgina|$2 pàgines}} més tretes de la categoria",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] treta de la categoria, [[Special:WhatLinksHere/$1|aquesta pàgina està inclosa en d'altres]]",
        "autochange-username": "Canvi automàtic del MediaWiki",
        "upload": "Carregueu un fitxer",
        "uploadbtn": "Carrega un fitxer",
        "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’esdeveniments <code>$1=\"$2\"</code> en 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-href-unsafe-target-svg": "S’ha trobat un element «href» amb dades no segures: destinació URI <code>&lt;$1 $2=\"$3\"&gt;</code> en el 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.",
        "uploadscriptednamespace": "Aquest fitxer SVG conté un espai de noms \"$1\" no autoritzat",
        "uploadinvalidxml": "No s'ha pogut analitzar l'XML del fitxer carregat.",
        "upload-dialog-button-upload": "Carrega",
        "upload-form-label-infoform-title": "Detalls",
        "upload-form-label-infoform-name": "Nom",
+       "upload-form-label-infoform-name-tooltip": "Un únic títol descriptiu pel fitxer, que servirà com a nom del fitxer. Podeu utilitzar llenguatge senzill amb espais. No hi inclogueu l'extensió del fitxer.",
        "upload-form-label-infoform-description": "Descripció",
        "upload-form-label-usage-title": "Ús",
        "upload-form-label-usage-filename": "Nom del fitxer",
-       "foreign-structured-upload-form-label-own-work": "Això és el meu propi treball",
-       "foreign-structured-upload-form-label-infoform-categories": "Categories",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "També podeu provar [[Special:Upload|la pàgina de càrrega per defecte]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Entenc que esteu carregant el fitxer en un repositori compartit. Confirmo que ho estic fent seguint les condicions d'ús i les polítiques de llicenciament que s'hi apliquen.",
+       "upload-form-label-own-work": "Això és el meu propi treball",
+       "upload-form-label-infoform-categories": "Categories",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-not-own-work-local-local": "També podeu provar [[Special:Upload|la pàgina de càrrega per defecte]].",
+       "upload-form-label-own-work-message-default": "Entenc que esteu carregant el fitxer en un repositori compartit. Confirmo que ho estic fent seguint les condicions d'ús i les polítiques de llicenciament que s'hi apliquen.",
        "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-read": "No s'ha pogut llegir el fitxer $1.",
        "backend-fail-create": "No s'ha pogut crear el fitxer $1.",
        "backend-fail-maxsize": "No s'ha pogut escriure el fitxer $1 perquè és més gran que {{PLURAL:$2|un byte|$2 bytes}}.",
-       "backend-fail-readonly": "El rerefons d'emmagatzemament «$1» actualment només és de lectura. Es va donar el motiu: «$2»",
+       "backend-fail-readonly": "El suport d'emmagatzemament «$1» actualment només és de lectura. S'ha donat el motiu: <em>$2</em>",
        "backend-fail-synced": "El fitxer «$1» es troba en un estat inconsistent amb els rerefons d'emmagatzemament interns.",
        "backend-fail-connect": "No s'ha pogut connectar al fitxer de rerefons d'emmagatzemament «$1».",
        "backend-fail-internal": "S'ha produït un error desconegut en el fitxer de rerefons d'emmagatzemament «$1».",
        "uploadstash-badtoken": "No s'ha pogut realitzar l'acció, possiblement perquè han caducat la vostra identificació. Intenteu-ho de nou.",
        "uploadstash-errclear": "S'estan netejant els fitxers que han fallat.",
        "uploadstash-refresh": "Actualitza la llista de fitxers",
+       "uploadstash-thumbnail": "mostra una miniatura",
        "invalid-chunk-offset": "El desplaçament del fragment no és vàlid",
        "img-auth-accessdenied": "Accés denegat",
        "img-auth-nopathinfo": "Hi manca PATH_INFO.\nEl servidor no està configurat per passar aquesta informació.\nPot estar basat en CGI i no ser compatible amb img_auth.\nConsulteu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "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 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.",
+       "deleting-backlinks-warning": "<strong>Atenció:</strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|Altres pàgines]] enllacen aquí o inclouen la pàgina que esteu a punt de suprimir.",
        "rollback": "Reverteix edicions",
        "rollbacklink": "Reverteix",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "watchlistedit-raw-done": "S'ha actualitzat la vostra llista de seguiment.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 títol s'ha|$1 títols s'han}} afegit:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 títol s'ha|$1 títols s'han}} eliminat:",
-       "watchlistedit-clear-title": "S'ha netejat la llista de seguiment",
+       "watchlistedit-clear-title": "Neteja de la llista de seguiment",
        "watchlistedit-clear-legend": "Neteja la llista de seguiment",
        "watchlistedit-clear-explain": "Se suprimiran tots els títols de la vostra llista de seguiment",
        "watchlistedit-clear-titles": "Títols:",
index e00c4a5..77dff52 100644 (file)
        "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-not-own-work-local-default": "ХӀара файл {{SITENAME}} сайтан бакъонашца чуйоккхила делахь, хьайн таро ю [[Special:Upload|хӀара агӀо]] лелаян.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Аса со хӀокху файлан авторан бакъонаш долахь ерг хилар бакъдо, цундела хӀара файл [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0] лицензица Викигуламан чуяккха бакъо ю, цул совнах [https://wikimediafoundation.org/wiki/ хӀокху хьолаца лело] а мега.",
-       "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": "ХӀара файл {{SITENAME}} сайтан бакъонашца чуйоккхила делахь, хьайн таро ю [[Special:Upload|хӀара агӀо]] лелаян.",
+       "upload-form-label-own-work": "ХӀара сан долара болх бу",
+       "upload-form-label-infoform-categories": "Категореш",
+       "upload-form-label-infoform-date": "Терахь",
+       "upload-form-label-not-own-work-local-default": "ХӀара файл {{SITENAME}} сайтан бакъонашца чуйоккхила делахь, хьайн таро ю [[Special:Upload|хӀара агӀо]] лелаян.",
+       "upload-form-label-own-work-message-shared": "Аса со хӀокху файлан авторан бакъонаш долахь ерг хилар бакъдо, цундела хӀара файл [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0] лицензица Викигуламан чуяккха бакъо ю, цул совнах [https://wikimediafoundation.org/wiki/ хӀокху хьолаца лело] а мега.",
+       "upload-form-label-not-own-work-message-shared": "ХӀокху файлан авторан бакъонаш хьай яцахь, я хьайна кхечу лицензица яржо лууш делахь хьажа [https://commons.wikimedia.org/wiki/Special:UploadWizard Викигуламера чуяхаран говзанча] лелон тароне.",
+       "upload-form-label-not-own-work-local-shared": "ХӀара файл {{SITENAME}} сайтан бакъонашца чуйоккхила делахь, хьайн таро ю [[Special:Upload|хӀара агӀо]] лелаян.",
        "backend-fail-stream": "ДӀаяккха цатарло файл «$1».",
        "backend-fail-backup": "Таро яц файлан $1 тӀаьхьалонан копиян.",
        "backend-fail-notexists": "Файл $1 яц.",
index 1fa3148..98b5cee 100644 (file)
        "changepassword-success": "Vaše heslo bylo změněno!",
        "changepassword-throttled": "Provedli jste příliš mnoho pokusů o přihlášení.\nČekejte prosím $1 a zkuste to znovu.",
        "botpasswords": "Hesla pro boty",
-       "botpasswords-summary": "<em>Hesla pro boty</em> umožňují přistupovat k uživatelskému účtu prostřednictví API bez použití hlavních přihlašovacích údajů účtu. Uživatelská oprávnění dostupná po přihlášení pomocí hesla pro boty mohou být omezena.\n\nPokud nevíte, k čemu byste to {{GENDER:|chtěl|chtěla|chtěli}} použít, pravděpodobně byste to používat {{GENDER:|neměl|neměla|neměli}}. Nikdo by vás nikdy neměl žádat, abyste si zde vygenerovali heslo a dali mu ho.",
+       "botpasswords-summary": "<em>Hesla pro boty</em> umožňují přistupovat k uživatelskému účtu prostřednictví API bez použití hlavních přihlašovacích údajů účtu. Uživatelská oprávnění dostupná po přihlášení pomocí hesla pro boty mohou být omezena.\n\nPokud nevíte, k čemu byste to {{GENDER:|chtěl|chtěla|chtěli}} použít, pravděpodobně byste to používat {{GENDER:|neměl|neměla|neměli}}. Nikdo by vás nikdy neměl žádat, abyste si zde {{GENDER:|vygeneroval heslo a dal|vygenerovala heslo a dala|vygenerovali heslo a dali}} mu ho.",
        "botpasswords-disabled": "Hesla pro boty jsou zakázána.",
        "botpasswords-no-central-id": "Abyste {{GENDER:|mohl|mohla|mohl(a)}} použít hesla pro boty, musíte být {{GENDER:|přihlášen|přihlášena|přihlášen(a)}} k centrálnímu účtu.",
        "botpasswords-existing": "Stávající hesla pro boty",
        "minoredit": "Tato změna je malá editace.",
        "watchthis": "Sledovat tuto stránku",
        "savearticle": "Uložit změny",
+       "publishpage": "Zveřejnit stránku",
        "preview": "Náhled",
        "showpreview": "Ukázat náhled",
        "showdiff": "Ukázat změny",
        "userpage-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.\nZkontrolujte, zda skutečně chcete tuto stránku vytvořit či editovat.",
        "userpage-userdoesnotexist-view": "Uživatelský účet „$1“ není zaregistrován.",
        "blocked-notice-logextract": "{{GENDER:$1|Tento uživatel|Tato uživatelka}} je momentálně {{GENDER:$1|zablokován|zablokována}}.\nZde je pro přehled zobrazen nejnovější záznam z knihy zablokování:",
-       "clearyourcache": "<strong>Poznámka:</strong> Po uložení musíte smazat cache vašeho prohlížeče, jinak změny neuvidíte.\n* <strong>Firefox / Safari:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Shift</em> nebo stiskněte <em>Ctrl-F5</em> nebo <em>Ctrl-R</em> (na Macu <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Stiskněte <em>Ctrl-Shift-R</em> (na Macu <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Ctrl</em> nebo stiskněte <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Smažte obsah cache v menu <em>Nástroje → Nastavení</em>",
+       "clearyourcache": "<strong>Poznámka:</strong> Po uložení musíte smazat cache vašeho prohlížeče, jinak změny neuvidíte.\n* <strong>Firefox / Safari:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Shift</em> nebo stiskněte <em>Ctrl-F5</em> nebo <em>Ctrl-R</em> (na Macu <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Stiskněte <em>Ctrl-Shift-R</em> (na Macu <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Při kliknutí na <em>Aktualizovat</em> držte <em>Ctrl</em> nebo stiskněte <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Jděte do <em>Menu → Nastavení</em> (na Macu <em>Opera → Nastavení</em>) a tam pak <em>Soukromí & bezpečnost → Vymazat údaje o prohlížení → Obrázky a soubory z cache</em>",
        "usercssyoucanpreview": "<strong>Tip:</strong> Použijte tlačítko „{{int:showpreview}}“ k testování vašeho nového CSS před uložením.",
        "userjsyoucanpreview": "<strong>Tip:</strong> Použijte tlačítko „{{int:showpreview}}“ k testování vašeho nového JavaScriptu před uložením.",
        "usercsspreview": "<strong>Pamatujte, že si prohlížíte jen náhled vašeho uživatelského CSS, jelikož dosud nebyl uložen!</strong>",
        "upload-form-label-infoform-description-tooltip": "Stručně popište všechny důležité informace o díle.\nU fotografií zmiňte hlavní zobrazené objekty, příležitost, při které fotografie vznikla, nebo místo.",
        "upload-form-label-usage-title": "Použití",
        "upload-form-label-usage-filename": "Jméno souboru",
-       "foreign-structured-upload-form-label-own-work": "Je to mé vlastní dílo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorie",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Potvrzuji, že tento soubor načítám v souladu s podmínkami užití a licenčními pravidly na {{grammar:6sg|{{SITENAME}}}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Pokud nemůžete tento soubor načíst v souladu s pravidly {{grammar:2sg|{{SITENAME}}}}, zavřete prosím tento dialog a zkuste jiný způsob.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Také můžete zkusit [[Special:Upload|standardní stránku pro načítání souborů]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Chápu, že soubor načítám na sdílené úložiště. Potvrzuji, že tak činím v souladu s tamními podmínkami užití a licenčními pravidly.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Pokud nemůžete tento soubor načíst v souladu s pravidly sdíleného úložiště, zavřete prosím tento dialog a zkuste jiný způsob.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Také můžete zkusit [[Special:Upload|stránku pro načítání souborů na {{grammar:6sg|{{SITENAME}}}}]], pokud tam lze soubor podle tamních pravidel načíst.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Potvrzuji, že jsem držitelem autorských práv k tomuto souboru a neodvolatelně souhlasím s jeho zveřejněním na Wikimedia Commons pod licencí [https://creativecommons.org/licenses/by-sa/4.0/deed.cs Creative Commons Uveďte původ – Zachovejte licenci 4.0] a souhlasím s [https://wikimediafoundation.org/wiki/Terms_of_Use/cs Podmínkami užití].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Pokud nejste držiteli autorských práv k tomuto souboru nebo si ho přejete zveřejnit pod jinou licencí, zvažte použití [https://commons.wikimedia.org/wiki/Special:UploadWizard Průvodce načítáním souborů na Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Také můžete zkusit [[Special:Upload|stránku pro načítání souborů na {{grammar:6sg|{{SITENAME}}}}]], pokud tamní pravidla načtení tohoto souboru dovolují.",
+       "upload-form-label-own-work": "Je to mé vlastní dílo",
+       "upload-form-label-infoform-categories": "Kategorie",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Potvrzuji, že tento soubor načítám v souladu s podmínkami užití a licenčními pravidly na {{grammar:6sg|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "Pokud nemůžete tento soubor načíst v souladu s pravidly {{grammar:2sg|{{SITENAME}}}}, zavřete prosím tento dialog a zkuste jiný způsob.",
+       "upload-form-label-not-own-work-local-local": "Také můžete zkusit [[Special:Upload|standardní stránku pro načítání souborů]].",
+       "upload-form-label-own-work-message-default": "Chápu, že soubor načítám na sdílené úložiště. Potvrzuji, že tak činím v souladu s tamními podmínkami užití a licenčními pravidly.",
+       "upload-form-label-not-own-work-message-default": "Pokud nemůžete tento soubor načíst v souladu s pravidly sdíleného úložiště, zavřete prosím tento dialog a zkuste jiný způsob.",
+       "upload-form-label-not-own-work-local-default": "Také můžete zkusit [[Special:Upload|stránku pro načítání souborů na {{grammar:6sg|{{SITENAME}}}}]], pokud tam lze soubor podle tamních pravidel načíst.",
+       "upload-form-label-own-work-message-shared": "Potvrzuji, že jsem držitelem autorských práv k tomuto souboru a neodvolatelně souhlasím s jeho zveřejněním na Wikimedia Commons pod licencí [https://creativecommons.org/licenses/by-sa/4.0/deed.cs Creative Commons Uveďte původ – Zachovejte licenci 4.0] a souhlasím s [https://wikimediafoundation.org/wiki/Terms_of_Use/cs Podmínkami užití].",
+       "upload-form-label-not-own-work-message-shared": "Pokud nejste držiteli autorských práv k tomuto souboru nebo si ho přejete zveřejnit pod jinou licencí, zvažte použití [https://commons.wikimedia.org/wiki/Special:UploadWizard Průvodce načítáním souborů na Commons].",
+       "upload-form-label-not-own-work-local-shared": "Také můžete zkusit [[Special:Upload|stránku pro načítání souborů na {{grammar:6sg|{{SITENAME}}}}]], pokud tamní pravidla načtení tohoto souboru dovolují.",
        "backend-fail-stream": "Soubor $1 nelze streamovat.",
        "backend-fail-backup": "Soubor $1 nelze zazálohovat.",
        "backend-fail-notexists": "Soubor $1 neexistuje.",
        "changecontentmodel-success-text": "Model obsahu stránky [[:$1]] byl změněn.",
        "changecontentmodel-cannot-convert": "Obsah stránky [[:$1]] nelze zkonvertovat na typ $2.",
        "changecontentmodel-nodirectediting": "Model obsahu $1 nepodporuje přímou editaci",
+       "changecontentmodel-emptymodels-title": "Nejsou k dispozici žádné modely obsahu",
+       "changecontentmodel-emptymodels-text": "Obsah stránky [[:$1]] nelze zkonvertovat na žádný typ.",
        "log-name-contentmodel": "Kniha změny modelů obsahu",
        "log-description-contentmodel": "Události týkající se modelů obsahu stránek",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|založil|založila}} stránku $3 za použití nestandardního modelu obsahu „$5“",
        "lockdbsuccesstext": "Databáze {{grammar:2sg|{{SITENAME}}}} byla úspěšně uzamčena.\n<br />Nezapomeňte ji po dokončení údržby [[Special:UnlockDB|odemknout]].",
        "unlockdbsuccesstext": "Databáze {{grammar:2sg|{{SITENAME}}}} je odemčena.",
        "lockfilenotwritable": "Do souboru zámku databáze nelze zapisovat. Pro zamčení či odemčení databáze musí mít webový server právo zápisu do tohoto souboru.",
+       "databaselocked": "Databáze je již zamčená.",
        "databasenotlocked": "Databáze není uzamčena.",
        "lockedbyandtime": "({{gender:$1|zamkl|zamkla|zamkl}} $1 $2 v $3)",
        "move-page": "Přesunout „$1“",
        "tooltip-ca-nstab-category": "Zobrazit kategorii",
        "tooltip-minoredit": "Označit změnu jako malou editaci",
        "tooltip-save": "Uložit vaše změny",
+       "tooltip-publish": "Zveřejnit vaše změny",
        "tooltip-preview": "Zobrazit náhled vašich změn; prosíme, zobrazte si ho před uložením!",
        "tooltip-diff": "Zobrazit, jaké změny jste v textu provedli",
        "tooltip-compareselectedversions": "Podívat se na rozdíly mezi dvěma vybranými verzemi této stránky.",
        "feedback-useragent": "Uživatelský agent:",
        "searchsuggest-search": "Hledat",
        "searchsuggest-containing": "obsahující…",
+       "api-error-autoblocked": "Vaše IP adresa byla automaticky zablokována, protože ji používal zablokovaný uživatel.",
        "api-error-badaccess-groups": "Nemáte povoleno nahrávat soubory na tuto wiki.",
        "api-error-badtoken": "Vnitřní chyba: špatný token.",
+       "api-error-blocked": "Byla vám zablokována možnost editace.",
        "api-error-copyuploaddisabled": "Načítání z URL je na tomto severu zakázáno.",
        "api-error-duplicate": "Na této wiki již {{PLURAL:$1|existuje jiný soubor|existují jiné soubory}} se shodným obsahem.",
        "api-error-duplicate-archive": "{{PLURAL:$1|Soubor|Soubory}} se stejným obsahem již zde dříve {{PLURAL:$1|byl|byly}}, ale {{PLURAL:$1|byl smazán|byly smazány}}.",
        "api-error-nomodule": "Interní chyba: není nastaven načítací modul.",
        "api-error-ok-but-empty": "Interní chyba: ze serveru nepřišla odpověď.",
        "api-error-overwrite": "Není dovoleno přepsat existující soubor.",
+       "api-error-ratelimited": "Pokoušíte se načíst v krátkém časovém rozmezí načíst více souborů, než je na této wiki dovoleno.\nZkuste to znovu za několik minut.",
        "api-error-stashfailed": "Vnitřní chyba: Serveru se nepodařilo uložit dočasný soubor.",
        "api-error-publishfailed": "Vnitřní chyba: Serveru se nepodařilo zveřejnit dočasný soubor.",
        "api-error-stasherror": "Při načítání souboru do skrýše došlo k chybě.",
index 454c0b1..4cbca02 100644 (file)
@@ -24,7 +24,7 @@
        "tog-hideminor": "Cuddio golygiadau bychain yn rhestr y newidiadau diweddar",
        "tog-hidepatrolled": "Cuddio golygiadau sydd wedi derbyn ymweliad patrôl rhag y rhestr newidiadau diweddar",
        "tog-newpageshidepatrolled": "Cuddio tudalennau a batroliwyd o'r rhestr y tudalennau newydd",
-       "tog-hidecategorization": "Cuddiwych y categoriau",
+       "tog-hidecategorization": "Cuddiwch y categoriau",
        "tog-extendwatchlist": "Ehangu'r rhestr wylio i ddangos pob golygiad yn hytrach na'r diweddaraf yn unig",
        "tog-usenewrc": "Grwpio'r newidiadau bob yn ddalen yn y 'newidiadau diweddar' a'r 'rhestr wylio'",
        "tog-numberheadings": "Rhifo penawdau'n awtomatig",
@@ -55,7 +55,7 @@
        "tog-watchlistreloadautomatically": "Ail-lwyther y Rhestr wylio yn otomatigpan newider ffiltr (angen JavaScript)",
        "tog-watchlisthideanons": "Cuddio golygiadau gan ddefnyddwyr anhysbys rhag y rhestr wylio",
        "tog-watchlisthidepatrolled": "Cuddio golygiadau sydd wedi derbyn ymweliad patrôl rhag y rhestr wylio",
-       "tog-watchlisthidecategorization": "Cuddiwych y categoriau",
+       "tog-watchlisthidecategorization": "Cuddiwch y categoriau",
        "tog-ccmeonemails": "Anfon copi ataf pan anfonaf e-bost at ddefnyddiwr arall",
        "tog-diffonly": "Peidio â dangos cynnwys y dudalen islaw'r gymhariaeth ar dudalennau cymharu",
        "tog-showhiddencats": "Dangos categorïau cuddiedig",
        "rcshowhidemine": "$1 fy ngolygiadau",
        "rcshowhidemine-show": "Dangoser",
        "rcshowhidemine-hide": "Cuddier",
-       "rcshowhidecategorization": "Categorieiddio tudalen $1",
+       "rcshowhidecategorization": "Categoreiddio tudalen $1",
        "rcshowhidecategorization-show": "Dangos",
        "rcshowhidecategorization-hide": "Cuddio",
        "rclinks": "Dangos y $1 newid diweddaraf yn ystod y(r) $2 diwrnod diwethaf<br />$3",
        "upload-form-label-infoform-description": "Disgrifiad",
        "upload-form-label-usage-title": "Defnydd",
        "upload-form-label-usage-filename": "Enw'r ffeil",
-       "foreign-structured-upload-form-label-own-work": "Dyma fy ngwaith fy hun",
-       "foreign-structured-upload-form-label-infoform-categories": "Categoriau",
-       "foreign-structured-upload-form-label-infoform-date": "Dyddiad",
-       "foreign-structured-upload-form-label-own-work-message-local": "Rwy'n cadarnhau fy mod yn uwchlwytho'r ffeil yma gan ddilyn amodau a pholisiau trwyddedu {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Efallai y carwch hefyd roi gynnig ar [[Special:Upload|y ddalen uwchlwytho diofyn]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Rwy'n cadarnhau fy mod yn uwchlwytho'r ffeil yma i fan sy'n cael ei rannu gan nifer. Rwy'n cadarnhau hefyd y gwnaf hyn gan ddilyn yr amodau a'r polisiau trwyddedu sydd yno.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Cadarnhaf mai fi yw perchennog hawlfraint y ffeil hon, a chytunaf  yn ddi-droi'n ôl i ryddhau'r ffeil hon i Gomin Wicimedia dan drwydded [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], a chytunaf gyda'r[https://wikimediafoundation.org/wiki/Terms_of_Use Amodau Defnyddio].",
+       "upload-form-label-own-work": "Dyma fy ngwaith fy hun",
+       "upload-form-label-infoform-categories": "Categoriau",
+       "upload-form-label-infoform-date": "Dyddiad",
+       "upload-form-label-own-work-message-local": "Rwy'n cadarnhau fy mod yn uwchlwytho'r ffeil yma gan ddilyn amodau a pholisiau trwyddedu {{SITENAME}}.",
+       "upload-form-label-not-own-work-local-local": "Efallai y carwch hefyd roi gynnig ar [[Special:Upload|y ddalen uwchlwytho diofyn]].",
+       "upload-form-label-own-work-message-default": "Rwy'n cadarnhau fy mod yn uwchlwytho'r ffeil yma i fan sy'n cael ei rannu gan nifer. Rwy'n cadarnhau hefyd y gwnaf hyn gan ddilyn yr amodau a'r polisiau trwyddedu sydd yno.",
+       "upload-form-label-own-work-message-shared": "Cadarnhaf mai fi yw perchennog hawlfraint y ffeil hon, a chytunaf  yn ddi-droi'n ôl i ryddhau'r ffeil hon i Gomin Wicimedia dan drwydded [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], a chytunaf gyda'r[https://wikimediafoundation.org/wiki/Terms_of_Use Amodau Defnyddio].",
        "backend-fail-stream": "Wedi methu ffrydio'r ffeil $1.",
        "backend-fail-backup": "Wedi methu gwneud copi wrth gefn o'r ffeil $1.",
        "backend-fail-notexists": "Nid yw'r ffeil $1 ar gael.",
index 2a80b92..05c4418 100644 (file)
        "recentchanges-legend-heading": "<strong>Forklaring:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se også [[Special:NewPages|listen over nye sider]])",
        "recentchanges-legend-plusminus": "(''±123'')",
+       "recentchanges-submit": "Vis",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfrom": "Vis nye ændringer startende fra den $3 kl. $2",
        "rcshowhideminor": "$1 mindre ændringer",
        "upload-form-label-infoform-name": "Navn",
        "upload-form-label-infoform-description": "Beskrivelse",
        "upload-form-label-usage-filename": "Filnavn",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorier",
-       "foreign-structured-upload-form-label-infoform-date": "Dato",
-       "foreign-structured-upload-form-label-own-work-message-local": "Jeg bekræfter at jeg uploader filen i overenstemmelse med betingelser for brug og licenseringspoltikken på {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Hvis du ikke kan uploade filen under politikerne på {{SITENAME}}, skal du lukke dialogboksen og prøve en anden metode.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Du kan også vælge at prøve [[Special:Upload|den almindelige uploadside]].",
+       "upload-form-label-infoform-categories": "Kategorier",
+       "upload-form-label-infoform-date": "Dato",
+       "upload-form-label-own-work-message-local": "Jeg bekræfter at jeg uploader filen i overenstemmelse med betingelser for brug og licenseringspoltikken på {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Hvis du ikke kan uploade filen under politikerne på {{SITENAME}}, skal du lukke dialogboksen og prøve en anden metode.",
+       "upload-form-label-not-own-work-local-local": "Du kan også vælge at prøve [[Special:Upload|den almindelige uploadside]].",
        "backend-fail-stream": "Kunne ikke streame filen $1.",
        "backend-fail-backup": "Kunne ikke lave sikkerhedskopi af filen $1.",
        "backend-fail-notexists": "Filen $1 findes ikke.",
        "apisandbox": "API-sandkassen",
        "apisandbox-api-disabled": "API er deaktiveret på dette websted.",
        "apisandbox-intro": "Brug denne side til at eksperimentere med '''MediaWiki web service API'''.\nVi henviser til [//www.mediawiki.org/wiki/API:Main_page dokumentationen af API] for yderligere oplysninger om brug af API.  Eksempel: [//www.mediawiki.org/wiki/API#A_simple_example få indholdet af en forside]. Vælg en handling at se flere eksempler.\n\nBemærk, at selv om dette er en sandkasse, vil handlinger du udfører på denne side redigere wikien.",
+       "apisandbox-unfullscreen": "Vis side",
        "apisandbox-submit": "Lav forespørgsel",
        "apisandbox-reset": "Ryd",
        "apisandbox-examples": "Eksempler",
        "specialloguserlabel": "Udført af:",
        "speciallogtitlelabel": "Mål (titel eller {{ns:user}}:brugernavn for bruger):",
        "log": "Loglister",
+       "logeventslist-submit": "Vis",
        "all-logs-page": "Alle offentlige logger",
        "alllogstext": "Samlet visning af alle loggene på {{SITENAME}}.\nDu kan afgrænse visningen ved at vælge en logtype, brugernavn eller påvirket side. Der skelnes mellem små og store bogstaver for både bruger- og sidenavne.",
        "logempty": "Intet passende fundet.",
        "cachedspecial-viewing-cached-ts": "Du ser en hengemt version af denne side, som måske ikke er helt aktuel.",
        "cachedspecial-refresh-now": "Vis seneste.",
        "categories": "Kategorier",
+       "categories-submit": "Vis",
        "categoriespagetext": "Følgende {{PLURAL:$1|kategori|kategorier}} indeholder sider eller media.\n[[Special:UnusedCategories|Ubrugte kategorier]] vises ikke her.\nSe også [[Special:WantedCategories|ønskede kategorier]].",
        "categoriesfrom": "Vis kategorier startende med:",
        "deletedcontributions": "Slettede brugerbidrag",
        "unwatchthispage": "Fjern overvågning",
        "notanarticle": "Ikke en artikel",
        "notvisiblerev": "Versionen er blevet slettet",
-       "watchlist-details": "Du har {{PLURAL:$1|side|sider}} på din overvågningsliste (uden at medregne diskussionssider).",
+       "watchlist-details": "Du har {{PLURAL:$1|$1 side|$1 sider}} på din overvågningsliste (uden at medregne diskussionssider).",
        "wlheader-enotif": "E-mail-underretning er slået til.",
        "wlheader-showupdated": "Sider, der er ændret siden dit sidste besøg, er vist med '''fed skrift'''.",
        "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",
        "watchlist-hide": "Skjul",
+       "watchlist-submit": "Vis",
        "wlshowtime": "Vis seneste:",
        "wlshowhideminor": "mindre ændringer",
        "wlshowhidebots": "robotter",
        "delete-confirm": "Slet \"$1\"",
        "delete-legend": "Slet",
        "historywarning": "<strong>Advarsel:</strong> Siden du er ved at slette har en historie med $1 {{PLURAL:$1|version|versioner}}:",
+       "historyaction-submit": "Vis",
        "confirmdeletetext": "Du er ved at slette en side sammen med hele dens tilhørende historik.\nBekræft venligst at du virkelig vil gøre dette, at du forstår konsekvenserne, og at du gør det i overensstemmelse med [[{{MediaWiki:Policy-url}}|retningslinjerne]].",
        "actioncomplete": "Gennemført",
        "actionfailed": "Handlingen mislykkedes",
        "revdelete-restricted": "tilføjede begrænsninger for administratorer",
        "revdelete-unrestricted": "fjernede begrænsninger for administratorer",
        "logentry-block-block": "$1 {{GENDER:$2|blokerede}} {{GENDER:$4|$3}} med en udløbstid på $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|ophævede blokering af}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|ændrede}} blokeringsindstillinger for {{GENDER:$4|$3}} med en udløbstid på $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|ændrede}} blokeringsindstillinger for {{GENDER:$4|$3}} med en udløbstid på $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|flyttede}} siden $3 til $4",
        "mw-widgets-titleinput-description-new-page": "side eksisterer ikke endnu",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "api-error-blacklisted": "Vælg venligst en anden, beskrivende titel.",
-       "randomrootpage": "Tilfældig stamside"
+       "randomrootpage": "Tilfældig stamside",
+       "log-action-filter-block": "Blokeringstype:",
+       "log-action-filter-move": "Flyttetype:",
+       "log-action-filter-patrol": "Patruljeringstype:",
+       "log-action-filter-protect": "Beskyttelsestype:",
+       "log-action-filter-block-block": "Blokering",
+       "log-action-filter-block-reblock": "Ændring af blokering",
+       "log-action-filter-delete-delete": "Sidesletning",
+       "log-action-filter-delete-restore": "Sidegendannelse",
+       "log-action-filter-delete-event": "Logsletning",
+       "log-action-filter-delete-revision": "Revisionssletning",
+       "log-action-filter-move-move": "Flytning uden overskrivelse af omdirigeringer",
+       "log-action-filter-move-move_redir": "Flytning med overskrivelse af omdirigeringer",
+       "log-action-filter-patrol-patrol": "Manuel patruljering",
+       "log-action-filter-patrol-autopatrol": "Automatisk patruljering",
+       "log-action-filter-protect-protect": "Beskyttelse",
+       "log-action-filter-protect-modify": "Ændring af beskyttelse",
+       "log-action-filter-protect-unprotect": "Fjernede beskyttelse",
+       "log-action-filter-protect-move_prot": "Flyttede beskyttelse"
 }
index c680d81..be7ed04 100644 (file)
        "tog-ccmeonemails": "Schicke mir Kopien der E-Mails, die ich anderen Benutzern sende",
        "tog-diffonly": "Beim Versionsvergleich nur die Unterschiede und nicht die vollständige Seite anzeigen",
        "tog-showhiddencats": "Versteckte Kategorien anzeigen",
-       "tog-norollbackdiff": "Unterschied nach dem Zurücksetzen unterdrücken",
+       "tog-norollbackdiff": "Unterschied nach dem Zurücksetzen nicht anzeigen",
        "tog-useeditwarning": "Warnen, sofern eine zur Bearbeitung geöffnete Seite verlassen wird, die nicht gespeicherte Änderungen enthält",
        "tog-prefershttps": "Wenn angemeldet, immer eine sichere Verbindung benutzen.",
        "underline-always": "immer",
        "category-empty": "''Diese Kategorie enthält zurzeit keine Seiten oder Medien.''",
        "hidden-categories": "{{PLURAL:$1|Versteckte Kategorie|Versteckte Kategorien}}",
        "hidden-category-category": "Versteckte Kategorien",
-       "category-subcat-count": "{{PLURAL:$2|Diese Kategorie enthält folgende Unterkategorie:|{{PLURAL:$1|Folgende Unterkategorie ist eine von insgesamt $2 Unterkategorien in dieser Kategorie:|Es werden $1 von insgesamt $2 Unterkategorien in dieser Kategorie angezeigt:}}}}",
+       "category-subcat-count": "{{PLURAL:$2|Diese Kategorie enthält folgende Unterkategorie:|{{PLURAL:$1|Folgende Unterkategorie ist eine von insgesamt $2 Unterkategorien in dieser Kategorie:|Es werden $1 von insgesamt $2 Unterkategorien in dieser Kategorie angezeigt.}}}}",
        "category-subcat-count-limited": "Diese Kategorie enthält folgende {{PLURAL:$1|Unterkategorie|$1 Unterkategorien}}:",
        "category-article-count": "{{PLURAL:$2|Diese Kategorie enthält folgende Seite:|{{PLURAL:$1|Folgende Seite ist eine von insgesamt $2 Seiten in dieser Kategorie:|Es werden $1 von insgesamt $2 Seiten in dieser Kategorie angezeigt.}}}}",
        "category-article-count-limited": "Folgende {{PLURAL:$1|Seite ist|$1 Seiten sind}} in dieser Kategorie enthalten:",
        "minoredit": "Nur Kleinigkeiten wurden verändert",
        "watchthis": "Diese Seite beobachten",
        "savearticle": "Seite speichern",
+       "publishpage": "Seite veröffentlichen",
        "preview": "Vorschau",
        "showpreview": "Vorschau zeigen",
        "showdiff": "Änderungen zeigen",
        "blankarticle": "<strong>Warnung:</strong> Die Seite, die du erstellst, ist leer.\nWenn du erneut auf „{{int:savearticle}}“ klickst, wird die Seite ohne Inhalt erstellt.",
        "anoneditwarning": "<strong>Warnung:</strong> Du bist nicht angemeldet. Deine IP-Adresse wird öffentlich sichtbar, falls du Bearbeitungen durchführst. Sofern du dich <strong>[$1 anmeldest]</strong> oder <strong>[$2 ein Benutzerkonto erstellst]</strong>, werden deine Bearbeitungen zusammen mit anderen Beiträgen deinem Benutzernamen zugeordnet.",
        "anonpreviewwarning": "''Du bist nicht angemeldet. Beim Speichern wird deine IP-Adresse in der Versionsgeschichte aufgezeichnet.''",
-       "missingsummary": "'''Hinweis:''' Du hast keine Zusammenfassung angegeben. Wenn du erneut auf „{{int:savearticle}}“ klickst, wird deine Änderung ohne Zusammenfassung übernommen.",
+       "missingsummary": "<strong>Hinweis:</strong> Du hast keine Zusammenfassung angegeben. Wenn du erneut auf „{{int:savearticle}}“ klickst, wird deine Änderung ohne Zusammenfassung übernommen.",
        "selfredirect": "<strong>Warnung:</strong> Du leitest auf diese Seite selbst weiter.\nDu hast vermutlich das falsche Weiterleitungsziel angegeben oder du bearbeitest die falsche Seite.\nWenn du erneut auf „{{int:savearticle}}“ klickst, wird die Weiterleitung dennoch erstellt.",
        "missingcommenttext": "Bitte gib unten einen Kommentar ein.",
        "missingcommentheader": "<strong>Achtung:</strong> Du hast keinen Betreff eingegeben. Wenn du erneut auf „{{int:savearticle}}“ klickst, wird deine Bearbeitung ohne Überschrift gespeichert.",
        "userpage-userdoesnotexist": "Das Benutzerkonto „<nowiki>$1</nowiki>“ ist nicht vorhanden. Bitte prüfe, ob du diese Seite wirklich erstellen/bearbeiten willst.",
        "userpage-userdoesnotexist-view": "Das Benutzerkonto „$1“ ist nicht vorhanden.",
        "blocked-notice-logextract": "{{GENDER:$1|Dieser Benutzer|Diese Benutzerin}} ist zurzeit gesperrt.\nZur Information folgt ein aktueller Auszug aus dem Benutzersperr-Logbuch:",
-       "clearyourcache": "'''Hinweis:''' Leere nach dem Speichern den Browser-Cache, um die Änderungen sehen zu können.\n* '''Firefox/Safari:''' ''Umschalttaste'' drücken und gleichzeitig ''Aktualisieren'' anklicken oder entweder ''Strg+F5'' oder ''Strg+R'' (''⌘+R'' auf dem Mac) drücken\n* '''Google Chrome:''' ''Umschalttaste+Strg+R'' (''⌘+Umschalttaste+R'' auf dem Mac) drücken\n* '''Internet Explorer:''' ''Strg+F5'' drücken oder ''Strg'' drücken und gleichzeitig ''Aktualisieren'' anklicken\n* '''Opera:''' ''Extras → Internetspuren löschen … → Individuelle Auswahl → Den kompletten Cache löschen''",
+       "clearyourcache": "<strong>Hinweis:</strong> Leere nach dem Speichern den Browser-Cache, um die Änderungen sehen zu können.\n* <strong>Firefox/Safari:</strong> <em>Umschalttaste</em> drücken und gleichzeitig <em>Aktualisieren</em> anklicken oder entweder <em>Strg+F5</em> oder <em>Strg+R</em> (<em>⌘+R</em> auf dem Mac) drücken\n* <strong>Google Chrome:</strong> <em>Umschalttaste+Strg+R</em> (<em>⌘+Umschalttaste+R</em> auf dem Mac) drücken\n* <strong>Internet Explorer:</strong> <em>Strg+F5</em> drücken oder <em>Strg</em> drücken und gleichzeitig <em>Aktualisieren</em> anklicken\n* <strong>Opera:</strong> Gehe zu <em>Menü → Einstellungen</em> (<em>Opera → Einstellungen</em> auf dem Mac) und dann auf <em>Datenschutz & Sicherheit → Browserdaten löschen → Gespeicherte Bilder und Dateien</em>.",
        "usercssyoucanpreview": "'''Tipp:''' Benutze den „{{int:showpreview}}“-Button, um dein neues CSS vor dem Speichern zu testen.",
        "userjsyoucanpreview": "'''Tipp:''' Benutze den „{{int:showpreview}}“-Button, um dein neues JavaScript vor dem Speichern zu testen.",
        "usercsspreview": "'''Beachte, dass du nur eine Vorschau deines Benutzer-CSS betrachtest.'''\n'''Es wurde noch nicht gespeichert!'''",
        "editpage-cannot-use-custom-model": "Das Inhaltsmodell dieser Seite kann nicht geändert werden.",
        "longpageerror": "'''Fehler: Der Text, den du zu speichern versuchst, ist {{PLURAL:$1|ein Kilobyte|$1 Kilobyte}} groß. Dies ist größer als das erlaubte Maximum von {{PLURAL:$2|ein Kilobyte|$2 Kilobyte}}.'''\nEr kann nicht gespeichert werden.",
        "readonlywarning": "<strong>Achtung: Die Datenbank wurde für Wartungsarbeiten gesperrt, so dass deine Änderungen derzeit nicht gespeichert werden können.\nSichere den Text bitte lokal auf deinem Computer und versuche zu einem späteren Zeitpunkt, die Änderungen zu übertragen.</strong>\n\nGrund für die Sperre: $1",
-       "protectedpagewarning": "'''Achtung: Diese Seite wurde geschützt. Nur Benutzer mit Administratorrechten können die Seite bearbeiten.'''\nZur Information folgt der aktuelle Logbucheintrag:",
+       "protectedpagewarning": "<strong>Achtung: Diese Seite wurde geschützt. Nur Benutzer mit Administratorrechten können die Seite bearbeiten.</strong>\nZur Information folgt der aktuelle Logbucheintrag:",
        "semiprotectedpagewarning": "'''Halbsperrung:''' Die Seite wurde so geschützt, dass nur registrierte Benutzer diese ändern können.\nZur Information folgt der aktuelle Logbucheintrag:",
        "cascadeprotectedwarning": "<strong>Achtung:</strong> Diese Seite wurde so geschützt, dass sie nur durch Benutzer mit Administratorrechten bearbeitet werden kann. Sie ist in die {{PLURAL:$1|folgende Seite|folgenden Seiten}} eingebunden, die mittels der Kaskadensperroption geschützt {{PLURAL:$1|ist|sind}}:",
        "titleprotectedwarning": "'''Achtung: Die Seitenerstellung wurde so geschützt, dass nur Benutzer mit [[Special:ListGroupRights|speziellen Rechten]] diese Seite erstellen können.'''\nZur Information folgt der aktuelle Logbucheintrag:",
        "permissionserrorstext": "Du bist nicht berechtigt, die Aktion auszuführen. {{PLURAL:$1|Grund|Gründe}}:",
        "permissionserrorstext-withaction": "Du bist aus {{PLURAL:$1|dem folgenden Grund|den folgenden Gründen}} nicht berechtigt, $2:",
        "contentmodelediterror": "Du kannst diese Version nicht bearbeiten, da das Inhaltsmodell <code>$1</code> vom aktuellen Inhaltsmodell der Seite <code>$2</code> abweicht.",
-       "recreate-moveddeleted-warn": "'''Achtung: Du erstellst eine Seite, die bereits früher gelöscht wurde.'''\n\nBitte prüfe sorgfältig, ob die erneute Seitenerstellung den Richtlinien entspricht.\nZu deiner Information folgt das Lösch- und Verschiebungs-Logbuch mit der Begründung für die vorhergehende Löschung:",
+       "recreate-moveddeleted-warn": "<strong>Achtung: Du erstellst eine Seite, die bereits früher gelöscht wurde.</strong>\n\nBitte prüfe sorgfältig, ob die erneute Seitenerstellung den Richtlinien entspricht.\nZu deiner Information folgt das Lösch- und Verschiebungs-Logbuch mit der Begründung für die vorhergehende Löschung:",
        "moveddeleted-notice": "Diese Seite wurde gelöscht. Zur Information folgt das Lösch- und Verschiebungs-Logbuch dieser Seite.",
        "moveddeleted-notice-recent": "Leider wurde diese Seite kürzlich gelöscht (innerhalb der letzten 24 Stunden).\nZur Information wird das Lösch- und Verschiebungs-Logbuch für die Seite unten angezeigt.",
        "log-fulllog": "Alle Logbucheinträge ansehen",
        "upload-form-label-infoform-description-tooltip": "Beschreibe kurz alles bedeutende über das Werk.\nErwähne für ein Foto die abgebildeten hauptsächlichen Dinge, das Ereignis oder den Ort.",
        "upload-form-label-usage-title": "Verwendung",
        "upload-form-label-usage-filename": "Dateiname",
-       "foreign-structured-upload-form-label-own-work": "Dies ist mein eigenes Werk",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorien",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Ich bestätige, dass ich diese Datei gemäß den Nutzungsbedingungen und Lizenzrichtlinien von {{SITENAME}} hochlade.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Wenn du diese Datei nicht unter den Richtlinien von {{SITENAME}} hochladen kannst, schließe bitte diesen Dialog und versuche eine andere Methode.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Du kannst auch [[Special:Upload|die Standard-Hochladeseite]] ausprobieren.",
-       "foreign-structured-upload-form-label-own-work-message-default": "Ich verstehe, dass ich diese Datei auf ein gemeinsames Repositorium hochlade. Ich bestätige, dass ich dies gemäß den dortigen Nutzungs- und Lizenzbedingungen tue.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Falls du diese Datei nicht unter den Bedingungen des gemeinsamen Repositoriums hochladen kannst, schließe bitte diesen Dialog und versuche eine andere Methode.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Du kannst auch [[Special:Upload|die Hochladeseite auf {{SITENAME}}]] ausprobieren, falls diese Datei dort unter ihren Richtlinien hochgeladen werden kann.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Ich bestätige, dass ich das Urheberrecht für diese Datei besitze und stimme unwiderruflich der Veröffentlichung dieser Datei auf Wikimedia Commons unter der Lizenz [https://creativecommons.org/licenses/by-sa/4.0/deed.de „Creative Commons Namensnennung – Weitergabe unter gleichen Bedingungen 4.0 International“] sowie den [https://wikimediafoundation.org/wiki/Terms_of_Use/de Nutzungsbedingungen] zu.",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Falls du nicht das Urheberrecht für diese Datei besitzt oder du diese Datei unter einer anderen Lizenz veröffentlichen möchtest, ziehe [https://commons.wikimedia.org/wiki/Special:UploadWizard den Hochladeassistenten auf Wikimedia Commons] in Erwägung.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Du kannst auch [[Special:Upload|die Hochladeseite auf {{SITENAME}}]] ausprobieren, falls die Website das Hochladen dieser Datei unter ihren Richtlinien erlaubt.",
+       "upload-form-label-own-work": "Dies ist mein eigenes Werk",
+       "upload-form-label-infoform-categories": "Kategorien",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Ich bestätige, dass ich diese Datei gemäß den Nutzungsbedingungen und Lizenzrichtlinien von {{SITENAME}} hochlade.",
+       "upload-form-label-not-own-work-message-local": "Wenn du diese Datei nicht unter den Richtlinien von {{SITENAME}} hochladen kannst, schließe bitte diesen Dialog und versuche eine andere Methode.",
+       "upload-form-label-not-own-work-local-local": "Du kannst auch [[Special:Upload|die Standard-Hochladeseite]] ausprobieren.",
+       "upload-form-label-own-work-message-default": "Ich verstehe, dass ich diese Datei auf ein gemeinsames Repositorium hochlade. Ich bestätige, dass ich dies gemäß den dortigen Nutzungs- und Lizenzbedingungen tue.",
+       "upload-form-label-not-own-work-message-default": "Falls du diese Datei nicht unter den Bedingungen des gemeinsamen Repositoriums hochladen kannst, schließe bitte diesen Dialog und versuche eine andere Methode.",
+       "upload-form-label-not-own-work-local-default": "Du kannst auch [[Special:Upload|die Hochladeseite auf {{SITENAME}}]] ausprobieren, falls diese Datei dort unter ihren Richtlinien hochgeladen werden kann.",
+       "upload-form-label-own-work-message-shared": "Ich bestätige, dass ich das Urheberrecht für diese Datei besitze und stimme unwiderruflich der Veröffentlichung dieser Datei auf Wikimedia Commons unter der Lizenz [https://creativecommons.org/licenses/by-sa/4.0/deed.de „Creative Commons Namensnennung – Weitergabe unter gleichen Bedingungen 4.0 International“] sowie den [https://wikimediafoundation.org/wiki/Terms_of_Use/de Nutzungsbedingungen] zu.",
+       "upload-form-label-not-own-work-message-shared": "Falls du nicht das Urheberrecht für diese Datei besitzt oder du diese Datei unter einer anderen Lizenz veröffentlichen möchtest, ziehe [https://commons.wikimedia.org/wiki/Special:UploadWizard den Hochladeassistenten auf Wikimedia Commons] in Erwägung.",
+       "upload-form-label-not-own-work-local-shared": "Du kannst auch [[Special:Upload|die Hochladeseite auf {{SITENAME}}]] ausprobieren, falls die Website das Hochladen dieser Datei unter ihren Richtlinien erlaubt.",
        "backend-fail-stream": "Die Datei $1 konnte nicht übertragen werden.",
        "backend-fail-backup": "Die Datei $1 konnte nicht gesichert werden.",
        "backend-fail-notexists": "Die Datei $1 ist nicht vorhanden.",
        "changecontentmodel-success-text": "Der Inhaltstyp von [[:$1]] wurde geändert.",
        "changecontentmodel-cannot-convert": "Der Inhalt von [[:$1]] kann nicht zum Typ $2 konvertiert werden.",
        "changecontentmodel-nodirectediting": "Das Inhaltsmodell „$1“ unterstützt keine direkten Bearbeitungen",
+       "changecontentmodel-emptymodels-title": "Keine Inhaltsmodelle verfügbar",
+       "changecontentmodel-emptymodels-text": "Der Inhalt auf [[:$1]] kann zu keinem Typ konvertiert werden.",
        "log-name-contentmodel": "Inhaltsmodell-Änderungs-Logbuch",
        "log-description-contentmodel": "Ereignisse bezüglich den Inhaltsmodellen einer Seite",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|erstellte}} die Seite $3 mit einem Nicht-Standard-Inhaltsmodell „$5“",
        "whatlinkshere-prev": "{{PLURAL:$1|vorheriger|vorherige $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|nächster|nächste $1}}",
        "whatlinkshere-links": "← Links",
-       "whatlinkshere-hideredirs": "Weiterleitungen $1",
-       "whatlinkshere-hidetrans": "Vorlageneinbindungen $1",
-       "whatlinkshere-hidelinks": "Links $1",
-       "whatlinkshere-hideimages": "Dateilinks $1",
+       "whatlinkshere-hideredirs": "Weiterleitungen ausblenden",
+       "whatlinkshere-hidetrans": "Vorlageneinbindungen ausblenden",
+       "whatlinkshere-hidelinks": "Links ausblenden",
+       "whatlinkshere-hideimages": "Dateilinks ausblenden",
        "whatlinkshere-filters": "Filter",
        "whatlinkshere-submit": "Los",
        "autoblockid": "Automatische Sperrung #$1",
        "lockdbsuccesstext": "Die {{SITENAME}}-Datenbank wurde gesperrt.<br />Bitte gib die Datenbank [[Special:UnlockDB|wieder frei]], sobald die Wartung abgeschlossen ist.",
        "unlockdbsuccesstext": "Die {{SITENAME}}-Datenbank wurde freigegeben.",
        "lockfilenotwritable": "Die Datenbank-Sperrdatei ist nicht beschreibbar. Zum Sperren oder Freigeben der Datenbank muss diese für den Webserver beschreibbar sein.",
+       "databaselocked": "Die Datenbank ist bereits gesperrt.",
        "databasenotlocked": "Die Datenbank ist nicht gesperrt.",
        "lockedbyandtime": "(von $1 am $2 um $3 Uhr)",
        "move-page": "Verschieben von „$1“",
        "movepagetext": "Mit untenstehendem Formular kannst du eine Seite umbenennen, indem du sie mitsamt allen Versionen auf einen neuen Titel verschiebst.\nDer alte Titel wird danach zum neuen weiterleiten.\nDu kannst Weiterleitungen, die auf den Originaltitel verlinken, automatisch korrigieren lassen.\nStelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|defekten Weiterleitungen]] überprüfst.\nDu bist dafür verantwortlich, dass Links weiterhin auf das korrekte Ziel verweisen.\n\nDie Seite wird <strong>nicht</strong> verschoben, sofern es bereits eine Seite mit dem vorgesehenen Titel gibt, es sei denn, letztere ist eine Weiterleitung ohne Versionsgeschichte.\nDies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine existierende Seite überschreiben.\n\n<strong>Hinweis:</strong>\nDie Verschiebung kann weitreichende und unerwartete Folgen für häufig besuchte Seiten haben.\nDu solltest daher die Konsequenzen verstanden haben, bevor du jetzt fortfährst.",
        "movepagetext-noredirectfixer": "Mit untenstehendem Formular kannst du eine Seite umbenennen, indem du sie mitsamt allen Versionen auf einen neuen Titel verschiebst.\nDer alte Titel wird danach zum neuen weiterleiten.\nStelle sicher, dass du im Anschluss alle [[Special:DoubleRedirects|doppelten]] oder [[Special:BrokenRedirects|defekten Weiterleitungen]] überprüfst.\nDu bist dafür verantwortlich, dass Links weiterhin auf das korrekte Ziel verweisen.\n\nDie Seite wird <strong>nicht</strong> verschoben, sofern es bereits eine Seite mit dem vorgesehenen Titel gibt, es sei denn, diese ist eine Weiterleitung ohne Versionsgeschichte.\nDies bedeutet, dass du die Umbenennung rückgängig machen kannst, sofern du einen Fehler gemacht hast. Du kannst hingegen keine existierende Seite überschreiben.\n\n<strong>Hinweis:</strong>\nDie Verschiebung kann weitreichende und unerwartete Folgen für häufig besuchte Seiten haben.\nDu solltest daher die Konsequenzen verstanden haben, bevor du jetzt fortfährst.",
        "movepagetalktext": "Falls du dieses Kästchen aktivierst, wird die dazugehörige Diskussionsseite automatisch auf den neuen Titel verschoben, sofern nicht bereits eine nicht-leere Diskussionsseite dort vorhanden ist.\n\nIn diesem Fall musst du die Seite manuell verschieben oder zusammenführen, falls erforderlich.",
-       "moveuserpage-warning": "'''Warnung:''' Du bist dabei, eine Benutzerseite zu verschieben. Bitte bedenke, dass dadurch nur die Benutzerseite verschoben, '''nicht''' aber der Benutzer umbenannt wird.",
+       "moveuserpage-warning": "<strong>Warnung:</strong> Du bist dabei, eine Benutzerseite zu verschieben. Bitte bedenke, dass dadurch nur die Benutzerseite verschoben, <em>nicht</em> aber der Benutzer umbenannt wird.",
        "movecategorypage-warning": "<strong>Warnung:</strong> Du bist gerade dabei, eine Kategorieseite zu verschieben. Bitte sei dir bewusst, dass nur die Seite verschoben wird. Alle der alten Kategorie zugeordneten Seiten werden <em>nicht</em> neu kategorisiert.",
        "movenologintext": "Du musst ein registrierter Benutzer und [[Special:UserLogin|angemeldet]] sein, um eine Seite zu verschieben.",
        "movenotallowed": "Du hast nicht die erforderliche Berechtigung, um Seiten verschieben zu können.",
        "imageinvalidfilename": "Der Ziel-Dateiname ist ungültig",
        "fix-double-redirects": "Nach dem Verschieben alle Weiterleitungen auf die Ursprungsseite bereinigen",
        "move-leave-redirect": "Weiterleitung erstellen",
-       "protectedpagemovewarning": "'''Warnung:''' Diese Seite wurde so geschützt, dass sie nur von Benutzern mit Administratorenrechten verschoben werden kann.\nZur Information folgt der aktuelle Logbucheintrag:",
+       "protectedpagemovewarning": "<strong>Warnung:</strong> Diese Seite wurde so geschützt, dass sie nur von Benutzern mit Administratorenrechten verschoben werden kann.\nZur Information folgt der aktuelle Logbucheintrag:",
        "semiprotectedpagemovewarning": "'''Hinweis:''' Diese Seite wurde so geschützt, dass sie nur von angemeldeten Benutzern verschoben werden kann.\nZur Information folgt der aktuelle Logbucheintrag:",
        "move-over-sharedrepo": "[[:$1]] existiert in einem gemeinsam genutzten Repositorium. Das Verschieben einer Datei zu diesem Titel überschreibt die gemeinsam genutzte Datei.",
        "file-exists-sharedrepo": "Der gewählte Dateiname wird bereits in einem gemeinsam genutzten Repositorium verwendet.\nBitte wähle einen anderen Namen.",
        "tooltip-ca-nstab-category": "Kategorieseite anzeigen",
        "tooltip-minoredit": "Diese Änderung als klein markieren.",
        "tooltip-save": "Änderungen speichern",
+       "tooltip-publish": "Deine Änderungen veröffentlichen",
        "tooltip-preview": "Vorschau der Änderungen an dieser Seite. Bitte vor dem Speichern benutzen!",
        "tooltip-diff": "Änderungen am Text zeigen",
        "tooltip-compareselectedversions": "Unterschied zwischen zwei ausgewählten Versionen dieser Seite anzeigen",
        "filedelete-archive-read-only": "Das Archiv-Verzeichnis „$1“ ist für den Webserver nicht beschreibbar.",
        "previousdiff": "← Zum vorherigen Versionsunterschied",
        "nextdiff": "Zum nächsten Versionsunterschied →",
-       "mediawarning": "'''Warnung:''' Dieser Dateityp kann böswilligen Programmcode enthalten.\nDurch das Herunterladen und Öffnen der Datei kann dein Computer beschädigt werden.",
+       "mediawarning": "<strong>Warnung:</strong> Dieser Dateityp kann böswilligen Programmcode enthalten.\nDurch das Herunterladen und Öffnen der Datei kann dein Computer beschädigt werden.",
        "imagemaxsize": "Maximale Bildgröße:<br />''(für Dateibeschreibungsseiten)''",
        "thumbsize": "Standardgröße der Vorschaubilder:",
        "widthheightpage": "$1 × $2, {{PLURAL:$3|1 Seite|$3 Seiten}}",
        "feedback-useragent": "User Agent:",
        "searchsuggest-search": "Suchen",
        "searchsuggest-containing": "enthält …",
+       "api-error-autoblocked": "Deine IP-Adresse wurde automatisch gesperrt, da sie von einem gesperrten Benutzer verwendet wurde.",
        "api-error-badaccess-groups": "Du hast nicht die Berechtigung Dateien in dieses Wiki hochzuladen.",
        "api-error-badtoken": "Interner Fehler: Der Token ist fehlerhaft.",
+       "api-error-blocked": "Du wurdest für das Bearbeiten gesperrt.",
        "api-error-copyuploaddisabled": "Das Hochladen via URL wurde auf diesem Server deaktiviert.",
        "api-error-duplicate": "Es gibt im Wiki bereits {{PLURAL:$1|eine andere Datei|mehrere andere Dateien}} gleichen Inhalts.",
        "api-error-duplicate-archive": "Es {{PLURAL:$1|war bereits eine andere Datei|waren bereits andere Dateien}} gleichen Inhalts vorhanden. Sie {{PLURAL:$1|wurde|wurden}} allerdings gelöscht.",
        "api-error-nomodule": "Interner Fehler: Es wurde kein Modul zum Hochladen festgelegt.",
        "api-error-ok-but-empty": "Interner Fehler: Der Server reagiert nicht.",
        "api-error-overwrite": "Das Überschreiben einer vorhandenen Datei ist nicht erlaubt.",
+       "api-error-ratelimited": "Du versuchst, mehr Dateien in kurzer Zeit hochzuladen, als dieses Wiki erlaubt.\nBitte versuche es in einigen Minuten erneut.",
        "api-error-stashfailed": "Interner Fehler: Der Server konnte keine temporäre Datei speichern.",
        "api-error-publishfailed": "Interner Fehler: Der Server konnte die temporäre Datei nicht veröffentlichen.",
        "api-error-stasherror": "Beim Hochladen der Datei gab es einen Fehler.",
index 9aac75d..3578658 100644 (file)
@@ -22,7 +22,8 @@
                        "아라",
                        "Calak",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Kumkumuk"
                ]
        },
        "tog-underline": "Bınê gırey de xete bance:",
        "hidden-category-category": "Kategoriyê nımıtey",
        "category-subcat-count": "{{PLURAL:$2|Na kategoriya de $1 bınkategoriyay estê.|$2 kategoriyan ra $1 bınkategoriyay asenê.}}",
        "category-subcat-count-limited": "Na kategoriye de {{PLURAL:$1|ena kategoriya bınêne esta|enê $1 kategoriyê bınêni estê}}.",
-       "category-article-count": "{{PLURAL:$2|Na kategoriye de teyna ena pele esta.|Na kategoriye de $2 ra pêro pia, {{PLURAL:$1|ena pele esta|enê $1 peli estê.}}, be $2 ra pêro pia}}",
+       "category-article-count": "{{PLURAL:$2|Na kategoriye de teyna ena pele esta.|Ebe $2 ra pêro piya {{PLURAL:$1|ena pela na kategoriye dera|$1 enê peli na kategoriye derê.}}",
        "category-article-count-limited": "{{PLURAL:$1|Pela cêrêne|$1 Pelê cêrêni}} na kategoriye derê.",
        "category-file-count": "<noinclude>{{PLURAL:$2|Na kategoriye tenya dosyayanê cêrênan muhtewa kena.}}</noinclude>\n*Na kategoriye de $2 dosyayan ra {{PLURAL:$1|yew dosya tenêka esta| $1 dosyey asenê}}.",
        "category-file-count-limited": "{{PLURAL:$1|Dosya cêrêne|$1 Dosyê cêrêni}} na kategoriye derê.",
        "unprotectthispage": "Starkerdışe ena peler bıvurne",
        "newpage": "Pela newiye",
        "talkpage": "Ena pele sero werêne",
-       "talkpagelinktext": "Werênayış",
+       "talkpagelinktext": "werênayış",
        "specialpage": "Pela xısusiye",
        "personaltools": "Hacetê şexsiy",
        "articlepage": "Pela zerreki bıvêne",
        "toc": "Sernameyê meselan",
        "showtoc": "bımocne",
        "hidetoc": "bınımne",
-       "collapsible-collapse": "Kılm ke",
+       "collapsible-collapse": "Teng ke",
        "collapsible-expand": "Hera ke",
        "confirmable-confirm": "{{GENDER:$1|Şıma }} do emeli?",
        "confirmable-yes": "Eya",
        "wrongpassword": "Parola ğeleta. Rêna / fına bıcerrebne .",
        "wrongpasswordempty": "Parola tola, venga. tekrar bınuse.",
        "passwordtooshort": "Paroley gani tewr senık be {{PLURAL:$1|1 karakter|$1 karakteran}} derg bê.",
+       "passwordtoolong": "Paroleyi be {{PLURAL:$1|1 karakter|$1 karakteran}} ra derg nêbenê.",
        "password-name-match": "Parola u nameyê şıma gani zeypê (seypê) nêbo.",
        "password-login-forbidden": "Nameyê nê karberi û gurenayışê parola biyo qedeğen.",
        "mailmypassword": "Parola reset ke",
        "resetpass_submit": "Parola eyar kere u newe ra dekewe",
        "changepassword-success": "Parola şıma be serkewtış vuriye!",
        "changepassword-throttled": "Şıma zaf ronıştış akerdış ke.Kerem ke verdi dekewten $1 bıpawe.",
+       "botpasswords-label-appid": "Nameyê boti:",
+       "botpasswords-label-create": "Vıraze",
+       "botpasswords-label-update": "Rocane ke",
        "botpasswords-label-cancel": "Bıtexelne",
        "botpasswords-label-delete": "Bestere",
+       "botpasswords-label-resetpassword": "Parola raçarne",
+       "botpasswords-label-grants-column": "Daye",
        "resetpass_forbidden": "parolayi nêvuryayi",
        "resetpass-no-info": "şıma gani hesab akere u hona bıeşke bırese cı",
        "resetpass-submit-loggedin": "Parola bıvurne",
        "userinvalidcssjstitle": "'''Teme:''' Mewzuyê \"$1\" çıniyo.\nDosyanê be namey .css u .js'i de herfa werdiye bıgurêne, mesela herında {{ns:user}}:Foo/Vector.css'i de {{ns:user}}:Foo/vector.css bınuse.",
        "updated": "(Rozeneya)",
        "note": "'''Not:'''",
-       "previewnote": "'''Xo vira mekerê ke ena yew verqayta.'''\nVurnayışê şıma hona qeyd nêbiyo!",
+       "previewnote": "'''Şıma bızanê ke eno yew verqayto.'''\nVurnayışê şıma hewna qeyd nêbiyê!",
        "continue-editing": "Şo herunda vurnayışi",
        "previewconflict": "No seyrkerdışê verqaydi serê qutiyê nuşte tezim kerdış de yo, eke şıma qayile vurnayişê maddeyi seyino bıvini, no mocneno şıma.",
        "session_fail_preview": "Ma ef kere. Vindibiyayişê tayê datay ra a kerdışê hesabê şıma de ma vurnayişê şıma qayd nêkerd. Newe ra tesel (cereb) bıkere. Eke no qayde zi nêbo, [[Special:UserLogout|hesabê xo bıqefelne]] u newera a kere.",
        "undo-summary-username-hidden": "Rewizyona veri $1'i hewada",
        "cantcreateaccounttitle": "Nêşenay hesab rakerê",
        "cantcreateaccount-text": "Hesabvıraştışê na IP adrese ('''$1''') terefê [[User:$3|$3]] kılit biyo.\n\nSebebo ke terefê $3 ra diyao ''$2''",
-       "viewpagelogs": "Heqa na pele de qeydan bıvêne",
+       "viewpagelogs": "Seba na pele rê qeydan bımocne",
        "nohistory": "Verê vurnayışanê na pele çıniyo.",
        "currentrev": "Çımraviyarnayışo rocane",
        "currentrev-asof": "Revizyonanê peniyan, tarixê $1",
        "prefs-help-signature": "Peran de vatenana de vatışi\"<nowiki>~~~~</nowiki>\" ya do imza bé, no bahdo beno çerğé imza u wahdey zemani",
        "badsig": "Îmzayê tu raşt niyo.\nEtiketê HTMLî kontrol bike.",
        "badsiglength": "İmzaya şıma zaf derga.\nA gani be $1 {{PLURAL:$1|karakter|karakteran}} ra zêde mebo.",
-       "yourgender": "Çıçiy cı esto?",
+       "yourgender": "Şeklê xitabi?",
        "gender-unknown": "Ez detay nivana",
        "gender-male": "Perané wiki camérd deyne ezo vırnena",
        "gender-female": "Perané wiki cıni deyne eza vırnena",
        "recentchanges-legend-plusminus": "''(±123)''",
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata vurnayışiyê asenê (tewr vêşi <strong>$1</strong> asenê).",
        "rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
-       "rcshowhideminor": "Vurnayışanê werdiyan $1",
+       "rcshowhideminor": "vurnayışê werdiyi $1",
        "rcshowhideminor-show": "Bımocne",
        "rcshowhideminor-hide": "Bınımne",
-       "rcshowhidebots": "Botan $1",
+       "rcshowhidebots": "botan $1",
        "rcshowhidebots-show": "Bımocne",
        "rcshowhidebots-hide": "Bınımne",
-       "rcshowhideliu": "Karberanê qeydbiyayeyan $1",
+       "rcshowhideliu": "karberê qeydbiyayeyi $1",
        "rcshowhideliu-show": "Bımocne",
        "rcshowhideliu-hide": "Bınımne",
-       "rcshowhideanons": "Karberanê bênameyan $1",
+       "rcshowhideanons": "karberê bênameyi $1",
        "rcshowhideanons-show": "Bımocne",
        "rcshowhideanons-hide": "Bınımne",
        "rcshowhidepatr": "$1 vurnayışê ke dewriya geyrayê",
        "rcshowhidepatr-show": "Bımocne",
        "rcshowhidepatr-hide": "Bınımne",
-       "rcshowhidemine": "Vurnayışanê mı $1",
+       "rcshowhidemine": "vurnayışanê mı $1",
        "rcshowhidemine-show": "Bımocne",
        "rcshowhidemine-hide": "Bınımne",
+       "rcshowhidecategorization": "kategorizasyonê pele $1",
        "rcshowhidecategorization-show": "Bımocne",
        "rcshowhidecategorization-hide": "Bınımne",
        "rclinks": "Peyniya $2 rocan de $1 vurnayışan bımocne <br />$3",
        "upload-form-label-infoform-description": "Şınasnayış",
        "upload-form-label-usage-title": "Gurenayış",
        "upload-form-label-usage-filename": "Nameyê dosya",
-       "foreign-structured-upload-form-label-own-work": "No karê mıno",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategoriyi",
-       "foreign-structured-upload-form-label-infoform-date": "Tarix",
+       "upload-form-label-own-work": "No karê mıno",
+       "upload-form-label-infoform-categories": "Kategoriyi",
+       "upload-form-label-infoform-date": "Tarix",
        "backend-fail-stream": "$1 nê vırazeyê",
        "backend-fail-backup": "$1 nê wendeyê",
        "backend-fail-notexists": "Dosyaya $1 çıniya.",
        "randomredirect-nopages": "Cayê nameyê \"$1\" de serşıkıtışi çıniyê.",
        "statistics": "İstatistiki",
        "statistics-header-pages": "İstatistikê pele",
-       "statistics-header-edits": "Îstatistikê vurnayîşî",
+       "statistics-header-edits": "İstatistikê vurnayışan",
        "statistics-header-users": "İstatistikê karberi",
-       "statistics-header-hooks": "Îstatistiksê binî",
+       "statistics-header-hooks": "Yewbina istatistiki",
        "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",
        "statistics-edits": "{{SITENAME}} saz kerdış ra hetana newke amora vırnayışan",
        "statistics-edits-average": "Her pele sero nısbi vurnayış",
-       "statistics-users": "Qeyd biye [[Special:ListUsers|karberî]]",
+       "statistics-users": "[[Special:ListUsers|Karber]]ê qeydıni",
        "statistics-users-active": "Karberê aktifi",
        "statistics-users-active-desc": "{{PLURAL:$1|roco peyin de|$1 roco peyin de}} karber ê ke kar kerdê.",
        "pageswithprop": "Peli be yew xısusiyetê pele",
        "listgrouprights-group": "Grube",
        "listgrouprights-rights": "Heqqî",
        "listgrouprights-helppage": "Help:Heqqanê gruban",
-       "listgrouprights-members": "(listey ezayan)",
+       "listgrouprights-members": "[lista ezayan]",
        "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|Grube|Gruban}} cı kerê: $1",
        "watchlist-details": "{{PLURAL:$1|$1 pele|$1 peleyan}} listeyê seyr-kerdışi şıma dı, peleyanê vurnayışi dahil niyo.",
        "wlheader-enotif": "E-mail xeber dayiş abiyo.",
        "wlheader-showupdated": "ziyaretê şıma ye peyini de vuryayişê peli pê '''nuşteyo qalıni''' mocyayo.",
-       "wlnote": "$3 seate u bahde $4 deqa dıma {{PLURAL:$2|ju seate dı|'''$2''' ju seate dı}} {{PLURAL:$1|vurnayışe peyeni|vurnayışe '''$1''' peyeni}} cêrdeyê",
+       "wlnote": "$3 saete $4 ra dıme {{PLURAL:$2|yew saete de|'''$2''' saetan de}} {{PLURAL:$1|vurnayışo peyên|vurnayışê '''$1''' peyêni}} cêrderê.",
        "wlshowlast": "Peyni de vurnayışan ra  $1 seata u $2 roca  bımocnê",
        "watchlist-hide": "Bınımne",
        "wlshowtime": "Peyênan bımocne:",
        "wlshowhideanons": "karberê anonimi",
        "wlshowhidepatr": "vurnayışê pawıteyi",
        "wlshowhidemine": "vurnayışê mı",
+       "wlshowhidecategorization": "kategorizasyonê pele",
        "watchlist-options": "Tercihê liste da seyri",
        "watching": "Seyr ke...",
        "unwatching": "Seyr meke...",
        "changecontentmodel-title-label": "Sernameyê pele",
        "changecontentmodel-model-label": "Modelê zerrekiyo newe",
        "changecontentmodel-reason-label": "Sebeb:",
+       "log-name-contentmodel": "Qeydê vurnayışanê modelê zerreki",
        "protectlogpage": "Qeydê staryayan",
        "protectlogtext": "Şıma vurnayişê gırewtışê/wedarnayışê pawıtişi vinenê.\nQey malumato ziyede [[Special:ProtectedPages|Peleyê ke star biye]] bewni rê êna .",
        "protectedarticle": "\"[[$1]]\" kılit biyo",
        "undelete": "Peleyê ke besterneyayê enê bımocnê",
        "undeletepage": "bıewn revizyonê peli yê hewn a şiyayeyan u tepiya biyar",
        "undeletepagetitle": "'''pelo [[:$1|$1]] cêrın, wayirê revizyonê hewn a şiyayeyan o'''.",
-       "viewdeletedpage": "bıewn pelê hewn a şiyayeyani",
+       "viewdeletedpage": "Pelanê esteriyayeyan bımocne",
        "undeletepagetext": "{{PLURAL:$1|pelo|$1 pelo}} cerın hewn a şiyo labele hema zi arşiv de yo u tepiya geriyeno.\nArşiv daimi pak beno.",
        "undelete-fieldset-title": "revizyonan tepiya bar ker",
        "undeleteextrahelp": "Qey ardışê pel u verê pelani tuşê '''tepiya biya!'''yi bıtıknê. qey ciya ciya ardışê verê pelani zi qutiye tesdiqi nişane kerê u tuşê '''tepiya biya!'''yi bıtıknê '''''{{int:undeletebtn}}'''''.. qey hewn a kerdışê qutiya tesdiqan u qey sıfır kerdışê cayê sebebani zi tuşê '''agêr caverd/aça ker'''i bıtıknê '''''{{int:undeletebtn}}'''''..",
        "sp-contributions-newbies": "Tenya iştıraqanê karberanê neweyan bımocne",
        "sp-contributions-newbies-sub": "Qe hesebê newe",
        "sp-contributions-newbies-title": "Îştîrakê karberî ser hesabê neweyî",
-       "sp-contributions-blocklog": "Qeydê blokey",
+       "sp-contributions-blocklog": "qeydê kılitbiyayeyi",
        "sp-contributions-deleted": "iştırakê karberi esterdi",
        "sp-contributions-uploads": "barkerdey",
        "sp-contributions-logs": "qeydi",
        "whatlinkshere-prev": "{{PLURAL:$1|veror|veror $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|verni|verni $1}}",
        "whatlinkshere-links": "← gırey",
-       "whatlinkshere-hideredirs": "Hetenayışê $1",
-       "whatlinkshere-hidetrans": "Açarnayışê $1",
-       "whatlinkshere-hidelinks": "Greyê $1",
+       "whatlinkshere-hideredirs": "Hetenayışan bınımne",
+       "whatlinkshere-hidetrans": "Gırêyanê açarnayışan bınımne",
+       "whatlinkshere-hidelinks": "Gırêyan bınımne",
        "whatlinkshere-hideimages": "Gıreyê dosya $1",
        "whatlinkshere-filters": "Avrêci",
        "autoblockid": "Otomatik vındarnayış #$1",
        "contribslink": "iştıraqi",
        "emaillink": "e-poste bırışe",
        "autoblocker": "Şıma otomatikmen kılit biy, çıke adresa şımaya ''IP''y terefê \"[[User:$1|$1]]\" gureniyena.\nSebebê kılitbiyayışê $1'i \"$2\"o",
-       "blocklogpage": "Qeydê bloqi",
+       "blocklogpage": "Qeydê astengi",
        "blocklog-showlog": "verniyê no/na karberi cıwa ver geriyayo/ya.",
        "blocklog-showsuppresslog": "verniyê no/na karberi cıwa ver geriyayo/ya.",
        "blocklogentry": "[[$1]] biyo bloqe, sebeb: $3, hetana $2 do bıramo.",
        "import-options-wrong": "{{PLURAL:$2|Weçenego|Weçenego}} xerpiyaye: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Sernuştey ena pela reçey cı raverde niyo.",
        "import-rootpage-nosubpage": "Qan de bınnaman reçe de \"$1\" re mısade nedano.",
-       "importlogpage": "Defterê seyırio idxal",
+       "importlogpage": "Qeydê ragozi",
        "importlogpagetext": "wiki yo ke nişane biyo tera kırıştışê zerredayişi nêbeno.",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|çımraviyarnayış|çımraviyarnayışi}}",
        "import-logentry-interwiki-detail": "$2 ra $1 {{PLURAL:$1|çımraviyarnayış|çımraviyarnayışi}}",
        "patrol-log-page": "Qeydé çımsernayoğan",
        "patrol-log-header": "Ena listeyê logi revizyonê devriyeyi mocneno.",
        "log-show-hide-patrol": "Qeydé Çımsernayoğan $1",
+       "log-show-hide-tag": "$1 qeydê etiketi",
        "deletedrevision": "Veriyono kihan $1 wederna",
        "filedeleteerror-short": "Wedarnayişê dosya de ğelati esto: $1",
        "filedeleteerror-long": "Eka dosya wedarnayişi de ğeleti biyê:\n\n$1",
        "exif-urgency-low": "($1) Kemiyo",
        "exif-urgency-high": "( $1 ) Vêşiyo",
        "exif-urgency-other": "Sıftê  şınasiya karberi ($1)",
-       "namespacesall": "pêro",
+       "namespacesall": "pêron",
        "monthsall": "pêro",
        "confirmemail": "Adresê e-posta tesdiq ker",
        "confirmemail_noemail": "Yew emaîlê tu raştîyê çin o ke [[Special:Preferences|tercihê karberî]] ayar bike.",
        "logentry-rights-rights-legacy": "$1 qandê $3 rê ezayiya grube {{GENDER:$2|vuriye}}",
        "logentry-rights-autopromote": "$1 otomatikmen $4 ra $5 {{GENDER:$2|terfi bi}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|bar kerd}} $3",
+       "log-name-managetags": "Qeydê idareyê etiketi",
+       "log-name-tag": "Qeydê etiketi",
        "rightsnone": "(çıniyo)",
        "revdelete-summary": "kılmvatışê vuriyayişi",
        "feedback-adding": "Pela rê peyxeberdar defêno...",
index 51104de..29c1cc1 100644 (file)
        "morenotlisted": "यो सूची पूरा नाइँ हो ।",
        "mypage": "पानो",
        "mytalk": "मेरी कुरडी",
-       "anontalk": "यà¥\88 à¤\86à¤\87. à¤ªà¥\80. à¤\95ा à¤¬à¤¾à¤°à¥\87मà¥\80 à¤\95à¥\81रडà¥\80 à¤\97र",
+       "anontalk": "à¤\95à¥\81रडà¥\80",
        "navigation": "खोज",
        "and": "&#32;र",
        "qbfind": "तम जाण",
index 5b96993..6d198c2 100644 (file)
@@ -46,7 +46,8 @@
                        "Giorgos456",
                        "SucreRouge",
                        "Gts-tg",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Αντιγόνη"
                ]
        },
        "tog-underline": "Υπογράμμιση συνδέσμων:",
        "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": "Εάν δεν είστε σε θέση να ανεβάσετε αυτό το αρχείο στο πλαίσιο των πολιτικών της shared repository, παρακαλώ κλείστε αυτό το παράθυρο διαλόγου και να επιχειρήσετε μια άλλη μέθοδος.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Επίσης, μπορεί να θέλετε να δοκιμάσετε χρησιμοποιώντας το [[Special:Upload|τη σελίδα ανεβάσματος για το {{SITENAME}}]], αν αυτό το αρχείο μπορεί να φορτωθεί κάτω σύμφωνα με τις πολιτικές τους.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Δηλώνω ότι κατέχω τα πνευματικά δικαιώματα για αυτό το αρχείο, και συμφωνώ αμετάκλητα στην απελευθέρωση  αυτού του  αρχείου στο Wikimedia Commons με άδεια  [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 Οδηγό Ανεβάσματος των Wikimedia Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Επίσης, μπορεί να θέλετε να δοκιμάσετε να χρησιμοποιήσετε  το [[Special:Upload|τη σελίδα ανεβάσματος για το {{SITENAME}}]], αν αυτό το αρχείο μπορεί να φορτωθεί σύμφωνα με  τις πολιτικές τους.",
+       "upload-form-label-own-work": "Αυτό είναι το δικό μου έργο",
+       "upload-form-label-infoform-categories": "Κατηγορίες",
+       "upload-form-label-infoform-date": "Ημερομηνία",
+       "upload-form-label-own-work-message-local": "Επιβεβαιώνω ότι επιφορτώνω  αυτό το αρχείο κατά τους όρους της υπηρεσίας και πολιτικές αδειοδότησης για τον ιστότοπο {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Εάν δεν είστε σε θέση να ανεβάσετε αυτό το αρχείο στο πλαίσιο των πολιτικών της  {{SITENAME}}, παρακαλώ κλείστε αυτό το παράθυρο διαλόγου και να επιχειρήσετε μια άλλη μέθοδος.",
+       "upload-form-label-not-own-work-local-local": "Επίσης, μπορεί να θέλετε να δοκιμάσετε [[Special:Upload|την προεπιλεγμένη σελίδα επιφόρτωσης]].",
+       "upload-form-label-own-work-message-default": "Καταλαβαίνω ότι είμαι φόρτωμα αυτό το αρχείο σε ένα κοινόχρηστο αρχείο. Επιβεβαιώνω ότι είμαι τόσο ακόλουθες τους όρους της υπηρεσίας και πολιτικές αδειοδότησης.",
+       "upload-form-label-not-own-work-message-default": "Εάν δεν είστε σε θέση να ανεβάσετε αυτό το αρχείο στο πλαίσιο των πολιτικών της shared repository, παρακαλώ κλείστε αυτό το παράθυρο διαλόγου και να επιχειρήσετε μια άλλη μέθοδος.",
+       "upload-form-label-not-own-work-local-default": "Επίσης, μπορεί να θέλετε να δοκιμάσετε χρησιμοποιώντας το [[Special:Upload|τη σελίδα ανεβάσματος για το {{SITENAME}}]], αν αυτό το αρχείο μπορεί να φορτωθεί κάτω σύμφωνα με τις πολιτικές τους.",
+       "upload-form-label-own-work-message-shared": "Δηλώνω ότι κατέχω τα πνευματικά δικαιώματα για αυτό το αρχείο, και συμφωνώ αμετάκλητα στην απελευθέρωση  αυτού του  αρχείου στο Wikimedia Commons με άδεια  [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], και συμφωνώ με την [https://wikimediafoundation.org/wiki/Terms_of_Use Όρους Χρήσης].",
+       "upload-form-label-not-own-work-message-shared": "Αν δεν κατέχει τα πνευματικά δικαιώματα για αυτό το αρχείο, ή επιθυμείτε να το δημοσιεύσετε υπό μια διαφορετική άδεια χρήσης, μπορείτε να χρησιμοποιήσετε τον [https://commons.wikimedia.org/wiki/Special:UploadWizard Οδηγό Ανεβάσματος των Wikimedia Commons].",
+       "upload-form-label-not-own-work-local-shared": "Επίσης, μπορεί να θέλετε να δοκιμάσετε να χρησιμοποιήσετε  το [[Special:Upload|τη σελίδα ανεβάσματος για το {{SITENAME}}]], αν αυτό το αρχείο μπορεί να φορτωθεί σύμφωνα με  τις πολιτικές τους.",
        "backend-fail-stream": "Αδύνατη η μετάδοση του αρχείου $1.",
        "backend-fail-backup": "Αδύνατη η δημιουργία αντίγραφου ασφαλείας του αρχείου $1.",
        "backend-fail-notexists": "Το αρχείο $1 δεν υπάρχει.",
        "wantedtemplates": "Ζητούμενα πρότυπα",
        "mostlinked": "Σελίδες με τους περισσότερους συνδέσμους προς αυτές",
        "mostlinkedcategories": "Κατηγορίες με τους περισσότερους συνδέσμους προς αυτές",
-       "mostlinkedtemplates": "ΣελίδεÏ\82 Ï\80οÏ\85 Î­Ï\87οÏ\85ν ÎµÎ½Ï\83Ï\89μαÏ\84Ï\89θεί Ï\80εÏ\81ιÏ\83Ï\83Ï\8cÏ\84εÏ\81ο Î±Ï\80Ï\8c Ï\8cλεÏ\82 Ï\84ιÏ\82 Î¬Î»Î»ες",
+       "mostlinkedtemplates": "ΠεÏ\81ιÏ\83Ï\83Ï\8cÏ\84εÏ\81ο ÎµÎ½Ï\83Ï\89μαÏ\84Ï\89μένεÏ\82 Ï\83ελίδες",
        "mostcategories": "Σελίδες με τις περισσότερες κατηγορίες",
        "mostimages": "Αρχεία με τους περισσότερους συνδέσμους προς αυτά",
        "mostinterwikis": "Σελίδες με τους περισσότερους διαγλωσσικούς συνδέσμους",
        "apisandbox-dynamic-parameters-add-placeholder": "Ονομασία παραμέτρου",
        "apisandbox-dynamic-error-exists": "Η παράμετρος με την ονομασία \"$1\" υπάρχει ήδη",
        "apisandbox-submit-invalid-fields-title": "Κάποια από τα πεδία δεν είναι έγκυρα",
-       "apisandbox-submit-invalid-fields-message": "ΠαÏ\81ακαλÏ\8e Î´Î¹Î¿Ï\81θÏ\8eÏ\83Ï\84ε Ï\84α Ï\83ημειÏ\89μένα Ï\80εδία ÎºÎ±Î¹ Ï\80Ï\81οÏ\83Ï\80αθείστε ξανά.",
+       "apisandbox-submit-invalid-fields-message": "ΠαÏ\81ακαλÏ\8e Î´Î¹Î¿Ï\81θÏ\8eÏ\83Ï\84ε Ï\84α Ï\83ημειÏ\89μένα Ï\80εδία ÎºÎ±Î¹ Ï\80Ï\81οÏ\83Ï\80αθήστε ξανά.",
        "apisandbox-results": "Αποτελέσματα",
        "apisandbox-sending-request": "Αποστολή αιτήματος API...",
        "apisandbox-loading-results": "Λήψη αποτελεσμάτων API...",
        "logentry-protect-protect": "$1 {{GENDER:$2|προστατευμένος|προστατευμένη}} $3 $4",
        "logentry-protect-modify": "$1 {{GENDER:$2|άλλαξε}} επίπεδο προστασίας για $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|άλλαξε}} επίπεδο προστασίας για $3 $4 [διαδοχική]",
-       "logentry-rights-rights": "{{GENDER:$2|Ο|Η}} $1 άλλαξε την ιδιότητα μέλους ομάδας για {{GENDER:$3|τον|την}} $3 από $4 σε $5",
+       "logentry-rights-rights": "{{GENDER:$2|Ο|Η}} $1 άλλαξε την ιδιότητα μέλους ομάδας για {{GENDER:$6|τον|την}} $3 από $4 σε $5",
        "logentry-rights-rights-legacy": "{{GENDER:$2|Ο|Η}} $1 άλλαξε την ιδιότητα μέλους ομάδας {{GENDER:$1|του|της}} $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|προωθήθηκε}} αυτόματα από το $4 στο $5",
        "logentry-upload-upload": "{{GENDER:$2|Ο|Η}} $1 ανέβασε το $3",
index fb10358..e7fa4c7 100644 (file)
@@ -43,7 +43,7 @@
        "tog-ccmeonemails": "Send me copies of emails I send to other users",
        "tog-diffonly": "Do not show page content below diffs",
        "tog-showhiddencats": "Show hidden categories",
-       "tog-norollbackdiff": "Omit diff after performing a rollback",
+       "tog-norollbackdiff": "Don't show diff after performing a rollback",
        "tog-useeditwarning": "Warn me when I leave an edit page with unsaved changes",
        "tog-prefershttps": "Always use a secure connection when logged in",
        "underline-always": "Always",
        "minoredit": "This is a minor edit",
        "watchthis": "Watch this page",
        "savearticle": "Save page",
+       "publishpage": "Publish page",
        "preview": "Preview",
        "showpreview": "Show preview",
        "showdiff": "Show changes",
        "userpage-userdoesnotexist": "User account \"$1\" is not registered.\nPlease check if you want to create/edit this page.",
        "userpage-userdoesnotexist-view": "User account \"$1\" is not registered.",
        "blocked-notice-logextract": "This user is currently blocked.\nThe latest block log entry is provided below for reference:",
-       "clearyourcache": "<strong>Note:</strong> After saving, you may have to bypass your browser's cache to see the changes.\n* <strong>Firefox / Safari:</strong> Hold <em>Shift</em> while clicking <em>Reload</em>, or press either <em>Ctrl-F5</em> or <em>Ctrl-R</em> (<em>⌘-R</em> on a Mac)\n* <strong>Google Chrome:</strong> Press <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> on a Mac)\n* <strong>Internet Explorer:</strong> Hold <em>Ctrl</em> while clicking <em>Refresh</em>, or press <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Clear the cache in <em>Tools → Preferences</em>",
+       "clearyourcache": "<strong>Note:</strong> After saving, you may have to bypass your browser's cache to see the changes.\n* <strong>Firefox / Safari:</strong> Hold <em>Shift</em> while clicking <em>Reload</em>, or press either <em>Ctrl-F5</em> or <em>Ctrl-R</em> (<em>⌘-R</em> on a Mac)\n* <strong>Google Chrome:</strong> Press <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> on a Mac)\n* <strong>Internet Explorer:</strong> Hold <em>Ctrl</em> while clicking <em>Refresh</em>, or press <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Go to <em>Menu → Settings</em> (<em>Opera → Preferences</em> on a Mac) and then to <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "<strong>Tip:</strong> Use the \"{{int:showpreview}}\" button to test your new CSS before saving.",
        "userjsyoucanpreview": "<strong>Tip:</strong> Use the \"{{int:showpreview}}\" button to test your new JavaScript before saving.",
        "usercsspreview": "<strong>Remember that you are only previewing your user CSS.\nIt has not yet been saved!</strong>",
        "upload-form-label-infoform-description-tooltip": "Briefly describe everything notable about the work.\nFor a photo, mention the main things that are depicted, the occasion, or the place.",
        "upload-form-label-usage-title": "Usage",
        "upload-form-label-usage-filename": "File name",
-       "foreign-structured-upload-form-label-own-work": "This is my own work",
-       "foreign-structured-upload-form-label-infoform-categories": "Categories",
-       "foreign-structured-upload-form-label-infoform-date": "Date",
-       "foreign-structured-upload-form-label-own-work-message-local": "I confirm that I am uploading this file following the terms of service and licensing policies on {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "If you are not able to upload this file under the policies of {{SITENAME}}, please close this dialog and try another method.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "You may also want to try [[Special:Upload|the default upload page]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "I understand that I am uploading this file to a shared repository. I confirm that I am doing so following the terms of service and licensing policies there.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "If you are not able to upload this file under the policies of the shared repository, please close this dialog and try another method.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if this file can be uploaded there under their policies.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "I attest that I own the copyright on this file, and agree to irrevocably release this file to Wikimedia Commons under the [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] license, and I agree to the [https://wikimediafoundation.org/wiki/Terms_of_Use Terms of Use].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "If you do not own the copyright on this file, or you wish to release it under a different license, consider using the [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if the site allows the upload of this file under their policies.",
+       "upload-form-label-own-work": "This is my own work",
+       "upload-form-label-infoform-categories": "Categories",
+       "upload-form-label-infoform-date": "Date",
+       "upload-form-label-own-work-message-local": "I confirm that I am uploading this file following the terms of service and licensing policies on {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "If you are not able to upload this file under the policies of {{SITENAME}}, please close this dialog and try another method.",
+       "upload-form-label-not-own-work-local-local": "You may also want to try [[Special:Upload|the default upload page]].",
+       "upload-form-label-own-work-message-default": "I understand that I am uploading this file to a shared repository. I confirm that I am doing so following the terms of service and licensing policies there.",
+       "upload-form-label-not-own-work-message-default": "If you are not able to upload this file under the policies of the shared repository, please close this dialog and try another method.",
+       "upload-form-label-not-own-work-local-default": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if this file can be uploaded there under their policies.",
+       "upload-form-label-own-work-message-shared": "I attest that I own the copyright on this file, and agree to irrevocably release this file to Wikimedia Commons under the [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] license, and I agree to the [https://wikimediafoundation.org/wiki/Terms_of_Use Terms of Use].",
+       "upload-form-label-not-own-work-message-shared": "If you do not own the copyright on this file, or you wish to release it under a different license, consider using the [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
+       "upload-form-label-not-own-work-local-shared": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if the site allows the upload of this file under their policies.",
        "backend-fail-stream": "Could not stream file \"$1\".",
        "backend-fail-backup": "Could not backup file \"$1\".",
        "backend-fail-notexists": "The file $1 does not exist.",
        "changecontentmodel-success-text": "The content type of [[:$1]] has been changed.",
        "changecontentmodel-cannot-convert": "The content on [[:$1]] cannot be converted to a type of $2.",
        "changecontentmodel-nodirectediting": "The $1 content model does not support direct editing",
+       "changecontentmodel-emptymodels-title": "No content models available",
+       "changecontentmodel-emptymodels-text": "The content on [[:$1]] cannot be converted to any type.",
        "log-name-contentmodel": "Content model change log",
        "log-description-contentmodel": "Events related to the content models of a page",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|created}} the page $3 using a non-default content model \"$5\"",
        "whatlinkshere-prev": "{{PLURAL:$1|previous|previous $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|next|next $1}}",
        "whatlinkshere-links": "← links",
-       "whatlinkshere-hideredirs": "$1 redirects",
-       "whatlinkshere-hidetrans": "$1 transclusions",
-       "whatlinkshere-hidelinks": "$1 links",
-       "whatlinkshere-hideimages": "$1 file links",
+       "whatlinkshere-hideredirs": "Hide redirects",
+       "whatlinkshere-hidetrans": "Hide transclusions",
+       "whatlinkshere-hidelinks": "Hide links",
+       "whatlinkshere-hideimages": "Hide file links",
        "whatlinkshere-filters": "Filters",
        "whatlinkshere-submit": "Go",
        "autoblockid": "Autoblock #$1",
        "lockdbsuccesstext": "The database has been locked.<br />\nRemember to [[Special:UnlockDB|remove the lock]] after your maintenance is complete.",
        "unlockdbsuccesstext": "The database has been unlocked.",
        "lockfilenotwritable": "The database lock file is not writable.\nTo lock or unlock the database, this needs to be writable by the web server.",
+       "databaselocked": "The database is already locked.",
        "databasenotlocked": "The database is not locked.",
        "lockedbyandtime": "(by {{GENDER:$1|$1}} on $2 at $3)",
        "move-page": "Move $1",
        "accesskey-ca-nstab-category": "c",
        "accesskey-minoredit": "i",
        "accesskey-save": "s",
+       "accesskey-publish": "s",
        "accesskey-preview": "p",
        "accesskey-diff": "v",
        "accesskey-compareselectedversions": "v",
        "tooltip-ca-nstab-category": "View the category page",
        "tooltip-minoredit": "Mark this as a minor edit",
        "tooltip-save": "Save your changes",
+       "tooltip-publish": "Publish your changes",
        "tooltip-preview": "Preview your changes. Please use this before saving.",
        "tooltip-diff": "Show which changes you made to the text",
        "tooltip-compareselectedversions": "See the differences between the two selected revisions of this page",
        "feedback-useragent": "User agent:",
        "searchsuggest-search": "Search",
        "searchsuggest-containing": "containing...",
+       "api-error-autoblocked": "Your IP address has been blocked automatically, because it was used by a blocked user.",
        "api-error-badaccess-groups": "You are not permitted to upload files to this wiki.",
        "api-error-badtoken": "Internal error: Bad token.",
+       "api-error-blocked": "You have been blocked from editing.",
        "api-error-copyuploaddisabled": "Uploading by URL is disabled on this server.",
        "api-error-duplicate": "There {{PLURAL:$1|is another file|are some other files}} already on the site with the same content.",
        "api-error-duplicate-archive": "There {{PLURAL:$1|was another file|were some other files}} already on the site with the same content, but {{PLURAL:$1|it was|they were}} deleted.",
        "api-error-nomodule": "Internal error: No upload module set.",
        "api-error-ok-but-empty": "Internal error: No response from server.",
        "api-error-overwrite": "Overwriting an existing file is not allowed.",
+       "api-error-ratelimited": "You're trying to upload more files in a short space of time than this wiki allows.\nPlease try again in a few minutes.",
        "api-error-stashfailed": "Internal error: Server failed to store temporary file.",
        "api-error-publishfailed": "Internal error: Server failed to publish temporary file.",
        "api-error-stasherror": "There was an error while uploading the file to stash.",
index 3135721..52e1cd1 100644 (file)
@@ -58,7 +58,7 @@
        "tog-usenewrc": "Grupigi ŝanĝojn laŭ paĝo en \"Lastaj ŝanĝoj\" kaj \"Atentaro\" (bezonas Ĝavaskripton)",
        "tog-numberheadings": "Aŭtomate numerigi sekciojn",
        "tog-showtoolbar": "Montri redakto-breton (per Ĝavaskripto)",
-       "tog-editondblclick": "Redakti per duobla alklako (per Ĝavaskripto)",
+       "tog-editondblclick": "Redakti paĝojn per duobla alklako",
        "tog-editsectiononrightclick": "Ŝalti sekcian redaktadon per dekstra musklako de sekciaj titoloj (per Ĝavaskripto)",
        "tog-watchcreations": "Aldoni miajn kreatajn paĝojn kaj miajn alŝutaĵojn al mia atentaro",
        "tog-watchdefault": "Aldoni al mia atentaro paĝojn kaj dosierojn redaktitajn de mi",
@@ -89,7 +89,7 @@
        "tog-ccmeonemails": "Sendi al mi kopiojn de retpoŝtaĵoj, kiujn mi sendis al aliaj uzantoj.",
        "tog-diffonly": "Ne montri paĝan enhavon sub la ŝanĝmontrilo",
        "tog-showhiddencats": "Montri kaŝitajn kategoriojn",
-       "tog-norollbackdiff": "Preterlasi ŝanĝoelmontron post malfaro",
+       "tog-norollbackdiff": "Nemontri diferencon post plenumado de ŝanĝomalfaro",
        "tog-useeditwarning": "Averti min kiam mi forlasas redaktan paĝon kun nekonservitaj ŝanĝoj",
        "tog-prefershttps": "Ĉiam uzu sekuran konekton ensalutite",
        "underline-always": "Ĉiam",
        "oct": "okt",
        "nov": "nov",
        "dec": "dec",
-       "january-date": "$1-a de januaro",
-       "february-date": "$1-a de februaro",
-       "march-date": "$1-a de marto",
-       "april-date": "$1-a de aprilo",
-       "may-date": "$1-a de majo",
-       "june-date": "$1-a de junio",
-       "july-date": "$1-a de julio",
-       "august-date": "$1-a de aŭgusto",
-       "september-date": "$1-a de septembro",
-       "october-date": "$1-a de oktobro",
-       "november-date": "$1-a de novembro",
-       "december-date": "$1-a de decembro",
+       "january-date": "$1a de januaro",
+       "february-date": "$1a de februaro",
+       "march-date": "$1a de marto",
+       "april-date": "$1a de aprilo",
+       "may-date": "$1a de majo",
+       "june-date": "$1a de junio",
+       "july-date": "$1a de julio",
+       "august-date": "$1a de aŭgusto",
+       "september-date": "$1a de septembro",
+       "october-date": "$1a de oktobro",
+       "november-date": "$1a de novembro",
+       "december-date": "$1a de decembro",
        "period-am": "ATM",
        "period-pm": "PTM",
        "pagecategories": "{{PLURAL:$1|Kategorio|Kategorioj}}",
        "help": "Helpo",
        "search": "Serĉi",
        "searchbutton": "Serĉi",
-       "go": "Ek!",
+       "go": "Ek",
        "searcharticle": "Ek",
        "history": "Historio de versioj",
        "history_short": "Historio",
        "newpage": "Nova paĝo",
        "talkpage": "Diskuti la paĝon",
        "talkpagelinktext": "diskuto",
-       "specialpage": "Speciala Paĝo",
+       "specialpage": "Speciala paĝo",
        "personaltools": "Personaj iloj",
        "articlepage": "Vidi paĝenhavon",
        "talk": "Diskuto",
        "views": "Vidoj",
        "toolbox": "Iloj",
-       "userpage": "Vidi uzantan paĝon",
+       "userpage": "Vidi uzulan paĝon",
        "projectpage": "Rigardi projektopaĝon",
        "imagepage": "Vidi dosieropaĝon",
        "mediawikipage": "Vidi mesaĝopaĝon",
        "missingarticle-rev": "(versio#: $1)",
        "missingarticle-diff": "(Diferenco inter versioj: $1, $2)",
        "readonly_lag": "La datumbazo estis aŭtomate ŝlosita dum la subdatumbazo atingas la ĉefan datumbazon.",
+       "nonwrite-api-promise-error": "La 'Promeso-Ne-Skribi-API-Ago' HTTPa titolo estis sendita sed la peto estis al API skriba modulo.",
        "internalerror": "Interna eraro",
        "internalerror_info": "Interna eraro: $1",
        "internalerror-fatal-exception": "Neriparebla escepto de la tipo \"$1\"",
        "nologin": "Ĉu vi ne havas konton? $1.",
        "nologinlink": "Krei konton",
        "createaccount": "Krei konton",
-       "gotaccount": "Ĉu vi jam havas konton? '''$1'''.",
+       "gotaccount": "Ĉu vi jam havas konton? $1.",
        "gotaccountlink": "Ensaluti",
        "userlogin-resetlink": "Ĉu vi forgesis ensalutajn detalojn?",
        "userlogin-resetpassword-link": "Ĉu vi forgesis vian pasvorton?",
        "noemail": "Retpoŝtadreso ne estas registrita por uzanto \"$1\".",
        "noemailcreate": "Vi devas provizi validan retadreson",
        "passwordsent": "Oni sendis novan pasvorton al la retpoŝtadreso\nregistrita por \"$1\".\nBonvolu ensaluti denove ricevinte ĝin.",
-       "blocked-mailpassword": "Via IP-adreso estas forbarita de redaktado. Por preventi fiuzojn, la pasvorto-restaŭron estas malpermesita per tiu IP-adreso.",
+       "blocked-mailpassword": "Via IP-adreso estas forbarita de redaktado. Por preventi fiuzojn, la pasvorto-restaŭro per tiu IP-adreso estas malpermesita.",
        "eauthentsent": "Konfirma retmesaĝo estis sendita al la nomita retadreso. Antaŭ ol iu ajn alia mesaĝo estos sendita al la konto, vi devos sekvi la instrukciojn en la mesaĝo por konfirmi ke la konto ja estas via.",
        "throttled-mailpassword": "Retpoŝto kun reŝargita pasvorto estis jam sendita ene de la {{PLURAL:$1|lasta horo|lastaj $1 horoj}}.\nPor preventi misuzon, nur unu reŝargita pasvorto estos sendita dum {{PLURAL:$1|horo|$1 horoj}}.",
        "mailerror": "Okazis eraro sendante retpoŝtaĵon: $1",
        "botpasswords-label-grants": "Uzeblaj permesdonoj:",
        "botpasswords-help-grants": "Ĉiu permesdono provizas aliron al listitaj uzantaj permisoj, kiujn uzantkonto jam havas. Vidu la [[Special:ListGrants|tabelon de permisdonoj]] por pli da informo.",
        "botpasswords-label-restrictions": "Limigoj de uzado:",
-       "botpasswords-label-grants-column": "Permisdonita",
+       "botpasswords-label-grants-column": "Permeso donita",
        "botpasswords-bad-appid": "La robota nomo \"$1\" estas malvalida.",
        "botpasswords-insert-failed": "Aldono de la robota nomo \"$1\" ne sukcesis. Ĉu ĝi jam estis aldonita?",
        "botpasswords-update-failed": "Ĝisdatigo de la robota nomo \"$1\" ne sukcesis. Ĉu ĝi estis forigita?",
        "botpasswords-updated-body": "La robota pasvorto por robota nomo \"$1\" de la uzanto \"$2\" estis ĝisdatigita.",
        "botpasswords-deleted-title": "Robota pasvorto forigita",
        "botpasswords-deleted-body": "La robota pasvorto por robota nomo \"$1\" de la uzanto \"$2\" estis forigita.",
-       "botpasswords-newpassword": "La nova pasvorto por ensaluti kun <strong>$1</strong> estas <strong>$2</strong>. <em>Bonvolu registri tiun por referenconto.",
+       "botpasswords-newpassword": "La nova pasvorto por ensaluti per <strong>$1</strong> estas <strong>$2</strong>. <em>Bonvolu noti ĝin por estonta konsultado.",
        "botpasswords-no-provider": "Robotopasvortensalutoprovizilo (''BotPasswordsSessionProvider'') maldisponeblas.",
-       "botpasswords-restriction-failed": "Limigoj pri robota pasvorto maleblas tiun uzantonomon.",
+       "botpasswords-restriction-failed": "Limigoj pri robota pasvorto malebligas tiun ensalutadon.",
        "botpasswords-invalid-name": "La difinita uzantnomo malenhavas la robotopasvortan disigilon (\"$1\").",
        "botpasswords-not-exist": "Uzanto \"$1\" ne havas robotopasvorton, kiu nomiĝas \"$2\".",
        "resetpass_forbidden": "Pasvortoj ne estas ŝanĝeblaj",
        "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-emailsentemail": "Se tiu ĉu retpoŝta adreso estas kunligita kun via konto, tiam al ĉi tiu adreso estos sendita retpoŝto por renovigi pasvorton.",
-       "passwordreset-emailsentusername": "Se estas retpoŝta adreso, kiu estas asocigita kun tiu uzantnomo, tiam sendos retpôstan mesaĝon pri reasigno de pasvorto.",
+       "passwordreset-emailsentusername": "Se estas retpoŝta adreso, kiu estas asociita kun tiu uzantnomo, tiam ni sendos retpoŝtan mesaĝon pri reagordado de la pasvorto.",
        "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",
        "subject": "Temo:",
        "minoredit": "Ĉi tiu ŝanĝo estas redakteto",
        "watchthis": "Atenti ĉi tiun paĝon",
-       "savearticle": "Konservi ŝanĝojn",
+       "savearticle": "Konservi paĝon",
+       "publishpage": "Publikigi paĝon",
        "preview": "Antaŭrigardo",
        "showpreview": "Antaŭrigardo",
        "showdiff": "Montri ŝanĝojn",
        "sitecsspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi CSS.'''\n'''Ĝi ne jam estis savita!''",
        "sitejspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi Ĝavaskripta kodon''. ''Ĝi ne jam estis konservita''.",
        "userinvalidcssjstitle": "'''Averto:''' Ne ekzistas etoso \"$1\".\nRememoru ke individuaj .css-aj kaj .js-aj paĝoj uzas minusklan titolon, ekz. {{ns:user}}:Foo/vector.css kontraŭe al {{ns:user}}:Foo/Vector.css.",
-       "updated": "(Ŝanĝo registrita)",
-       "note": "'''Noto:'''",
+       "updated": "(Ĝisdatigita)",
+       "note": "<strong>Noto:</strong>",
        "previewnote": "'''Memoru, ke ĉi tio estas nur antaŭrigardo.''' \nViaj ŝanĝoj ne ankoraŭ estas konservitaj!",
        "continue-editing": "Iri al redakta spaco",
        "previewconflict": "La jena antaŭrigardo montras la tekston el la supra tekstujo,\nkiel ĝi aperos se vi elektos konservi la paĝon.",
        "permissionserrors": "Eraro pri permeso",
        "permissionserrorstext": "Vi ne rajtas fari tion pro la {{PLURAL:$1|sekva kialo|sekvaj kialoj}}:",
        "permissionserrorstext-withaction": "Vi ne rajtas $2, pro la {{PLURAL:$1|jena kialo|jenaj kialoj}}:",
-       "contentmodelediterror": "Vi ne povas prilabori ĉi tiun reviziaĵo, ĉar ĝia enhavoŝablono estas <code>$1</code>, kiu malsamas la aktualan enhavoŝablonon de la paĝo <code>$2</code>.",
+       "contentmodelediterror": "Vi ne povas prilabori ĉi tiun version, ĉar ĝia enhavomodelo estas <code>$1</code>, kiu malsamas la aktualan enhavomodelon de la paĝo <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Averto: Vi rekreas paĝon, kiu estis antaŭe forigita.'''\n\nVi konsideru, ĉu konvenas daŭre redakti ĉi tiun paĝon.\nJen la protokolo de forigoj kaj alinomigado por via oportuno:",
        "moveddeleted-notice": "Ĉi tiu paĝo estis forigita.\nPliaj detaloj estas en protokolo pri forigado kaj alinomado de tiu ĉi paĝo.",
-       "moveddeleted-notice-recent": "Pardonon, tiu paĝo freŝdate estis forigita (en la dauro de la lasta 24 horoj).\nLa forigo kaj la movprotokolo pri la paĝo estas provizitaj sube por referenco.",
+       "moveddeleted-notice-recent": "Pardonon, tiu ĉi paĝo freŝdate estis forigita (en la daŭro de la lastaj 24 horoj).\nLa foriga kaj la nomŝanĝa protokoloj pri la paĝo estas provizitaj sube por referenco.",
        "log-fulllog": "Vidi kompletan protokolon",
        "edit-hook-aborted": "Redakto estis ĉesigita per etendaĵo de la Vikia softvaro.\nĜi ne donis eksplikon.",
        "edit-gone-missing": "Ne eblis ĝisdatigi la paĝon.\nVerŝajne ĝi estis forigita.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Malplena objeto",
        "content-json-empty-array": "Malplena tabelo",
-       "duplicate-args-warning": "'''Averto:''' [[:$1]] vokas je [[:$2]] kun pli ol unu valoro por la parametro \"$3\". Nur la lasta liverita valoro estas uzonta.",
+       "duplicate-args-warning": "'''Averto:''' [[:$1]] vokas al [[:$2]] kun pli ol unu valoro por la parametro \"$3\". Nur la lasta liverita valoro estos uzata.",
        "duplicate-args-category": "Paĝoj kun pluroblaj argumentoj en ŝablonvokoj",
        "duplicate-args-category-desc": "La paĝo enhavas uzon de ŝablono kun pluroble uzitaj argumentoj, kiel ekzemple <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> aŭ <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Averto: Ĉi tiu paĝo enhavas tro da multekostaj sintaksaj funkcio-vokoj.\n\nĜi havu malpli ol $2 {{PLURAL:$2|vokon|vokojn}}, sed nun estas $1 {{PLURAL:$1|voko|vokoj}}.",
        "revdelete-submit": "Apliki al {{PLURAL:$1|elektita revizio|elektitaj revizioj}}",
        "revdelete-success": "'''Revizivideblecon ĝisdatigis.'''",
        "revdelete-failure": "'''Videblecon de revizio ne eblis ĝisdatigi:'''\n$1",
-       "logdelete-success": "'''Protokolovideblecon ensignitan.'''",
+       "logdelete-success": "'''Protokolovidebleco agordita.'''",
        "logdelete-failure": "'''Protokola videbleco ne estis akordebla:'''\n$1",
        "revdel-restore": "Ŝanĝi videblecon",
        "pagehist": "Paĝa historio",
        "mergehistory-fail-invalid-source": "Fonta paĝo estas malvalida.",
        "mergehistory-fail-invalid-dest": "Cela paĝo estas malvalida.",
        "mergehistory-fail-no-change": "Historio-kunfandado kunfandis neniun revizion. Bonvolu rekontroli la paĝon kaj la tempo-parametrojn.",
-       "mergehistory-fail-permission": "Nesufiĉa permesoj por kunfadi historion.",
+       "mergehistory-fail-permission": "Nesufiĉaj permesoj por kunfandi historion.",
        "mergehistory-fail-self-merge": "Fonta kaj cela paĝoj samas.",
-       "mergehistory-fail-timestamps-overlap": "Fonta revizio surkunigas aŭ postokuras la celan revizion.",
+       "mergehistory-fail-timestamps-overlap": "Fontaj modifoj okazis dum aŭ post la celaj modifoj.",
        "mergehistory-fail-toobig": "Ne eblas kunigi historiojn ĉar pli ol sojlo de $1 {{PLURAL:$1|revizio|revizioj}} estus {{PLURAL:$1|movita|movitaj}}.",
        "mergehistory-no-source": "Fontpaĝo $1 ne ekzistas.",
        "mergehistory-no-destination": "Celpaĝo $1 ne ekzistas.",
        "lineno": "Linio $1:",
        "compareselectedversions": "Kompari la elektitajn versiojn",
        "showhideselectedversions": "Montri/kaŝi elektitajn versiojn",
-       "editundo": "Redaktomalfaru",
+       "editundo": "malfari",
        "diff-empty": "(Neniu diferenco)",
        "diff-multi-sameuser": "({{PLURAL:$1|Unu meza versio|$1 mezaj versioj}} de la sama uzanto ne montriĝas)",
        "diff-multi-otherusers": "({{PLURAL:$1|Unu meza versio|$1 mezaj versioj}} de {{PLURAL:$2|alia uzanto|$2 uzantoj}} ne montriĝas)",
        "search-category": "(kategorio $1)",
        "search-file-match": "(kongruas kun dosiera enhavo)",
        "search-suggest": "Ĉu vi intenciis: $1",
-       "search-rewritten": "Montru rezultojn por $1. Serĉita anstataŭ $2.",
+       "search-rewritten": "Ni montras rezultojn por $1. Serĉi anstataŭe pri $2.",
        "search-interwiki-caption": "Kunprojektoj",
        "search-interwiki-default": "Rezultoj de $1:",
        "search-interwiki-more": "(plu)",
        "prefs-help-recentchangescount": "Ĉi tiu inkluzivas lastajn ŝanĝojn, paĝajn historiojn, kaj protokolojn.",
        "prefs-help-watchlist-token2": "Tio estas la sekreta ŝlosilo al la retfluo de via atentaro.\nĈiu, kiu konas ĝin, povas legi vian atentaron. Do, ne kunhavigu ĝin.\nSe vi devas, [[Special:ResetTokens|vi povas rekomencigi ĝin]].",
        "savedprefs": "Viaj preferoj estas konservitaj.",
-       "savedrights": "La uzanto-rajtojn de {{GENDER:$1|$1}} konservigis.",
+       "savedrights": "La uzanto-rajtoj de {{GENDER:$1|$1}} estis konservitaj.",
        "timezonelegend": "Horzono:",
        "localtime": "Loka tempo:",
        "timezoneuseserverdefault": "Uzi defaŭlton de servilo ($1)",
        "right-createpage": "Kreu paĝojn (kiuj ne estas diskuto-paĝoj)",
        "right-createtalk": "Krei diskuto-paĝojn",
        "right-createaccount": "Krei novajn uzanto-kontojn",
-       "right-autocreateaccount": "Aŭtomate ensaluti eksteruzantan konton",
+       "right-autocreateaccount": "Aŭtomate ensaluti per ekstera uzokonto",
        "right-minoredit": "Marki redaktojn kiel etajn",
        "right-move": "Movi paĝojn",
        "right-move-subpages": "Alinomigi paĝojn kun ĝiaj subpaĝoj",
        "right-bigdelete": "Forigi paĝojn kun grandaj historioj",
        "right-deletelogentry": "Forigi kaj malforigi specifajn enmetojn en la registro.",
        "right-deleterevision": "Forigi kaj malforigi specifajn versiojn de paĝoj",
-       "right-deletedhistory": "Vidi forigitajn historieroj, sen ties asociaj tekstoj",
+       "right-deletedhistory": "Vidi forigitajn historierojn, sen iliaj ligita teksto",
        "right-deletedtext": "Rigardi forigitan tekston kaj ŝanĝojn inter forigitaj revizioj.",
        "right-browsearchive": "Serĉi forigitajn paĝojn",
        "right-undelete": "Restarigi paĝon",
        "grant-group-file-interaction": "Interagi aŭdvidaĵajn dosierojn",
        "grant-group-watchlist-interaction": "Interagi vian atentaron",
        "grant-group-email": "Sendi retpoŝton",
-       "grant-group-high-volume": "Efektivigi ampleksege aktivecon",
+       "grant-group-high-volume": "Efektivigi ampleksegajn agojn",
        "grant-group-customization": "Personecigoj kaj preferoj",
        "grant-group-administration": "Efektivigi administrajn agojn",
        "grant-group-other": "Diversaj aktivecoj",
        "grant-createeditmovepage": "Krei, redakti kaj alinomi paĝojn",
        "grant-delete": "Forigi paĝojn, reviziaĵojn kaj protokolerojn",
        "grant-editinterface": "Redakti la MediaVikian nomspacon kaj la CSS/Ĝavoskripto de uzanto",
-       "grant-editmycssjs": "Redakti vian uzantan CSS/Ĝavoskripton",
-       "grant-editmyoptions": "Redakti vian uzantan preferojn",
+       "grant-editmycssjs": "Redakti viajn personajn CSS-kodon / Ĝavoskripton",
+       "grant-editmyoptions": "Redakti viajn personajn agordojn",
        "grant-editmywatchlist": "Redakti vian atentaron",
        "grant-editpage": "Redakti ekzistantajn paĝojn",
        "grant-editprotected": "Redakti protektitajn paĝojn",
-       "grant-highvolume": "Ampleksegaj redaktado",
+       "grant-highvolume": "Ampleksega redaktado",
        "grant-oversight": "Kaŝi uzantojn kaj forigi reviziaĵojn",
        "grant-patrol": "Patroli ŝanĝojn al pâgoj",
        "grant-protect": "Protekti kaj malprotekti paĝojn",
-       "grant-rollback": "Malvalidi ŝanĝojn al paĝoj",
+       "grant-rollback": "Malfari ŝanĝojn de paĝoj",
        "grant-sendemail": "Retpoŝti al aliaj uzantoj",
        "grant-uploadeditmovefile": "Alŝuti, anstataŭigi kaj alinomi dosierojn",
        "grant-uploadfile": "Alŝuti novajn dosierojn",
        "action-createpage": "krei paĝojn",
        "action-createtalk": "krei diskuto-paĝojn",
        "action-createaccount": "krei ĉi tiun uzanto-konton",
+       "action-autocreateaccount": "Aŭtomate krei tiun eksteruzantan konton",
        "action-history": "vidi historion de tiu ĉi paĝo",
        "action-minoredit": "marki ĉi tiun redakton eta",
        "action-move": "movi ĉi tiun paĝon",
        "rcshowhidemine": "$1 miajn redaktojn",
        "rcshowhidemine-show": "Montri",
        "rcshowhidemine-hide": "Kaŝi",
+       "rcshowhidecategorization": "$1 paĝa enkategoriigo",
        "rcshowhidecategorization-show": "Montri",
        "rcshowhidecategorization-hide": "Kaŝi",
        "rclinks": "Montri $1 lastajn ŝanĝojn dum la $2 lastaj tagoj.<br />$3",
        "recentchangeslinked-summary": "Jen listo de ŝanĝoj faritaj lastatempe al paĝoj ligitaj el specifa paĝo (aŭ al membroj de specifa kategorio).\nPaĝoj en [[Special:Watchlist|via atentaro]] estas '''grasaj'''.",
        "recentchangeslinked-page": "Nomo de paĝo:",
        "recentchangeslinked-to": "Montru ŝanĝojn al paĝoj ligitaj al la specifa paĝo anstataŭe.",
+       "recentchanges-page-added-to-category": "[[:$1]] aldonita al la kategorio",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] kategorialdonita, [[Special:WhatLinksHere/$1|tiu paĝo estas inkluzivita ene de aliaj paĝoj]]",
+       "recentchanges-page-removed-from-category": "[[:$1]] kategoriforigita",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] kategoriforigita, [[Special:WhatLinksHere/$1|tiu paĝo estas inkluzivita ene de aliaj paĝoj]]",
+       "autochange-username": "Aŭtomata ŝanĝo de Mediavikio",
        "upload": "Alŝuti dosieron",
        "uploadbtn": "Alŝuti dosieron",
        "reuploaddesc": "Reveni al la alŝuta formularo.",
        "uploaddisabledtext": "Alŝutado de dosieroj estas malebligita.",
        "php-uploaddisabledtext": "Dosiera alŝutado estas malŝalta en PHP. Bonvolu kontroli la preferon file_uploads.",
        "uploadscripted": "HTML-aĵo aŭ skriptokodaĵo troviĝas en tiu ĉi tiu dosiero, kiun TTT-foliumilo eble interpretus erare.",
+       "upload-scripted-pi-callback": "Malalŝuteblas dosieron, kiu enhavas instrukcion de XML-stilfolia traktado",
+       "uploaded-script-svg": "Trovis skriptelbero \"$1\" en la alŝutita SVGa dosiero.",
+       "uploaded-hostile-svg": "Trovis malsekuran CSS-kodon en la stila elemento de alŝutita SVG-a dosiero.",
+       "uploaded-event-handler-on-svg": "Ensigni eventotraktilajn atributojn <code>$1=\"$2\"</code> estas malpermisita en SVGaj dosieroj.",
+       "uploaded-href-attribute-svg": "Atributoj je \"href\" en SVGaj dosieroj nur povas ligi al \"http://\" aŭ \"https://\" celoj, trovis  <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Trovis je \"href\" ligita al malsekuraj datenoj: URIa celo <code>&lt;$1 $2=\"$3\"&gt;</code> en la alŝuta SVGa dosiero.",
+       "uploaded-animate-svg": "Trovis markon je \"animate\", kiu povus ŝanĝi la atributon je \"href\", per uzi la atributon je \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> en la alŝuta SVGa dosiero.",
+       "uploaded-setting-event-handler-svg": "Ensigni eventotraktilajn atributojn estas blokita, trovis <code>&lt;$1 $2=\"$3\"&gt;</code> en la alŝuta SVGa dosiero.",
+       "uploaded-setting-href-svg": "Uzi la markon je \"set\" por aldoni atributon je \"href\" al ujero estas blokita.",
+       "uploaded-wrong-setting-svg": "Uzi la ''ensigni'' (''<span lang=\"en\">set</span>'') markon por aldoni foran/datenan/skriptan celon al ajn atributon estas blokita. Trovis <code>&lt;set to=\"$1\"&gt;</code> en la alŝutita SVGan dosieron.",
+       "uploaded-setting-handler-svg": "SVGa dosiero kiu ensignas la traktilan atributon (''<span lang=\"en\">handler</span>'') kun fora/datena/skripta estas blokita. Trovis <code>$1=\"$2\"</code> en la alsûtita SVGa dosiero.",
+       "uploaded-remote-url-svg": "SVG-a dosiero kiu asignas ajnan stilan atributon kun fora URL estas blokita. Ni trovis <code>$1=\"$2\"</code> en la alsûtita SVG-a dosiero.",
+       "uploaded-image-filter-svg": "Trovis bildan filtrilon kun URL:  <code>&lt;$1 $2=\"$3\"&gt;</code> en la alŝutita SVGa dosiero.",
        "uploadscriptednamespace": "Ĉi tiu SVG-dosiero enhavas nevalidan nomspacon \"$1\"",
        "uploadinvalidxml": "Ne eblas interpreti la XML-sintakson en la alŝutita dosiero",
        "uploadvirus": "Viruso troviĝas en la dosiero! Detaloj: $1",
        "upload-options": "Alŝutaj agordoj",
        "watchthisupload": "Atenti ĉi tiun dosieron",
        "filewasdeleted": "Dosiero de ĉi tiu nomo estis antaŭe alŝutita kaj poste forigita. Bonvolu kontroli en la $1 antaŭ alŝuti ĝin denove.",
+       "filename-thumb-name": "Ĉi tiu aspektas kiel titolo de etigita versio de plena bildo. Bonvolu ne alŝuti etigitajn versiojn de bildoj al la sama vikio. Alimaniere, bonvolu modifi la dosiernomon al pli signifa, kiu ne havas la eta-versian prefikson.",
        "filename-bad-prefix": "La nomo de la dosiero kiun vi alŝutas komencas kun '''\"$1\"''', kiu estas nepriskriba nomo ofte aŭtomate donata de ciferecaj fotiloj. Bonvolu elekti pli priskriban nomon por via bildo.",
        "upload-proto-error": "Malvalida protokolo",
        "upload-proto-error-text": "Fora alŝuto devas URL-on komence de <code>http://</code> aŭ <code>ftp://</code>.",
        "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-foreign-cant-upload": "Tiu vikio ne estas agorita por alŝuti alŝutitan dosieron al la petita fora dosierdeponejo.",
        "upload-dialog-title": "Alŝuti dosieron",
        "upload-dialog-button-cancel": "Nuligi",
        "upload-dialog-button-done": "Farite",
        "upload-dialog-button-upload": "Alŝuti",
        "upload-form-label-infoform-title": "Detaloj",
        "upload-form-label-infoform-name": "Nomo",
+       "upload-form-label-infoform-name-tooltip": "Unika priskriba titolo por tiu ĉi dosiero, kiu servos kiel dosiernomo. Eblas uzi normalan lingvaĵon kun interspacoj. Ne aldonu la dosieran aldonaĵon.",
        "upload-form-label-infoform-description": "Priskribo",
+       "upload-form-label-infoform-description-tooltip": "Bonvolu koncize priskribi ĉion notindan pri la verko.\nPri foto, menciu la esencajn aĵojn bildigitajn, la okazon, aŭ la lokon.",
        "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",
+       "upload-form-label-own-work": "Tio estas mia propra laboro",
+       "upload-form-label-infoform-categories": "Kategorioj",
+       "upload-form-label-infoform-date": "Dato",
+       "upload-form-label-own-work-message-local": "Mi konfirmas ke mi alŝutas tiun dosieron respektante pri la uzadokondiĉoj kaj permesopolitikoj de  {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Se vi ne eblas alŝuti tiun dosieron respektante de politikoj de {{SITENAME}}, bonvolu fermi tiun dialogon kaj provi denove kun alia metodo.",
+       "upload-form-label-not-own-work-local-local": "Vi eble ŝatu egale pravi [[Special:Upload|la defaŭltan paĝon]].",
+       "upload-form-label-own-work-message-default": "Mi komprenas ke mi alŝutas tiun dosieron al komunigita deponejo. Mi konfirmas ke mi faras tiun respektante de la uzadtermoj kaj de la permisilopolitikoj tie.",
+       "upload-form-label-not-own-work-message-default": "Se vi ne eblas alŝuti tiun dosieron respektante de politikoj de komuna deponejo, bonvolu fermi tiun dialogon kaj provi denove kun alia metodo.",
+       "upload-form-label-not-own-work-local-default": "Vi ankaŭ eble dezirus provi per uzi [[Special:Upload|la alŝutan paĝon sur {{SITENAME}}]], se ĉi tiu dosiero povas esti alŝutita tie respektante de iliaj politikoj.",
+       "upload-form-label-own-work-message-shared": "Mi atestas ke mi posedas la kopirajton sur ĉi tiu dosiero kaj konsenti al neeksvalidiĝebla liberigo de ĉi tiu dosiero al Vikimedia Komunejo sub la [https://creativecommons.Org/licencoj/de-sa/4.0/ Krea Komunaĵo Atribuite Samkondiĉe 4.0] permisilo kaj mi konsentas al la [https://wikimediafoundation.Org/vikiaj/Terminoj_de_Uzaj kondiĉoj de uzo].",
+       "upload-form-label-not-own-work-message-shared": "Se vi ne posedas la kopirajton sur ĉi tiu dosiero aŭ vi deziras liberigi ĝin sub malsama licenco, konsideru uzi la [https://commons.Wikimedia.Org/vikia/Specialaĵo:UploadWizard asistanto de  alŝutado al komunejo].",
+       "upload-form-label-not-own-work-local-shared": "Vi ankaŭ eble dezirus provi per uzi [[Special:Upload|la paĝon de alŝutado sur {{SITENAME}}]], se ĉi tiu dosiero povas esti alŝutita tie respektante de iliaj politikoj.",
        "backend-fail-stream": "Ne povis fluigi dosieron $1.",
        "backend-fail-backup": "Ne povis enarkivigi dosieron $1.",
        "backend-fail-notexists": "La dosiero $1 ne ekzistas.",
        "backend-fail-read": "Ne povas legi dosieron \"$1\".",
        "backend-fail-create": "Ne povas skribi dosieron $1.",
        "backend-fail-maxsize": "Ne povis skribi la dosieron \"$1,\" ĉar ĝi estas pli granda ol {{PLURAL:$2|bitoko|$2 bitokoj}}.",
-       "backend-fail-readonly": "La interna konservujo \"$1\" nune estas nurlega. La indikata kialo estas: \"''$2''\"",
+       "backend-fail-readonly": "La interna konservujo \"$1\" nune estas nurlega. La indikata kialo estas: <em>$2</em>",
        "backend-fail-synced": "La dosiero \"$1\" estas en nekohera stato kun la internaj konservujoj",
        "backend-fail-connect": "Ne eblis konekti la internan konservujon \"$1\".",
        "backend-fail-internal": "Nekonata eraro okazis en interna konservujo \"$1\".",
        "uploadstash-summary": "Tiu ĉi paĝo alirebligas la dosierojn alŝutitajn (aŭ alŝutatajn), kiuj ne jam estas publikigitaj per la vikio. Tiujn ĉi dosierojn ne povas vidi  iu ajn, krom la alŝutinto mem.",
        "uploadstash-clear": "Malplenigi la dosierkonversejon.",
        "uploadstash-nofiles": "Mankas dosieroj en la konservejo.",
-       "uploadstash-badtoken": "Malsukcesis tiu ago, eble pro tio ke viaj ensalutiloj senvalidiĝis. Reprovu.",
-       "uploadstash-errclear": "Sensukcesis la forigo de la dosieroj.",
+       "uploadstash-badtoken": "Malsukcesis tiu ago, eble pro tio ke viaj ensalutiloj eksvalidiĝis. Bonvolu reprovi.",
+       "uploadstash-errclear": "Malsukcesis la forigo de la dosieroj.",
        "uploadstash-refresh": "Aktualigi la dosierliston.",
-       "uploadstash-thumbnail": "Vidi bildetigon",
+       "uploadstash-thumbnail": "Vidi bildeton",
        "invalid-chunk-offset": "Malvalida deŝovo de dosierpeco",
        "img-auth-accessdenied": "Atingo malpermisita",
        "img-auth-nopathinfo": "Mankas PATH_INFO (informo pri dosiervojo).\nVia servilo ne estas konfigurita por sendi ĉi tiun informon.\nEble ĝi estas CGI-bazita kaj ne subtenas img_auth.\nVidu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization (angle).",
        "listfiles-latestversion-no": "Ne",
        "file-anchor-link": "Dosiero",
        "filehist": "Dosiera historio",
-       "filehist-help": "Klaku daton/tempon por vidi la dosieron kiel ĝin ŝajnitan tiame.",
+       "filehist-help": "Klaku daton/tempon por vidi la dosieron kia ĝi aspektis tiam.",
        "filehist-deleteall": "forigi ĉiujn",
        "filehist-deleteone": "forigi",
        "filehist-revert": "restarigi",
        "apihelp": "Helpo pri API",
        "apihelp-no-such-module": "Modulo \"$1\" ne estis trovita.",
        "apisandbox": "API testejo",
+       "apisandbox-jsonly": "JavaScript estas postulita por uzi la API provejon.",
        "apisandbox-api-disabled": "API estas malŝalta en ĉi tiu retejo.",
        "apisandbox-intro": "Uzu tiun ĉi paĝon por eksperimenti kun '''MediaWiki API'''.\nVidu [//www.mediawiki.org/wiki/API:Main_page la API-dokumentadon] por pli da detaloj pri la uzo de API. Ekz-e: [//www.mediawiki.org/wiki/API#A_simple_example atingi la enhavon de la Ĉefpaĝo]. Elektu agon por vidi pliajn ekzemplojn.\n\nNotu ke, kvankam ĉi tiu estas provejo, agoj kiun vi faros en ĉi tiu paĝo povas modifi la vikion.",
+       "apisandbox-unfullscreen": "Montri paĝon",
        "apisandbox-submit": "Fari mendon",
        "apisandbox-reset": "Nuligi",
+       "apisandbox-retry": "Reprovi",
+       "apisandbox-helpurls": "Ligiloj pri helpo",
        "apisandbox-examples": "Ekzemploj",
        "apisandbox-dynamic-parameters": "Aldonaj parametroj",
        "apisandbox-dynamic-parameters-add-label": "Aldoni parametron:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomo de parametro",
        "apisandbox-dynamic-error-exists": "Parametro nomata \"$1\" jam ekzistas.",
+       "apisandbox-deprecated-parameters": "Evitindajn parametrojn",
+       "apisandbox-fetch-token": "Aŭtoplenigu ĵetonon",
+       "apisandbox-submit-invalid-fields-title": "Iuj kampoj estas malvalidaj.",
+       "apisandbox-submit-invalid-fields-message": "Bonvolu ĝustigi la markitajn kampojn kaj provi denove.",
        "apisandbox-results": "Rezultoj",
+       "apisandbox-sending-request": "Sendanta aplikprograminterfacan peton…",
        "apisandbox-request-url-label": "Mendi URL-on.",
-       "apisandbox-request-time": "Tempo de peto: $1",
+       "apisandbox-request-time": "Tempo de peto:{{PLURAL:$1|$1 ms}}",
        "booksources": "Librofontoj",
        "booksources-search-legend": "Serĉi librofontojn",
        "booksources-search": "Serĉi",
        "booksources-text": "Jen ligilaro al aliaj TTT-ejoj, kiuj vendas librojn,\nkaj/aŭ informumos pri la libro ligita.\nLa {{SITENAME}} ne estas komerce ligita al tiuj vendejoj, kaj la listo ne estu\nkomprenata kiel rekomendo aŭ reklamo.",
        "booksources-invalid-isbn": "La donata ISBN verŝajne estas nevalida; kontrolu pri erara kopiado el la originala fonto.",
        "specialloguserlabel": "Faranto:",
-       "speciallogtitlelabel": "Celo (titolo aŭ uzanto):",
+       "speciallogtitlelabel": "Celo (titolo aŭ  {{ns:user}}:salutnomo por uzanto):",
        "log": "Protokoloj",
        "logeventslist-submit": "Montri",
        "all-logs-page": "Ĉiuj publikaj protokoloj",
        "listgrouprights-namespaceprotection-header": "Nomspacaj restriktoj",
        "listgrouprights-namespaceprotection-namespace": "Nomspaco",
        "listgrouprights-namespaceprotection-restrictedto": "Rajtoj, kiuj permesas al uzanto redakti",
-       "listgrants": "Rajdonaro",
+       "listgrants": "Rajtoj donitaj",
        "trackingcategories": "Kategorioj por kontrolado",
        "trackingcategories-summary": "Ĉi tiu paĝo listigas kategoriojn por kontrolado, aŭtomate farita de la Mediavikia programaro. Ties nomoj estas ŝanĝebla, ŝanĝante la paran sistemmesaĝon en la nomspaco {{ns:8}}.",
        "trackingcategories-msg": "Kategorio pri kontrolado",
        "wlshowhideanons": "anonimaj uzantoj",
        "wlshowhidepatr": "patrolitaj redaktoj",
        "wlshowhidemine": "miaj redaktoj",
+       "wlshowhidecategorization": "paĝa enkategoriigo.",
        "watchlist-options": "Opcioj por atentaro",
        "watching": "Aldonata al la atentaro...",
        "unwatching": "Malatentante...",
        "deletepage": "Forigi paĝon",
        "confirm": "Konfirmi",
        "excontent": "enhavis: '$1'",
-       "excontentauthor": "la enteno estis : '$1' (kaj la sola kontribuinto estis '$2')",
+       "excontentauthor": "la enteno estis: '$1', kaj la sola kontribuinto estis \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]])",
        "exbeforeblank": "antaŭ malplenigo enhavis: '$1'",
        "delete-confirm": "Forigi \"$1\"",
        "delete-legend": "Forigi",
        "delete-toobig": "Ĉi tiu paĝo havas grandan redakto-historion, pli ol $1 {{PLURAL:$1|version|versiojn}}. Forigo de ĉi tiaj paĝoj estis limigitaj por preventi akcidentan disrompigon de {{SITENAME}}.",
        "delete-warning-toobig": "Ĉi tiu paĝo havas grandan redakto-historion, pli ol $1 {{PLURAL:$1|version|versiojn}}. Forigo de ĝi povas disrompigi operacion de {{SITENAME}}; forigu singarde.",
        "deleteprotected": "Vi ne povas forigi ĉi tiun paĝon ĉar ĝi estis protektita.",
-       "deleting-backlinks-warning": "'''Atentigo:'''\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|Aliaj paĝoj]] ligas al aŭ transkludas tiun ĉi forigotan paĝon.",
+       "deleting-backlinks-warning": "<strong>Atentigo:</strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|Aliaj paĝoj]] ligas al aŭ transkludas tiun ĉi forigotan paĝon.",
        "rollback": "Restarigi antaŭan redakton",
-       "rollbacklink": "malvalidi",
+       "rollbacklink": "malfari",
        "rollbacklinkcount": "nuligi $1 {{PLURAL:$1|redakton|redaktojn}}",
        "rollbacklinkcount-morethan": "nuligi pli ol $1 {{PLURAL:$1|redakton|redaktojn}}",
        "rollbackfailed": "Malfaro malsukcesis",
        "ipb-unblock": "Malforbari salutnomon aŭ IP-adreson",
        "ipb-blocklist": "Vidi ekzistantajn forbarojn",
        "ipb-blocklist-contribs": "Kontribuoj de {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 restas",
        "unblockip": "Malforbari IP-adreson/nomon",
        "unblockiptext": "Per la jena formulo vi povas repovigi al iu\nforbarita IP-adreso/nomo la povon enskribi en la vikio.",
        "ipusubmit": "Forigi ĉi tiun forbaron",
        "tooltip-n-currentevents": "Trovi fonajn informojn pri nunaj eventoj",
        "tooltip-n-recentchanges": "Listo de la lastaj ŝanĝoj en la vikio.",
        "tooltip-n-randompage": "Iri al hazarda paĝo",
-       "tooltip-n-help": "Serĉopaĝo.",
+       "tooltip-n-help": "La loko por eltrovi",
        "tooltip-t-whatlinkshere": "Listo de ĉiuj vikiaj paĝoj kiuj ligas ĉi tien",
        "tooltip-t-recentchangeslinked": "Lastaj ŝanĝoj en paĝoj kiuj ligas al tiu ĉi paĝo",
        "tooltip-feed-rss": "RSS-fonto por tiu ĉi paĝo",
        "tooltip-watchlistedit-raw-submit": "Ĝisdatigi atentaron",
        "tooltip-recreate": "Rekrei la paĝon malgraŭ ĝi estis forigita",
        "tooltip-upload": "Ekalŝuti",
-       "tooltip-rollback": "\"Malvalidi\" malfaras redakto(j)n al ĉi tiu paĝo de la lasta kontribuanto per unu klako.",
+       "tooltip-rollback": "\"Malfari\" per unu klako nuligas redakto(j)n de la lasta kontribuanto al ĉi tiu paĝo.",
        "tooltip-undo": "\"Malfari\" malfaris ĉi tiun redakton kaj malfermas la redakto-paĝon en antaŭvida reĝimo. Permesas aldoni kialon en la resumo.",
        "tooltip-preferences-save": "Konservi preferojn",
        "tooltip-summary": "Enigu mallongan resumon",
        "watchlistedit-raw-done": "Via atentaro estas ĝisdatigita.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 titolo estis aldonita|$1 titoloj estis aldonitaj}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 titolo estis forigita|$1 titoloj estis forigitaj}}:",
-       "watchlistedit-clear-title": "Malplenigita atentaro",
+       "watchlistedit-clear-title": "Malplenigi la atentaron",
        "watchlistedit-clear-legend": "Malplenigi la atentaron",
        "watchlistedit-clear-explain": "Ĉiuj el la titoloj estos forigitaj el via atentaro",
        "watchlistedit-clear-titles": "Titoloj:",
        "hebrew-calendar-m11-gen": "abo",
        "hebrew-calendar-m12-gen": "elulo",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskuto]])",
+       "timezone-local": "Loka",
        "duplicate-defaultsort": "'''Averto:''' Defaŭlta ordiga ŝlosilo \"$2\" anstataŭigas pli fruan defaŭltan ordigan ŝlosilon \"$1\".",
        "duplicate-displaytitle": "<strong>Atentigo:</strong> La montrata titolo \"$2\" transpasas la antaŭan titolon \"$1\".",
        "invalid-indicator-name": "<strong>Eraro:</strong> Atributo de la paĝstata indikilo <code>name</code> maldevas esti malplena.",
        "htmlform-cloner-create": "Aldoni plian",
        "htmlform-cloner-delete": "Forigi",
        "htmlform-cloner-required": "Almenaŭ unu valoro estas nepra.",
+       "htmlform-title-not-exists": "$1 ne ekzistas.",
+       "htmlform-user-not-exists": "<strong>$1</strong> ne ekzistas.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ne estas valida salutnomo.",
        "sqlite-has-fts": "$1 kun tut-teksta subteno",
        "sqlite-no-fts": "$1 sen tut-teksta subteno",
        "logentry-delete-delete": "$1 forigis paĝon $3",
        "special-characters-title-minus": "minus-signo",
        "mw-widgets-dateinput-placeholder-day": "JJJJ-MM-TT",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
+       "mw-widgets-titleinput-description-new-page": "paĝo ankoraŭ ne ekzistas",
+       "mw-widgets-titleinput-description-redirect": "alidirekti al $1",
        "api-error-blacklisted": "Bonvolu elekti alian, priskriban titolon.",
+       "sessionprovider-generic": "$1 seancoj",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "kuketaj seancoj",
        "randomrootpage": "Hazarda radika paĝo",
        "log-action-filter-all": "Ĉia",
+       "log-action-filter-block-block": "Forbari",
        "log-action-filter-protect-unprotect": "Malprotektado",
        "log-action-filter-upload-upload": "Novalŝuta",
        "log-action-filter-upload-overwrite": "Realŝuta"
index 210f886..0337736 100644 (file)
                        "Mgpena",
                        "Transonlohk",
                        "Eloy",
-                       "Lemondoge"
+                       "Lemondoge",
+                       "Jdforrester",
+                       "Indiralena",
+                       "Rubentl134"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "tog-ccmeonemails": "Recibir copias de los correos electrónicos que envíe a otros usuarios",
        "tog-diffonly": "No mostrar el contenido de la página debajo de la lista de diferencias",
        "tog-showhiddencats": "Mostrar categorías ocultas",
-       "tog-norollbackdiff": "Omitir la lista de diferencias después de revertir",
+       "tog-norollbackdiff": "No mostrar la lista de diferencias después de revertir",
        "tog-useeditwarning": "Avisarme cuando abandone una página en edición con cambios sin guardar",
        "tog-prefershttps": "Utilizar siempre conexiones seguras en mis sesiones",
        "underline-always": "Siempre",
        "minoredit": "Esta es una edición menor",
        "watchthis": "Vigilar esta página",
        "savearticle": "Guardar la página",
+       "publishpage": "Publicar la página",
        "preview": "Previsualizar",
        "showpreview": "Mostrar previsualización",
        "showdiff": "Mostrar los cambios",
        "userpage-userdoesnotexist": "El usuario «$1» no está registrado. Asegúrate de que realmente quieres crear o editar esta página.",
        "userpage-userdoesnotexist-view": "El usuario «$1» no está registrado.",
        "blocked-notice-logextract": "Este usuario se encuentra actualmente bloqueado.\nA continuación se muestra la última entrada del registro de bloqueos para más información:",
-       "clearyourcache": "<strong>Nota:</strong> tras guardar, quizás necesites actualizar la caché de tu navegador para ver los cambios.\n* <strong>Firefox/Safari:</strong> Mantén presionada la tecla <em>Mayús</em> mientras pulsas el botón <em>Actualizar</em>, o presiona <em>Ctrl+F5</em> o <em>Ctrl+R</em> (<em>⌘+R</em> en Mac)\n* <strong>Google Chrome:</strong> presiona <em>Ctrl+Shift+R</em> (<em>⌘+Mayús+R</em> en Mac)\n* <strong>Internet Explorer:</strong> mantén presionada <em>Ctrl</em> mientras pulsas <em>Actualizar</em>, o presiona <em>Ctrl+F5</em>\n* <strong>Opera:</strong> vacía la caché en <em>Herramientas → Preferencias</em>",
+       "clearyourcache": "<strong>Nota:</strong> tras guardar, quizás necesites actualizar la caché de tu navegador para ver los cambios.\n* <strong>Firefox/Safari:</strong> Mantén presionada la tecla <em>Mayús</em> mientras pulsas el botón <em>Actualizar</em>, o presiona <em>Ctrl+F5</em> o <em>Ctrl+R</em> (<em>⌘+R</em> en Mac)\n* <strong>Google Chrome:</strong> presiona <em>Ctrl+Shift+R</em> (<em>⌘+Mayús+R</em> en Mac)\n* <strong>Internet Explorer:</strong> mantén presionada <em>Ctrl</em> mientras pulsas <em>Actualizar</em>, o presiona <em>Ctrl+F5</em>\n* <strong>Opera:</strong> dirígete a <em>Menú → Configuración</em> (<em>Opera → Preferencias</em> en Mac) y luego a <em>Privacidad y seguridad → Borrar datos de navegación → Imágenes y archivos en caché</em>.",
        "usercssyoucanpreview": "<strong>Consejo:</strong> usa el botón «{{int:showpreview}}» para probar el nuevo CSS antes de guardarlo.",
        "userjsyoucanpreview": "<strong>Consejo:</strong> usa el botón «{{int:showpreview}}» para probar el nuevo código JavaScript antes de guardarlo.",
        "usercsspreview": "<strong>Recuerda que solo estás previsualizando tu CSS de usuario.\n¡Aún no se ha guardado!</strong>",
        "upload-form-label-infoform-description-tooltip": "Describe brevemente todo lo destacable acerca del trabajo.\nPara una foto, menciona las cosas principales que se representan, la ocasión o el lugar.",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nombre del archivo",
-       "foreign-structured-upload-form-label-own-work": "Esto es mi trabajo propio",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorías",
-       "foreign-structured-upload-form-label-infoform-date": "Fecha",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que estoy subiendo este archivo siguiendo los términos del servicio y las políticas de concesión de licencias en {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Si no es capaz de subir este archivo bajo las políticas de {{SITENAME}}, por favor cierre este cuadro de diálogo e intente otro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Quizás también quieras probar [[Special:Upload|la página predeterminada de subidas]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Entiendo que voy a subir este archivo a un repositorio compartido. Confirmo que estoy haciéndolo que siguiendo los términos de servicio y políticas de licenciamiento de allí.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Si usted no es capaz de cargar este archivo en virtud de las políticas del repositorio compartido, por favor cierre este cuadro de diálogo y probar con otro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Puede que también quieras usar [[Special:Upload|la página de subidas en {{SITENAME}}]], si se puede subir este archivo bajo sus políticas.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Doy fe que soy dueño de los derechos de autor de este archivo, y acepto irrevocablemente liberar este archivo a Wikimedia Commons bajo la licencia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], y acepto los [https://wikimediafoundation.org/wiki/Terms_of_Use Términos de Uso].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Si no es dueño de los derechos de autor de este archivo, o desea publicarlo bajo una licencia diferentes, considere usar el [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de Carga de Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Puede que también quieras usar [[Special:Upload|la página de subidas en {{SITENAME}}]], si el sitio permite la subida de este archivo bajo sus políticas.",
+       "upload-form-label-own-work": "Esto es mi trabajo propio",
+       "upload-form-label-infoform-categories": "Categorías",
+       "upload-form-label-infoform-date": "Fecha",
+       "upload-form-label-own-work-message-local": "Confirmo que estoy subiendo este archivo siguiendo los términos del servicio y las políticas de concesión de licencias en {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Si no es capaz de subir este archivo bajo las políticas de {{SITENAME}}, por favor cierre este cuadro de diálogo e intente otro método.",
+       "upload-form-label-not-own-work-local-local": "Quizás también quieras probar [[Special:Upload|la página predeterminada de subidas]].",
+       "upload-form-label-own-work-message-default": "Entiendo que voy a subir este archivo a un repositorio compartido. Confirmo que estoy haciéndolo que siguiendo los términos de servicio y políticas de licenciamiento de allí.",
+       "upload-form-label-not-own-work-message-default": "Si usted no es capaz de cargar este archivo en virtud de las políticas del repositorio compartido, por favor cierre este cuadro de diálogo y probar con otro método.",
+       "upload-form-label-not-own-work-local-default": "Puede que también quieras usar [[Special:Upload|la página de subidas en {{SITENAME}}]], si se puede subir este archivo bajo sus políticas.",
+       "upload-form-label-own-work-message-shared": "Doy fe que soy dueño de los derechos de autor de este archivo, y acepto irrevocablemente liberar este archivo a Wikimedia Commons bajo la licencia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], y acepto los [https://wikimediafoundation.org/wiki/Terms_of_Use Términos de Uso].",
+       "upload-form-label-not-own-work-message-shared": "Si no es dueño de los derechos de autor de este archivo, o desea publicarlo bajo una licencia diferentes, considere usar el [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de Carga de Commons].",
+       "upload-form-label-not-own-work-local-shared": "Puede que también quieras usar [[Special:Upload|la página de subidas en {{SITENAME}}]], si el sitio permite la subida de este archivo bajo sus políticas.",
        "backend-fail-stream": "No se pudo transmitir el archivo «$1».",
        "backend-fail-backup": "No se pudo hacer copia de seguridad del archivo «$1».",
        "backend-fail-notexists": "El archivo  $1  no existe.",
        "changecontentmodel-success-text": "Se ha cambiado el tipo de contenido de [[:$1]].",
        "changecontentmodel-cannot-convert": "El contenido de [[:$1]] no se puede convertir a un tipo de $2.",
        "changecontentmodel-nodirectediting": "El modelo de contenido $1 no admite la edición directa",
+       "changecontentmodel-emptymodels-title": "No hay modelos de contenido disponibles",
        "log-name-contentmodel": "Registro de cambios del modelo de contenido",
        "log-description-contentmodel": "Eventos relacionados con los modelos de contenido de una página",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|creó}} la página $3 usando un modelo de contenido no predeterminado \"$5\"",
        "whatlinkshere-hideredirs": "$1 redirecciones",
        "whatlinkshere-hidetrans": "$1 inclusiones",
        "whatlinkshere-hidelinks": "$1 enlaces",
-       "whatlinkshere-hideimages": "$1 enlaces a archivos",
+       "whatlinkshere-hideimages": "Ocultar los vínculos de archivo",
        "whatlinkshere-filters": "Filtros",
        "whatlinkshere-submit": "Ir",
        "autoblockid": "Bloqueo automático #$1",
        "lockdbsuccesstext": "La base de datos de {{SITENAME}} ha sido bloqueada.\n<br />Recuerde retirar el bloqueo después de completar las tareas de mantenimiento.",
        "unlockdbsuccesstext": "La base de datos de {{SITENAME}} ha sido desbloqueada.",
        "lockfilenotwritable": "El archivo-cerrojo de la base de datos no tiene permiso de escritura. Para bloquear o desbloquear la base de datos, este archivo tiene que ser escribible por el servidor web.",
+       "databaselocked": "La base de datos ya está bloqueada.",
        "databasenotlocked": "La base de datos no está bloqueada.",
        "lockedbyandtime": "(por {{GENDER:$1|$1}} el $2 a las $3)",
        "move-page": "Trasladar $1",
        "tooltip-ca-nstab-category": "Ver la página de categoría",
        "tooltip-minoredit": "Marcar este cambio como menor",
        "tooltip-save": "Guardar los cambios",
+       "tooltip-publish": "Publicar tus cambios",
        "tooltip-preview": "Previsualiza tus cambios. ¡Hazlo antes de grabar!",
        "tooltip-diff": "Mostrar los cambios que has hecho en el texto.",
        "tooltip-compareselectedversions": "Ver las diferencias entre las dos versiones seleccionadas de esta página.",
index 038f823..aae6430 100644 (file)
        "upload-form-label-infoform-description": "Kirjeldus",
        "upload-form-label-usage-title": "Kasutus",
        "upload-form-label-usage-filename": "Failinimi",
-       "foreign-structured-upload-form-label-own-work": "See on minu enda töö",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategooriad",
-       "foreign-structured-upload-form-label-infoform-date": "Kuupäev",
-       "foreign-structured-upload-form-label-own-work-message-local": "Kinnitan, et seda faili üles laadides järgin saidi {{SITENAME}} kasutustingimusi ja litsentsipõhimõtteid.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Kui sul pole võimalik laadida seda faili üles kooskõlas saidi {{SITENAME}} reeglitega, siis palun sule see dialoog ja proovi teisiti toimida.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Võimalik, et soovid kasutada [[Special:Upload|harilikku üleslaadimislehekülge]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Saan aru, et laadin selle faili jagatud varamusse. Kinnitan, et teen seda kooskõlas sealsete kasutustingimuste ja litsentsipõhimõtetega.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Kui sul pole võimalik laadida seda faili üles kooskõlas jagatud varamu reeglitega, siis palun sule see dialoog ja proovi teisiti toimida.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Võimalik, et soovid [[Special:Upload|laadida selle faili üles saidil {{SITENAME}}]], kui seda on võimalik teha kooskõlas siinsete reeglitega.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Kinnitan, et olen selle faili autoriõiguse valdaja ja nõustun faili avaldamisega Wikimedia Commonsis pöördumatult Creative Commonsi litsentsi \"[https://creativecommons.org/licenses/by-sa/4.0/deed.et Autorile viitamine + jagamine samadel tingimustel 4.0]\" all. Samuti nõustun [https://wikimediafoundation.org/wiki/Terms_of_Use kasutustingimustega].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Kui sa pole selle faili autoriõiguse valdaja või kui soovid avaldada seda teise litsentsi all, siis on sul võimalik kasutada [https://commons.wikimedia.org/wiki/Special:UploadWizard Commonsi üleslaadimisviisardit].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Võimalik, et soovid kasutada [[Special:Upload|saidi {{SITENAME}} üleslaadimislehekülge]], kui seda faili on lubatud üles laadida kooskõlas siinsete reeglitega.",
+       "upload-form-label-own-work": "See on minu enda töö",
+       "upload-form-label-infoform-categories": "Kategooriad",
+       "upload-form-label-infoform-date": "Kuupäev",
+       "upload-form-label-own-work-message-local": "Kinnitan, et seda faili üles laadides järgin saidi {{SITENAME}} kasutustingimusi ja litsentsipõhimõtteid.",
+       "upload-form-label-not-own-work-message-local": "Kui sul pole võimalik laadida seda faili üles kooskõlas saidi {{SITENAME}} reeglitega, siis palun sule see dialoog ja proovi teisiti toimida.",
+       "upload-form-label-not-own-work-local-local": "Võimalik, et soovid kasutada [[Special:Upload|harilikku üleslaadimislehekülge]].",
+       "upload-form-label-own-work-message-default": "Saan aru, et laadin selle faili jagatud varamusse. Kinnitan, et teen seda kooskõlas sealsete kasutustingimuste ja litsentsipõhimõtetega.",
+       "upload-form-label-not-own-work-message-default": "Kui sul pole võimalik laadida seda faili üles kooskõlas jagatud varamu reeglitega, siis palun sule see dialoog ja proovi teisiti toimida.",
+       "upload-form-label-not-own-work-local-default": "Võimalik, et soovid [[Special:Upload|laadida selle faili üles saidil {{SITENAME}}]], kui seda on võimalik teha kooskõlas siinsete reeglitega.",
+       "upload-form-label-own-work-message-shared": "Kinnitan, et olen selle faili autoriõiguse valdaja ja nõustun faili avaldamisega Wikimedia Commonsis pöördumatult Creative Commonsi litsentsi \"[https://creativecommons.org/licenses/by-sa/4.0/deed.et Autorile viitamine + jagamine samadel tingimustel 4.0]\" all. Samuti nõustun [https://wikimediafoundation.org/wiki/Terms_of_Use kasutustingimustega].",
+       "upload-form-label-not-own-work-message-shared": "Kui sa pole selle faili autoriõiguse valdaja või kui soovid avaldada seda teise litsentsi all, siis on sul võimalik kasutada [https://commons.wikimedia.org/wiki/Special:UploadWizard Commonsi üleslaadimisviisardit].",
+       "upload-form-label-not-own-work-local-shared": "Võimalik, et soovid kasutada [[Special:Upload|saidi {{SITENAME}} üleslaadimislehekülge]], kui seda faili on lubatud üles laadida kooskõlas siinsete reeglitega.",
        "backend-fail-stream": "Faili $1 ei saanud edastada.",
        "backend-fail-backup": "Faili $1 ei saanud varundada.",
        "backend-fail-notexists": "Faili $1 pole olemas.",
index 9531e2c..4926942 100644 (file)
        "upload-form-label-infoform-description": "Deskribapena",
        "upload-form-label-usage-title": "Erabilera",
        "upload-form-label-usage-filename": "Fitxategiaren izena",
-       "foreign-structured-upload-form-label-own-work": "Hau neure lana da",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategoriak",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work": "Hau neure lana da",
+       "upload-form-label-infoform-categories": "Kategoriak",
+       "upload-form-label-infoform-date": "Data",
        "backend-fail-stream": "Ezin izan da \"$1\" fitxategiaren stream egin.",
        "backend-fail-backup": "Ezin izan da \"$1\" fitxategiaren backup egin.",
        "backend-fail-notexists": "$1 fitxategia ez da existitzen.",
        "tooltip-ca-nstab-category": "Kategoria orrialdea ikusi",
        "tooltip-minoredit": "Markatu aldaketa hau txikitzat",
        "tooltip-save": "Zure aldaketak gorde",
+       "tooltip-publish": "Argitaratu zure aldaketak",
        "tooltip-preview": "Zure aldaketak aurreikusi, mesedez gorde aurretik erabili!",
        "tooltip-diff": "Testuari egindako aldaketak erakutsi.",
        "tooltip-compareselectedversions": "Ikusi orri honen bi bertsio hautatuen arteko aldeak.",
index eac16c4..d60607c 100644 (file)
@@ -70,6 +70,7 @@
        "tog-watchdefault": "افزودن صفحه‌ها و پرونده‌هایی که ویرایش می‌کنم به فهرست پیگیری‌های من",
        "tog-watchmoves": "افزودن صفحه‌ها و پرونده‌هایی که منتقل می‌کنم به فهرست پی‌گیری‌های من",
        "tog-watchdeletion": "افزودن صفحات و پرونده‌هایی که حذف می‌کنم به فهرست پی‌گیری‌های من",
+       "tog-watchuploads": "افزودن پرونده‌های جدید به فهرست پیگیری من",
        "tog-watchrollback": "افزودن صفحاتی که واگردانی می‌کنم به فهرست پیگیری‌های من",
        "tog-minordefault": "علامت زدن همهٔ ویرایش‌ها به عنوان «جزئی» به طور پیش‌فرض",
        "tog-previewontop": "نمایش دادن پیش‌نمایش بالای جعبهٔ ویرایش",
        "minoredit": "این ویرایش، جزئی است",
        "watchthis": "پی‌گیری این صفحه",
        "savearticle": "صفحه ذخیره شود",
+       "publishpage": "انتشار صفحه",
        "preview": "پیش‌نمایش",
        "showpreview": "پیش‌نمایش",
        "showdiff": "نمایش تغییرات",
        "upload-form-label-infoform-description-tooltip": "به صورت خلاصه هرچیز سرشناسی که در مورد اثر باشد را توضیح دهید.\nبرای تصویر موارد اصلی مانند محل وقوع یا موقعیت را شرح دهید.",
        "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}}]] استفاده کنید.",
+       "upload-form-label-own-work": "این کار خودم است",
+       "upload-form-label-infoform-categories": "رده‌ها",
+       "upload-form-label-infoform-date": "تاریخ",
+       "upload-form-label-own-work-message-local": "تائید می کنم که این پرونده را تحت مجوزها و سیاست‌های {{SITENAME}} بارگذاری می‌کنم.",
+       "upload-form-label-not-own-work-message-local": "اگر امکان بارگذاری پرونده تحت سیاست‌های {{SITENAME}} را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "upload-form-label-not-own-work-local-local": "ممکن بخواهید از [[Special:Upload|پنجرهٔ بارگذاری پیش‌فرض]] استفاده کنید.",
+       "upload-form-label-own-work-message-default": "متوجهم که این پرونده را بر روی مخزن مشترک بارگذاری می‌کنم و تائید می‌کنم که تحت سیاست‌ها و مجوزهای آنجا عمل می‌کنم.",
+       "upload-form-label-not-own-work-message-default": "اگر امکان بارگذاری پرونده تحت سیاست‌ها و مجوزهای مخزن اشتراک‌گذاری را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "upload-form-label-not-own-work-local-default": "در صورتی که نمی‌شود پرونده را تحت سیاست‌ها بارگذاری کنید ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
+       "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 سیاست نحوهٔ استفاده] هستم.",
+       "upload-form-label-not-own-work-message-shared": "اگر مالک حق تکثیر این پرونده نیستید یا قصد بارگذاری تحت مجوز دیگری دارید، از [https://commons.wikimedia.org/wiki/Special:UploadWizard جادوگر بارگذاری ویکی‌انبار] استفاده کنید.",
+       "upload-form-label-not-own-work-local-shared": "در صورتی که سایت امکان بارگذاری پرونده را تحت سیاست‌ها بارگذاری می‌دهد ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
        "backend-fail-stream": "نمی‌توان پروندهٔ $1 را ارسال کرد.",
        "backend-fail-backup": "نمی‌توان نسخهٔ پشتیبان برای پروندهٔ $1 ایجاد کرد.",
        "backend-fail-notexists": "پروندهٔ $1 وجود ندارد.",
        "exbeforeblank": "محتوای صفحه قبل از خالی‌کردن این بود: «$1»",
        "delete-confirm": "حذف «$1»",
        "delete-legend": "حذف",
-       "historywarning": "<strong>هشدار:</strong> صفحه‌ای که در حال پاک‌کردن آن هستید دارای یک تاریخچه همراه $1 {{PLURAL:$1|بازبینی|بازبینی‌ها}} است:",
+       "historywarning": "<strong>هشدار:</strong> صفحه‌ای که در حال پاک‌کردن آن هستید دارای یک تاریخچه همراه $1 {{PLURAL:$1|بازبینی|بازبینی}} است:",
        "historyaction-submit": "نمایش",
        "confirmdeletetext": "شما در حال حذف کردن یک صفحه یا تصویر از پایگاه داده‌ها همراه با تمام تاریخچهٔ آن هستید.\nلطفاً این عمل را تأیید کنید و اطمینان حاصل کنید که عواقب این کار را می‌دانید و این عمل را مطابق با [[{{MediaWiki:Policy-url}}|سیاست‌ها]] انجام می‌دهید.",
        "actioncomplete": "عمل انجام شد",
        "tooltip-ca-nstab-category": "دیدن صفحهٔ رده",
        "tooltip-minoredit": "این ویرایش را ویرایش جزئی نشانه‌گذاری کن",
        "tooltip-save": "تغییرات خود را ذخیره کنید",
+       "tooltip-publish": "انتشار تغییراتتان",
        "tooltip-preview": "پیش‌نمایش تغییرات شما، لطفاً قبل از ذخیره کردن صفحه از این کلید استفاده کنید.",
        "tooltip-diff": "نمایش تغییراتی که شما در متن داده‌اید.",
        "tooltip-compareselectedversions": "دیدن تفاوت‌های دو نسخهٔ انتخاب‌شده از این صفحه",
        "confirmemail_body_set": "یک نفر، احتمالاً خود شما، از نشانی آی‌پی $1,\nآدرس ایمیل حساب «$2» در {{SITENAME}} را به این آدرس تغییر داده است.\n\nبرای تأیید این که این حساب واقعاً به شما تعلق دارد و فعال کردن دوبارهٔ قابلیت ایمیل در {{SITENAME}}، پیوند زیر را در مرورگرتان باز کنید:\n\n$3\n\nاگر این حساب متعلق به شما نیست، پیوند زیر را باز تا تغییر آدرس ایمیل، لغو شود:\n\n$5\n\nاین تأییدیه در $4 منقضی می‌گردد.",
        "confirmemail_invalidated": "تأیید نشانی ایمیل لغو شد",
        "invalidateemail": "لغو تأیید نشانی ایمیل",
+       "notificationemail_subject_changed": "نشانی ایمیل ثبت شدهٔ {{SITENAME}} تغییر یافته است",
+       "notificationemail_subject_removed": "نشانی ایمیل ثبت شدهٔ {{SITENAME}} حذف شده است",
        "scarytranscludedisabled": "[تراگنجانش بین‌ویکیانه فعال نیست]",
        "scarytranscludefailed": "[فراخوانی الگو برای $1 میسر نشد]",
        "scarytranscludefailed-httpstatus": "[فراخوانی الگو برای $1 میسر نشد: خطای اچ‌تی‌تی‌پی $2]",
        "searchsuggest-containing": "صفحه‌های دربردارنده...",
        "api-error-badaccess-groups": "شما اجازهٔ بارگذاری پرونده‌ها را در این ویکی ندارید.",
        "api-error-badtoken": "خطای داخلی: کد امنیتی اشتباه (Bad token).",
+       "api-error-blocked": "شما از ویرایش بسته شده‌اید.",
        "api-error-copyuploaddisabled": "بارگذاری با استفاده از نشانی اینترنتی در این کارساز غیرفعال است.",
        "api-error-duplicate": "{{PLURAL:$1|پروندهٔ دیگری|چند پروندهٔ دیگر}} در تارنما با محتوای یکسان وجود داشت.",
        "api-error-duplicate-archive": "{{PLURAL:$1| پروندهٔ دیگری|چند پروندهٔ دیگر}} در تارنما با محتوای یکسان وجود داشت، ولی حذف {{PLURAL:$1|شده است|شده‌اند}}.",
        "sessionprovider-nocookies": "کوکی‌ها ممکن است غیر فعال شده باشند. اطمینان کسب کنید که کوکی‌ها را فعال کرده‌اید و دوباره آغاز کنید.",
        "randomrootpage": "صفحهٔ ریشهٔ تصادفی",
        "log-action-filter-block": "نوع بسته شدن:",
+       "log-action-filter-contentmodel": "تغییر نوع contentmodel:",
        "log-action-filter-delete": "نوع حذف:",
        "log-action-filter-import": "نوع واردات",
        "log-action-filter-managetags": "نوع مدیریت",
        "log-action-filter-block-reblock": "تصحیح بلاک",
        "log-action-filter-block-unblock": "باز شدن",
        "log-action-filter-contentmodel-change": "تغییر نوع محتوا",
+       "log-action-filter-contentmodel-new": "ایجاد صفحه با contentmodel غیر استاندارد",
        "log-action-filter-delete-delete": "حذف صفحه",
        "log-action-filter-delete-restore": "احیای صفحه",
        "log-action-filter-delete-event": "حذف سیاهه",
        "log-action-filter-newusers-create2": "ایجاد شده توسط کاربر ثبت نام شده",
        "log-action-filter-newusers-autocreate": "ایجاد خودکار",
        "log-action-filter-newusers-byemail": "ایجاد پسورد با ارسال به ایمیل",
+       "log-action-filter-patrol-patrol": "گشت غیرخودکار",
        "log-action-filter-patrol-autopatrol": "گشت خودکار",
        "log-action-filter-protect-protect": "محافظت",
        "log-action-filter-protect-modify": "اصلاح حفاظت",
        "log-action-filter-suppress-event": "جلوگیری از ورود",
        "log-action-filter-suppress-revision": "جلوگیری از ویرایش",
        "log-action-filter-suppress-delete": "متوقف سازی صفحه",
+       "log-action-filter-suppress-block": "مخفی‌سازی کاربر با بستن",
+       "log-action-filter-suppress-reblock": "مخفی‌سازی کاربر با بستن مجدد",
        "log-action-filter-upload-upload": "بارگذاری جدید",
        "log-action-filter-upload-overwrite": "بارگذاری دوباره"
 }
index a2001d4..89834e6 100644 (file)
        "botpasswords-label-resetpassword": "Uudista salasana",
        "botpasswords-label-grants": "Valittavissa olevat toimintaoikeudet:",
        "botpasswords-label-restrictions": "Käyttörajoitukset:",
+       "botpasswords-label-grants-column": "Myönnetään",
        "botpasswords-bad-appid": "Botin nimi \"$1\" ei kelpaa.",
        "botpasswords-insert-failed": "Botin nimen \"$1\" lisääminen epäonnsitui. Onko se jo lisätty?",
        "botpasswords-update-failed": "Botin nimen \"$1\" päivittäminen epäonnistui. Onko se poistettu?",
        "minoredit": "Tämä on pieni muutos",
        "watchthis": "Tarkkaile tätä sivua",
        "savearticle": "Tallenna sivu",
+       "publishpage": "Julkaise sivu",
        "preview": "Esikatselu",
        "showpreview": "Esikatsele",
        "showdiff": "Näytä muutokset",
        "right-applychangetags": "Asettaa [[Special:Tags|merkkauksia]] omien muutosten yhteyteen",
        "right-changetags": "Lisätä ja poistaa satunnaisia [[Special:Tags|merkkauksia]] yksittäisissä sivuversioissa tai lokimerkinnöissä",
        "grant-generic": "\"$1\" oikeuksien joukko",
+       "grant-group-page-interaction": "Ole vuorovaikutuksessa sivujen kanssa",
+       "grant-group-file-interaction": "Ole vuorovaikutuksessa mediatiedostojen kanssa",
+       "grant-group-watchlist-interaction": "Ole vuorovaikutuksessa oman tarkkailulistasi kanssa",
        "grant-group-email": "Lähettää sähköpostia",
        "grant-group-high-volume": "Suorittaa suuri määrä toimintoja",
        "grant-group-customization": "Mukauttaminen ja asetukset",
        "upload-form-label-infoform-description-tooltip": "Kuvaa lyhyesti kaikkea, mikä on teoksessa huomionarvoista.\nJos kyseessä on valokuva, mainitse kuvatut pääasiat, tapahtuma tai paikka.",
        "upload-form-label-usage-title": "Käyttö",
        "upload-form-label-usage-filename": "Tiedostonimi",
-       "foreign-structured-upload-form-label-own-work": "Tämä on oma työni",
-       "foreign-structured-upload-form-label-infoform-categories": "Luokat",
-       "foreign-structured-upload-form-label-infoform-date": "Päivämäärä",
-       "foreign-structured-upload-form-label-own-work-message-local": "Vakuutan, että tallennan tämän tiedoston noudattaen sivustolla {{SITENAME}} voimassa olevia käyttöehtoja sekä lisenssejä koskevia käytäntöjä.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa sivustolla {{SITENAME}}, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Voit myös kokeilla [[Special:Upload|yleistä tallentamista]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Ymmärrän, että olen tallentamassa tätä tiedostoa yhteiseen mediasäilöön. Vakuutan, että teen tämän noudattaen asiaankuuluvia käyttöehtoja ja lisenssejä koskevia käytäntöjä.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa yhteisessä mediasäilössä, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Voit myös kokeilla [[Special:Upload|tallennussivua sivustolla {{SITENAME}}]]. Saattaa olla, että tämän tiedoston tallentaminen sinne on mahdollista siellä voimassa olevien käytäntöjen mukaisesti.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Vakuutan, että minä omistan tämän tiedoston tekijänoikeudet, ja sitoudun siihen, että luovutan peruuttamattomasti tämän tiedoston kohteeseen Wikimedia Commons niillä ehdoilla, jotka liittyvät lisenssiin [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0]. Sitoudun myös noudattamaan [https://wikimediafoundation.org/wiki/Terms_of_Use käyttöehtoja].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Jos sinulla ei ole tähän tiedostoon tekijänoikeutta tai jos haluat luovuttaa tiedoston käyttäen jotain toista lisenssiä, voit käyttää erityistä [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] -toimintoa.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Voit myös kokeilla [[Special:Upload|tallennussivua sivustolla {{SITENAME}}]]. Saattaa olla, että sivusto antaa tallentaa tämän tiedoston sinne siellä voimassa olevien käytäntöjen mukaisesti.",
+       "upload-form-label-own-work": "Tämä on oma työni",
+       "upload-form-label-infoform-categories": "Luokat",
+       "upload-form-label-infoform-date": "Päivämäärä",
+       "upload-form-label-own-work-message-local": "Vakuutan, että tallennan tämän tiedoston noudattaen sivustolla {{SITENAME}} voimassa olevia käyttöehtoja sekä lisenssejä koskevia käytäntöjä.",
+       "upload-form-label-not-own-work-message-local": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa sivustolla {{SITENAME}}, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
+       "upload-form-label-not-own-work-local-local": "Voit myös kokeilla [[Special:Upload|yleistä tallentamista]].",
+       "upload-form-label-own-work-message-default": "Ymmärrän, että olen tallentamassa tätä tiedostoa yhteiseen mediasäilöön. Vakuutan, että teen tämän noudattaen asiaankuuluvia käyttöehtoja ja lisenssejä koskevia käytäntöjä.",
+       "upload-form-label-not-own-work-message-default": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa yhteisessä mediasäilössä, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
+       "upload-form-label-not-own-work-local-default": "Voit myös kokeilla [[Special:Upload|tallennussivua sivustolla {{SITENAME}}]]. Saattaa olla, että tämän tiedoston tallentaminen sinne on mahdollista siellä voimassa olevien käytäntöjen mukaisesti.",
+       "upload-form-label-own-work-message-shared": "Vakuutan, että minä omistan tämän tiedoston tekijänoikeudet, ja sitoudun siihen, että luovutan peruuttamattomasti tämän tiedoston kohteeseen Wikimedia Commons niillä ehdoilla, jotka liittyvät lisenssiin [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0]. Sitoudun myös noudattamaan [https://wikimediafoundation.org/wiki/Terms_of_Use käyttöehtoja].",
+       "upload-form-label-not-own-work-message-shared": "Jos sinulla ei ole tähän tiedostoon tekijänoikeutta tai jos haluat luovuttaa tiedoston käyttäen jotain toista lisenssiä, voit käyttää erityistä [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] -toimintoa.",
+       "upload-form-label-not-own-work-local-shared": "Voit myös kokeilla [[Special:Upload|tallennussivua sivustolla {{SITENAME}}]]. Saattaa olla, että sivusto antaa tallentaa tämän tiedoston sinne siellä voimassa olevien käytäntöjen mukaisesti.",
        "backend-fail-stream": "Tiedoston $1 virtauttaminen epäonnistui.",
        "backend-fail-backup": "Tiedostoa $1 ei voitu varmuuskopioida.",
        "backend-fail-notexists": "Tiedostoa $1 ei ole olemassa.",
        "apisandbox-results-error": "Tapahtui virhe ladattaessa API-kyselyn vastausta: $1",
        "apisandbox-request-url-label": "Pyynnön URL",
        "apisandbox-request-time": "Pyyntöön kulunut aika: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Korjaa \"token\" ja lähetä uudelleen",
        "apisandbox-alert-page": "Tällä sivulla olevat kentät eivät ole kelvollisia.",
        "apisandbox-alert-field": "Tässä kentässä oleva arvo ei ole kelvollinen.",
        "booksources": "Kirjalähteet",
        "tooltip-ca-nstab-category": "Näytä luokkasivu",
        "tooltip-minoredit": "Merkitse tämä pieneksi muutokseksi",
        "tooltip-save": "Tallenna muokkaukset",
+       "tooltip-publish": "Julkaise tekemäsi muutokset",
        "tooltip-preview": "Esikatsele muokkausta ennen tallennusta",
        "tooltip-diff": "Näytä tehdyt muutokset",
        "tooltip-compareselectedversions": "Vertaile valittuja versioita",
        "log-action-filter-block-reblock": "Estoasetusten muuttaminen",
        "log-action-filter-block-unblock": "Eston poistaminen",
        "log-action-filter-contentmodel-change": "Sisältömallin muuttaminen",
+       "log-action-filter-contentmodel-new": "Luotu sivu, jossa on poikkeava Sisältömalli",
        "log-action-filter-delete-delete": "Sivun poistaminen",
        "log-action-filter-delete-restore": "Sivun palauttaminen",
        "log-action-filter-delete-event": "Lokimerkinnän poistaminen",
index 7128f68..672b071 100644 (file)
                        "C13m3n7",
                        "Gnangbade",
                        "Frigory",
-                       "Lemondoge"
+                       "Lemondoge",
+                       "Jdforrester",
+                       "Yasten"
                ]
        },
        "tog-underline": "Soulignement des liens :",
        "tog-editsectiononrightclick": "Activer la modification des sections par un clic droit sur les titres de section",
        "tog-watchcreations": "Ajouter à ma liste de suivi les pages que je crée et les fichiers que j’importe",
        "tog-watchdefault": "Ajouter à ma liste de suivi les pages et les fichiers que je modifie",
-       "tog-watchmoves": "Ajouter à ma liste de suivi les pages et les fichiers que je renomme",
+       "tog-watchmoves": "Ajouter les pages et les fichiers que je déplace dans ma liste de suivi",
        "tog-watchdeletion": "Ajouter à ma liste de suivi les pages et les fichiers que je supprime",
        "tog-watchuploads": "Ajouter les nouveaux fichiers que j’importe à ma liste de suivi",
        "tog-watchrollback": "Ajouter à ma liste de suivi les pages sur lesquelles j’ai effectué une révocation",
-       "tog-minordefault": "Marquer mes modifications comme étant mineures par défaut",
+       "tog-minordefault": "Marquer toutes les modifications comme étant mineures par défaut",
        "tog-previewontop": "Afficher la prévisualisation avant la zone d’édition",
        "tog-previewonfirst": "Afficher la prévisualisation lors de la première modification",
        "tog-enotifwatchlistpages": "M’avertir par courriel lorsqu’une page ou un fichier de ma liste de suivi est modifié",
        "tog-enotifusertalkpages": "M’avertir par courriel si ma page de discussion est modifiée",
        "tog-enotifminoredits": "M’avertir par courriel également lors des modifications mineures des pages ou des fichiers",
        "tog-enotifrevealaddr": "Afficher mon adresse électronique dans les courriels de notification",
-       "tog-shownumberswatching": "Afficher le nombre d’utilisateurs qui suivent la page",
+       "tog-shownumberswatching": "Afficher le nombre d’utilisateurs en cours",
        "tog-oldsig": "Signature existante :",
        "tog-fancysig": "Traiter la signature comme du wikitexte (sans lien automatique)",
        "tog-uselivepreview": "Utiliser l’aperçu rapide",
        "viewhelppage": "Voir la page d'aide",
        "categorypage": "Voir la page de catégorie",
        "viewtalkpage": "Voir la page de discussion",
-       "otherlanguages": "Autres langues",
+       "otherlanguages": "Dans d'autres langues",
        "redirectedfrom": "(Redirigé depuis $1)",
        "redirectpagesub": "Page de redirection",
        "redirectto": "Rediriger vers :",
        "confirmable-no": "Non",
        "thisisdeleted": "Désirez-vous afficher ou restaurer $1 ?",
        "viewdeleted": "Voir $1 ?",
-       "restorelink": "{{PLURAL:$1|la modification effacée|les $1 modifications effacées}}",
+       "restorelink": "{{PLURAL:$1|une modification effacée|$1 modifications effacées}}",
        "feedlinks": "Flux :",
-       "feed-invalid": "Type de flux invalide.",
+       "feed-invalid": "Type de flux invalide pour abonnement.",
        "feed-unavailable": "Les flux de syndication ne sont pas disponibles",
        "site-rss-feed": "Flux RSS de $1",
        "site-atom-feed": "Flux Atom de $1",
        "yourpasswordagain": "Confirmez le mot de passe :",
        "createacct-yourpasswordagain": "Confirmez le mot de passe",
        "createacct-yourpasswordagain-ph": "Entrez à nouveau le mot de passe",
-       "remembermypassword": "Me reconnecter automatiquement lors des prochaines visites avec ce navigateur (durant au maximum $1 jour{{PLURAL:$1||s}})",
+       "remembermypassword": "Mémoriser mes données de connection avec ce navigateur (durant au maximum $1 jour{{PLURAL:$1||s}})",
        "userlogin-remembermypassword": "Garder ma session active",
        "userlogin-signwithsecure": "Utiliser une connexion sécurisée",
        "cannotloginnow-title": "Impossible de se connecter maintenant",
        "cannotloginnow-text": "La connexion n’est pas possible en utilisant $1.",
        "yourdomainname": "Votre domaine :",
        "password-change-forbidden": "Vous ne pouvez pas modifier les mots de passe sur ce wiki.",
-       "externaldberror": "Une erreur s’est produite sur la base de données d’authentification externe, ou bien vous n’êtes pas autorisé à mettre à jour votre compte externe.",
+       "externaldberror": "Soit une erreur s’est produite sur la base de données d’authentification, soit vous n’êtes pas autorisé à mettre à jour votre compte externe.",
        "login": "Connexion",
        "nav-login-createaccount": "Créer un compte ou se connecter",
        "userlogin": "Créer un compte ou se connecter",
        "nocookiesfornew": "Le compte utilisateur n’a pas été créé, car nous n’avons pas pu identifier son origine.\nVérifiez que vous avez activé les cookies, rechargez la page et essayez à nouveau.",
        "noname": "Vous n’avez pas saisi un nom d’utilisateur valide.",
        "loginsuccesstitle": "Connecté",
-       "loginsuccess": "Vous êtes maintenant connecté{{GENDER:$1||e|(e)}} à {{SITENAME}} en tant que « $1 ».",
+       "loginsuccess": "<strong>Vous êtes maintenant connecté{{GENDER:$1||e|(e)}} à {{SITENAME}} en tant que « $1 ».</strong>",
        "nosuchuser": "L'utilisateur « $1 » n’existe pas.\nLes noms d’utilisateurs sont sensibles à la casse.\nVérifiez l’orthographe, ou [[Special:UserLogin/signup|créez un nouveau compte]].",
        "nosuchusershort": "Il n’y a pas de contributeur avec le nom « $1 ».\nVeuillez vérifier l’orthographe.",
        "nouserspecified": "Vous devez saisir un nom d’utilisateur.",
        "noemail": "Aucune adresse de courriel n’a été enregistrée pour l'utilisateur « $1 ».",
        "noemailcreate": "Vous devez fournir une adresse de courriel valide",
        "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisateur « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.",
-       "blocked-mailpassword": "Votre adresse IP est bloquée pour la modification. Pour éviter les abus, il n’est pas autorisé d’utiliser la récupération de mot de passe à partir de cette adresse IP.",
+       "blocked-mailpassword": "Votre adresse IP est bloquée en modification. Pour éviter les abus, il n’est pas autorisé d’utiliser la récupération de mot de passe à partir de cette adresse IP.",
        "eauthentsent": "Un courriel de confirmation a été envoyé à l’adresse indiquée.\nAvant qu’un autre courriel ne soit envoyé à ce compte, vous devrez suivre les instructions du courriel et confirmer que le compte est bien le vôtre.",
        "throttled-mailpassword": "Un courriel de réinitialisation de votre mot de passe a déjà été envoyé durant {{PLURAL:$1|la dernière heure|les $1 dernières heures}}. \nAfin d’éviter les abus, un seul courriel de réinitialisation de votre mot de passe sera envoyé par {{PLURAL:$1|heure|intervalle de $1 heures}}.",
        "mailerror": "Erreur lors de l’envoi du courriel : $1",
        "minoredit": "Modification mineure",
        "watchthis": "Suivre cette page",
        "savearticle": "Enregistrer",
+       "publishpage": "Publier la page",
        "preview": "Prévisualisation",
        "showpreview": "Prévisualiser",
        "showdiff": "Voir les modifications",
        "userpage-userdoesnotexist": "Le compte utilisateur « <nowiki>$1</nowiki> » n'est pas enregistré. Veuillez vérifier que vous voulez créer cette page.",
        "userpage-userdoesnotexist-view": "Le compte utilisateur « $1 » n'est pas enregistré.",
        "blocked-notice-logextract": "Cet utilisateur est actuellement bloqué.\nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d’information :",
-       "clearyourcache": "'''Note :''' après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* '''Firefox / Safari :''' Maintenez la touche ''Maj'' (''Shift'') en cliquant sur le bouton ''Actualiser'' ou pressez ''Ctrl-F5'' ou ''Ctrl-R'' (''⌘-R'' sur un Mac) ;\n* '''Google Chrome :''' Appuyez sur ''Ctrl-Maj-R'' (''⌘-Shift-R'' sur un Mac) ;\n* '''Internet Explorer :''' Maintenez la touche ''Ctrl'' en cliquant sur le bouton ''Actualiser'' ou pressez ''Ctrl-F5'' ;\n* '''Opera :''' Videz le cache dans ''Outils → Préférences''.",
+       "clearyourcache": "<strong>Note :</strong> après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* <strong>Firefox / Safari :</strong> Maintenez la touche <em>Maj</em> (<em>Shift</em>) en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac) ;\n* <strong>Google Chrome :</strong> Appuyez sur <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> sur un Mac) ;\n* <strong>Internet Explorer :</strong> Maintenez la touche <em>Ctrl</em> en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ;\n* <strong>Opera :</strong> Allez dans <em>Menu → Settings</em> (<em>Opera → Préférences</em> sur un Mac) et ensuite à <em>Confidentialité & sécurité → Effacer les données d'exploration → Images et fichiers en cache</em>.",
        "usercssyoucanpreview": "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l'enregistrer.",
        "userjsyoucanpreview": "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l'enregistrer.",
        "usercsspreview": "'''Rappelez-vous que vous n'êtes qu'en train de prévisualiser votre propre feuille CSS.'''\n'''Elle n'a pas encore été enregistrée !'''",
        "upload-form-label-infoform-description-tooltip": "Décrire brièvement tout ce qu’il y a de particulier concernant cette œuvre.\nPour une photo, mentionner les choses principales qui sont vues, l’occasion, ou l’endroit.",
        "upload-form-label-usage-title": "Utilisation",
        "upload-form-label-usage-filename": "Nom du fichier",
-       "foreign-structured-upload-form-label-own-work": "Je suis l’auteur de cette œuvre",
-       "foreign-structured-upload-form-label-infoform-categories": "Catégories",
-       "foreign-structured-upload-form-label-infoform-date": "Date",
-       "foreign-structured-upload-form-label-own-work-message-local": "Je confirme que je télécharge ce fichier suivant les conditions et les politiques de licence de {{SITENAME}}",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Si vous ne pouvez pas télécharger ce fichier d’après les politiques de {{SITENAME}}, veuillez fermer cette boîte de dialogue et essayer une autre méthode.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Vous pouvez aussi essayer [[Special:Upload|la page de téléchargement par défaut]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Je comprends que je téléverse ce fichier vers un dépôt partagé. Je confirme agir en accord avec les conditions d’utilisation et les règles relatives aux licences de celui-ci.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Si vous n’êtes pas en mesure de téléverser ce fichier de façon conforme aux règles de ce dépôt partagé, veuillez fermer cette boîte de dialogue et essayer une autre méthode.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si les règles du site autorisent le téléversement du fichier.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Je certifie être le détenteur des droits d’auteur sur ce fichier, j’accepte de publier ce fichier sur Wikimedia Commons en le plaçant irrévocablement sous licence [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] et j’accepte les [https://wikimediafoundation.org/wiki/Terms_of_Use conditions d’utilisation].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Si vous n’êtes pas le détenteur des droits d’auteur sur ce fichier ou que vous voulez le publier sous une licence différente, vous pouvez utiliser l’[https://commons.wikimedia.org/wiki/Special:UploadWizard assistant d’import].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si les règles du site autorisent le téléversement du fichier.",
+       "upload-form-label-own-work": "Je suis l’auteur de cette œuvre",
+       "upload-form-label-infoform-categories": "Catégories",
+       "upload-form-label-infoform-date": "Date",
+       "upload-form-label-own-work-message-local": "Je confirme que je télécharge ce fichier suivant les conditions et les politiques de licence de {{SITENAME}}",
+       "upload-form-label-not-own-work-message-local": "Si vous ne pouvez pas télécharger ce fichier d’après les politiques de {{SITENAME}}, veuillez fermer cette boîte de dialogue et essayer une autre méthode.",
+       "upload-form-label-not-own-work-local-local": "Vous pouvez aussi essayer [[Special:Upload|la page de téléchargement par défaut]].",
+       "upload-form-label-own-work-message-default": "Je comprends que je téléverse ce fichier vers un dépôt partagé. Je confirme agir en accord avec les conditions d’utilisation et les règles relatives aux licences de celui-ci.",
+       "upload-form-label-not-own-work-message-default": "Si vous n’êtes pas en mesure de téléverser ce fichier de façon conforme aux règles de ce dépôt partagé, veuillez fermer cette boîte de dialogue et essayer une autre méthode.",
+       "upload-form-label-not-own-work-local-default": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si les règles du site autorisent le téléversement du fichier.",
+       "upload-form-label-own-work-message-shared": "Je certifie être le détenteur des droits d’auteur sur ce fichier, j’accepte de publier ce fichier sur Wikimedia Commons en le plaçant irrévocablement sous licence [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] et j’accepte les [https://wikimediafoundation.org/wiki/Terms_of_Use conditions d’utilisation].",
+       "upload-form-label-not-own-work-message-shared": "Si vous n’êtes pas le détenteur des droits d’auteur sur ce fichier ou que vous voulez le publier sous une licence différente, vous pouvez utiliser l’[https://commons.wikimedia.org/wiki/Special:UploadWizard assistant d’import].",
+       "upload-form-label-not-own-work-local-shared": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si les règles du site autorisent le téléversement du fichier.",
        "backend-fail-stream": "Impossible de lire le fichier $1.",
        "backend-fail-backup": "Impossible de sauvegarder le fichier $1.",
        "backend-fail-notexists": "Le fichier $1 n’existe pas.",
        "changecontentmodel-success-text": "Le modèle de contenu de [[:$1]] a été modifié.",
        "changecontentmodel-cannot-convert": "Le contenu sur [[:$1]] n’a pas pu être converti en un type de $2.",
        "changecontentmodel-nodirectediting": "Le modèle de contenu $1 ne permet pas la modification directe",
+       "changecontentmodel-emptymodels-title": "Aucun modèle de contenu disponible",
+       "changecontentmodel-emptymodels-text": "Le contenu sur [[:$1]] ne peut être converti en aucun type.",
        "log-name-contentmodel": "Journal de modification de modèle de contenu",
        "log-description-contentmodel": "Événements relatifs aux modèles de contenu d’une page",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|a créé}} la page $3 en utilisant un modèle de contenu « $5 » autre que celui par défaut",
        "whatlinkshere-prev": "{{PLURAL:$1|précédente|$1 précédentes}}",
        "whatlinkshere-next": "{{PLURAL:$1|suivante|$1 suivantes}}",
        "whatlinkshere-links": "← liens",
-       "whatlinkshere-hideredirs": "$1 les redirections",
-       "whatlinkshere-hidetrans": "$1 les inclusions",
-       "whatlinkshere-hidelinks": "$1 les liens",
-       "whatlinkshere-hideimages": "$1 les liens vers le fichier",
+       "whatlinkshere-hideredirs": "Masquer les redirections",
+       "whatlinkshere-hidetrans": "Masquer les inclusions",
+       "whatlinkshere-hidelinks": "Masquer les liens",
+       "whatlinkshere-hideimages": "Masquer les liens vers le fichier",
        "whatlinkshere-filters": "Filtres",
        "whatlinkshere-submit": "Lister",
        "autoblockid": "Blocage automatique #$1",
        "lockdbsuccesstext": "La base de données a été verrouillée.<br />\nN'oubliez pas de la [[Special:UnlockDB|déverrouiller]] lorsque vous aurez terminé votre opération de maintenance.",
        "unlockdbsuccesstext": "La base de données a été déverrouillée.",
        "lockfilenotwritable": "Le fichier de verrouillage de la base de données n'est pas inscriptible.\nPour bloquer ou débloquer la base de données, il doit être accessible par le serveur web.",
+       "databaselocked": "La base de données est déjà verrouillée.",
        "databasenotlocked": "La base de données n'est pas verrouillée.",
        "lockedbyandtime": "(par $1 le $2 à $3)",
        "move-page": "Renommer $1",
        "tooltip-ca-nstab-category": "Voir la page de la catégorie",
        "tooltip-minoredit": "Marquer mes modifications comme mineures",
        "tooltip-save": "Enregistrer vos modifications",
+       "tooltip-publish": "Publier vos modifications",
        "tooltip-preview": "Merci de prévisualiser vos modifications avant de les publier",
        "tooltip-diff": "Affiche les modifications que vous avez apportées au texte",
        "tooltip-compareselectedversions": "Afficher les différences entre deux versions de cette page",
        "anonusers": "{{PLURAL:$2|l'utilisateur anonyme|les utilisateurs anonymes}} $1 de {{SITENAME}}",
        "creditspage": "Crédits de la page",
        "nocredits": "Il n'y a pas d'informations d'attribution disponibles pour cette page.",
-       "spamprotectiontitle": "Filtre de protection anti-spam",
+       "spamprotectiontitle": "Filtre de protection anti-pollupostage",
        "spamprotectiontext": "La page que vous avez voulu sauvegarder a été bloquée par le filtre anti-spam. Ceci est probablement dû à l'introduction d'un lien vers un site externe apparaissant sur la liste noire.",
-       "spamprotectionmatch": "Le texte suivant a déclenché notre filtre de protection anti-spam : $1",
+       "spamprotectionmatch": "Le texte suivant a déclenché notre filtre de protection anti-pollupostage : $1",
        "spambot_username": "Nettoyage de pourriels par MediaWiki",
        "spam_reverting": "Rétablissement de la dernière version ne contenant pas de lien vers $1",
        "spam_blanking": "Toutes les versions contenant des liens vers $1 sont blanchies",
        "invalidateemail": "Annuler la confirmation de l'adresse de courriel",
        "notificationemail_subject_changed": "L’adresse courriel enregistrée sur {{SITENAME}} a été changée",
        "notificationemail_subject_removed": "L’adresse courriel enregistrée sur {{SITENAME}} a été supprimée",
-       "notificationemail_body_changed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1,\na changé l’adresse courriel associée au compte « $2 » sur {{SITENAME}}\nen « $3 ».\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
+       "notificationemail_body_changed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1, a changé l’adresse courriel\nassociée au compte « $2 » sur {{SITENAME}} en « $3 ».\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
        "notificationemail_body_removed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1,\na suprrimé l’adresse courriel associée au compte « $2 » sur {{SITENAME}}.\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
        "scarytranscludedisabled": "[La transclusion interwiki est désactivée]",
        "scarytranscludefailed": "[La récupération de modèle a échoué pour $1]",
        "feedback-useragent": "Agent utilisateur :",
        "searchsuggest-search": "Rechercher",
        "searchsuggest-containing": "contenant...",
+       "api-error-autoblocked": "Votre adresse IP a été bloquée automatiquement, parce qu’elle a été utilisée par un utilisateur bloqué.",
        "api-error-badaccess-groups": "Vous n'êtes pas autorisé à verser des fichiers sur ce wiki.",
        "api-error-badtoken": "Erreur interne : mauvais « jeton ».",
+       "api-error-blocked": "Vous avez été bloqué en édition.",
        "api-error-copyuploaddisabled": "Les versements via URL sont désactivés sur ce serveur.",
        "api-error-duplicate": "Il y a déjà {{PLURAL:$1|un autre fichier présent|d'autres fichiers présents}} sur le site avec le même contenu.",
        "api-error-duplicate-archive": "Il y avait déjà {{PLURAL:$1|un autre fichier présent|d'autres fichiers présents}} sur le site avec le même contenu, mais {{PLURAL:$1|il a été supprimé|ils ont été supprimés}}.",
        "api-error-nomodule": "Erreur interne : aucun module de versement défini.",
        "api-error-ok-but-empty": "Erreur interne : Le serveur n'a pas répondu.",
        "api-error-overwrite": "Écraser un fichier existant n'est pas autorisé.",
+       "api-error-ratelimited": "Vous essayez de téléverser plus de fichiers dans un court espace de temps que ce que ce wiki peut accepter.\nVeuillez réessayer dans quelques minutes.",
        "api-error-stashfailed": "Erreur interne : le serveur n'a pas pu enregistrer le fichier temporaire.",
        "api-error-publishfailed": "Erreur interne : Le serveur n'a pas pu publier le fichier temporaire.",
        "api-error-stasherror": "Une erreur s'est produite lors du téléchargement du fichier pour le dissimuler.",
index 6f53f26..e86bd46 100644 (file)
        "category-empty": "<em>Ora cela catègoria contint gins de pâge de mèdiâ.</em>",
        "hidden-categories": "{{PLURAL:$1|Catègoria cachiêe|Catègories cachiêes}}",
        "hidden-category-category": "Catègories cachiêes",
-       "category-subcat-count": "Cela catègoria at {{PLURAL:$2|mas que cela sot-catègoria-que.|{{PLURAL:$1|cela sot-catègoria|celes $1 sot-catègories}}-que, sur na soma de $2.}}",
-       "category-subcat-count-limited": "Cela catègoria at {{PLURAL:$1|cela sot-catègoria|celes $1 sot-catègories}}-que.",
-       "category-article-count": "{{PLURAL:$2|Cela catègoria contint mas que cela pâge-que.|{{PLURAL:$1|Cela pâge-que est|Celes $1 pâges-que sont}} a cela catègoria, sur na soma de $2.}}",
-       "category-article-count-limited": "{{PLURAL:$1|Cela pâge-que figure|Celes $1 pâges-que figuront}} dedens la presenta catègoria.",
-       "category-file-count": "{{PLURAL:$2|Cela catègoria contint mas que cél fichiér-que.|{{PLURAL:$1|Cél fichiér-que est|Celos $1 fichiérs-que sont}} a cela catègoria, sur na soma de $2.}}",
-       "category-file-count-limited": "{{PLURAL:$1|Cél fichiér-que figure|Celos $1 fichiérs-que figuront}} dedens la presenta catègoria.",
+       "category-subcat-count": "Cela catègoria at {{PLURAL:$2|mas que ceta sot-catègoria.|{{PLURAL:$1|ceta sot-catègoria|cetes $1 sot-catègories}}, sur na soma de $2.}}",
+       "category-subcat-count-limited": "Cela catègoria at {{PLURAL:$1|ceta sot-catègoria|cetes $1 sot-catègories}}.",
+       "category-article-count": "{{PLURAL:$2|Cela catègoria contint mas que ceta pâge.|{{PLURAL:$1|Ceta pâge est|Cetes $1 pâges sont}} a cela catègoria, sur na soma de $2.}}",
+       "category-article-count-limited": "{{PLURAL:$1|Ceta pâge figure|Cetes $1 pâges figuront}} dedens la presenta catègoria.",
+       "category-file-count": "{{PLURAL:$2|Cela catègoria contint mas que ceti fichiér.|{{PLURAL:$1|Ceti fichiér est|Cetos $1 fichiérs sont}} a cela catègoria, sur na soma de $2.}}",
+       "category-file-count-limited": "{{PLURAL:$1|Ceti fichiér figure|Cetos $1 fichiérs figuront}} dedens la presenta catègoria.",
        "listingcontinuesabbrev": "(suita)",
        "index-category": "Pâges endèxâyes",
        "noindex-category": "Pâges pas endèxâyes",
        "title-invalid-magic-tilde": "Lo titro de la pâge demandâye contint na cobla de tildes magicos pas justa (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "Lo titro de la pâge demandâye est trop long. Dêt pas dèpassar $1 octèt{{PLURAL:$1||s}} dens l’encodâjo UTF-8.",
        "title-invalid-leading-colon": "Lo titro de la pâge demandâye contint un doux-pouents pas justo u comencement.",
-       "perfcached": "Celes balyês-que sont en cacho et pôvont pas étre a jorn. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.",
-       "perfcachedts": "Celes balyês-que sont en cacho et sont étâyes betâyes a jorn por lo dèrriér côp lo $1. Por lo més {{PLURAL:$4|un rèsultat est disponiblo|$4 rèsultats sont disponiblos}} dedens lo cacho.",
+       "perfcached": "Cetes balyês sont en cacho et pôvont pas étre a jorn. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.",
+       "perfcachedts": "Cetes balyês sont en cacho et sont étâyes betâyes a jorn por lo dèrriér côp lo $1. Por lo més {{PLURAL:$4|un rèsultat est disponiblo|$4 rèsultats sont disponiblos}} dedens lo cacho.",
        "querypage-no-updates": "Ora les mêses a jorn por cela pâge sont dèsactivâyes.\nLes balyês ique seront pas betâyes a jorn.",
        "viewsource": "Vêre lo tèxto sôrsa",
        "viewsource-title": "Vêre lo tèxto sôrsa de $1",
        "protectedinterface": "Cela pâge balye de tèxto d’entredoux por la programeria sur cél vouiqui et est vêr protègiêe por èvitar los abus.\nPor apondre ou ben changiér de traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
        "editinginterface": "<strong>Atencion :</strong> vos éte aprés changiér na pâge empleyêe por fâre lo tèxto d’entredoux de la programeria.\nLos changements sè cognetront sur l’aparence de l’entredoux utilisator por los ôtros utilisators de cél vouiqui.",
        "translateinterface": "Por apondre changiér de traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
-       "cascadeprotected": "Cela pâge est protègiêe contre los changements, el est transcllua per {{PLURAL:$1|cela pâge-que qu’est étâye protègiêe|celes pâges-que que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ :\n$2",
+       "cascadeprotected": "Cela pâge est protègiêe contre los changements, el est transcllua per {{PLURAL:$1|ceta pâge qu’est étâye protègiêe|cetes pâges que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ :\n$2",
        "namespaceprotected": "Vos éd pas la pèrmission de changiér les pâges de l’èspâço de noms « <strong>$1</strong> ».",
        "customcssprotected": "Vos éd pas la pèrmission de changiér cela pâge CSS, contint la configuracion a sè d’un ôtr’utilisator.",
        "customjsprotected": "Vos éd pas la pèrmission de changiér cela pâge JavaScript, contint la configuracion a sè d’un ôtr’utilisator.",
        "mailerror": "Fôta pendent l’èxpèdicion du mèssâjo : $1",
        "acct_creation_throttle_hit": "Des vesitors de cél vouiqui qu’emplèyont voutron adrèce IP ant fêt $1 comptio{{PLURAL:$1||s}} pendent lo jorn passâ, cen qu’est lo més ôtorisâ dens ceti temps.\nDu côp los vesitors qu’emplèyont cel’adrèce IP pôvont fâre gins de comptio por lo moment.",
        "emailauthenticated": "Voutron adrèce èlèctronica est étâye confirmâye lo $2 a $3.",
-       "emailnotauthenticated": "Voutron adrèce èlèctronica est p’oncor confirmâye.\nNion mèssâjo serat mandâ por châcuna de celes fonccionalitâts-que.",
+       "emailnotauthenticated": "Voutron adrèce èlèctronica est p’oncor confirmâye.\nNion mèssâjo serat mandâ por châcuna de cetes fonccionalitâts.",
        "noemailprefs": "Spècifiâd un’adrèce èlèctronica dens voutres prèferences por empleyér celes fonccionalitâts.",
        "emailconfirmlink": "Confirmâd voutron adrèce èlèctronica",
        "invalidemailaddress": "Cel’adrèce èlèctronica pôt pas étre accèptâye, semble avêr un format pas justo.\nSe vos plét, buchiéd un’adrèce ben formatâye ou ben lèssiéd cél champ vouedo.",
        "passwordreset-capture-help": "Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat montrâ quand serat mandâ a l’utilisator.",
        "passwordreset-email": "Adrèce èlèctronica :",
        "passwordreset-emailtitle": "Dètalys du comptio dessus {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Yon (de sûr vos, avouéc l’adrèce IP $1) at demandâ na remês’a zérô de voutron\ncontresegno por {{SITENAME}} ($4). {{PLURAL:$3|Cél comptio utilisator-que est associyê|Celos comptios utilisators-que sont associyês}}\na cel’adrèce èlèctronica :\n\n$2\n\n{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.\nOra vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos\nou ben se vos vos éte rapelâ de voutron contresegno originâl et que vos en voléd pas més changiér,\nvos pouede ignorar cél mèssâjo et continuar a empleyér voutron viely contresegno.",
-       "passwordreset-emailtext-user": "L’utilisator $1 dessus {{SITENAME}} at demandâ na remês’a zérô de voutron contresegno por {{SITENAME}}\n($4). {{PLURAL:$3|Cél comptio utilisator-que est associyê|Celos comptios utilisators-que sont associyês}}\na cel’adrèce èlèctronica :\n\n$2\n\n{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.\nOra vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos\nou ben se vos vos éte rapelâ de voutron contresegno originâl et que vos en voléd pas més changiér,\nvos pouede ignorar cél mèssâjo et continuar a empleyér voutron viely contresegno.",
+       "passwordreset-emailtext-ip": "Yon (de sûr vos, avouéc l’adrèce IP $1) at demandâ na remês’a zérô de voutron\ncontresegno por {{SITENAME}} ($4). {{PLURAL:$3|Ceti comptio utilisator est associyê|Cetos comptios utilisators sont associyês}}\na cel’adrèce èlèctronica :\n\n$2\n\n{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.\nOra vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos\nou ben se vos vos éte rapelâ de voutron contresegno originâl et que vos en voléd pas més changiér,\nvos pouede ignorar cél mèssâjo et continuar a empleyér voutron viely contresegno.",
+       "passwordreset-emailtext-user": "L’utilisator $1 dessus {{SITENAME}} at demandâ na remês’a zérô de voutron contresegno por {{SITENAME}}\n($4). {{PLURAL:$3|Ceti comptio utilisator est associyê|Cetos comptios utilisators sont associyês}}\na cel’adrèce èlèctronica :\n\n$2\n\n{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.\nOra vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos\nou ben se vos vos éte rapelâ de voutron contresegno originâl et que vos en voléd pas més changiér,\nvos pouede ignorar cél mèssâjo et continuar a empleyér voutron viely contresegno.",
        "passwordreset-emailelement": "Nom d’utilisator :\n$1\n\nContresegno temporèro :\n$2",
        "passwordreset-emailsentemail": "Se cel’adrèce èlèctronica est associyêe a voutron comptio, adonc un mèssâjo de remês’a zérô de contresegno serat mandâ.",
        "passwordreset-emailsentusername": "S’y at un’adrèce èlèctronica associyêe a cél nom d’utilisator, adonc un mèssâjo de remês’a zérô de contresegno serat mandâ.",
        "minoredit": "O est un petiôt changement",
        "watchthis": "Siuvre cela pâge",
        "savearticle": "Encartar la pâge",
+       "publishpage": "Publeyér la pâge",
        "preview": "Apèrçu",
        "showpreview": "Montrar un apèrçu",
        "showdiff": "Montrar los changements",
        "userpage-userdoesnotexist": "Lo comptio utilisator « $1 » est pas encartâ.\nSe vos plét, controlâd se vos voléd fâre changiér cela pâge.",
        "userpage-userdoesnotexist-view": "Lo comptio utilisator « $1 » est pas encartâ.",
        "blocked-notice-logextract": "Ora {{GENDER:$1|cél utilisator|cel’utilisatrice}} est blocâ{{GENDER:$1||ye}}.\nLa dèrriére entrâ du jornâl des blocâjos est balyêe ce-desot coment rèference :",
-       "clearyourcache": "<strong>Nota :</strong> aprés avêr encartâ, sè pôt que vos deveyéd forciér lo rechargement complèt du cacho de voutron navegator por vêre los changements.\n* <strong>Firefox / Safari :</strong> mantegnéd la toche <em>Granta Lètra</em> (<em>Shift</em>) en clliquent dessus <em>Rechargiér</em> (<em>Reload</em>) ou ben apoyéd dessus <em>Ctrl-F5</em> <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac)\n* <strong>Google Chrome :</strong> apoyéd dessus <em>Ctrl-Shift-R</em> (''⌘-Shift-R</em> sur un Mac)\n* <strong>Internet Explorer :</strong> mantegnéd la toche <em>Ctrl</em> en clliquent dessus <em>Rafrèchir</em> (<em>Refresh</em>) ou ben apoyéd dessus <em>Ctrl-F5</em>\n* <strong>Opera :</strong> vouedâd lo cacho dedens <em>Outils → Prèferences</em>",
+       "clearyourcache": "<strong>Nota :</strong> aprés avêr encartâ, sè pôt que vos deveyéd forciér lo rechargement complèt du cacho de voutron navegator por vêre los changements.\n* <strong>Firefox / Safari :</strong> mantegnéd la toche <em>Granta Lètra</em> (<em>Shift</em>) en clliquent dessus <em>Rechargiér</em> (<em>Reload</em>) ou ben apoyéd dessus <em>Ctrl-F5</em> <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac)\n* <strong>Google Chrome :</strong> apoyéd dessus <em>Ctrl-Shift-R</em> (''⌘-Shift-R</em> sur un Mac)\n* <strong>Internet Explorer :</strong> mantegnéd la toche <em>Ctrl</em> en clliquent dessus <em>Rafrèchir</em> (<em>Refresh</em>) ou ben apoyéd dessus <em>Ctrl-F5</em>\n* <strong>Opera :<strong> alâd dedens <em>Menu → Settings</em> (<em>Opera → Prèferences</em> sur un Mac) et pués a <em>Confidencialitât & sècuritât → Vouedar les balyês d’èxploracion → Émâges et fichiérs en cacho</em>.",
        "usercssyoucanpreview": "<strong>Combina :</strong> empleyéd lo boton « {{int:showpreview}} » por èprovar voutra fôlye CSS novèla devant que l’encartar.",
        "userjsyoucanpreview": "<strong>Combina :</strong> empleyéd lo boton « {{int:showpreview}} » por èprovar voutra fôlye JavaScript novèla devant que l’encartar.",
        "usercsspreview": "<strong>Rapelâd-vos que vos éte ren qu’aprés prèvêre voutra fôlye CSS.\nEl est p’oncor étâye encartâye !</strong>",
        "readonlywarning": "<strong>Atencion : la bâsa de balyês est étâye cotâye por na rotina d’entretin, cen fât que vos porréd vêr pas encartar voutros changements orendrêt.</strong>\nVos pouede copiyér et côlar voutron tèxto dedens un fichiér tèxto et pués l’encartar por ples târd.\n\nL’administrator sistèmo que l’at cotâ at balyê cel’èxplicacion : $1",
        "protectedpagewarning": "<strong>Atencion : cela pâge est étâye protègiêe por que solament los utilisators qu’ant los drêts d’administrator la pouessont changiér.</strong>\nLa dèrriére entrâ du jornâl est balyêe ce-desot coment rèference :",
        "semiprotectedpagewarning": "<strong>Nota :</strong> cela pâge est étâye protègiêe por que solament los utilisators encartâs la pouessont changiér.\nLa dèrriére entrâ du jornâl est balyêe ce-desot coment rèference :",
-       "cascadeprotectedwarning": "<strong>Atencion :</strong> cela pâge est étâye protègiêe por que solament los utilisators qu’ant los drêts d’administrator la pouessont changiér, el est transcllua dedens {{PLURAL:$1|cela pâge protègiêe|celes pâges protègiêes}}-que avouéc la « protèccion en cascâda » activâye :",
+       "cascadeprotectedwarning": "<strong>Atencion :</strong> cela pâge est étâye protègiêe por que solament los utilisators qu’ant los drêts d’administrator la pouessont changiér, el est transcllua dedens {{PLURAL:$1|ceta pâge protègiêe|cetes pâges protègiêes}} avouéc la « protèccion en cascâda » activâye :",
        "titleprotectedwarning": "<strong>Atencion : cela pâge est étâye protègiêe por que de [[Special:ListGroupRights|drêts spècificos]] sont nècèssèros por la povêr fâre.</strong>\nLa dèrriére entrâ du jornâl est balyêe ce-desot coment rèference :",
        "templatesused": "{{PLURAL:$1|Modèlo empleyê|Modèlos empleyês}} per cela pâge :",
        "templatesusedpreview": "{{PLURAL:$1|Modèlo empleyê|Modèlos empleyês}} dedens cél apèrçu :",
        "sectioneditnotsupported-title": "Changement de sèccion pas recognu",
        "sectioneditnotsupported-text": "Lo changement d’una sèccion est pas recognu dens cela pâge.",
        "permissionserrors": "Fôta de pèrmission",
-       "permissionserrorstext": "Vos éd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|cela rêson|celes rêsons}}-que :",
-       "permissionserrorstext-withaction": "Vos éd pas la pèrmission de $2 por {{PLURAL:$1|cela rêson|celes rêsons}}-que :",
+       "permissionserrorstext": "Vos éd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|ceta rêson|cetes rêsons}} :",
+       "permissionserrorstext-withaction": "Vos éd pas la pèrmission de $2 por {{PLURAL:$1|ceta rêson|cetes rêsons}} :",
        "contentmodelediterror": "Vos pouede pas changiér cela vèrsion, son modèlo de contegnu est <code>$1</code>, cen que sè difèrence du modèlo de contegnu d’ora de la pâge <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Atencion : vos éte aprés refâre na pâge qu’est étâye suprimâye dês devant.</strong>\n\nDemandâd-vos se fôt franc continuar son changement.\nLo jornâl de les suprèssions et des dèplacements de cela pâge est balyê ce-desot por comoditât :",
        "moveddeleted-notice": "Cela pâge est étâye suprimâye.\nLo jornâl de les suprèssions et des dèplacements de cela pâge est balyê ce-desot coment rèference.",
        "logdelete-text": "Los èvènements du jornâl suprimâs continueront a aparêtre dedens los jornâls, mas na partia de lor contegnu serat inaccèssibla u publico.",
        "revdelete-text-others": "Los ôtros administrators porront adés arrevar u contegnu cachiê et lo refâre, a muens que des rèstriccions de més seyont dèfenies.",
        "revdelete-confirm": "Se vos plét, confirmâd qu’o est franc cen que vos voléd fâre, que vos en compregnéd les consèquences, et pués que vos o féte en acôrd avouéc les [[{{MediaWiki:Policy-url}}|politiques]].",
-       "revdelete-suppress-text": "La rèprèssion dêt étre empleyêe <strong>ren que</strong> dens celos câs-que :\n* Enformacions que pôvont étre difamatouères\n* Enformacions a sè que vant pas avouéc\n*: <em>adrèce, numerô de tèlèfono, numerô d’identificacion nacionâl, et tot cen que vat avouéc</em>",
+       "revdelete-suppress-text": "La rèprèssion dêt étre empleyêe <strong>ren que</strong> dens cetos câs :\n* Enformacions que pôvont étre difamatouères\n* Enformacions a sè que vant pas avouéc\n*: <em>adrèce, numerô de tèlèfono, numerô d’identificacion nacionâl, et tot cen que vat avouéc</em>",
        "revdelete-legend": "Dèfenir de rèstriccions de visibilitât",
        "revdelete-hide-text": "Tèxto de la vèrsion",
        "revdelete-hide-image": "Cachiér lo contegnu du fichiér",
        "mergehistory-from": "Pâge d’origina :",
        "mergehistory-into": "Pâge de dèstinacion :",
        "mergehistory-list": "Historico des changements que pôvont étre fusionâs",
-       "mergehistory-merge": "Celes vèrsions-que de [[:$1]] pôvont étre fusionâyes dedens [[:$2]].\nEmpleyéd la colona de botons de chouèx por fusionar mas que les vèrsions fêtes dês lo comencement tant qu’a la dâta spècifiâye.\nNotâd que l’usâjo des lims de navegacion rebeterat a zérô cela colona.",
+       "mergehistory-merge": "Cetes vèrsions de [[:$1]] pôvont étre fusionâyes dedens [[:$2]].\nEmpleyéd la colona de botons de chouèx por fusionar mas que les vèrsions fêtes dês lo comencement tant qu’a la dâta spècifiâye.\nNotâd que l’usâjo des lims de navegacion rebeterat a zérô cela colona.",
        "mergehistory-go": "Montrar los changements que pôvont étre fusionâs",
        "mergehistory-submit": "Fusionar les vèrsions",
        "mergehistory-empty": "Niona vèrsion pôt étre fusionâye.",
        "upload_directory_read_only": "Lo rèpèrtouèro de tèlèchargement ($1) est pas enscriptiblo per lo sèrvior Vouèbe.",
        "uploaderror": "Fôta pendent lo tèlèchargement",
        "upload-recreate-warning": "<strong>Atencion : un fichiér avouéc cél nom est étâ suprimâ dèplaciê.</strong>\n\nLo jornâl de les suprèssions et des dèplacements de cela pâge est balyê ique por comoditât :",
-       "uploadtext": "Empleyéd lo formulèro ce-desot por tèlèchargiér de fichiérs.\nPor vêre rechèrchiér de fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los (re-)tèlèchargements sont asse-ben encartâs dessus lo [[Special:Log/upload|jornâl des tèlèchargements]], et les suprèssions dessus lo [[Special:Log/delete|jornâl de les suprèssions]].\n\nPor rapondre un fichiér dedens na pâge, empleyéd un lim de yona de celes fôrmes-que :\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.jpg]]</nowiki></code></strong> por empleyér la vèrsion en plêna largior du fichiér\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.png|200px|thumb|left|tèxto dèscriptif]]</nowiki></code></strong> por empleyér na miniatura de 200 pixèls de lârjo dedens na bouèt’a gôche avouéc « tèxto dèscriptif » coment dèscripcion\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Fichiér.ogg]]</nowiki></code></strong> por liyér tot drêt vers lo fichiér sen lo fâre vêre",
+       "uploadtext": "Empleyéd lo formulèro ce-desot por tèlèchargiér de fichiérs.\nPor vêre rechèrchiér de fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los (re-)tèlèchargements sont asse-ben encartâs dessus lo [[Special:Log/upload|jornâl des tèlèchargements]], et les suprèssions dessus lo [[Special:Log/delete|jornâl de les suprèssions]].\n\nPor rapondre un fichiér dedens na pâge, empleyéd un lim de yona de cetes fôrmes :\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.jpg]]</nowiki></code></strong> por empleyér la vèrsion en plêna largior du fichiér\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.png|200px|thumb|left|tèxto dèscriptif]]</nowiki></code></strong> por empleyér na miniatura de 200 pixèls de lârjo dedens na bouèt’a gôche avouéc « tèxto dèscriptif » coment dèscripcion\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Fichiér.ogg]]</nowiki></code></strong> por liyér tot drêt vers lo fichiér sen lo fâre vêre",
        "upload-permitted": "Tipo{{PLURAL:$2||s}} de fichiérs ôtorisâ{{PLURAL:$2||s}} : $1.",
        "upload-preferred": "Tipo{{PLURAL:$2||s}} de fichiérs prèferâ{{PLURAL:$2||s}} : $1.",
        "upload-prohibited": "Tipo{{PLURAL:$2||s}} de fichiérs dèfendu{{PLURAL:$2||s}} : $1.",
        "file-thumbnail-no": "Lo nom du fichiér comence per <strong>$1</strong>.\nSemble étre un’émâge en talye rèduita <em>(miniatura)</em>.\nSe vos éd cel’émâge en hôta rèsolucion, tèlèchargiéd-la, ôtrament changiéd son nom, se vos plét.",
        "fileexists-forbidden": "Un fichiér avouéc cél nom ègziste ja et pôt pas étre ècllafâ.\nSe vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Un fichiér avouéc cél nom ègziste ja dedens lo dèpôt de fichiérs partagiê.\nSe vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.\n[[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "Cél fichiér est un doblo de {{PLURAL:$1|cél fichiér|celos fichiérs}}-que :",
+       "file-exists-duplicate": "Cél fichiér est un doblo de {{PLURAL:$1|ceti fichiér|cetos fichiérs}} :",
        "file-deleted-duplicate": "Un fichiér pariér a ceti ([[:$1]]) est ja étâ suprimâ.\nVos devriâd controlar lo jornâl de les suprèssions de cél fichiér devant que lo tornar tèlèchargiér.",
        "file-deleted-duplicate-notitle": "Un fichiér pariér a ceti est ja étâ suprimâ et pués lo titro rèprimâ.\nVos devriâd demandar a quârqu’un avouéc la possibilitât de vêre les balyês du fichiér rèprimâ por ègzamenar la situacion devant que lo tornar tèlèchargiér.",
        "uploadwarning": "Atencion !",
        "upload-form-label-infoform-description-tooltip": "Dècrire vito tot cen qu’y at de particuliér por cel’ôvra.\nPor na fotô, mencionar les chouses principâles que sont semondues, l’ocasion ou ben l’endrêt.",
        "upload-form-label-usage-title": "Usâjo",
        "upload-form-label-usage-filename": "Nom du fichiér",
-       "foreign-structured-upload-form-label-own-work": "Su l’ôtor de cel’ôvra",
-       "foreign-structured-upload-form-label-infoform-categories": "Catègories",
-       "foreign-structured-upload-form-label-infoform-date": "Dâta",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que tèlèchârjo cél fichiér d’aprés les condicions d’usâjo et les politiques de licence de {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Se vos pouede pas tèlèchargiér cél fichiér d’aprés les politiques de {{SITENAME}}, se vos plét cllôde cela bouèta de dialogo et pués èprovâd un’ôtra mètoda.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Vos pouede asse-ben èprovar la [[Special:Upload|pâge de tèlèchargement per dèfôt]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Compregno que tèlèchârjo cél fichiér vers un dèpôt partagiê. Confirmo qu’o fé d’aprés les condicions d’usâjo et les politiques de licence de ceti.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Se vos pouede pas tèlèchargiér cél fichiér d’aprés les politiques du dèpôt partagiê, se vos plét cllôde cela bouèta de dialogo et pués èprovâd un’ôtra mètoda.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Vos pouede asse-ben èprovar d’empleyér la [[Special:Upload|pâge de tèlèchargement de {{SITENAME}}]], se cél fichiér y pôt étre tèlèchargiê d’aprés lors politiques.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Cèrtifio étre lo dètentior des drêts d’ôtor sur cél fichiér, et j’accèpto de publeyér cél fichiér dessus Wikimedia Commons en lo betent irrèvocâblament desot licence [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribucion - Partâjo dens les Mémes Condicions 4.0] et pués j’accèpto les [https://wikimediafoundation.org/wiki/Terms_of_Use condicions d’usâjo].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Se vos éte pas lo dètentior des drêts d’ôtor sur cél fichiér ou ben que vos lo voléd publeyér desot na licence difèrenta, vos pouede empleyér l’[https://commons.wikimedia.org/wiki/Special:UploadWizard assistent de tèlèchargement de Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Vos pouede asse-ben èprovar d’empleyér la [[Special:Upload|pâge de tèlèchargement de {{SITENAME}}]], se cél fichiér y pôt étre tèlèchargiê d’aprés lors politiques.",
+       "upload-form-label-own-work": "Su l’ôtor de cel’ôvra",
+       "upload-form-label-infoform-categories": "Catègories",
+       "upload-form-label-infoform-date": "Dâta",
+       "upload-form-label-own-work-message-local": "Confirmo que tèlèchârjo cél fichiér d’aprés les condicions d’usâjo et les politiques de licence de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Se vos pouede pas tèlèchargiér cél fichiér d’aprés les politiques de {{SITENAME}}, se vos plét cllôde cela bouèta de dialogo et pués èprovâd un’ôtra mètoda.",
+       "upload-form-label-not-own-work-local-local": "Vos pouede asse-ben èprovar la [[Special:Upload|pâge de tèlèchargement per dèfôt]].",
+       "upload-form-label-own-work-message-default": "Compregno que tèlèchârjo cél fichiér vers un dèpôt partagiê. Confirmo qu’o fé d’aprés les condicions d’usâjo et les politiques de licence de ceti.",
+       "upload-form-label-not-own-work-message-default": "Se vos pouede pas tèlèchargiér cél fichiér d’aprés les politiques du dèpôt partagiê, se vos plét cllôde cela bouèta de dialogo et pués èprovâd un’ôtra mètoda.",
+       "upload-form-label-not-own-work-local-default": "Vos pouede asse-ben èprovar d’empleyér la [[Special:Upload|pâge de tèlèchargement de {{SITENAME}}]], se cél fichiér y pôt étre tèlèchargiê d’aprés lors politiques.",
+       "upload-form-label-own-work-message-shared": "Cèrtifio étre lo dètentior des drêts d’ôtor sur cél fichiér, et j’accèpto de publeyér cél fichiér dessus Wikimedia Commons en lo betent irrèvocâblament desot licence [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribucion - Partâjo dens les Mémes Condicions 4.0] et pués j’accèpto les [https://wikimediafoundation.org/wiki/Terms_of_Use condicions d’usâjo].",
+       "upload-form-label-not-own-work-message-shared": "Se vos éte pas lo dètentior des drêts d’ôtor sur cél fichiér ou ben que vos lo voléd publeyér desot na licence difèrenta, vos pouede empleyér l’[https://commons.wikimedia.org/wiki/Special:UploadWizard assistent de tèlèchargement de Commons].",
+       "upload-form-label-not-own-work-local-shared": "Vos pouede asse-ben èprovar d’empleyér la [[Special:Upload|pâge de tèlèchargement de {{SITENAME}}]], se cél fichiér y pôt étre tèlèchargiê d’aprés lors politiques.",
        "backend-fail-stream": "Y at pas moyen de tramandar lo fichiér « $1 ».",
        "backend-fail-backup": "Y at pas moyen d’encartar lo fichiér « $1 ».",
        "backend-fail-notexists": "Lo fichiér $1 ègziste pas.",
        "filehist-filesize": "Talye du fichiér",
        "filehist-comment": "Comentèro",
        "imagelinks": "Usâjo du fichiér",
-       "linkstoimage": "{{PLURAL:$1|Cela pâge-que emplèye|Celes $1 pâges-que emplèyont}} cél fichiér :",
-       "linkstoimage-more": "Més {{PLURAL:$1|d’una pâge emplèye|de $1 pâges emplèyont}} cél fichiér.\nCela lista-que montre mas que {{PLURAL:$1|la premiére pâge qu’emplèye|les $1 premiéres pâges qu’emplèyont}} cél fichiér.\nNa [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.",
+       "linkstoimage": "{{PLURAL:$1|Ceta pâge emplèye|Cetes $1 pâges emplèyont}} cél fichiér :",
+       "linkstoimage-more": "Més {{PLURAL:$1|d’una pâge emplèye|de $1 pâges emplèyont}} cél fichiér.\nCeta lista montre mas que {{PLURAL:$1|la premiére pâge qu’emplèye|les $1 premiéres pâges qu’emplèyont}} cél fichiér.\nNa [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.",
        "nolinkstoimage": "Niona pâge emplèye cél fichiér.",
        "morelinkstoimage": "Vêde [[Special:WhatLinksHere/$1|més de lims]] de vers cél fichiér.",
        "linkstoimage-redirect": "$1 (redirèccion de fichiér) $2",
        "unusedtemplatestext": "Cela pâge liste totes les pâges de l’èspâço de noms « {{ns:template}} » que sont pas rapondues dedens nion’ôtra pâge.\nOubliâd pas de controlar s’y at gins d’ôtro lim de vers los modèlos devant que los suprimar.",
        "unusedtemplateswlh": "ôtros lims",
        "randompage": "Pâge a l’hasârd",
-       "randompage-nopages": "Y at gins de pâge dedens {{PLURAL:$2|cél èspâço|celos èspâços}} de noms-que : $1.",
+       "randompage-nopages": "Y at gins de pâge dedens {{PLURAL:$2|cet’èspâço|cetos èspâços}} de noms : $1.",
        "randomincategory": "Pâge a l’hasârd dedens la catègoria",
        "randomincategory-invalidcategory": "« $1 » est pas un nom de catègoria justo.",
        "randomincategory-nopages": "Y at gins de pâge dedens la catègoria [[:Category:$1|$1]].",
        "double-redirect-fixed-maintenance": "Corrèccion ôtomatica de la redirèccion dobla de [[$1]] de vers [[$2]] dens un ovrâjo d’entretin.",
        "double-redirect-fixer": "Corrèctor de redirèccion",
        "brokenredirects": "Redirèccions câsses",
-       "brokenredirectstext": "Celes redirèccions-que mènont vers de pâges inègzistentes :",
+       "brokenredirectstext": "Cetes redirèccions mènont vers de pâges inègzistentes :",
        "brokenredirects-edit": "changiér",
        "brokenredirects-delete": "suprimar",
        "withoutinterwiki": "Pâges sen lims entèrlengoues",
-       "withoutinterwiki-summary": "Celes pâges-que ant gins de lim de vers des vèrsions en ôtres lengoues.",
+       "withoutinterwiki-summary": "Cetes pâges ant gins de lim de vers des vèrsions en ôtres lengoues.",
        "withoutinterwiki-legend": "Prèfixo",
        "withoutinterwiki-submit": "Montrar",
        "fewestrevisions": "Pâges les muens changiêes",
        "ntransclusions": "empleyê dessus $1 pâge{{PLURAL:$1||s}}",
        "specialpage-empty": "Y at gins de rèsultat a fâre vêre.",
        "lonelypages": "Pâges orfenes",
-       "lonelypagestext": "Celes pâges-que sont ni liyêes ni transcllues per d’ôtres pâges de {{SITENAME}}.",
+       "lonelypagestext": "Cetes pâges sont ni liyêes ni transcllues per d’ôtres pâges de {{SITENAME}}.",
        "uncategorizedpages": "Pâges sen catègories",
        "uncategorizedcategories": "Catègories sen catègories",
        "uncategorizedimages": "Fichiérs sen catègories",
        "wantedpages-summary": "Lista de les pâges inègzistentes qu’ant lo més de lims de vers lor, en èxcllusent les pâges qu’ant ren que de redirèccions pouentent vers lor. Por avêr na lista de les pâges inègzistentes qu’ant de redirèccions pouentent vers lor, vêde la [[{{#special:BrokenRedirects}}|lista de les redirèccions câsses]].",
        "wantedpages-badtitle": "Titro pas justo dedens l’ensemblo de rèsultats : $1",
        "wantedfiles": "Fichiérs demandâs",
-       "wantedfiletext-cat": "Celos fichiérs-que sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>. Et pués les pâges qu’apondont de fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].",
-       "wantedfiletext-cat-noforeign": "Celos fichiérs-que sont empleyês, mas ègzistont pas. Et pués les pâges qu’apondont de fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].",
-       "wantedfiletext-nocat": "Celos fichiérs-que sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>.",
-       "wantedfiletext-nocat-noforeign": "Celos fichiérs-que sont empleyês, mas ègzistont pas.",
+       "wantedfiletext-cat": "Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>. Et pués les pâges qu’apondont de fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].",
+       "wantedfiletext-cat-noforeign": "Cetos fichiérs sont empleyês, mas ègzistont pas. Et pués les pâges qu’apondont de fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].",
+       "wantedfiletext-nocat": "Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>.",
+       "wantedfiletext-nocat-noforeign": "Cetos fichiérs sont empleyês, mas ègzistont pas.",
        "wantedtemplates": "Modèlos demandâs",
        "mostlinked": "Pâges les ples liyêes",
        "mostlinkedcategories": "Catègories les ples liyêes",
        "shortpages": "Pâges côrtes",
        "longpages": "Pâges longes",
        "deadendpages": "Pâges en charriére borgne",
-       "deadendpagestext": "Celes pâges-que contegnont gins de lim de vers d’ôtres pâges de {{SITENAME}}.",
+       "deadendpagestext": "Cetes pâges contegnont gins de lim de vers d’ôtres pâges de {{SITENAME}}.",
        "protectedpages": "Pâges protègiêes",
        "protectedpages-indef": "Mas que les protèccions sen fin",
        "protectedpages-summary": "Cela pâge liste les pâges ègzistentes que sont ora protègiêes. Por na lista des titros protègiês contre la crèacion, vêde [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "ancientpages": "Pâges les ples vielyes",
        "move": "Dèplaciér",
        "movethispage": "Dèplaciér cela pâge",
-       "unusedimagestext": "Celos fichiérs-que ègzistont, mas sont pas apondus a niona pâge.\nSe vos plét, notâd que d’ôtros setos Vouèbe pôvont avêr un lim de vers un fichiér avouéc un’URL drêta, adonc un fichiér pôt adés étre listâ ique pendent qu’il est en usâjo actif.",
-       "unusedcategoriestext": "Celes catègories-que ègzistont, mas nion’ôtra pâge niona catègoria les emplèye.",
+       "unusedimagestext": "Cetos fichiérs ègzistont, mas sont pas apondus a niona pâge.\nSe vos plét, notâd que d’ôtros setos Vouèbe pôvont avêr un lim de vers un fichiér avouéc un’URL drêta, adonc un fichiér pôt adés étre listâ ique pendent qu’il est en usâjo actif.",
+       "unusedcategoriestext": "Cetes catègories ègzistont, mas nion’ôtra pâge niona catègoria les emplèye.",
        "notargettitle": "Niona ciba",
        "notargettext": "Vos éd pas spècifiâ na pâge un utilisator ciba que vos voléd fâre cel’accion.",
        "nopagetitle": "Niona pâge ciba d’ense",
        "cachedspecial-refresh-now": "Vêre la ples novèla.",
        "categories": "Catègories",
        "categories-submit": "Montrar",
-       "categoriespagetext": "{{PLURAL:$1|Cela catègoria-que contint|Celes catègories-que contegnont}} de pâges de mèdiâs.\nLes [[Special:UnusedCategories|catègories pas empleyêes]] sont pas montrâyes ique.\nVêde avouéc les [[Special:WantedCategories|catègories demandâyes]].",
+       "categoriespagetext": "{{PLURAL:$1|Ceta catègoria contint|Cetes catègories contegnont}} de pâges de mèdiâs.\nLes [[Special:UnusedCategories|catègories pas empleyêes]] sont pas montrâyes ique.\nVêde avouéc les [[Special:WantedCategories|catègories demandâyes]].",
        "categoriesfrom": "Fâre vêre les catègories dês :",
        "deletedcontributions": "Contribucions suprimâyes",
        "deletedcontributions-title": "Contribucions suprimâyes",
        "protect-locked-blocked": "Vos pouede pas changiér los nivéls de protèccion tant que vos éte blocâ{{GENDER:||ye}}.\nVê-que la configuracion d’ora de la pâge <strong>$1</strong> :",
        "protect-locked-dblock": "Los nivéls de protèccion pôvont pas étre changiês, la bâsa de balyês est cotâye.\nVê-que la configuracion d’ora de la pâge <strong>$1</strong> :",
        "protect-locked-access": "Voutron comptio at pas los drêts nècèssèros por changiér los nivéls de protèccion de pâges.\nVê-que la configuracion d’ora de la pâge <strong>$1</strong> :",
-       "protect-cascadeon": "Ora cela pâge est protègiêe, el est transcllua dedens {{PLURAL:$1|cela pâge-que qu’est étâye protègiêe|celes pâges-que que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ.\nLos changements du nivél de protèccion de cela pâge afècteront pas la protèccion en cascâda.",
+       "protect-cascadeon": "Ora cela pâge est protègiêe, el est transcllua dedens {{PLURAL:$1|ceta pâge qu’est étâye protègiêe|cetes pâges que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ.\nLos changements du nivél de protèccion de cela pâge afècteront pas la protèccion en cascâda.",
        "protect-default": "Ôtorisar tôs los utilisators",
        "protect-fallback": "Ôtorisar mas que los utilisators avouéc lo drêt « $1 »",
        "protect-level-autoconfirmed": "Ôtorisar mas que los utilisators ôtoconfirmâs",
        "restriction-level-all": "tôs los nivéls",
        "undelete": "Vêre les pâges suprimâyes",
        "undeletepage": "Vêre et refâre de pâges suprimâyes",
-       "undeletepagetitle": "<strong>Cela lista-que contint de vèrsions suprimâyes de [[:$1|$1]].</strong>",
+       "undeletepagetitle": "<strong>Ceta lista contint de vèrsions suprimâyes de [[:$1|$1]].</strong>",
        "viewdeletedpage": "Vêre les pâges suprimâyes",
-       "undeletepagetext": "{{PLURAL:$1|Cela pâge-que est étâye suprimâye et pués sè trôve|Celes pâges-que sont étâyes suprimâyes et pués sè trôvont}} adés dedens les arch·ives, de yô que pô{{PLURAL:$1||von}}t étre refêt{{PLURAL:$1|a|es}}.\nLes arch·ives pôvont étre neteyêes règuliérement.",
+       "undeletepagetext": "{{PLURAL:$1|Ceta pâge est étâye suprimâye et pués sè trôve|Cetes pâges sont étâyes suprimâyes et pués sè trôvont}} adés dedens les arch·ives, de yô que pô{{PLURAL:$1||von}}t étre refêt{{PLURAL:$1|a|es}}.\nLes arch·ives pôvont étre neteyêes règuliérement.",
        "undelete-fieldset-title": "Refâre les vèrsions",
        "undeleteextrahelp": "Por refâre l’historico complèt de la pâge, lèssiéd totes les câses pas pouentâyes et pués cllicâd dessus <strong><em>{{int:undeletebtn}}</em></strong>.\nPor fâre na rèstoracion a mêtiêt, pouentâd les câses que corrèspondont a les vèrsions a refâre et pués cllicâd dessus <strong><em>{{int:undeletebtn}}</em></strong>.",
        "undeleterevisions": "$1 {{PLURAL:$1|vèrsion suprimâye|vèrsions suprimâyes}}",
        "whatlinkshere": "Pâges liyêes",
        "whatlinkshere-title": "Pâges que pouentont vers « $1 »",
        "whatlinkshere-page": "Pâge :",
-       "linkshere": "Celes pâges-que contegnont un lim de vers <strong>[[:$1]]</strong> :",
+       "linkshere": "Cetes pâges contegnont un lim de vers <strong>[[:$1]]</strong> :",
        "nolinkshere": "Niona pâge contint de lim de vers <strong>[[:$1]]</strong>.",
        "nolinkshere-ns": "Niona pâge contint de lim de vers <strong>[[:$1]]</strong> dedens l’èspâço de noms chouèsi.",
        "isredirect": "pâge de redirèccion",
        "import-interwiki-submit": "Importar",
        "import-mapping-default": "Importar ux endrêts per dèfôt",
        "import-mapping-namespace": "Importar vers un èspâço de noms :",
-       "import-mapping-subpage": "Importar coment sot-pâges de cela pâge-que :",
+       "import-mapping-subpage": "Importar coment sot-pâges de ceta pâge :",
        "import-upload-filename": "Nom du fichiér :",
        "import-comment": "Comentèro :",
        "importtext": "Se vos plét, èxportâd lo fichiér dês lo vouiqui d’origina en empleyent son [[Special:Export|outil d’èxportacion]].\nEncartâd-lo sur voutron ordenator et pués tèlèchargiéd-lo ique.",
        "import-error-special": "La pâge « $1 » est pas étâye importâye, el est a un èspâço de noms spèciâl qu’ôtorise gins de pâge.",
        "import-error-invalid": "La pâge « $1 » est pas étâye importâye, lo nom que lyé serêt étâye importâye desot est pas justo sur cél vouiqui.",
        "import-error-unserialize": "La vèrsion $2 de la pâge « $1 » pôt pas étre dèssèrialisâye. La vèrsion ére raportâye coment empleyent lo modèlo de contegnu $3 sèrialisâ en $4.",
-       "import-error-bad-location": "La vèrsion $2 qu’emplèye lo modèlo de contegnu $3 at pas possu étre stocâye dessus « $1 » sur cél vouiqui-que, cél modèlo est pas recognu sur cela pâge.",
+       "import-error-bad-location": "La vèrsion $2 qu’emplèye lo modèlo de contegnu $3 at pas possu étre stocâye dessus « $1 » sur ceti vouiqui, cél modèlo est pas recognu sur cela pâge.",
        "import-options-wrong": "{{PLURAL:$2|Crouyo chouèx|Crouyos chouèx}} : <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "La pâge racena balyêe est un titro pas justo.",
        "import-rootpage-nosubpage": "L’èspâço de noms « $1 » de la pâge racena ôtorise pas les sot-pâges.",
        "tooltip-ca-nstab-category": "Vêre la pâge de la catègoria",
        "tooltip-minoredit": "Marcar mos changements coment petiôts",
        "tooltip-save": "Encartar voutros changements",
+       "tooltip-publish": "Publeyér voutros changements",
        "tooltip-preview": "Prèvêde voutros changements. Se vos plét, empleyéd-lo devant qu’encartar.",
        "tooltip-diff": "Montrar los changements que vos éd aportâs u tèxto",
        "tooltip-compareselectedversions": "Fâre ressortir les difèrences entre les doves vèrsions chouèsies de cela pâge",
        "nocredits": "Y at gins d’enformacion d’atribucion disponibla por cela pâge.",
        "spamprotectiontitle": "Filtro de protèccion contre los mèssâjos cofos",
        "spamprotectiontext": "Lo tèxto que vos éd volu encartar est étâ blocâ per lo filtro contre los mèssâjos cofos.\nO est probâblament diu a un lim de vers un seto de defôr qu’aparêt sur la lista nêre.",
-       "spamprotectionmatch": "Cél tèxto-que est cen qu’at dècllenchiê noutron filtro contre los mèssâjos cofos : $1",
+       "spamprotectionmatch": "Ceti tèxto est cen qu’at dècllenchiê noutron filtro contre los mèssâjos cofos : $1",
        "spambot_username": "Neteyâjo de mèssâjos cofos per MediaWiki",
        "spam_reverting": "Rètablissement de la dèrriére vèrsion que contint gins de lim de vers $1",
        "spam_blanking": "Totes les vèrsions que contegnont de lims de vers $1 sont blanchies",
        "exif-meteringmode-0": "Encognua",
        "exif-meteringmode-1": "Moyena",
        "exif-meteringmode-2": "Moyena d’aplomb u centro",
-       "exif-meteringmode-3": "Pouent",
-       "exif-meteringmode-4": "MultiPouent",
+       "exif-meteringmode-3": "Spote",
+       "exif-meteringmode-4": "Multi-spote",
        "exif-meteringmode-5": "Modèlo",
-       "exif-meteringmode-6": "Encomplèta",
+       "exif-meteringmode-6": "Parciâla",
        "exif-meteringmode-255": "Ôtra",
        "exif-lightsource-0": "Encognua",
        "exif-lightsource-1": "Lumiére du jorn",
        "exif-lightsource-2": "Fluorèscenta",
-       "exif-lightsource-3": "Tungstène (lumiére chôdâ a blanc)",
+       "exif-lightsource-3": "Tungstène (lumiére enfarâye)",
        "exif-lightsource-4": "Èludo",
        "exif-lightsource-9": "Temps cllâr",
        "exif-lightsource-10": "Temps enneblo",
        "exif-lightsource-11": "Ombra",
-       "exif-lightsource-12": "Lumiére fluorèscenta « lumiére du jorn » (D 5700 – 7100 K)",
-       "exif-lightsource-13": "Lumiére fluorèscenta blanche « jorn » (N 4600 – 5400 K)",
-       "exif-lightsource-14": "Lumiére fluorèscenta blanche « frêd » (W 3900 – 4500 K)",
-       "exif-lightsource-15": "Lumiére fluorèscenta blanche (WW 3200 – 3700 K)",
-       "exif-lightsource-17": "Lumiére estandârd A",
-       "exif-lightsource-18": "Lumiére estandârd B",
-       "exif-lightsource-19": "Lumiére estandârd C",
+       "exif-lightsource-12": "Ècllèrâjo fluorèscent « lumiére du jorn » (D 5700 – 7100 K)",
+       "exif-lightsource-13": "Ècllèrâjo fluorèscent blanc « jorn » (N 4600 – 5400 K)",
+       "exif-lightsource-14": "Ècllèrâjo fluorèscent blanc « frêd » (W 3900 – 4500 K)",
+       "exif-lightsource-15": "Ècllèrâjo fluorèscent blanc (WW 3200 – 3700 K)",
+       "exif-lightsource-17": "Lumiére standârd A",
+       "exif-lightsource-18": "Lumiére standârd B",
+       "exif-lightsource-19": "Lumiére standârd C",
        "exif-lightsource-24": "Tungstène ISO de studiô",
        "exif-lightsource-255": "Ôtra sôrsa de lumiére",
        "exif-flash-fired-0": "Èludo pas dècllenchiê",
        "exif-flash-fired-1": "Èludo dècllenchiê",
-       "exif-flash-return-0": "nion stroboscopo retorne una fonccion de dètèccion",
-       "exif-flash-return-2": "lo stroboscopo retorne una lumiére pas dècelâ",
-       "exif-flash-return-3": "lo stroboscopo retorne una lumiére dècelâ",
+       "exif-flash-return-0": "nion stroboscopo retôrne na fonccion de dècelâjo",
+       "exif-flash-return-2": "lo stroboscopo dècèle gins de lumiére retornâye",
+       "exif-flash-return-3": "lo stroboscopo dècèle un retôrn de lumiére",
        "exif-flash-mode-1": "lumiére de l’èludo oblegatouèra",
        "exif-flash-mode-2": "suprèssion de l’èludo oblegatouèra",
        "exif-flash-mode-3": "fôrma ôtomatica",
-       "exif-flash-function-1": "Gins de fonccion d’èludo",
+       "exif-flash-function-1": "Niona fonccion d’èludo",
        "exif-flash-redeye-1": "fôrma anti-uelys rojos",
        "exif-focalplaneresolutionunit-2": "pôjos",
        "exif-sensingmethod-1": "Pas dèfeni",
-       "exif-sensingmethod-2": "Captior de color a yona puge",
+       "exif-sensingmethod-2": "Captior de color a na puge",
        "exif-sensingmethod-3": "Captior de color a doves puges",
        "exif-sensingmethod-4": "Captior de color a três puges",
        "exif-sensingmethod-5": "Captior de color sèquencièl",
        "exif-sensingmethod-7": "Captior trilinèâr",
        "exif-sensingmethod-8": "Captior de color linèâr sèquencièl",
        "exif-filesource-3": "Aparèly-fotô numerico",
-       "exif-scenetype-1": "Émâge fotografiâ tot drêt",
-       "exif-customrendered-0": "Maniére normala",
-       "exif-customrendered-1": "Maniére pèrsonalisâ",
+       "exif-scenetype-1": "Émâge fotografiâye tot drêt",
+       "exif-customrendered-0": "Pratica normala",
+       "exif-customrendered-1": "Pratica pèrsonalisâye",
        "exif-exposuremode-0": "Èxposicion ôtomatica",
-       "exif-exposuremode-1": "Ã\88xposicion manuèla",
+       "exif-exposuremode-1": "Ã\88xposicion manuâla",
        "exif-exposuremode-2": "Forchèta ôtomatica",
        "exif-whitebalance-0": "Balance des blancs ôtomatica",
-       "exif-whitebalance-1": "Balance des blancs manuèla",
-       "exif-scenecapturetype-0": "Estandârd",
+       "exif-whitebalance-1": "Balance des blancs manuâla",
+       "exif-scenecapturetype-0": "Standârd",
        "exif-scenecapturetype-1": "Payisâjo",
        "exif-scenecapturetype-2": "Portrèt",
        "exif-scenecapturetype-3": "Scèna de nuet",
        "exif-gaincontrol-0": "Nion",
-       "exif-gaincontrol-1": "Guen fêblament positif",
-       "exif-gaincontrol-2": "Guen fôrtament positif",
-       "exif-gaincontrol-3": "Guen fêblament nègatif",
-       "exif-gaincontrol-4": "Guen fôrtament nègatif",
+       "exif-gaincontrol-1": "Fêblo guen positif",
+       "exif-gaincontrol-2": "Fôrt guen positif",
+       "exif-gaincontrol-3": "Fêblo guen nègatif",
+       "exif-gaincontrol-4": "Fôrt guen nègatif",
        "exif-contrast-0": "Normal",
        "exif-contrast-1": "Fêblo",
        "exif-contrast-2": "Fôrt",
        "exif-saturation-0": "Normala",
-       "exif-saturation-1": "Saturacion fêbla",
+       "exif-saturation-1": "Saturacion bâssa",
        "exif-saturation-2": "Saturacion hôta",
        "exif-sharpness-0": "Normala",
        "exif-sharpness-1": "Doce",
        "exif-subjectdistancerange-1": "Vision en grôs",
        "exif-subjectdistancerange-2": "Vision de prés",
        "exif-subjectdistancerange-3": "Vision de luen",
-       "exif-gpslatitude-n": "Latituda bise (''nord'')",
-       "exif-gpslatitude-s": "Latituda mié-jorn (''sud'')",
-       "exif-gpslongitude-e": "Longituda levant (''èst'')",
-       "exif-gpslongitude-w": "Longituda ponant (''ouèst'')",
-       "exif-gpsaltitude-above-sealevel": "$1 mètre{{PLURAL:$1||s}} en-d’amont du nivél de la mar",
-       "exif-gpsaltitude-below-sealevel": "$1 mètre{{PLURAL:$1||s}} en-desot du nivél de la mar",
+       "exif-gpslatitude-n": "Latituda bise (<em>nord</em>)",
+       "exif-gpslatitude-s": "Latituda mié-jorn (<em>sud</em>)",
+       "exif-gpslongitude-e": "Longituda levant (<em>èste</em>)",
+       "exif-gpslongitude-w": "Longituda cuchient (<em>ouèste</em>)",
+       "exif-gpsaltitude-above-sealevel": "$1 mètro{{PLURAL:$1||s}} d’amont lo nivél de la mar",
+       "exif-gpsaltitude-below-sealevel": "$1 mètro{{PLURAL:$1||s}} desot lo nivél de la mar",
        "exif-gpsstatus-a": "Mesera en cors",
-       "exif-gpsstatus-v": "Entèropèrabilitât de la mesera",
+       "exif-gpsstatus-v": "Entèrfonccionement de la mesera",
        "exif-gpsmeasuremode-2": "Mesera a 2 dimensions",
        "exif-gpsmeasuremode-3": "Mesera a 3 dimensions",
-       "exif-gpsspeed-k": "Kilomètres per hora",
-       "exif-gpsspeed-m": "Miles per hora",
+       "exif-gpsspeed-k": "Kilomètros a l’hora",
+       "exif-gpsspeed-m": "Milos a l’hora",
        "exif-gpsspeed-n": "Nuods",
-       "exif-gpsdestdistance-k": "Kilomètres",
-       "exif-gpsdestdistance-m": "Miles",
-       "exif-gpsdestdistance-n": "Miles marins",
+       "exif-gpsdestdistance-k": "Kilomètros",
+       "exif-gpsdestdistance-m": "Milos",
+       "exif-gpsdestdistance-n": "Milos navâls",
        "exif-gpsdop-excellent": "Famosa ($1)",
        "exif-gpsdop-good": "Bôna ($1)",
        "exif-gpsdop-moderate": "Moyena ($1)",
-       "exif-gpsdop-fair": "Passâbla ($1)",
+       "exif-gpsdop-fair": "Tot justo bôna ($1)",
        "exif-gpsdop-poor": "Crouye ($1)",
-       "exif-objectcycle-a": "Matin solament",
-       "exif-objectcycle-p": "Nuet solament",
+       "exif-objectcycle-a": "Ren qu’u matin",
+       "exif-objectcycle-p": "Ren qu’a nuet",
        "exif-objectcycle-b": "Matin et nuet",
-       "exif-gpsdirection-t": "Veré dirèccion",
-       "exif-gpsdirection-m": "Dirèccion magnètica",
+       "exif-gpsdirection-t": "Veretâbla bise (<em>nord</em>)",
+       "exif-gpsdirection-m": "Bise (<em>nord</em>) magnètica",
        "exif-ycbcrpositioning-1": "Centrâ",
-       "exif-ycbcrpositioning-2": "Co-situâ",
+       "exif-ycbcrpositioning-2": "Co-placiê",
        "exif-dc-contributor": "Contributors",
-       "exif-dc-coverage": "Portâ espaciâla ou ben temporèla du mèdia",
+       "exif-dc-coverage": "Portâ spaciâla ou ben temporâla du mèdiâ",
        "exif-dc-date": "Dâta(/-es)",
        "exif-dc-publisher": "Èditor",
-       "exif-dc-relation": "Mèdias liyês",
+       "exif-dc-relation": "Mèdiâs liyês",
        "exif-dc-rights": "Drêts",
-       "exif-dc-source": "Mèdia sôrsa",
-       "exif-dc-type": "Tipo de mèdia",
+       "exif-dc-source": "Mèdiâ sôrsa",
+       "exif-dc-type": "Tipo de mèdiâ",
        "exif-rating-rejected": "Refusâ",
        "exif-isospeedratings-overflow": "Ples grant que 65535",
-       "exif-iimcategory-ace": "Ârts, cultura et amusament",
+       "exif-iimcategory-ace": "Ârts, cultura et spèctâcllos",
        "exif-iimcategory-clj": "Crimo et drêt",
        "exif-iimcategory-dis": "Catastrofes et accidents",
        "exif-iimcategory-fin": "Èconomia et afâres",
        "exif-iimcategory-edu": "Èducacion",
        "exif-iimcategory-evn": "Enveronance",
        "exif-iimcategory-hth": "Santât",
-       "exif-iimcategory-hum": "Entèrèt de l’homo",
+       "exif-iimcategory-hum": "Entèrèt d’homo",
        "exif-iimcategory-lab": "Travâly",
        "exif-iimcategory-lif": "Fôrma de via et pâssa-temps",
        "exif-iimcategory-pol": "Politica",
        "exif-iimcategory-rel": "Religion et creyences",
-       "exif-iimcategory-sci": "Science et tècnolog·ie",
+       "exif-iimcategory-sci": "Science et tècnologia",
        "exif-iimcategory-soi": "Quèstions sociâles",
        "exif-iimcategory-spo": "Sports",
-       "exif-iimcategory-war": "Guèrra, conflit et troblo",
-       "exif-iimcategory-wea": "Mètèô",
+       "exif-iimcategory-war": "Guèrra, disputa et troblo",
+       "exif-iimcategory-wea": "Temps",
        "exif-urgency-normal": "Normala ($1)",
-       "exif-urgency-low": "Fêbla ($1)",
+       "exif-urgency-low": "Bâssa ($1)",
        "exif-urgency-high": "Hôta ($1)",
-       "exif-urgency-other": "Prioritât dèfenia per l’usanciér ($1)",
+       "exif-urgency-other": "Prioritât dèfenia per l’utilisator ($1)",
        "namespacesall": "Tôs",
        "monthsall": "tôs",
        "confirmemail": "Confirmar l’adrèce èlèctronica",
-       "confirmemail_noemail": "Vos éd pas dèfeni una adrèce èlèctronica valida dens voutres [[Special:Preferences|prèferences]].",
-       "confirmemail_text": "{{SITENAME}} at fôta du contrôlo de voutra adrèce èlèctronica devant que povêr utilisar tota fonccion de mèssageria.\nUtilisâd lo boton ce-desot por mandar un mèssâjo de confirmacion a voutra adrèce.\nLo mèssâjo encllurat un lim que contint un code a usâjo solèt et limitâ dens lo temps ;\nchargiéd cél lim dens voutron navigator por confirmar que voutra adrèce èlèctronica est valida.",
-       "confirmemail_pending": "Un code de confirmacion vos at ja étâ mandâ per mèssageria èlèctronica ;\nse vos vegnéd de fâre voutron compto, volyéd atendre doux-três menutes que lo mèssâjo arreve devant que demandar un code novél.",
+       "confirmemail_noemail": "Vos éd pas dèfeni un’adrèce èlèctronica justa dens voutres [[Special:Preferences|prèferences]].",
+       "confirmemail_text": "{{SITENAME}} at fôta du contrôlo de voutron adrèce èlèctronica devant que povêr empleyér tota fonccionalitât de mèssageria èlèctronica.\nEmpleyéd lo boton ce-desot por mandar un mèssâjo de confirmacion a voutron adrèce.\nLo mèssâjo rapondrat un lim que contint un code ;\nchargiéd cél lim dedens voutron navegator por confirmar que voutron adrèce èlèctronica est justa.",
+       "confirmemail_pending": "Un code de confirmacion vos est ja étâ mandâ per mèssageria èlèctronica ;\nse vos vegnéd de fâre voutron comptio, se vos plét atende-vos doux-três menutes que lo mèssâjo arreve devant que demandar un code novél.",
        "confirmemail_send": "Mandar un code de confirmacion",
        "confirmemail_sent": "Mèssâjo de confirmacion mandâ.",
-       "confirmemail_oncreate": "Un code de confirmacion at étâ mandâ a voutra adrèce èlèctronica.\nCél code est pas nècèssèro por sè branchiér, mas vos lo devréd balyér por activar tota fonccionalitât liyê a la mèssageria èlèctronica sur ceti vouiqui.",
-       "confirmemail_sendfailed": "{{SITENAME}} vos at pas possu mandar lo mèssâjo de confirmacion.\nVolyéd controlar que voutra adrèce èlèctronica contint gins de caractèro dèfendu.\n\nLo programo d’èxpèdicion de mèssâjo at retornâ ceta endicacion : $1",
-       "confirmemail_invalid": "Code de confirmacion fôx.\nCeti at pôt-étre èxpirâ.",
-       "confirmemail_needlogin": "Vos vos dête $1 por confirmar voutra adrèce èlèctronica.",
-       "confirmemail_success": "Voutra adrèce èlèctronica at étâ confirmâ.\nOra, vos vos pouede [[Special:UserLogin|branchiér]] et profitar du vouiqui.",
-       "confirmemail_loggedin": "Ora, voutra adrèce èlèctronica est confirmâ.",
+       "confirmemail_oncreate": "Un code de confirmacion est étâ mandâ a voutron adrèce èlèctronica.\nCél code est pas nècèssèro por sè branchiér, mas vos lo devréd balyér por activar tota fonccionalitât de mèssageria èlèctronica sur cél vouiqui.",
+       "confirmemail_sendfailed": "{{SITENAME}} vos at pas possu mandar lo mèssâjo de confirmacion.\nSe vos plét, controlâd que voutron adrèce èlèctronica contint gins de caractèro pas justo.\n\nLo programo d’èxpèdicion de mèssâjo at retornâ cen : $1",
+       "confirmemail_invalid": "Code de confirmacion pas justo.\nPôt-étre ceti at èxpirâ.",
+       "confirmemail_needlogin": "Vos vos dête $1 por confirmar voutron adrèce èlèctronica.",
+       "confirmemail_success": "Voutron adrèce èlèctronica est étâye confirmâye.\nOra vos vos pouede [[Special:UserLogin|branchiér]] et pués profitar du vouiqui.",
+       "confirmemail_loggedin": "Ora voutron adrèce èlèctronica est confirmâye.",
        "confirmemail_subject": "Confirmacion d’adrèce èlèctronica por {{SITENAME}}",
-       "confirmemail_body": "Quârqu’un, probâblament vos, avouéc l’adrèce IP $1,\nat encartâ un compto « $2 » avouéc cela adrèce èlèctronica dessus {{SITENAME}}.\n\nPor confirmar que cél compto est franc a vos et por\nactivar les fonccions de mèssageria dessus {{SITENAME}},\nvolyéd uvrir ceti lim dens voutron navigator :\n\n$3\n\nSe vos éd *pas* encartâ lo compto, siude ceti lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
-       "confirmemail_body_changed": "Quârqu’un, probâblament vos, avouéc l’adrèce IP $1,\nat changiê l’adrèce èlèctronica du compto « $2 » a cela adrèce dessus {{SITENAME}}.\n\nPor confirmar que cél compto est franc a vos et por\nreactivar les fonccions de mèssageria dessus {{SITENAME}},\nvolyéd uvrir ceti lim dens voutron navigator :\n\n$3\n\nSe lo compto est *pas* a vos, siude ceti lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
-       "confirmemail_body_set": "Quârqu’un, probâblament vos, avouéc l’adrèce IP $1,\nat changiê l’adrèce èlèctronica du compto « $2 » a cela adrèce dessus {{SITENAME}}.\n\nPor confirmar que cél compto est franc a vos et por\nreactivar les fonccions de mèssageria dessus {{SITENAME}},\nvolyéd uvrir ceti lim dens voutron navigator :\n\n$3\n\nSe lo compto est *pas* a vos, siude ceti lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
-       "confirmemail_invalidated": "Confirmacion de l’adrèce èlèctronica anulâ",
+       "confirmemail_body": "Yon, de sûr vos, avouéc l’adrèce IP $1,\nat encartâ un comptio « $2 » avouéc cel’adrèce èlèctronica dessus {{SITENAME}}.\n\nPor confirmar que cél comptio est franc a vos et por activar\nles fonccionalitâts de mèssageria èlèctronica dessus {{SITENAME}},\nse vos plét uvréd cél lim dedens voutron navegator :\n\n$3\n\nSe vos éd *pas* encartâ lo comptio, siude l’ôtro lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
+       "confirmemail_body_changed": "Yon, de sûr vos, avouéc l’adrèce IP $1,\nat changiê l’adrèce èlèctronica du comptio « $2 » dessus {{SITENAME}} en cel’adrèce.\n\nPor confirmar que cél comptio est franc a vos et por reactivar\nles fonccionalitâts de mèssageria èlèctronica dessus {{SITENAME}},\nse vos plét uvréd cél lim dedens voutron navegator :\n\n$3\n\nSe lo compto est *pas* a vos, siude l’ôtro lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
+       "confirmemail_body_set": "Yon, de sûr vos, avouéc l’adrèce IP $1,\nat dèfeni l’adrèce èlèctronica du comptio « $2 » dessus {{SITENAME}} en cel’adrèce.\n\nPor confirmar que cél comptio est franc a vos et por activar\nles fonccionalitâts de mèssageria èlèctronica dessus {{SITENAME}},\nse vos plét uvréd cél lim dedens voutron navegator :\n\n$3\n\nSe lo compto est *pas* a vos, siude l’ôtro lim\npor anular la confirmacion de l’adrèce èlèctronica :\n\n$5\n\nCél code de confirmacion èxpirerat lo $4.",
+       "confirmemail_invalidated": "Confirmacion de l’adrèce èlèctronica anulâye",
        "invalidateemail": "Anular la confirmacion de l’adrèce èlèctronica",
-       "scarytranscludedisabled": "[La transcllusion entèrvouiqui est dèsactivâ]",
-       "scarytranscludefailed": "[La rècupèracion de modèlo at pas reussia por $1]",
+       "notificationemail_subject_changed": "L’adrèce èlèctronica encartâye dessus {{SITENAME}} est étâye changiêe",
+       "notificationemail_subject_removed": "L’adrèce èlèctronica encartâye dessus {{SITENAME}} est étâye enlevâye",
+       "notificationemail_body_changed": "Yon, de sûr vos, avouéc l’adrèce IP $1,\nat changiê l’adrèce èlèctronica du comptio « $2 » dessus {{SITENAME}} en « $3 ».\n\nS’o ére pas vos, veriéd-vos d’abôrd vers un administrator du seto.",
+       "notificationemail_body_removed": "Yon, de sûr vos, avouéc l’adrèce IP $1,\nat enlevâ l’adrèce èlèctronica du comptio « $2 » dessus {{SITENAME}}.\n\nS’o ére pas vos, veriéd-vos d’abôrd vers un administrator du seto.",
+       "scarytranscludedisabled": "[La transcllusion entèrvouiqui est dèsactivâye]",
+       "scarytranscludefailed": "[La rècupèracion de modèlo at pas reussi por $1]",
+       "scarytranscludefailed-httpstatus": "[La rècupèracion de modèlo at pas reussi por $1 : HTTP $2]",
        "scarytranscludetoolong": "[L’URL est trop longe]",
-       "deletedwhileediting": "'''Atencion :''' ceta pâge at étâ suprimâ aprés que vos vos éte betâ a la changiér !",
-       "confirmrecreate": "L’usanciér [[User:$1|$1]] ([[User talk:$1|Discussion]]) at suprimâ ceta pâge, pendent que vos vos érâd betâ a la changiér, por ceta rêson :\n: ''$2''\nVolyéd confirmar que vos voléd franc refâre cela pâge.",
-       "confirmrecreate-noreason": "L’usanciér [[User:$1|$1]] ([[User talk:$1|Discussion]]) at suprimâ ceta pâge, pendent que vos vos érâd betâ a la changiér.  Volyéd confirmar que vos voléd franc refâre cela pâge.",
+       "deletedwhileediting": "<strong>Atencion :</strong> cela pâge est étâye suprimâye aprés que vos vos éte betâ a la changiér !",
+       "confirmrecreate": "L’utilisat{{GENDER:$1|or|rice}} [[User:$1|$1]] ([[User talk:$1|discussion]]) at suprimâ cela pâge, pendent que vos vos érâd betâ a la changiér, por ceta rêson :\n: <em>$2</em>\nSe vos plét, confirmâd que vos voléd franc refâre cela pâge.",
+       "confirmrecreate-noreason": "L’utilisat{{GENDER:$1|or|rice}} [[User:$1|$1]] ([[User talk:$1|discussion]]) at suprimâ cela pâge, pendent que vos vos érâd betâ a la changiér. Se vos plét, confirmâd que vos voléd franc refâre cela pâge.",
        "recreate": "Refâre",
        "confirm_purge_button": "Confirmar",
-       "confirm-purge-top": "Voléd-vos purgiér lo cache de ceta pâge ?",
-       "confirm-purge-bottom": "Purgiér una pâge èface lo cache et pués fôrce la dèrriére vèrsion a étre montrâ.",
+       "confirm-purge-top": "Vos voléd purgiér lo cacho de cela pâge ?",
+       "confirm-purge-bottom": "Purgiér na pâge vouede lo cacho et pués fôrce la dèrriére vèrsion a étre montrâye.",
        "confirm-watch-button": "D’acôrd",
-       "confirm-watch-top": "Apondre ceta pâge a voutra lista de survelyence ?",
+       "confirm-watch-top": "Apondre cela pâge a voutra lista de gouârda ?",
        "confirm-unwatch-button": "D’acôrd",
-       "confirm-unwatch-top": "Enlevar ceta pâge de voutra lista de survelyence ?",
+       "confirm-unwatch-top": "Enlevar cela pâge de voutra lista de gouârda ?",
        "semicolon-separator": "&nbsp;;&#32;",
        "colon-separator": "&nbsp;:&#32;",
        "percent": "$1&#160;%",
+       "quotation-marks": "« $1 »",
        "imgmultipageprev": "← pâge devant",
        "imgmultipagenext": "pâge aprés →",
        "imgmultigo": "Emmodar !",
        "imgmultigoto": "Alar a la pâge $1",
+       "img-lang-default": "(lengoua per dèfôt)",
+       "img-lang-info": "Montrar cel’émâge en $1 $2.",
        "img-lang-go": "Emmodar",
-       "ascending_abbrev": "que crêt",
-       "descending_abbrev": "que dècrêt",
+       "ascending_abbrev": "crès.",
+       "descending_abbrev": "dècr.",
        "table_pager_next": "Pâge aprés",
        "table_pager_prev": "Pâge devant",
        "table_pager_first": "Premiére pâge",
        "table_pager_last": "Dèrriére pâge",
-       "table_pager_limit": "Montrar $1 èlèment{{PLURAL:$1||s}} per pâge",
-       "table_pager_limit_label": "Rèsultats per pâge :",
+       "table_pager_limit": "Montrar $1 piéces per pâge",
+       "table_pager_limit_label": "Piéces per pâge :",
        "table_pager_limit_submit": "Emmodar",
-       "table_pager_empty": "Gins de rèsultat",
+       "table_pager_empty": "Nion rèsultat",
        "autosumm-blank": "Pâge blanchia",
        "autosumm-replace": "Contegnu remplaciê per « $1 »",
-       "autoredircomment": "Pâge redirigiê vers [[$1]]",
+       "autoredircomment": "Pâge redirigiêe vers [[$1]]",
        "autosumm-new": "Pâge fêta avouéc « $1 »",
+       "autosumm-newblank": "Pâge voueda fêta",
        "size-bytes": "$1 o",
        "size-kilobytes": "$1 Kio",
        "size-megabytes": "$1 Mio",
        "size-gigabytes": "$1 Gio",
-       "lag-warn-normal": "Los changements que dâtont de muens de $1 {{PLURAL:$1|seconda|secondes}} pôvont pas aparêtre dens ceta lista.",
-       "lag-warn-high": "En rêson d’un retârd important du sèrvor de bâsa de balyês, los changements que dâtont de muens de $1 {{PLURAL:$1|seconda|secondes}} pôvont pas aparêtre dens ceta lista.",
-       "watchlistedit-normal-title": "Changiér la lista de survelyence",
-       "watchlistedit-normal-legend": "Enlevar des titros de la lista de survelyence",
-       "watchlistedit-normal-explain": "Los titros de voutra lista de survelyence sont montrâs ce-desot.\nPor enlevar un titro (et sa pâge de discussion), pouentâd la câsa a coutâ et pués clicâd sur lo boton « {{int:Watchlistedit-normal-submit}} ».\nVos pouede asse-ben changiér la [[Special:EditWatchlist/raw|lista en fôrma bruta]].",
+       "lag-warn-normal": "Los changements que dâtont de muens de $1 second{{PLURAL:$1|a|es}} pôvont pas aparêtre dedens cela lista.",
+       "lag-warn-high": "A côsa d’un retârd important du sèrvior de bâsa de balyês, los changements que dâtont de muens de $1 second{{PLURAL:$1|a|es}} pôvont pas aparêtre dedens cela lista.",
+       "watchlistedit-normal-title": "Changiér la lista de gouârda",
+       "watchlistedit-normal-legend": "Enlevar de titros de la lista de gouârda",
+       "watchlistedit-normal-explain": "Los titros de voutra lista de gouârda sont montrâs ce-desot.\nPor enlevar un titro, pouentâd la câsa a coutâ et pués cllicâd sur lo boton « {{int:Watchlistedit-normal-submit}} ».\nVos pouede asse-ben [[Special:EditWatchlist/raw|changiér la lista en fôrma bruta]].",
        "watchlistedit-normal-submit": "Enlevar los titros",
-       "watchlistedit-normal-done": "{{PLURAL:$1|Yon titro at étâ enlevâ|$1 titros ont étâ enlevâs}} de voutra lista de survelyence :",
-       "watchlistedit-raw-title": "Changiér la lista de survelyence en fôrma bruta",
-       "watchlistedit-raw-legend": "Changement de la lista de survelyence en fôrma bruta",
-       "watchlistedit-raw-explain": "Los titros de voutra lista de survelyence sont montrâs ce-desot et pôvont étre changiês en los apondent ou ben en los enlevent de la lista ;\nyon titro per legne.\nQuand vos éd feni, clicâd sur lo boton « {{int:Watchlistedit-raw-submit}} ».\nVos pouede asse-ben utilisar l’[[Special:EditWatchlist|èditor normal]].",
+       "watchlistedit-normal-done": "{{PLURAL:$1|Un titro est étâ enlevâ|$1 titros sont étâs enlevâs}} de voutra lista de gouârda :",
+       "watchlistedit-raw-title": "Changiér la lista de gouârda en fôrma bruta",
+       "watchlistedit-raw-legend": "Changement de la lista de gouârda en fôrma bruta",
+       "watchlistedit-raw-explain": "Los titros de voutra lista de gouârda sont montrâs ce-desot et pôvont étre changiês en los apondent los enlevent de la lista ;\nun titro per legne.\nQuand vos éd chavono, cllicâd sur lo boton « {{int:Watchlistedit-raw-submit}} ».\nVos pouede asse-ben [[Special:EditWatchlist|empleyér l’èditor standârd]].",
        "watchlistedit-raw-titles": "Titros :",
-       "watchlistedit-raw-submit": "Betar a jorn la lista de survelyence",
-       "watchlistedit-raw-done": "Voutra lista de survelyence at étâ betâ a jorn.",
-       "watchlistedit-raw-added": "{{PLURAL:$1|Yon titro at étâ apondu|$1 titros ont étâ apondus}} :",
-       "watchlistedit-raw-removed": "{{PLURAL:$1|Yon titro at étâ enlevâ|$1 titros ont étâ enlevâs}} :",
-       "watchlisttools-view": "Lista de survelyence",
-       "watchlisttools-edit": "Vêre et changiér la lista de survelyence",
-       "watchlisttools-raw": "Changiér la lista de survelyence en fôrma bruta",
+       "watchlistedit-raw-submit": "Betar a jorn la lista de gouârda",
+       "watchlistedit-raw-done": "Voutra lista de gouârda est étâye betâye a jorn.",
+       "watchlistedit-raw-added": "{{PLURAL:$1|Un titro est étâ apondu|$1 titros sont étâs apondus}} :",
+       "watchlistedit-raw-removed": "{{PLURAL:$1|Un titro est étâ enlevâ|$1 titros sont étâs enlevâs}} :",
+       "watchlistedit-clear-title": "Vouedar la lista de gouârda",
+       "watchlistedit-clear-legend": "Vouedar la lista de gouârda",
+       "watchlistedit-clear-explain": "Tôs los titros seront enlevâs de voutra lista de gouârda",
+       "watchlistedit-clear-titles": "Titros :",
+       "watchlistedit-clear-submit": "Vouedar la lista de gouârda (o est por de bon !)",
+       "watchlistedit-clear-done": "Voutra lista de gouârda est étâye vouedâye.",
+       "watchlistedit-clear-removed": "{{PLURAL:$1|Un titro est étâ enlevâ|$1 titros sont étâs enlevâs}} :",
+       "watchlistedit-too-many": "Y at trop de pâges a fâre vêre ique.",
+       "watchlisttools-clear": "Vouedar la lista de gouârda",
+       "watchlisttools-view": "Lista de gouârda",
+       "watchlisttools-edit": "Vêre et changiér la lista de gouârda",
+       "watchlisttools-raw": "Changiér la lista de gouârda en fôrma bruta",
        "iranian-calendar-m1": "de farvardin",
        "iranian-calendar-m2": "d’ordibehèch·ete",
        "iranian-calendar-m3": "de c’hordâde",
        "hebrew-calendar-m10-gen": "de tamouz",
        "hebrew-calendar-m11-gen": "d’av",
        "hebrew-calendar-m12-gen": "d’èloul",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discutar]])",
-       "duplicate-defaultsort": "'''Atencion :''' la cllâf de tri per dèfôt « $2 » ècllafe cela « $1 ».",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussion]])",
+       "timezone-local": "Locâl",
+       "duplicate-defaultsort": "<strong>Atencion :</strong> la cllâf de chouèx per dèfôt « $2 » ècllafe la vielye cllâf « $1 ».",
+       "duplicate-displaytitle": "<strong>Atencion :</strong> lo titro de viua « $2 » ècllafe lo viely titro « $1 ».",
+       "invalid-indicator-name": "<strong>Fôta :</strong> l’atribut <code>name</code> des endiquiors d’ètat de la pâge dêt pas étre vouedo.",
        "version": "Vèrsion",
-       "version-extensions": "Èxtensions enstalâs",
-       "version-skins": "Habelyâjos",
+       "version-extensions": "Èxtensions enstalâyes",
+       "version-skins": "Habelyâjos enstalâs",
        "version-specialpages": "Pâges spèciâles",
-       "version-parserhooks": "Grèfons du parsor",
+       "version-parserhooks": "Èxtensions parsiors",
        "version-variables": "Variâbles",
-       "version-antispam": "Prèvencion du spame",
+       "version-antispam": "Prèvencion de mèssâjos cofos",
        "version-other": "De totes sôrtes",
-       "version-mediahandlers": "Maneyors de mèdia",
-       "version-hooks": "Grèfons",
-       "version-parser-extensiontags": "Balises d’èxtension du parsor",
-       "version-parser-function-hooks": "Grèfons de les fonccions du parsor",
-       "version-hook-name": "Nom du grèfon",
-       "version-hook-subscribedby": "Soscrit per",
+       "version-mediahandlers": "Maneyors de mèdiâs",
+       "version-hooks": "Èxtensions",
+       "version-parser-extensiontags": "Balises d’èxtensions parsiors",
+       "version-parser-function-hooks": "Èxtensions de les fonccions parsiors",
+       "version-hook-name": "Nom de l’èxtension",
+       "version-hook-subscribedby": "Abonâs :",
        "version-version": "($1)",
-       "version-license": "Licence",
-       "version-poweredby-credits": "Ceti vouiqui fonccione grâce a '''[https://www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
+       "version-no-ext-name": "[nion nom]",
+       "version-license": "Licence MediaWiki",
+       "version-ext-license": "Licence",
+       "version-ext-colheader-name": "Èxtension",
+       "version-skin-colheader-name": "Habelyâjo",
+       "version-ext-colheader-version": "Vèrsion",
+       "version-ext-colheader-license": "Licence",
+       "version-ext-colheader-description": "Dèscripcion",
+       "version-ext-colheader-credits": "Ôtors",
+       "version-license-title": "Licence por $1",
+       "version-license-not-found": "Nion’enformacion dètalyêe de la licence est étâye trovâye por cel’èxtension.",
+       "version-credits-title": "Grant-marci por $1",
+       "version-credits-not-found": "Nion’enformacion dètalyêe du grant-marci est étâye trovâye por cel’èxtension.",
+       "version-poweredby-credits": "Cél vouiqui fonccione grâce a <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
        "version-poweredby-others": "ôtros",
-       "version-license-info": "MediaWiki est una programeria libra ; vos la pouede tornar distribuar et / ou changiér d’aprés los tèrmos de la Licence publica g·ènèrala GNU coment publeyê per la Free Software Foundation ; seye la vèrsion 2 de la Licence, ou ben (a voutron chouèx) tota novèla vèrsion.\n\nMediaWiki est distribuâ dens l’èsperance que serat utila, mas SEN GINS DE GARANTIA ; sen mémo la garantia emplicita de COMÈRCIALISACION ou ben d’ADAPTACION A UN USÂJO PARTICULIÉR. Vêde la Licence publica g·ènèrala GNU por més de dètalys.\n\nVos devriâd avêr reçu un [{{SERVER}}{{SCRIPTPATH}}/COPYING ègzemplèro de la Licence publica g·ènèrala GNU] avouéc ceti programo ; ôtrament, ècrîde a la « Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA » ou ben [//www.gnu.org/licenses/old-licenses/gpl-2.0.html liéséd-la en legne].",
-       "version-software": "Programeries enstalâs",
+       "version-poweredby-translators": "traductors de translatewiki.net",
+       "version-credits-summary": "Nos tegnens a remarciér cetes gens por lor contribucion a [[Special:Version|MediaWiki]].",
+       "version-license-info": "MediaWiki est na programeria libra ; vos la pouede redistribuar et / ou changiér d’aprés los tèrmos de la Licence publica g·ènèrâla GNU coment publeyêe per la Free Software Foundation ; ou ben la vèrsion 2 de la Licence ou ben (a voutron chouèx) tota vèrsion ples novèla.\n\nMediaWiki est distribuâ dens l’èsperance que serat utila, mas SEN NIONA GARANTIA ; sen mémo la garantia sosentendua de COMÈRCIALISACION d’ADAPTACION A UN USÂJO PARTICULIÉR. Vêde la Licence publica g·ènèrâla GNU por més de dètalys.\n\nVos devriâd avêr reçu na [{{SERVER}}{{SCRIPTPATH}}/COPYING copia de la Licence publica g·ènèrâla GNU] avouéc cél programo ; ôtrament, ècrîde a la « Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA » ou ben [//www.gnu.org/licenses/old-licenses/gpl-2.0.html liéséd-la en legne].",
+       "version-software": "Programeries enstalâyes",
        "version-software-product": "Marchandie",
        "version-software-version": "Vèrsion",
-       "version-entrypoints": "URL de pouent d’entrâ",
+       "version-entrypoints": "URLs des pouents d’entrâ",
        "version-entrypoints-header-entrypoint": "Pouent d’entrâ",
        "version-entrypoints-header-url": "URL",
+       "version-libraries": "Bibliotèques enstalâyes",
+       "version-libraries-library": "Bibliotèca",
+       "version-libraries-version": "Vèrsion",
+       "version-libraries-license": "Licence",
+       "version-libraries-description": "Dèscripcion",
+       "version-libraries-authors": "Ôtors",
+       "redirect": "Redirigiér per ID de fichiér, utilisator, pâge, vèrsion ou ben jornâl",
+       "redirect-summary": "Cela pâge spèciâla redirige vers un fichiér (lo nom de fichiér balyê), na pâge (l’ID de vèrsion de pâge balyê), na pâge d’utilisator (l’ID numerico a l’utilisator balyê) ou ben un’entrâ de jornâl (l’ID du jornâl balyê). Usâjo : [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] ou ben [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Emmodar",
+       "redirect-lookup": "Rechèrche :",
+       "redirect-value": "Valor :",
+       "redirect-user": "ID a l’utilisator",
+       "redirect-page": "ID de pâge",
+       "redirect-revision": "Vèrsion de la pâge",
+       "redirect-file": "Nom du fichiér",
+       "redirect-logid": "ID du jornâl",
+       "redirect-not-exists": "Valor entrovâbla",
        "fileduplicatesearch": "Rechèrche des fichiérs en doblo",
        "fileduplicatesearch-summary": "Rechèrche des fichiérs en doblo d’aprés lor mârca de chaplâjo.",
        "fileduplicatesearch-filename": "Nom du fichiér :",
        "fileduplicatesearch-submit": "Rechèrchiér",
        "fileduplicatesearch-info": "$1 × $2 pixèls<br />Talye du fichiér : $3<br />Tipo MIME : $4",
        "fileduplicatesearch-result-1": "Lo fichiér « $1 » at gins de doblo pariér.",
-       "fileduplicatesearch-result-n": "Lo fichiér « $1 » at $2 {{PLURAL:$2|doblo pariér|doblos pariérs}}.",
-       "fileduplicatesearch-noresults": "Nion fichiér apelâ « $1 » at étâ trovâ.",
+       "fileduplicatesearch-result-n": "Lo fichiér « $1 » at {{PLURAL:$2|1 doblo pariér|$2 doblos pariérs}}.",
+       "fileduplicatesearch-noresults": "Nion fichiér apelâ « $1 » est étâ trovâ.",
        "specialpages": "Pâges spèciâles",
-       "specialpages-note": "* Pâges spèciâles normales.\n* <span class=\"mw-specialpagerestricted\">Pâges spèciâles rètrentes.</span>\n* <span class=\"mw-specialpagecached\">Pâges spèciâles solament en cache (porriant étre dèpassâs).</span>",
-       "specialpages-group-maintenance": "Rapôrts de mantegnence",
+       "specialpages-note-top": "Lègenda",
+       "specialpages-note": "* Pâges spèciâles normales.\n* <span class=\"mw-specialpagerestricted\">Pâges spèciâles rètrentes.</span>",
+       "specialpages-group-maintenance": "Rapôrts d’entretin",
        "specialpages-group-other": "Ôtres pâges spèciâles",
-       "specialpages-group-login": "Sè branchiér / fâre un compto",
-       "specialpages-group-changes": "Dèrriérs changements et jornals",
-       "specialpages-group-media": "Rapôrts et tèlèchargements de fichiérs mèdia",
-       "specialpages-group-users": "Usanciérs et drêts apondus",
+       "specialpages-group-login": "Sè branchiér / fâre un comptio",
+       "specialpages-group-changes": "Dèrriérs changements et jornâls",
+       "specialpages-group-media": "Rapôrts de mèdiâs et tèlèchargements",
+       "specialpages-group-users": "Utilisators et drêts",
        "specialpages-group-highuse": "Pâges d’usâjo important",
        "specialpages-group-pages": "Listes de pâges",
        "specialpages-group-pagetools": "Outils por les pâges",
-       "specialpages-group-wiki": "Balyês du vouiqui et outils",
-       "specialpages-group-redirects": "Pâges spèciâles redirigiês",
-       "specialpages-group-spam": "Outils anti-spame",
-       "specialpages-group-developer": "Outils u dèvelopor",
+       "specialpages-group-wiki": "Balyês et outils",
+       "specialpages-group-redirects": "Pâges spèciâles que redirijont",
+       "specialpages-group-spam": "Outils contre los mèssâjos cofos",
+       "specialpages-group-developer": "Outils u dèvelopior",
        "blankpage": "Pâge voueda",
-       "intentionallyblankpage": "Ceta pâge est lèssiê èxprès voueda.",
-       "external_image_whitelist": "  #Lèssiéd ceta legne justo d’ense.<pre>\n#Endicâd los bocons d’èxprèssions racionèles (solament la partia endicâ entre-mié los //) ce-desot.\n#Corrèspondront avouéc los lims hipèrtèxtos de les émâges (ben liyês) de defôr.\n#Celos que corrèspondont sè montreront coment des émâges, ôtrament solament un lim de vers l’émâge serat montrâ.\n#Les legnes que començont per un # seront considèrâs coment des comentèros.\n#Ceta lista est pas sensibla a la câssa.\n\n#Betâd tôs los bocons d’èxprèssions racionèles (*RegEx*) en-dessus de ceta legne. Lèssiéd ceta legne justo d’ense.</pre>",
-       "tags": "Balises des changements valides",
+       "intentionallyblankpage": "Cela pâge est lèssiêe volontèrament voueda.",
+       "external_image_whitelist": " #Lèssiéd ceta legne justo d’ense.<pre>\n#Endicâd los bocons d’èxprèssions racionâles (solament la partia endicâye entre-mié los //) ce-desot.\n#Corrèspondront avouéc les URLs de les émâges (ben liyêes) de defôr.\n#Celos que corrèspondont sè faront vêre coment d’émâges, ôtrament solament un lim de vers l’émâge serat montrâ.\n#Les legnes que començont per un # seront considèrâyes coment de comentèros.\n#O est pas sensiblo a la câssa.\n\n#Betâd tôs los bocons d’èxprèssions racionâles d’amont ceta legne. Lèssiéd cela legne justo d’ense.</pre>",
+       "tags": "Balises des changements justos",
        "tag-filter": "Filtrar les [[Special:Tags|balises]] :",
        "tag-filter-submit": "Filtrar",
        "tag-list-wrapper": "([[Special:Tags|Balis{{PLURAL:$1|a|es}}]] : $2)",
        "tags-title": "Balises",
-       "tags-intro": "Ceta pâge liste les balises que la programeria pôt utilisar por marcar un changement et lor significacion.",
+       "tags-intro": "Cela pâge liste les balises que la programeria pôt empleyér por marcar un changement et lor significacion.",
        "tags-tag": "Nom de la balisa",
-       "tags-display-header": "Aparence dens les listes de changements",
+       "tags-display-header": "Aparence dedens les listes de changements",
        "tags-description-header": "Dèscripcion complèta de la balisa",
+       "tags-source-header": "Sôrsa",
+       "tags-active-header": "Actif ?",
        "tags-hitcount-header": "Changements balisâs",
+       "tags-actions-header": "Accions",
+       "tags-active-yes": "Ouè",
+       "tags-active-no": "Nan",
+       "tags-source-extension": "Dèfenia per un’èxtension",
+       "tags-source-manual": "Aplicâye a la man per los utilisators et los robots",
+       "tags-source-none": "Dèpassâye",
        "tags-edit": "changiér",
+       "tags-delete": "suprimar",
+       "tags-activate": "activar",
+       "tags-deactivate": "dèsactivar",
        "tags-hitcount": "$1 changement{{PLURAL:$1||s}}",
+       "tags-manage-no-permission": "Vos éd pas la pèrmission de maneyér les balises de changement.",
+       "tags-manage-blocked": "Vos pouede pas maneyér les balises de changement quand vos éte blocâ{{GENDER:||ye}}.",
+       "tags-create-heading": "Fâre na balisa novèla",
+       "tags-create-explanation": "Per dèfôt, les balises novèles fêtes seront disponibles por los utilisators et los robots.",
+       "tags-create-tag-name": "Nom de la balisa :",
+       "tags-create-reason": "Rêson :",
+       "tags-create-submit": "Fâre",
+       "tags-create-no-name": "Vos dête spècifiar un nom de balisa.",
        "comparepages": "Comparar des pâges",
        "compare-page1": "Pâge 1",
        "compare-page2": "Pâge 2",
index d8659c0..1fcf778 100644 (file)
        "morenotlisted": "Chan eil an liosta seo iomlan.",
        "mypage": "Duilleag",
        "mytalk": "Deasbaireachd",
-       "anontalk": "Deasbaireachd airson an IP seo",
+       "anontalk": "Deasbaireachd",
        "navigation": "Seòladh",
        "and": "&#32;agus",
        "qbfind": "Lorg",
        "laggedslavemode": "<strong>Rabhadh:</strong> Faodaidh nach eil ùrachaidhean a rinneadh o chionn ghoirid a' nochdadh san duilleag.",
        "readonly": "Stòr-dàta glaiste",
        "enterlockreason": "Cuir a-steach adhbhar a' ghlais, a' gabhail a-steach tuairmeas air fuasgladh a' ghlais.",
-       "readonlytext": "Tha an stòr-dàta glaiste do chlàir ùra 's mùthaidhean eile, ma dh'fhaoidte air sgàth obair-chàraidh chunbhalach an stòir-dhàta 's bidh e mar as àbhaist às dèidh sin.\n\nChuir an rianadair a ghlas e an cèill na leanas: $1",
+       "readonlytext": "Tha an stòr-dàta glaiste do chlàir ùra ’s mùthaidhean eile, ma dh’fhaoidte air sgàth obair-chàraidh chunbhalach an stòir-dhàta ’s bidh e mar as àbhaist às dèidh sin.\n\nThuirt rianadair an t-siostaim a ghlas e na leanas: $1",
        "missing-article": "Cha do lorg an stòr-dàta teacsa de dhuilleag a bu chòir a bhith air a lorg aige 's air a bheil \"$1\" $2.\n\n'S e diofar no ceangal eachdraidheil ro shean ri duilleag a chaidh a sguabadh às a bhios coireach à seo mar is trice.\n\nMur eil seo fìor, faodaidh gun do lorg thu buga sa bhathar-bhog.\nAn dèan thu aithris air seo do [[Special:ListUsers/sysop|rianadair]], ag innse dhaibh dè an t-URL a bha ann.",
        "missingarticle-rev": "(mùthadh#: $1)",
        "missingarticle-diff": "(Diofar: $1, $2)",
        "viewsource": "Seall an tùs",
        "viewsource-title": "Seall an tùs aig $1",
        "actionthrottled": "Gnìomh air a mhùchadh",
-       "actionthrottledtext": "Gus casg a chur air spama, chan urrainn dhut an gnìomh seo a dhèanamh ro thric am broinn ùine ghoirid agus chaidh thu thairis air a' chrìoch seo.\nFeuch ris a-rithist às a dhèidh seo.",
+       "actionthrottledtext": "Gus casg a chur air droch-ghiùlan, chan urrainn dhut an gnìomh seo a dhèanamh ro thric am broinn ùine ghoirid agus chaidh thu thairis air a’ chrìoch seo.\nFeuch ris a-rithist ann am beagan mhionaidean.",
        "protectedpagetext": "Chaidh an duilleag seo a dhìon gus casg a chur air deasachadh.",
-       "viewsourcetext": "'S urrainn dhut coimhead air tùs na duilleige seo 's lethbhreac a dhèanamh dheth:",
-       "viewyourtext": "'S urrainn dhut coimhead air <strong>na dheasaich thu</strong> 's lethbhreac a dhèanamh dheth air an duilleag seo:",
+       "viewsourcetext": "’S urrainn dhut coimhead air tùs na duilleige seo ’s lethbhreac a dhèanamh dheth.",
+       "viewyourtext": "’S urrainn dhut coimhead air <strong>na dheasaich thu</strong> ’s lethbhreac a dhèanamh dheth air an duilleag seo.",
        "protectedinterface": "Bheir an duilleag seo dhut teacsa eadar-aghaidh airson a' bhathar-bhog air an uicidh seo 's chaidh a ghlasadh gus casg a chur air mì-chleachdadh. Gus eadar-theangachadh atharrachadh no a chur ris airson gach uicidh, cleachd [//translatewiki.net/ translatewiki.net], pròiseactan eadar-theangachadh MediaWiki.",
        "editinginterface": "<strong>Rabhadh:</strong> Tha thu a' deasachadh duilleag a tha 'ga chleachdadh a chum teacsa eadar-aghaidh a sholar airson a' bhathar-bhog.\nMa dh'atharraicheas tu an duilleag seo, bidh buaidh ann air coltas na h-eadar-aghaidh mar a chì càch e air an uicidh seo.",
        "translateinterface": "Gus eadar-theangachadh atharrachadh no a chur ris airson gach uicidh, cleachd [//translatewiki.net/ translatewiki.net], am pròiseact eadar-theangachaidh aig MediaWiki.",
-       "cascadeprotected": "Chaidh an duilleag seo a dhìon o dheasachadh a chionn 's gu bheil e am broinn {{PLURAL:$1|na duilleige|nan duilleagan}} a leanas a chaidh a dhìon 's an roghainn \"mar eas\" air:\n$2",
+       "cascadeprotected": "Chaidh an duilleag seo a dhìon o dheasachadh a chionn ’s gu bheil e fillte a-staigh {{PLURAL:$1|san duilleag|sna duilleagan}} a leanas a chaidh a dhìon ’s an roghainn “mar eas” air:\n$2",
        "namespaceprotected": "Chan eil cead agad duilleagan san ainm-spàs <strong>$1</strong> a dheasachadh.",
        "customcssprotected": "Chan eil cead agad an duilleag CSS seo a dheasachadh a chionn 's gu bheil na roghainnean pearsanta aig cleachdaiche eile innte.",
        "customjsprotected": "Chan eil cead agad an duilleag JavaScript seo a dheasachadh a chionn 's gu bheil na roghainnean pearsanta aig cleachdaiche eile innte.",
        "mypreferencesprotected": "Chan eil cead agad na roghainnean agad a dheasachadh.",
        "ns-specialprotected": "Chan ghabh duilleagan sònraichte a dheasachadh.",
        "titleprotected": "Chaidh an duilleag seo a dhìon o chruthachadh le [[User:$1|$1]].\nSeo am mìneachadh: <em>$2</em>.",
-       "filereadonlyerror": "Cha ghabh am faidhle \"$1\" atharrachadh a chionn 's gu bheil ionad-tasgaidh fhaidhlichean \"$2\" ri leughadh a-mhàin.\nThug an rianaire a ghlais e seachad an t-adhbhar a leanas: \"$3\".",
+       "filereadonlyerror": "Cha ghabh am faidhle “$1” atharrachadh a chionn ’s gu bheil ionad-tasgaidh fhaidhlichean “$2” ri leughadh a-mhàin.\nThuirt rianaire an t-siostaim a ghlais e na leanas: “$3”.",
        "invalidtitle-knownnamespace": "Tiotal mì-dhligheach leis an ainm-spàs \"$2\" agus an teacsa \"$3\"",
        "invalidtitle-unknownnamespace": "Tiotal mì-dhligheach leis an àireamh ainm-spàis $1 agus an teacsa \"$2\"",
        "exception-nologin": "Chan eil thu air logadh a-steach",
        "createacct-reason": "Adhbhar",
        "createacct-reason-ph": "Carson a tha thu a' cruthachadh cunntas eile?",
        "createacct-submit": "Cruthaich an cunntas agad",
-       "createacct-another-submit": "Cruthaich cunntas eile",
+       "createacct-another-submit": "Cruthaich cunntas",
        "createacct-benefit-heading": "Tha {{SITENAME}} 'ga chruthachadh le daoine mar thu fhèin.",
        "createacct-benefit-body1": "{{PLURAL:$1|deasachadh|deasachaidhean}}",
        "createacct-benefit-body2": "{{PLURAL:$1|duilleag|duilleagan}}",
        "noemail": "Cha deach post-d a chlàradh airson a' chleachdaiche \"$1\".",
        "noemailcreate": "Feumaidh tu post-d dligheach a chur ann",
        "passwordsent": "Chaidh facal-faire ùr a chur dhan phost-d a chaidh a chlàradh airson \"$1\".\nDèan logadh a-steach a-rithist nuair a gheibh thu e.",
-       "blocked-mailpassword": "Chaidh bacadh a chur air an t-seòladh IP agad 's chan eil cead deasachaidh agad agus chan urrainn dhut an gleus a chum aiseag an fhacail-fhaire a chleachdadh gus casg a chur air mì-ghnàthachadh.",
+       "blocked-mailpassword": "Chaidh bacadh deasachaidh a chur air an t-seòladh IP agad. Airson casg a chur air mì-ghnàthachadh, chan urrainn dhut an gleus a chum aiseag an fhacail-fhaire a chleachdadh an-dràsta fhèin.",
        "eauthentsent": "Chaidh post-d dearbhaidh a chur dhan phost-d a chaidh ainmeachadh.\nMus dèid post-d sam bith eile a chur dhan chunntas, feumaidh tu leantainn ris an stiùireadh sa phost-d mar dhearbhadh gur ann agadsa a tha an cunntas.",
        "throttled-mailpassword": "Chaidh post-d a chur airson ath-shuidheachadh facail-fhaire mu thràth $1 {{PLURAL:$1|uair|uair|uairean|uair}} a thìde air ais.\nGus casg a chur air mì-ghnàthachadh, cha chuir sinn ach aon chuimhneachan facail-fhaire gach $1 {{PLURAL:$1|uair|uair|uairean|uair}} a thìde.",
        "mailerror": "Mearachd a' cur post: $1",
        "createaccount-title": "Cruthachadh cunntais airson {{SITENAME}}",
        "createaccount-text": "Chruthaich cuideigin cunntas airson a' phost-d agad air {{SITENAME}} ($4) air a bheil \"$2\", leis an fhacal-fhaire \"$3\".\nBu chòir dhut logadh a-steach agus am facal-faire agad atharrachadh gu h-ìosal an-dràsta.\n\n'S urrainn dhut an teachdaireachd seo a leigeil seachad ma chaidh an cunntas a chruthachadh air mhearachd.",
        "login-throttled": "Dh'fheuch thu ri logadh a-steach ro thric o chionn ghoirid.\nFuirich ort $1 mus feuch thu ris a-rithist.",
-       "login-abort-generic": "Cha do shoirbhich leat leis an logadh a-steach - Chaidh sgur dheth",
+       "login-abort-generic": "Dh’fhàillig an logadh a-steach - Sguireadh dheth",
        "login-migrated-generic": "Chaidh an cunntas agad imrich 's chan eil an t-ainm cleachdaiche agad ann tuilleadh air an uicidh seo.",
        "loginlanguagelabel": "Cànan: $1",
        "suspicious-userlogout": "Chaidh d' iarrtas airson logadh a-mach a dhiùltadh a chionn 's gu bheil coltas gun deach a chur le brabhsair briste no le progsaidh tasglannaidh.",
        "resetpass-no-info": "Feumaidh tu logadh a-steach mus dèan thu inntrigeadh dìreach dhan duilleag seo.",
        "resetpass-submit-loggedin": "Atharraich am facal-faire",
        "resetpass-submit-cancel": "Sguir dheth",
-       "resetpass-wrong-oldpass": "Tha am facal-faire sealach no làithreach mì-dhligheach.\nSaoil an do dh'atharraich thu am facal-faire agad mu thràth no an do dh'iarr thu facal-faire sealach ùr?",
+       "resetpass-wrong-oldpass": "Tha am facal-faire sealach no làithreach mì-dhligheach.\nSaoil an do dh’atharraich thu am facal-faire agad mu thràth no an do dh’iarr thu facal-faire sealach ùr?",
        "resetpass-recycled": "Tagh facal-faire ùr nach eil co-ionnann ris an fhacal-fhaire a tha agad an-dràsta.",
        "resetpass-temp-emailed": "Rinn thu logadh a-steach le còd sealach a fhuair thu air a' phost-d.\nAirson logadh a-steach slàn a dhèanamh, feumaidh tu facal-faire ùr a shuidheachadh an-seo:",
        "resetpass-temp-password": "Facal-faire sealach:",
        "passwordreset-emailtext-ip": "Dh'iarr cuideigin (thu fhèin, 's mathaid, on t-seòladh IP $1) am facal-faire airson {{SITENAME}} ($4) ath-shuidheachadh. Tha {{PLURAL:$3|an cunntas|na cunntasan}} a leanas co-cheangailte ris a' phost-d seo:\n\n$2\n\nFalbhaidh an ùine air {{PLURAL:$3|an fhacal-fhaire shealach|na faclan-faire sealach}} seo an ceann $5 {{PLURAL:$5|latha|latha|làithean|latha}}.\nBu chòir dhut logadh a-steach agus facal-faire ùr a thaghadh an-dràsta. Ma dh'iarr cuideigin eile seo no ma chuimhnich thu air an fhacal-fhaire agad 's mur eil thu airson atharrachadh tuilleadh, leig seachad an teachdaireachd seo 's lean ort leis an t-seann fhacal-fhaire.",
        "passwordreset-emailtext-user": "Dh'iarr an cleachdaiche $1 air {{SITENAME}} ath-shuidheachadh an fhacail-fhaire air {{SITENAME}} ($4). Tha {{PLURAL:$3|an cunntas-cleachdaiche|na cunntasan-cleachdaiche}} a leanas co-cheangailte ris an t-seòladh puist-d seo:\n\n$2\n\nFalbhaidh an ùine air {{PLURAL:$3|an fhacal-fhaire shealach|na faclan-faire sealach}} seo an ceann $5 {{PLURAL:$5|latha|latha|làithean|latha}}.\nBu chòir dhut logadh a-steach agus facal-faire ùr a thaghadh an-dràsta. Ma dh'iarr cuideigin eile seo no ma chuimhnich thu air an fhacal-fhaire agad 's mur eil thu airson atharrachadh tuilleadh, leig seachad an teachdaireachd seo 's lean ort leis an t-seann fhacal-fhaire.",
        "passwordreset-emailelement": "Ainm-cleachdaiche: \n$1\n\nFacal-faire sealach: \n$2",
-       "passwordreset-emailsentemail": "Chaidh post-d airson ath-shuidheachadh an fhacail-fhaire a chur.",
+       "passwordreset-emailsentemail": "Ma tha am post-d seo co-cheangailte ris a’ chunntas agad, thèid post-d airson ath-shuidheachadh an fhacail-fhaire a chur.",
        "passwordreset-emailsent-capture": "Chaidh post-d a chum ath-shuidheachadh an fhacail-fhaire a chur agus chì thu sin gu h-ìosal.",
        "passwordreset-emailerror-capture": "Chaidh post-d a chum ath-shuidheachadh an fhacail-fhaire a ghintinn agus chì thu sin gu h-ìosal ach cha b' urrainn dhuinn a chur dhan chleachdaiche: $1",
-       "changeemail": "Atharraich am post-d",
-       "changeemail-header": "Atharraich cunntas a' phuist-d",
+       "changeemail": "Atharraich no thoir air falbh an seòladh puist-d",
+       "changeemail-header": "Lìon am foirm seo a dh’atharrachadh an t-seòlaidh phuist-d agad. Ma tha thu airson an co-cheangal eadar post-d sam bith is an cunntas agad a thoirt air falbh, fàg an seòladh ùr bàn nuair a chuireas tu am foirm.",
        "changeemail-no-info": "Feumaidh tu logadh a-steach mus dèan thu inntrigeadh dìreach dhan duilleag seo.",
        "changeemail-oldemail": "An seòladh puist-d làithreach:",
        "changeemail-newemail": "An seòladh puist-d ùr:",
        "sig_tip": "D' ainm sgrìobhte le stampa-ama",
        "hr_tip": "Loidhne rèidh (na cleachd ro thric e)",
        "summary": "Gearr-chunntas:",
-       "subject": "Cuspair/ceann-loidhne:",
+       "subject": "Cuspair:",
        "minoredit": "Seo mùthadh beag",
        "watchthis": "Cum sùil air an duilleag seo",
        "savearticle": "Sàbhail an duilleag",
        "missingsummary": "<strong>Cuimhnich:</strong> Cha dug thu seachad gearr-chunntas air na dh'atharraich thu.\nMa bhriogas tu air \"{{int:savearticle}}\" a-rithist, thèid na dheasaich thu a shàbhaladh as aonais gearr-chunntais.",
        "selfredirect": "<strong>Rabhadh:</strong> Tha thu ag ath-stiùireadh duilleag dha fhèin.\nDh'fhaoidte gun do shònraich thu an t-amas cearr airson an ath-stiùiridh no gu bheil thu a' deasachadh an duilleag cearr.\nMa nì thu briogadh air \"{{int:savearticle}}\" a-rithist,m thèid an ath-stiùireadh a chruthachadh co-dhiù.",
        "missingcommenttext": "Cuir a-steach beachd gu h-ìosal.",
-       "missingcommentheader": "<strong>Cuimhnich:</strong> Cha dug thu seachad cuspair/ceann airson a' bheachd seo.\nMa bhriogas tu air \"{{int:savearticle}}\" a-rithist, thèid na dheasaich thu a shàbhaladh as aonais.",
+       "missingcommentheader": "<strong>Cuimhnich:</strong> Cha dug thu seachad cuspair airson a’ bheachd seo.\nMa bhriogas tu air “{{int:savearticle}}” a-rithist, thèid na dheasaich thu a shàbhaladh as aonais.",
        "summary-preview": "Ro-shealladh a' ghearr-chunntais:",
-       "subject-preview": "Ro-shealladh air a' chuspair/air a' cheann:",
+       "subject-preview": "Ro-shealladh a’ chuspair:",
        "blockedtitle": "Tha an cleachdair air a bhacadh",
        "blockedtext": "<strong>Chaidh an t-ainm-cleachdaiche no an seòladh IP agad a bhacadh.</strong>\n\n'S e $1 a chur am bacadh seo ort.\n{{GENDER:$1|Thug e|Thug i|Thugadh}} an cèill gun do {{GENDER:$1|rinn e|rinn i|rinneadh}} sin air sgàth an adhbhair seo: <em>$2</em>.\n\n* Toiseach a' bhacaidh: $8\n* Deireadh a' bhacaidh: $6\n* An neach air a bheil am bacadh: $7\n\n'S urrainn dhut fios a chur gu $1 no [[{{MediaWiki:Grouppage-sysop}}|rianair]] eile gus am bacadh seo a dheasbad.\nChan urrainn dhut am feart \"Cuir post-d dhan chleachdaiche seo\" a chleachdadh ach ma tha seòladh puist-d dligheach ann an [[Special:Preferences|roghainnean a' chunntais agad]] agus mura deach bacadh a chur air a chleachdadh.\n'S e $3 an seòladh IP làithreach agus agus 's e #$5 ID a' bhacaidh.\nThoir iomradh air a' mhion-fhiosrachadh gu h-àrd ma chuireas tu ceist sam bith mu dhèidhinn.",
        "autoblockedtext": "Chaidh an seòladh IP agad a bhacadh gu fèin-obrachail a chionn 's gun deach a chleachdadh le cuideigin eile a chaidh a bhacadh le $1.\n{{GENDER:$1|Thug e|Thug i|Thugadh}} an cèill gun do {{GENDER:$1|rinn e|rinn i|rinneadh}} sin air sgàth an adhbhair seo: \n\n:<em>$2</em>.\n\n* Toiseach a' bhacaidh: $8\n* Deireadh a' bhacaidh: $6\n* An neach air a bheil am bacadh: $7\n\n'S urrainn dhut fios a chur gu $1 no [[{{MediaWiki:Grouppage-sysop}}|rianair]] eile gus am bacadh seo a dheasbad.\n\nDh'fhaoidte nach urrainn dhut am feart \"Cuir post-d dhan chleachdaiche seo\" a chleachdadh ach ma tha seòladh puist-d dligheach ann an [[Special:Preferences|roghainnean a' chunntais agad]] agus mura deach bacadh a chur air a chleachdadh.\n\n'S e $3 an seòladh IP làithreach agus agus 's e #$5 ID a' bhacaidh.\nThoir iomradh air a' mhion-fhiosrachadh gu h-àrd ma chuireas tu ceist sam bith mu dhèidhinn.",
        "newarticle": "(Ùr)",
        "newarticletext": "Lean thu ri ceangal gu duilleag nach eil ann fhathast.\nCuir teacs sa bhogsa gu h-ìosal gus an duilleag seo a chruthachadh (seall air [$1 duilleag na cobharach] airson barrachd fiosrachaidh).\nMura robh dùil agad ris an duilleag seo a ruigsinn, briog air a' phutan <strong>air ais</strong> 'nad bhrabhsair.",
        "anontalkpagetext": "----\n<em>Seo an duilleag deasbaireachd aig cleachdaiche gun urra nach do chruthaich cunntas fhathast no nach eil 'ga chleachdadh.</em>\nFeumaidh sinn an àireamh IP aca a chleachdadh air sgàth sin.\nFaodadh grunn chleachdaichean seòladh IP mar a chleachdadh còmhla.\nMas e cleachdaiche gun urra a tha annad 's ma tha thu dhen bheachd nach eil na beachdan seo a' buntainn riut, nach [[Special:UserLogin/signup|clàraich thu]] no nach dèan thu [[Special:UserLogin|logadh a-steach]] gus bùrach mar seo a sheachnadh san àm ri teachd?",
-       "noarticletext": "Chan eil teacsa sam bith anns an duilleag seo an-dràsta.\n'S urrainn dhut [[Special:Search/{{PAGENAME}}|an tiotal seo a lorg]] ann an duilleagan eile,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} na logaichean co-cheangailte a rannsachadh],\nno [{{fullurl:{{FULLPAGENAME}}|action=edit}} an duilleag seo a dheasachadh]</span>.",
+       "noarticletext": "Chan eil teacsa sam bith anns an duilleag seo an-dràsta.\n'S urrainn dhut [[Special:Search/{{PAGENAME}}|an tiotal seo a lorg]] ann an duilleagan eile,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} na logaichean co-cheangailte a rannsachadh],\nno [{{fullurl:{{FULLPAGENAME}}|action=edit}} an duilleag seo a chruthachadh]</span>.",
        "noarticletext-nopermission": "Chan eil teacsa sam bith san duilleag seo an-dràsta.\n'S urrainn dhut [[Special:Search/{{PAGENAME}}|tiotal na duilleige seo a lorg]] ann an duilleagan eile, no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} na logaichean co-cheangailte a rannsachadh]</span> ach chan eil cead agad an duilleag seo a chruthachadh.",
        "missing-revision": "Chan eil mùthadh #$1 na duilleige \"{{FULLPAGENAME}}\" ann.\n\nMar is trice, tachraidh seo ma leanas tu ceangal san eachdraidh a tha fìor aosta 's a tha a' dol gu duilleag a chaidh a sguabadh às.\nGheibh thu mion-fhiosrachadh ann an [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} loga nan duilleagan a chaidh a sguabadh às].",
        "userpage-userdoesnotexist": "Chan e cunntas clàraichte a tha ann an \"$1\".\nDèan cinnteach gu bheil thu airson an duilleag seo a chruthachadh/dheasachadh.",
        "userpage-userdoesnotexist-view": "Cha deach an cunntas cleachdaiche \"$1\" a chlàradh.",
        "blocked-notice-logextract": "Tha an cleachdaiche seo air a bhacadh an-dràsta fhèin.\nChì thu loga a' bhacaidh mu dheireadh gu h-ìosal mar fhiosrachadh dhut:",
-       "clearyourcache": "<strong>An aire:</strong> As dèidh dhut sàbhaladh, 's mathaid gum bi agad tasgadan a' bhrabhsair agad a chur air gleus mus fhaic thu na dh'atharraich thu.\n* <strong>Firefox / Safari:</strong> Cum shìos <em>Shift</em> is briog air <em>Ath-luchdaich</em> no brùth <em>Ctrl-F5</em> no <em>Ctrl-R</em> (<em>⌘-R</em> air Mac)\n* <strong>Google Chrome:</strong> Brùth <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> air Mac)\n* <strong>Internet Explorer:</strong> Cum shìos <em>Ctrl</em> is briog air <em>Ath-nuadhaich</em> no brùth <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Falamhaich an tasgadan ann an <em>Innealan → Roghainnean</em>",
+       "clearyourcache": "<strong>An aire:</strong> As dèidh dhut sàbhaladh, ’s mathaid gum bi agad tasgadan a’ bhrabhsair agad a chur air gleus mus fhaic thu na dh’atharraich thu.\n* <strong>Firefox / Safari:</strong> Cum shìos <em>Shift</em> is briog air <em>Ath-luchdaich</em> no brùth <em>Ctrl-F5</em> no <em>Ctrl-R</em> (<em>⌘-R</em> air Mac)\n* <strong>Google Chrome:</strong> Brùth <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> air Mac)\n* <strong>Internet Explorer:</strong> Cum shìos <em>Ctrl</em> is briog air <em>Ath-nuadhaich</em> no brùth <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Rach gu <em>Clàr-taice → Roghainnean</em> (<em>Opera → Roghainnean</em> air Mac) agus an uairsin gu <em>Prìobhaideachd ⁊ tèarainteachd → Falamhaich an dàta brabhsaidh → Dealbhan is faidhlichean san tasgadan</em>.",
        "usercssyoucanpreview": "<strong>Gliocas:</strong> Cleachd am putan \"{{int:showpreview}}\" airson an CSS agad a chur fo dheuchainn mus sàbhail thu e.",
        "userjsyoucanpreview": "<strong>Gliocas:</strong> Cleachd am putan \"{{int:showpreview}}\" gus an JavaScript ùr agad a chur fo dheuchainn mus sàbhail thu e.",
        "usercsspreview": "<strong>Cuimhnich nach e seo ach ro-shealladh air a' CSS chleachdaiche agad.\nCha deach a shàbhaladh fhathast!</strong>",
        "previewnote": "<strong>Cuimhnich nach eil ann ach ro-shealladh.</strong>\nCha deach na mùthaidhean agad a shàbhaladh fhathast!",
        "continue-editing": "Rach gun raon deasachaidh",
        "previewconflict": "Tha an ro-shealladh seo a' sealltainn dhut an teacsa san raon teacsa gu h-àrd mar a nochdas e ma shàbhaileas tu an-dràsta.",
-       "session_fail_preview": "<strong>Duilich! Cha b' urrainn dhuinn na dheasaich thu a làimhseachadh air sgàth call dàta an t-seisein.</strong>\nNach fheuch thu ris a-rithist?\nMur obraich e fhathast, feuch is [[Special:UserLogout|log a-mach]] is a-steach a-rithist an uairsin.",
-       "session_fail_preview_html": "<strong>Duilich! Cha b' urrainn dhuinn na dheasaich thu a làimhseachadh air sgàth call dàta an t-seisein.</strong>\n\n<em>A chionn 's gun do chuir {{SITENAME}} còd HTML an comas, tha an ro-shealladh falaichte mar dhìon an aghaidh ionnsaighean JavaScript.</em>\n\n<strong>Mas e deasachadh dligheach a tha seo, feuch ris a-rithist.</strong>\nMur obraich e fhathast, feuch is dèan [[Special:UserLogout|logadh a-mach]] is a-steach a-rithist an uairsin.",
+       "session_fail_preview": "Tha sinn duilich ach cha b’ urrainn dhuinn na dheasaich thu a làimhseachadh air sgàth call dàta an t-seisein.\n\nDh’fhaoidte gun deach do chlàradh a-mach. <strong>Dèan cinnteach gu bheil thu clàraichte a-staigh fhathast is feuch ris a-rithist</strong>.\nMur obraich e fhathast, feuch is [[Special:UserLogout|log a-mach]] is a-steach a-rithist an uairsin is dèan cinnteach gu bheil am brabhsair agad a’ gabhail ri briosgaidean on làrach seo.",
+       "session_fail_preview_html": "Tha sinn duilich ach cha b’ urrainn dhuinn na dheasaich thu a làimhseachadh air sgàth call dàta an t-seisein.\n\n<em>A chionn ’s gun do chuir {{SITENAME}} còd HTML an comas, tha an ro-shealladh falaichte mar dhìon an aghaidh ionnsaighean JavaScript.</em>\n\n<strong>Mas e deasachadh dligheach a tha seo, feuch ris a-rithist.</strong>\nMur obraich e fhathast, feuch is dèan [[Special:UserLogout|logadh a-mach]] is a-steach a-rithist an uairsin is dèan cinnteach gu bheil am brabhsair agad a’ gabhail ri briosgaidean on làrach seo.",
        "token_suffix_mismatch": "<strong>Dhiùlt sinn na dheasaich thu a chionn 's gun do chuir an cliant agad na caractaran puingeachaidh tro chèile san tòcan deasachaidh.</strong>\nDhiùlt sinn na dheasaich thu air eagal 's gun coirbeadh e teacsa na duilleige.\nTachraidh seo uaireannan ma chleachdar seirbheis-lìn progsaidh gun urra a tha làn de mhearachdan.",
        "edit_form_incomplete": "<strong>Cha do ràinig cuid dhen fhoirm deasachaidh am frithealaichte; dèan cinnteach gu bheil gach deasachadh agad slàn is feuch ris a-rithist.</strong>",
        "editing": "A' deasachadh $1",
        "copyrightwarning": "Thoir an aire gu bheilear a' tuigsinn gu bheil gach obair a chuireas tu ri {{SITENAME}} air a leigeil mu sgaoil fo $2 (see $1 airson mion-fhiosrachadh).\nMura bi thu toilichte 's daoine eile a' deasachadh gun tròcair na sgrìobh tu 's 'ga sgaoileadh mar a thogras iad, na cuir an-seo e.<br />\nTha thu a' toirt geall cuideachd gun do sgrìobh thu fhèin seo no gun do rinn thu lethbhreac dheth o àrainn phoblach no tùs saor coltach ris.\n<strong>Na cuir ann rudan fo chòir-lethbhreac gun chead!</strong>",
        "copyrightwarning2": "Thoir an aire gum faod deasaichean eile gach obair a chuireas tu ri {{SITENAME}} a dheasachadh, atharrachadh no a thoirt air falbh.\nMur eil thu ag iarraidh gun deasaich cuideigin eile na sgrìobh thu gun truas, na cuir a-null e.<br />\nNì thu gealladh dhuinn cuideachd gur e thu fhèin a sgrìobh e no gun do rinn thu lethbhreac dheth o Public Domain no stòras saor dhen leithid (faic $1 airson barrachd fiosrachaidh). <br />\n<strong>Na cuir a-null obair a tha fo chòir-lethbhreac gun chead!</strong>",
        "longpageerror": "<strong>Mearachd: Tha an teacsa a chur thu thugainn $1 {{PLURAL:$1|chileabaidht|chileabaidht|cileabaidhtichean|cileabaidht}} a dh'fhaid is tha sin nas fhaide na tha ceadaichte ($2 {{PLURAL:$2|chileabaidht|chileabaidht|cileabaidhtichean|cileabaidht}}).</strong>\nCha ghabh a shàbhaladh.",
-       "readonlywarning": "<strong>Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na dheasaich thu a shàbhaladh an-dràsta fhèin.</strong>\n'S mathaid gum b' fheairrde dhut lethbhreac a dhèanamh dhen teacsa agus a shàbhaladh ann am faidhle ach an urrainn dhut a chleachdadh as a dhèidh seo.\n\nSeo am mìneachadh a thug an rianaire a ghlais e: $1",
+       "readonlywarning": "<strong>Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na dheasaich thu a shàbhaladh an-dràsta fhèin.</strong>\n’S mathaid gum b’ fheairrde dhut lethbhreac a dhèanamh dhen teacsa agus a shàbhaladh ann am faidhle ach an urrainn dhut a chleachdadh as a dhèidh seo.\n\nSeo am mìneachadh a thug rianaire an t-siostaim a ghlais e: $1",
        "protectedpagewarning": "<strong>Rabhadh: Chaidh an duilleag seo a dhìon 's chan urrainn ach dhan fheadhainn aig a bheil ùghdarras rianaire a dheasachadh.</strong>\nChì thu an clàr mu dheireadh san loga mar fhiosrachadh dhut gu h-ìosal:",
        "semiprotectedpagewarning": "<strong>An aire:</strong> Chaidh an duilleag seo a dhìon 's chan fhaod ach cleachdaichean clàraichte a dheasachadh.\nSeo an rud mu dheireadh san loga mar fhiosrachadh dhut:",
-       "cascadeprotectedwarning": "<strong>Rabhadh:</strong> Chaidh an duilleag seo a dhìon 's chan fhaod ach rianairean a dheasachadh a chionn 's gun robh e am broinn {{PLURAL:$1|na duilleige|nan duilleagan}} a leanas a tha dìonta o bhith mar eas.",
+       "cascadeprotectedwarning": "<strong>Rabhadh:</strong> Chaidh an duilleag seo a dhìon ’s chan fhaod ach rianairean a dheasachadh a chionn ’s gun robh e fillte a-staigh {{PLURAL:$1|san duilleag|sna duilleagan}} a leanas a tha dìonta o bhith mar eas.",
        "titleprotectedwarning": "<strong>Rabhadh: Chaidh an duilleag seo a dhìon 's feumar [[Special:ListGroupRights|ceadan sònraichte]] gus a dheasachadh.</strong>\nSeo an rud mu dheireadh san loga mar fhiosrachadh dhut:",
        "templatesused": "Tha {{PLURAL:$1|teamplaid 'ga cleachdadh|teamplaidean 'gan cleachdadh}} air an duilleag seo:",
        "templatesusedpreview": "Tha {{PLURAL:$1|teamplaid 'ga cleachdadh|teamplaidean 'gan cleachdadh}} san ro-shealladh seo:",
        "rev-showdeleted": "seall",
        "revisiondelete": "Sguab às/neo-dhèan sguabadh às mùthaidhean",
        "revdelete-nooldid-title": "Tha am mùthadh seo mì-dhligheach",
-       "revdelete-nooldid-text": "Cha do shònraich thu mùthadh airson seo a dhèanamh, chan eil e ann no tha thu a' feuchainn ris am mùthadh làithreach a chur am falach.",
+       "revdelete-nooldid-text": "Cha do shònraich thu mùthadh airson seo a dhèanamh, chan eil e ann no tha thu a feuchainn ris am mùthadh làithreach a chur am falach.",
        "revdelete-no-file": "Chan eil am faidhle a shònraich thu ann.",
        "revdelete-show-file-confirm": "A bheil thu cinnteach gu bheil thu airson coimhead air mùthadh an fhaidhle \"<nowiki>$1</nowiki>\" a chaidh a sguabadh às $2 aig $3?",
        "revdelete-show-file-submit": "Tha",
        "revdelete-unsuppress": "Thoir air falbh na bacaidhean air mùthaidhean a chaidh aiseag",
        "revdelete-log": "Adhbhar:",
        "revdelete-submit": "Cuir an sàs e air {{PLURAL:$1|am mùthadh|na mùthaidhean}} a thagh thu",
-       "revdelete-success": "Chaidh so-fhaicsinneachd a' mhùthaidh ùrachadh.",
+       "revdelete-success": "Chaidh so-fhaicsinneachd a mhùthaidh ùrachadh.",
        "revdelete-failure": "Cha b' urrainn dhuinn so-fhaicsinneachd a' mhùthaidh ùrachadh:\n$1",
        "logdelete-success": "Chaidh faicsinneachd an loga a shuidheachadh.",
        "logdelete-failure": "Cha b' urrainn dhuinn faicsinneachd an loga a shuidheachadh:\n$1",
        "prefs-watchlist-token": "Tòcan a' chlàir-fhaire:",
        "prefs-misc": "Measgachadh",
        "prefs-resetpass": "Atharraich am facal-faire",
-       "prefs-changeemail": "Atharraich am post-d",
+       "prefs-changeemail": "Atharraich no thoirt air falbh post-d",
        "prefs-setemail": "Suidhich seòladh puist-d",
        "prefs-email": "Roghainnean a' phuist-d",
        "prefs-rendering": "Coltas",
        "rows": "Sreathan",
        "columns": "Colbhan",
        "searchresultshead": "Lorg",
-       "stub-threshold": "An stairsneach airson fòrmatadh <a href=\"#\" class=\"stub\">cheanglaichean nam bun</a> (bytes):",
+       "stub-threshold": "An stairsneach airson fòrmatadh cheanglaichean nam bun ($1):",
        "stub-threshold-disabled": "À comas",
        "recentchangesdays": "Co mheud latha a thèid a shealltainn sna mùthaidhean ùra:",
        "recentchangesdays-max": "$1 {{PLURAL:$1|latha|latha|làithean|latha}} air a' char as motha",
        "badsig": "Tha co-chàradh an t-soidhnidh mì-dhligheach.\nThoir sùil air na tagaichean HTML.",
        "badsiglength": "Tha an t-earr-sgrìobhadh agad ro fhada.\nChan fhaod e a bhith nas fhaide na $1 {{PLURAL:$1|charactar|charactar|caractaran|caractar}}.",
        "yourgender": "Do ghnè:",
-       "gender-unknown": "B' fhearr leam gun a bhith 'ga leigeil ris",
+       "gender-unknown": "Nì am bathar-bog a dhìcheall gun a bhith a’ cleachdadh faclan a nochdas gnè seach gnè",
        "gender-male": "Deasaichidh e duilleagan na h-uicidh",
        "gender-female": "Deasaichidh i duilleagan na h-Uicipeid",
        "prefs-help-gender": "Cha leig thu leas an roghainn seo a shuidheachadh.\nCleachdaidh am bathar-bog an luach aice gus bruidhinn riut le d' ainm 's iomradh a thoirt ort gu càch leis a' ghnè ghramataigeach iomchaidh.\nBidh am fiosrachadh seo poblach.",
        "userrights": "Stiùireadh ceadan a' chleachdaiche",
        "userrights-lookup-user": "Stiùirich na buidhnean chleachdaichean",
        "userrights-user-editname": "Cuir a-steach ainm-cleachdaiche:",
-       "editusergroup": "Deasaich na buidhnean chleachdaichean",
-       "editinguser": "Ag atharrachadh ceadan a' chleachdaiche <strong>[[User:$1|$1]]</strong> $2",
+       "editusergroup": "Deasaich na buidhnean {{GENDER:$1|chleachdaichean}}",
+       "editinguser": "Ag atharrachadh ceadan a’ {{GENDER:$1|chleachdaiche}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Deasaich na buidhnean chleachdaichean",
-       "saveusergroups": "Sàbhail na buidhnean chleachdaichean",
+       "saveusergroups": "Sàbhail na buidhnean {{GENDER:$1|chleachdaichean}}",
        "userrights-groupsmember": "Ball de:",
        "userrights-groupsmember-auto": "Ball fèin-obrachail de:",
        "userrights-groupsmember-type": "$1",
        "group-bot": "Bots",
        "group-sysop": "Rianadairean",
        "group-bureaucrat": "Biurocratan",
-       "group-suppress": "Marasgalan",
+       "group-suppress": "Mùchadairean",
        "group-all": "(na h-uile)",
        "group-user-member": "cleachdaiche",
        "group-autoconfirmed-member": "cleachdaiche fèin-dearbhte",
        "group-bot-member": "bot",
        "group-sysop-member": "rianaire",
        "group-bureaucrat-member": "biùrocrat",
-       "group-suppress-member": "marasgal",
+       "group-suppress-member": "{{GENDER:$1|mùchadair}}",
        "grouppage-user": "{{ns:project}}:Cleachdaichean",
        "grouppage-autoconfirmed": "{{ns:project}}:Cleachdaichean fèin-dearbhte",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Rianadairean",
        "grouppage-bureaucrat": "{{ns:project}}:Biurocratan",
-       "grouppage-suppress": "{{ns:project}}:Marasgal",
+       "grouppage-suppress": "{{ns:project}}:Mùch",
        "right-read": "Cead-leughaidh",
        "right-edit": "Cead-deasachaidh",
        "right-createpage": "Cead-cruthachaidh (de dhuilleagan nach eil 'nan duilleagan deasbaireachd)",
        "boteditletter": "bt",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[Tha $1 {{PLURAL:$1|chleachdaiche|chleachdaiche|cleachdaichean|cleachdaiche}} a' cumail sùil air]",
-       "rc_categories": "Cuingich gu roinnean-seòrsa (sgaraich le \"|\")",
-       "rc_categories_any": "Roinn-seòrsa sam bith",
+       "rc_categories": "Dìreach sna roinnean-seòrsa (sgaraich le “|”):",
+       "rc_categories_any": "Gin dhe na chaidh a thaghadh",
        "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{PLURAL:$1|bhaidht|bhaidht|baidhtichean|baidht}} às dèidh an atharrachaidh",
        "newsectionsummary": "Earrann ùr /* $1 */",
        "backend-fail-read": "Cha b' urrainn dhuinn am faidhle \"$1\" a leughadh.",
        "backend-fail-create": "Cha b' urrainn dhuinn sgrìobhadh san fhaidhle \"$1\".",
        "backend-fail-maxsize": "Cha b' urrainn dhuinn am faidhle \"$1\" a sgrìobhadh on a tha e nas motha na $2 {{PLURAL:$2|bhaidht|bhaidht|baidhtichean|baidht}}.",
-       "backend-fail-readonly": "Chan eil backend an stòraidh \"$1\" ach ri leughadh a-mhàin an-dràsta. Seo as adhbhar: \"<em>$2</em>\"",
+       "backend-fail-readonly": "Chan eil backend an stòraidh “$1” ach ri leughadh a-mhàin an-dràsta. Seo as adhbhar: <em>$2</em>",
        "backend-fail-synced": "Tha am faidhle \"$1\" ann an staid mì-chòrdail a thaobh nam backends stòraidh inntearnail.",
        "backend-fail-connect": "Cha deach leinn ceangal ri backend an stòraidh \"$1\".",
        "backend-fail-internal": "Chathair mearachd neo-aithnichte le backend an stòraidh \"$1\".",
        "uploadstash-summary": "Bheir an duilleag seo inntrigeadh dhut a dh'fhaidhlichean a chaidh a luchdadh suas no a tha 'gan luchdadh suas ach nach deach fhoillseachadh air an uicidh fhathast. Chan fhaic duine na faidhlichean seo ach an cleachdaiche a rinn an luchdadh suas.",
        "uploadstash-clear": "Glan na faidhlichean ann an tasgadan an luchdaidh suas",
        "uploadstash-nofiles": "Chan eil faidhle agad ann an tasgadan an luchdaidh suas.",
-       "uploadstash-badtoken": "Cha deach an gnìomh seo a choileanadh, 's dòcha air sgàth 's gun do dh'fhalbh an ùine air an teisteanas deasachaidh agad. Am feuch thu ris a-rithist?",
+       "uploadstash-badtoken": "Cha deach an gnìomh seo a choileanadh, ’s dòcha air sgàth ’s gun do dh’fhalbh an ùine air an teisteanas deasachaidh agad. Am feuch thu ris a-rithist?",
        "uploadstash-errclear": "Cha deach leinn na faidhlichean a ghlanadh air falbh.",
        "uploadstash-refresh": "Ath-nuadhaich liosta nam faidhlichean",
        "invalid-chunk-offset": "Frith-àireamh a' chnaip mhì-dhligheach",
        "nopagetext": "Chan eil an duilleag-uidhe a thug thu seachad ann.",
        "pager-newer-n": "{{PLURAL:$1|an $1 nas ùire|na $1 nas ùire}}",
        "pager-older-n": "{{PLURAL:$1|an $1 nas sine|na $1 nas sine}}",
-       "suppress": "Marasgal",
+       "suppress": "Mùch",
        "querypage-disabled": "Chaidh an duilleag shònraichte seo a chur à comas a chum dèanadais.",
        "booksources": "Tùsan a tha 'nan leabhraichean",
        "booksources-search-legend": "Lorg tùsan a tha 'nan leabhraichean",
        "booksources-text": "Chì thu liosta dhe cheanglaichean gu làraichean eile a reiceas leabhraichean ùra 's cleachdte gu h-ìosal 's ma dh'fhaoidte gum faigh thu barrachd fiosrachaidh orra mu leabhraichean a tha thu a' sireadh:",
        "booksources-invalid-isbn": "Tha coltas mì-dhligheach air an ISBN a chaidh a thoirt seachad; dearbhaich gun deach lethbhreac a dhèanamh dheth on tùs gun mhearachd.",
        "specialloguserlabel": "Cò rinn e:",
-       "speciallogtitlelabel": "Ceann-uidhe (tiotal no cleachdaiche):",
+       "speciallogtitlelabel": "Ceann-uidhe (tiotal no {{ns:user}}:ainm-cleachdaiche a’ chleachdaiche):",
        "log": "Logaichean",
        "all-logs-page": "A h-uile loga poblach",
        "alllogstext": "Sealladh co-mheasgaichte dhen a h-uile loga aig {{SITENAME}} a tha ri làimh.\n'S urrainn dhut an sealladh a chuingeachadh 's tu a' taghadh seòrsa an loga, ainm a' chleachdaiche (le aire do litrichean mòra 's beaga) no an duilleag a tha fo bhuaidh (le aire do litrichean mòra 's beaga).",
index 0a4357f..ba7e524 100644 (file)
        "minoredit": "Esta é unha edición pequena",
        "watchthis": "Vixiar esta páxina",
        "savearticle": "Gardar a páxina",
+       "publishpage": "Publicar páxina",
        "preview": "Vista previa",
        "showpreview": "Mostrar a vista previa",
        "showdiff": "Mostrar os cambios",
        "userpage-userdoesnotexist": "A conta de usuario \"$1\" non está rexistrada.\nComprobe se desexa crear/editar esta páxina.",
        "userpage-userdoesnotexist-view": "A conta de usuario \"$1\" non está rexistrada.",
        "blocked-notice-logextract": "Este usuario está bloqueado.\nVelaquí está a última entrada do rexistro de bloqueos, por se quere consultala:",
-       "clearyourcache": "'''Nota:''' Despois de gardar, cómpre limpar a memoria caché do seu navegador para ver os cambios.\n* '''Firefox/Safari:''' Prema ''Maiúsculas'' á vez que en ''Recargar'', ou prema en ''Ctrl-F5'' ou ''Ctrl-R'' (''⌘-R'' nos Mac)\n* '''Google Chrome:''' Prema en ''Ctrl-Maiús-R'' (''⌘-Maiús-R'' nos Mac)\n* '''Internet Explorer:''' Prema ''Ctrl'' ao tempo que fai clic en ''Refrescar'', ou prema en ''Ctrl-F5''\n* '''Opera:''' Limpe a súa memoria caché en ''Ferramentas → Preferencias''",
+       "clearyourcache": "<strong>Nota:</strong> Despois de gardar, cómpre limpar a memoria caché do seu navegador para ver os cambios.\n* <strong>Firefox/Safari:</strong> Prema <em>Maiúsculas</em> á vez que en <em>Recargar</em>, ou prema en <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> nos Mac)\n* <strong>Google Chrome:</strong> Prema en <em>Ctrl-Maiús-R</em> (<em>⌘-Maiús-R</em> nos Mac)\n* <strong>Internet Explorer:</strong> Prema <em>Ctrl</em> ao tempo que fai clic en <em>Refrescar</em>, ou prema en <em>Ctrl-F5</em>\n* <strong>Opera:<strong> Vaia a  <em>Menú → Configuración</em> (<em>Opera → Preferencias</em> nun Mac) e logo a <em>Privacidade & seguridade → Limpar datos de navegación → Ficheiros e imaxes na caché</em>.",
        "usercssyoucanpreview": "'''Nota:''' Use o botón \"{{int:showpreview}}\" para verificar o novo CSS antes de gardalo.",
        "userjsyoucanpreview": "<strong>Nota:</strong> Use o botón \"{{int:showpreview}}\" para verificar o novo JavaScript antes de gardalo.",
        "usercsspreview": "'''Lembre que só está vendo a vista previa do seu CSS de usuario.'''\n'''Este aínda non foi gardado!'''",
        "upload-form-label-infoform-description-tooltip": "Describa brevemente todo o destacable acerca do traballo.\nPara unha foto, mencione as cousas principais que se representan, a ocasión ou o lugar.",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nome do ficheiro",
-       "foreign-structured-upload-form-label-own-work": "Isto é o meu propio traballo",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorías",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que estou a cargar este ficheiro seguindo os termos de uso e políticas de licenza de {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Se non é capaz de cargar este ficheiro baixo as políticas de {{SITENAME}}, por favor peche este diálogo e intente outro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Quizais tamén queira probar [[Special:Upload|a páxina predeterminada de subidas]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Comprendo que estou a cargar este ficheiro nun repositorio compartido. Confirmo que fago isto seguindo os termos de uso e políticas de licenza existentes alí.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Se non é capaz de cargar este ficheiro baixo as políticas do repositorio compartido, por favor peche este diálogo e intente outro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Tamén pode interesarlle usar [[Special:Upload|a páxina de carga en {{SITENAME}}]], se este ficheiro pode ser cargado alí baixo as súas políticas.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Certifico que son o propietario dos dereitos de autor deste ficheiro, e que concordo a liberar irrevocablemente este ficheiro a Wikimedia Commons baixo a licenza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], e que concordo cos [https://wikimediafoundation.org/wiki/Terms_of_Use Termos de uso].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Se non posúe os dereitos de autor deste ficheiro, ou quere liberalo baixo unha licenza diferente, considere usar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de subas de Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Tamén pode interesarlle usar [[Special:Upload|a páxina de carga en {{SITENAME}}]], se o sitio permite a suba deste ficheiro nas súas políticas.",
+       "upload-form-label-own-work": "Isto é o meu propio traballo",
+       "upload-form-label-infoform-categories": "Categorías",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Confirmo que estou a cargar este ficheiro seguindo os termos de uso e políticas de licenza de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Se non é capaz de cargar este ficheiro baixo as políticas de {{SITENAME}}, por favor peche este diálogo e intente outro método.",
+       "upload-form-label-not-own-work-local-local": "Quizais tamén queira probar [[Special:Upload|a páxina predeterminada de subidas]].",
+       "upload-form-label-own-work-message-default": "Comprendo que estou a cargar este ficheiro nun repositorio compartido. Confirmo que fago isto seguindo os termos de uso e políticas de licenza existentes alí.",
+       "upload-form-label-not-own-work-message-default": "Se non é capaz de cargar este ficheiro baixo as políticas do repositorio compartido, por favor peche este diálogo e intente outro método.",
+       "upload-form-label-not-own-work-local-default": "Tamén pode interesarlle usar [[Special:Upload|a páxina de carga en {{SITENAME}}]], se este ficheiro pode ser cargado alí baixo as súas políticas.",
+       "upload-form-label-own-work-message-shared": "Certifico que son o propietario dos dereitos de autor deste ficheiro, e que concordo a liberar irrevocablemente este ficheiro a Wikimedia Commons baixo a licenza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], e que concordo cos [https://wikimediafoundation.org/wiki/Terms_of_Use Termos de uso].",
+       "upload-form-label-not-own-work-message-shared": "Se non posúe os dereitos de autor deste ficheiro, ou quere liberalo baixo unha licenza diferente, considere usar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Asistente de subas de Commons].",
+       "upload-form-label-not-own-work-local-shared": "Tamén pode interesarlle usar [[Special:Upload|a páxina de carga en {{SITENAME}}]], se o sitio permite a suba deste ficheiro nas súas políticas.",
        "backend-fail-stream": "Non se puido transmitir o ficheiro \"$1\".",
        "backend-fail-backup": "Non se puido facer unha copia de seguridade do ficheiro \"$1\".",
        "backend-fail-notexists": "O ficheiro \"$1\" non existe.",
        "changecontentmodel-success-text": "O tipo de contido de [[:$1]] foi modificado.",
        "changecontentmodel-cannot-convert": "O contido en [[:$1]] non pode converterse ó tipo de $2.",
        "changecontentmodel-nodirectediting": "O modelo de contido $1 non permite a modificación directa",
+       "changecontentmodel-emptymodels-title": "Non hai modelos de contido dispoñibles",
+       "changecontentmodel-emptymodels-text": "O contido de [[:$1]] non pode converterse a ningún tipo.",
        "log-name-contentmodel": "Rexistro de cambios de modelo de contido",
        "log-description-contentmodel": "Eventos relacinados cos modelos de contido dunha páxina",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|creou}} a páxina $3 usando un modelo de contido non predeterminado \"$5\"",
        "whatlinkshere-prev": "{{PLURAL:$1|anterior|$1 anteriores}}",
        "whatlinkshere-next": "{{PLURAL:$1|seguinte|$1 seguintes}}",
        "whatlinkshere-links": "← ligazóns",
-       "whatlinkshere-hideredirs": "$1 as redireccións",
-       "whatlinkshere-hidetrans": "$1 as inclusións",
-       "whatlinkshere-hidelinks": "$1 as ligazóns",
-       "whatlinkshere-hideimages": "$1 as ligazóns ao ficheiro",
+       "whatlinkshere-hideredirs": "Ocultar as redireccións",
+       "whatlinkshere-hidetrans": "Ocultar as inclusións",
+       "whatlinkshere-hidelinks": "Ocultar as ligazóns",
+       "whatlinkshere-hideimages": "Ocultar as ligazóns ao ficheiro",
        "whatlinkshere-filters": "Filtros",
        "whatlinkshere-submit": "Ir",
        "autoblockid": "Bloqueo automático nº$1",
        "lockdbsuccesstext": "Pechouse a base de datos.<br />\nLembre [[Special:UnlockDB|eliminar o bloqueo]] unha vez completado o seu mantemento.",
        "unlockdbsuccesstext": "A base de datos foi desbloqueada.",
        "lockfilenotwritable": "Non se pode escribir no ficheiro de bloqueo da base de datos. Para bloquear ou desbloquear a base de datos, o servidor web ten que poder escribir neste ficheiro.",
+       "databaselocked": "A base de datos xa está bloqueada.",
        "databasenotlocked": "A base de datos non está bloqueada.",
        "lockedbyandtime": "(por $1 o $2 ás $3)",
        "move-page": "Mover \"$1\"",
        "tooltip-ca-nstab-category": "Ver a páxina da categoría",
        "tooltip-minoredit": "Marcar isto coma unha edición pequena",
        "tooltip-save": "Gravar os seus cambios",
+       "tooltip-publish": "Publicar os seus cambios",
        "tooltip-preview": "Vista previa dos seus cambios; por favor, úsea antes de gravalos!",
        "tooltip-diff": "Mostrar os cambios que fixo no texto",
        "tooltip-compareselectedversions": "Ver as diferenzas entre dúas versións seleccionadas desta páxina",
        "feedback-useragent": "Axente de usuario:",
        "searchsuggest-search": "Procurar",
        "searchsuggest-containing": "que conteña...",
+       "api-error-autoblocked": "A súa dirección IP foi bloqueada automaticamente porque foi usada por un usuario bloqueado.",
        "api-error-badaccess-groups": "Non ten os permisos necesarios para cargar ficheiros neste wiki.",
        "api-error-badtoken": "Erro interno: Pase incorrecto.",
+       "api-error-blocked": "Foi bloqueado fronte á edición.",
        "api-error-copyuploaddisabled": "As cargas mediante URL están desactivadas neste servidor.",
        "api-error-duplicate": "Xa hai {{PLURAL:$1|outro ficheiro| outros ficheiros}} no wiki co mesmo contido.",
        "api-error-duplicate-archive": "Había {{PLURAL:$1|outro ficheiro|outros ficheiros}} no sitio co mesmo contido, pero {{PLURAL:$1|foi borrado|foron borrados}}.",
        "api-error-nomodule": "Erro interno: Non hai ningún módulo de cargas.",
        "api-error-ok-but-empty": "Erro interno: Non hai resposta do servidor.",
        "api-error-overwrite": "Non está permitido sobrescribir un ficheiro existente.",
+       "api-error-ratelimited": "Está intentando subir máis ficheiros nun pequeno espazo de tempo do que permite este wiki.\nPor favor, inténteo de novo nuns minutos.",
        "api-error-stashfailed": "Erro interno: O servidor non puido almacenar o ficheiro temporal.",
        "api-error-publishfailed": "Erro interno: O servidor non puido publicar o ficheiro temporal.",
        "api-error-stasherror": "Houbo un erro ao subir o ficheiro ao depósito.",
index 9441df7..a56f74a 100644 (file)
@@ -96,8 +96,8 @@
        "category-empty": "''Hea vorgan sodhea ekui pan vo madheom na''",
        "hidden-categories": "{{PLURAL:$1|Lipoilolo vorg|Lipoilole vorg}}",
        "hidden-category-category": "Lipoiloleo vorg",
-       "category-subcat-count": "{{PLURAL:$2|Hea vorgan fokot hi ek upvorg asa.|Hea vorgan {{PLURAL:$1|hi upvorg asa|heo $1 upvorg asat}}, beriz $2 upvorga modem.}}",
-       "category-article-count": "{{PLURAL:$2|Hea vorgan fokot hi ek pan asa.|Hea vorgan {{PLURAL:$1|hi pan asa|him $1 panam asat}} beriz $2 panam modem.}}",
+       "category-subcat-count": "{{PLURAL:$2|Hea vorgan fokot ho ek upvorg asa.|Hea vorgan {{PLURAL:$1|ho upvorg asa|heo $1 upvorg asat}}, beriz $2 upvorga modem.}}",
+       "category-article-count": "{{PLURAL:$2|Hea vorgan fokot hem ek pan asa.|Hea vorgan {{PLURAL:$1|hem pan asa|him $1 panam asat}} beriz $2 panam modem.}}",
        "category-file-count": "{{PLURAL:$2|Hea vorgan fokot hi ek fail asa.|Hea vorgan {{PLURAL:$1|hi fail asa|heo $1 faili asat}}, beriz $2 faili modem.}}",
        "listingcontinuesabbrev": "chalu",
        "index-category": "Suchi-potran zodlelim panam",
        "newpassword": "Novem gupitutor:",
        "retypenew": "Novem gupitutor portun boroi:",
        "resetpass_submit": "Gupitutor tharai ani sotrorombh kor",
-       "changepassword-success": "Tujem gupitutor bodlop yoshosvi tharlam.",
+       "changepassword-success": "Tujem gupitutor bodol'lam!",
        "resetpass_forbidden": "Gupitutram bodlunk zaina",
        "resetpass-submit-loggedin": "Gupitutoor bodol",
        "resetpass-submit-cancel": "Roddh kor",
index 75906f0..149b65e 100644 (file)
        "upload-form-label-infoform-description": "Beschrybig",
        "upload-form-label-usage-title": "Verwändig",
        "upload-form-label-usage-filename": "Dateiname",
-       "foreign-structured-upload-form-label-own-work": "Das han i sälber gmacht.",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorië",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "I bestätige, das i die Datei under de Nutzigsbedingigen und Lizänzrichtlinje vo {{SITENAME}} ufelade.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "We du die Datei nid under de Nutzigsbedingigen und Lizänzrichtlinje vo {{SITENAME}} chasch ufelade, de schliess bitte dä Dialog u probier’s uf’nen anderi Art.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Du chasch es ou mit der [[Special:Upload|Standardsyte zum Ufelade]] probiere.",
-       "foreign-structured-upload-form-label-own-work-message-default": "I bi mer bewusst, das i die Datei in es gmeinsams Repository ufelade. I bestätige, das mi derby a d Nutzigs- und Lizänzbedingige dört halte.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Bitte schliess dä Dialog und versuech’s mit eren andere Methode, falls du die Datei nid under de Bedingige vom gmeinsame Repository chasch ufelade.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Du chasch es ou mit der [[Special:Upload|Syte zum Ufeladen uf {{SITENAME}}]] probiere, falls du die Datei dört under denen irne Bedingige chasch ufelade.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "I bestätige, das ds Copyright vo dere Datei mir ghört. I stimmen unwiderruefflech zue, das die Datei uf Wikimedia Commons under der Lizänz [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] veröffentlecht wird. I bi mit de [https://wikimediafoundation.org/wiki/Terms_of_Use/de Nutzigsbedingigen] yverstande.",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Falls ds Copyright vo dere Datei nid dir ghört oder falls du sen under eren andere Lizänz wosch veröffentleche, de chönntsch der [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] bruuche.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Du chasch es ou mit der [[Special:Upload|Syte zum Ufeladen uf {{SITENAME}}]] probiere, falls dä Website ds Ufelade vo der Datei under syne Bedingige zuelat.",
+       "upload-form-label-own-work": "Das han i sälber gmacht.",
+       "upload-form-label-infoform-categories": "Kategorië",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "I bestätige, das i die Datei under de Nutzigsbedingigen und Lizänzrichtlinje vo {{SITENAME}} ufelade.",
+       "upload-form-label-not-own-work-message-local": "We du die Datei nid under de Nutzigsbedingigen und Lizänzrichtlinje vo {{SITENAME}} chasch ufelade, de schliess bitte dä Dialog u probier’s uf’nen anderi Art.",
+       "upload-form-label-not-own-work-local-local": "Du chasch es ou mit der [[Special:Upload|Standardsyte zum Ufelade]] probiere.",
+       "upload-form-label-own-work-message-default": "I bi mer bewusst, das i die Datei in es gmeinsams Repository ufelade. I bestätige, das mi derby a d Nutzigs- und Lizänzbedingige dört halte.",
+       "upload-form-label-not-own-work-message-default": "Bitte schliess dä Dialog und versuech’s mit eren andere Methode, falls du die Datei nid under de Bedingige vom gmeinsame Repository chasch ufelade.",
+       "upload-form-label-not-own-work-local-default": "Du chasch es ou mit der [[Special:Upload|Syte zum Ufeladen uf {{SITENAME}}]] probiere, falls du die Datei dört under denen irne Bedingige chasch ufelade.",
+       "upload-form-label-own-work-message-shared": "I bestätige, das ds Copyright vo dere Datei mir ghört. I stimmen unwiderruefflech zue, das die Datei uf Wikimedia Commons under der Lizänz [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] veröffentlecht wird. I bi mit de [https://wikimediafoundation.org/wiki/Terms_of_Use/de Nutzigsbedingigen] yverstande.",
+       "upload-form-label-not-own-work-message-shared": "Falls ds Copyright vo dere Datei nid dir ghört oder falls du sen under eren andere Lizänz wosch veröffentleche, de chönntsch der [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] bruuche.",
+       "upload-form-label-not-own-work-local-shared": "Du chasch es ou mit der [[Special:Upload|Syte zum Ufeladen uf {{SITENAME}}]] probiere, falls dä Website ds Ufelade vo der Datei under syne Bedingige zuelat.",
        "backend-fail-stream": "D Datei $1 het nit chenne ibertrait wäre.",
        "backend-fail-backup": "D Datei $1 het nit chenne gsicheret wäre.",
        "backend-fail-notexists": "D Datei $1 git s nit.",
index aef6122..0d61e70 100644 (file)
@@ -39,7 +39,7 @@
        },
        "tog-underline": "סימון קישורים בקו תחתי:",
        "tog-hideminor": "הסתרת עריכות משניות בדף השינויים האחרונים",
-       "tog-hidepatrolled": "×\94סתרת ×©×\99× ×\95×\99×\99×\9d ×\91×\93×\95ק×\99×\9d בדף השינויים האחרונים",
+       "tog-hidepatrolled": "×\94סתרת ×¢×¨×\99×\9b×\95ת ×\91×\93×\95ק×\95ת בדף השינויים האחרונים",
        "tog-newpageshidepatrolled": "הסתרת דפים בדוקים ברשימת הדפים החדשים",
        "tog-hidecategorization": "הסתרת שינויים בקטגוריות של דפים",
        "tog-extendwatchlist": "הרחבת רשימת המעקב כך שתציג את כל השינויים, לא רק את השינויים האחרונים בכל דף",
@@ -77,7 +77,7 @@
        "tog-ccmeonemails": "לשלוח אליי העתקים של הודעות דוא\"ל ששלחתי למשתמשים אחרים",
        "tog-diffonly": "ביטול הצגת תוכן הדף מתחת להשוואת הגרסאות",
        "tog-showhiddencats": "הצגת קטגוריות מוסתרות",
-       "tog-norollbackdiff": "×\94ש×\9e×\98ת ההבדלים בין הגרסאות לאחר ביצוע שחזור",
+       "tog-norollbackdiff": "×\9c×\90 ×\9c×\94צ×\99×\92 ×\90ת ההבדלים בין הגרסאות לאחר ביצוע שחזור",
        "tog-useeditwarning": "הצגת אזהרה בעת עזיבת דף עריכה עם שינויים שטרם נשמרו",
        "tog-prefershttps": "תמיד להשתמש בתקשורת מאובטחת לאחר הכניסה לחשבון",
        "underline-always": "תמיד",
        "category_header": "דפים בקטגוריה \"$1\"",
        "subcategories": "קטגוריות משנה",
        "category-media-header": "קובצי מדיה בקטגוריה \"$1\"",
-       "category-empty": "'''קטגוריה זו אינה כוללת דפים או קובצי מדיה.'''",
+       "category-empty": "<em>קטגוריה זו אינה כוללת דפים או קובצי מדיה.</em>",
        "hidden-categories": "{{PLURAL:$1|קטגוריה מוסתרת|קטגוריות מוסתרות}}",
        "hidden-category-category": "קטגוריות מוסתרות",
        "category-subcat-count": "{{PLURAL:$2|קטגוריה זו כוללת את קטגוריית המשנה הבאה בלבד.|קטגוריה זו כוללת את {{PLURAL:$1|קטגוריית המשנה המוצגת להלן|$1 קטגוריות המשנה המוצגות להלן}}, וכוללת בסך־הכול $2 קטגוריות משנה.}}",
        "redirectedfrom": "(הופנה מהדף $1)",
        "redirectpagesub": "דף הפניה",
        "redirectto": "הפניה ל:",
-       "lastmodifiedat": "ש×\95× ×\94 ×\9c×\90×\97ר×\95× ×\94 ×\91Ö¾$2, $1.",
+       "lastmodifiedat": "×\93×£ ×\96×\94 ×©×\95Ö¼× ×\94 ×\9c×\90×\97ר×\95× ×\94 ×\91Ö¾$1, ×\91שע×\94 $2.",
        "viewcount": "דף זה נצפה {{PLURAL:$1|פעם אחת|פעמיים|$1 פעמים}}.",
        "protectedpage": "דף מוגן",
        "jumpto": "קפיצה אל:",
        "perfcachedts": "המידע הבא הוא עותק שמור בזיכרון המטמון של המידע, שעודכן לאחרונה ב־$1. לכל היותר {{PLURAL:$4|תוצאה אחת נשמרת|$4 תוצאות נשמרות}} בזיכרון המטמון.",
        "querypage-no-updates": "העדכונים לדף זה כרגע מופסקים, והמידע לא יעודכן באופן שוטף.",
        "viewsource": "הצגת מקור",
-       "viewsource-title": "הצגת המקור של $1",
+       "viewsource-title": "הצגת המקור של הדף \"$1\"",
        "actionthrottled": "הפעולה הוגבלה",
        "actionthrottledtext": "כאמצעי נגד שימוש לרעה, קיימת מגבלה על ביצוע פעולה זו פעמים רבות מדי בזמן קצר, וחרגת מהמגבלה הזאת.\nנא לנסות שוב בעוד מספר דקות.",
        "protectedpagetext": "דף זה מוגן כדי למנוע עריכה ופעולות אחרות.",
        "subject": "נושא:",
        "minoredit": "זוהי עריכה משנית",
        "watchthis": "מעקב אחרי דף זה",
-       "savearticle": "שמירה",
+       "savearticle": "שמירת הדף",
+       "publishpage": "פרסום הדף",
        "preview": "תצוגה מקדימה",
        "showpreview": "תצוגה מקדימה",
        "showdiff": "הצגת שינויים",
        "userpage-userdoesnotexist": "חשבון המשתמש \"$1\" אינו רשום.\nאנא בִּדקו אם ברצונכם ליצור/לערוך את הדף הזה.",
        "userpage-userdoesnotexist-view": "חשבון המשתמש \"$1\" אינו רשום.",
        "blocked-notice-logextract": "{{GENDER:$1|המשתמש הזה חסום|המשתמשת הזו חסומה}} כרגע.\nהפעולה האחרונה ביומן החסימות מוצגת להלן:",
-       "clearyourcache": "<strong>×\94ער×\94:</strong> ×\9c×\90×\97ר ×\94ש×\9e×\99ר×\94, ×\99×\99ת×\9b×\9f ×©×ª×¦×\98ר×\9b×\95 ×\9cנק×\95ת ×\90ת ×\96×\99×\9bר×\95×\9f ×\94×\9e×\98×\9e×\95×\9f (cache) ×©×\9c ×\94×\93פ×\93פ×\9f ×\9b×\93×\99 ×\9c×\94×\91×\97×\99×\9f ×\91ש×\99× ×\95×\99×\99×\9d.\n* <strong>פ×\99×\99רפ×\95קס / ×¡×¤×\90ר×\99:</strong> ×\9c×\97צ×\95 ×\95×\94×\97×\96×\99ק×\95 ×\90ת ×\94×\9eקש <em>Shift</em> ×\91עת ×\9c×\97×\99צת×\9b×\9d ×¢×\9c <strong>×\98×¢×\99× ×\94 ×\9e×\97×\93ש</strong> (Reload), ×\90×\95 ×\9c×\97צ×\95 ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-F5</em> ×\90×\95 <em>Ctrl-R</em>&rlm; (<em><span dir=\"ltr\">â\8c\98-R</span></em> ×\91×\9e×\97ש×\91 ×\9eק)\n* <strong>×\92×\95×\92×\9c ×\9bר×\95×\9d:</strong> ×\9c×\97צ×\95 ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-Shift-R</em>&rlm; (<em><span dir=\"ltr\">â\8c\98-Shift-R</span></em> ×\91×\9e×\97ש×\91 ×\9eק)\n* <strong>×\90×\99× ×\98רנ×\98 ×\90קספ×\9c×\95רר:</strong> ×\9c×\97צ×\95 ×\95×\94×\97×\96×\99ק×\95 ×\90ת ×\94×\9eקש <em>Ctrl</em> ×\91עת ×\9c×\97×\99צת×\9b×\9d ×¢×\9c <strong>רענ×\9f</strong> (Refresh), ×\90×\95 ×\9c×\97צ×\95 ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-F5</em>\n* <strong>×\90×\95פר×\94:</strong> × ×§×\95 ×\90ת ×\94×\9e×\98×\9e×\95×\9f ×\91Ö¾<em>Toolsâ\80\8f â\86\90 Preferences</em>",
+       "clearyourcache": "<strong>×\94ער×\94:</strong> ×\9c×\90×\97ר ×\94ש×\9e×\99ר×\94, ×\99×\99ת×\9b×\9f ×©×\99×\94×\99×\94 ×¦×\95ר×\9a ×\9cנק×\95ת ×\90ת ×\96×\99×\9bר×\95×\9f ×\94×\9e×\98×\9e×\95×\9f (cache) ×©×\9c ×\94×\93פ×\93פ×\9f ×\9b×\93×\99 ×\9c×\94×\91×\97×\99×\9f ×\91ש×\99× ×\95×\99×\99×\9d.\n* <strong>פ×\99×\99רפ×\95קס / ×¡×¤×\90ר×\99:</strong> ×\9c×\94×\97×\96×\99ק ×\90ת ×\94×\9eקש <em>Shift</em> ×\91עת ×\9c×\97×\99צ×\94 ×¢×\9c <strong>×\98×¢×\99× ×\94 ×\9e×\97×\93ש</strong> (Reload), ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-F5</em> ×\90×\95 <em>Ctrl-R</em> (×\91×\9e×\97ש×\91 ×\9eק: <em dir=\"ltr\">â\8c\98-R</em>)\n* <strong>×\92×\95×\92×\9c ×\9bר×\95×\9d:</strong> ×\9c×\9c×\97×\95×¥ ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-Shift-R</em> (×\91×\9e×\97ש×\91 ×\9eק: <em dir=\"ltr\">â\8c\98-Shift-R</em>)\n* <strong>×\90×\99× ×\98רנ×\98 ×\90קספ×\9c×\95רר:</strong> ×\9c×\9c×\97×\95×¥ ×\95×\9c×\94×\97×\96×\99ק ×\90ת ×\94×\9eקש <em>Ctrl</em> ×\91עת ×\9c×\97×\99צ×\94 ×¢×\9c <strong>רענ×\9f</strong> (Refresh), ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c ×¦×\99ר×\95×£ ×\94×\9eקש×\99×\9d <em>Ctrl-F5</em>\n* <strong>×\90×\95פר×\94:</strong> ×\9cפת×\95×\97 <em>תפר×\99×\98 â\86\90 ×\94×\92×\93ר×\95ת</em> (×\91×\9e×\97ש×\91 ×\9eק <em>Opera â\86\90 ×\94×¢×\93פ×\95ת</em>) ×\95×\90×\96 ×\9c×\9c×\97×\95×¥ ×¢×\9c <em>פר×\98×\99×\95ת ×\95×\90×\91×\98×\97×\94 â\86\90 ×\9e×\97ק ×\94×\99ס×\98×\95ר×\99×\99ת ×\92×\9c×\99ש×\94 â\86\90 Cached images and files</em>.",
        "usercssyoucanpreview": "<strong>עצה:</strong> השתמשו בכפתור \"{{int:showpreview}}\" כדי לבחון את גיליון ה־CSS החדש שלכם לפני השמירה.",
        "userjsyoucanpreview": "<strong>עצה:</strong> השתמשו בכפתור \"{{int:showpreview}}\" כדי לבחון את סקריפט ה־JavaScript החדש שלכם לפני השמירה.",
        "usercsspreview": "<strong>זִכרו שזו רק תצוגה מקדימה של גיליון ה־CSS שלכם.\nהוא עדיין לא נשמר!</strong>",
        "userinvalidcssjstitle": "'''אזהרה:''' העיצוב \"$1\" אינו קיים.\nדפי .css ו־.js מותאמים אישית משתמשים בכותרת עם אותיות קטנות – למשל, {{ns:user}}:דוגמה/vector.css ולא {{ns:user}}:דוגמה/Vector.css.",
        "updated": "(מעודכן)",
        "note": "'''הערה:'''",
-       "previewnote": "<strong>×\96Ö´×\9bר×\95 ×©×\96×\95 ×¨×§ ×ª×¦×\95×\92×\94 ×\9eק×\93×\99×\9e×\94.</strong>\n×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\9b×\9d ×\98ר×\9d נשמרו!",
+       "previewnote": "<strong>×\96Ö´×\9bר×\95 ×©×\96×\95 ×¨×§ ×ª×¦×\95×\92×\94 ×\9eק×\93×\99×\9e×\94.</strong>\n×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\9b×\9d ×¢×\93×\99×\99×\9f ×\9c×\90 נשמרו!",
        "continue-editing": "מעבר לאזור העריכה",
        "previewconflict": "תצוגה מקדימה זו מציגה כיצד ייראה הטקסט בחלון העריכה העליון, אם תבחרו לשמור אותו.",
        "session_fail_preview": "מצטערים! לא ניתן לבצע את עריכתכם עקב אובדן מידע הכניסה.\n\nייתכן שנותקתם מהחשבון. <strong>אנא ודאו שאתם עדיין מחוברים לחשבון ונסו שוב.</strong>\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "edit-no-change": "המערכת התעלמה מעריכתך כיוון שלא נעשה שינוי בטקסט.",
        "postedit-confirmation-created": "הדף נוצר.",
        "postedit-confirmation-restored": "הדף שוחזר.",
-       "postedit-confirmation-saved": "ער×\99×\9bתך נשמרה.",
+       "postedit-confirmation-saved": "×\94ער×\99×\9b×\94 ×©×\9cך נשמרה.",
        "edit-already-exists": "לא ניתן ליצור דף חדש.\nהוא כבר קיים.",
        "defaultmessagetext": "טקסט ההודעה המקורי",
        "content-failed-to-parse": "פענוח $2 כתוכן מסוג $1 נכשל: $3",
        "editwarning-warning": "עזיבת דף זה עשויה לגרום לאובדן כל השינויים שביצעתם.\nאם אתם מחוברים לחשבון, תוכלו לבטל אזהרה זו בחלק \"{{int:prefs-editing}}\" שבהעדפות שלכם.",
        "editpage-notsupportedcontentformat-title": "סוג התוכן אינו נתמך",
        "editpage-notsupportedcontentformat-text": "תוכן מסוג $1 אינו נתמך על־ידי מודל התוכן $2.",
-       "content-model-wikitext": "×\98קס×\98 ויקי",
+       "content-model-wikitext": "ק×\95×\93 ויקי",
        "content-model-text": "טקסט פשוט",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "revdelete-unsuppress": "הסרת הגבלות בגרסאות המשוחזרות",
        "revdelete-log": "סיבה:",
        "revdelete-submit": "ביצוע על {{PLURAL:$1|הגרסה שנבחרה|הגרסאות שנבחרו}}",
-       "revdelete-success": "×\9eצ×\91 ×\94תצ×\95×\92×\94 ×©×\9c ×\94×\92רס×\94 ×©×\81×\95Ö¼× ×\94.",
+       "revdelete-success": "מצב התצוגה של הגרסה שוּנה.",
        "revdelete-failure": "לא ניתן היה לשנות את מצב התצוגה של הגרסה:\n$1",
-       "logdelete-success": "×\9eצ×\91 ×\94תצ×\95×\92×\94 ×©×\9c ×¤×¢×\95×\9cת ×\94×\99×\95×\9e×\9f ×©×\81×\95Ö¼× ×\94.",
+       "logdelete-success": "מצב התצוגה של פעולת היומן שוּנה.",
        "logdelete-failure": "לא ניתן היה לשנות את מצב התצוגה של היומן:\n$1",
        "revdel-restore": "שינוי מצב התצוגה",
        "pagehist": "היסטוריית הדף",
        "mergehistory-fail-permission": "הרשאות לא מספיקות למיזוג היסטוריה.",
        "mergehistory-fail-self-merge": "דף המקור זהה לדף היעד.",
        "mergehistory-fail-timestamps-overlap": "גרסאות המקור חופפות או מגיעות אחרי גרסאות היעד.",
-       "mergehistory-fail-toobig": "לא ניתן לבצע את מיזוג הגרסאות כיוון שצריך להעביר יותר גרסאות מהמגבלה, שהיא {{PLURAL:$1|גרסה אחת|‏‏֫$1 גרסאות}}.",
+       "mergehistory-fail-toobig": "לא ניתן לבצע את מיזוג הגרסאות כיוון שצריך להעביר יותר גרסאות מהמגבלה, שהיא {{PLURAL:$1|גרסה אחת|$1 גרסאות}}.",
        "mergehistory-no-source": "דף המקור $1 אינו קיים.",
        "mergehistory-no-destination": "דף היעד $1 אינו קיים.",
        "mergehistory-invalid-source": "דף המקור חייב להיות בעל כותרת תקינה.",
        "searchrelated": "קשור",
        "searchall": "הכול",
        "showingresults": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} החל ממספר <strong>$2</strong>:",
-       "showingresultsinrange": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} בין המספרים <strong>$2</strong> ו‏‏־<strong>$3</strong>:",
+       "showingresultsinrange": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</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": "לא נמצאו תוצאות המתאימות לחיפוש באתר זה.",
        "prefs-help-gender": "אין חובה למלא העדפה זו.\nהמערכת משתמשת במידע זה כדי לפנות אליך/אלייך ולציין את שם המשתמש שלך במין הדקדוקי הנכון.\nהמידע יהיה ציבורי.",
        "email": "דוא\"ל",
        "prefs-help-realname": "אין חובה למלא את השם האמיתי.\nהשם האמיתי עשוי לשמש כדי לייחס לך את עבודתך.",
-       "prefs-help-email": "כתובת דואר אלקטרוני היא אופציונלית, אבל היא חיונית לאיפוס הסיסמה במקרה שתשכחו אותה.",
+       "prefs-help-email": "כתובת דואר אלקטרוני היא אופציונלית, אבל היא חיונית לאיפוס הסיסמה במקרה ש{{GENDER:|תשכח|תשכחי}} אותה.",
        "prefs-help-email-others": "באפשרותך גם לבחור לאפשר לאחרים ליצור איתך קשר באמצעות דוא\"ל דרך קישור בדף המשתמש או בדף השיחה שלך.\nכתובת הדוא\"ל שלך לא תיחשף כשמשתמשים אחרים ייצרו איתך קשר.",
        "prefs-help-email-required": "כתובת דואר אלקטרוני נדרשת לכתיבה באתר.",
        "prefs-info": "מידע בסיסי",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ראו גם [[Special:NewPages|רשימת דפים חדשים]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "הצגה",
-       "rcnotefrom": "×\9c×\94×\9c×\9f {{PLURAL:$5|×\94ש×\99× ×\95×\99 ×©×\91×\95צע|×\94ש×\99× ×\95×\99×\99×\9d ×©×\91×\95צע×\95}} ×\94×\97×\9c ×\9eâ\80\8fâ\80\8fÖ«Ö¾<b>$2</b> (×¢×\93 <b>$1</b> ×\9e×\95צ×\92×\99×\9d).",
+       "rcnotefrom": "×\9c×\94×\9c×\9f {{PLURAL:$5|×\94ש×\99× ×\95×\99 ×©×\91×\95צע|×\94ש×\99× ×\95×\99×\99×\9d ×©×\91×\95צע×\95}} ×\9e×\90×\96 <strong>$3, $4</strong> (×\9e×\95צ×\92×\99×\9d ×¢×\93 <strong>$1</strong>).",
        "rclistfrom": "הצגת שינויים חדשים החל מ־$2, $3",
        "rcshowhideminor": "$1 עריכות משניות",
        "rcshowhideminor-show": "הצגת",
        "recentchangeslinked": "שינויים בדפים המקושרים",
        "recentchangeslinked-feed": "שינויים בדפים המקושרים",
        "recentchangeslinked-toolbox": "שינויים בדפים המקושרים",
-       "recentchangeslinked-title": "שינויים בדפים המקושרים מהדף $1",
+       "recentchangeslinked-title": "שינויים בדפים המקושרים מהדף \"$1\"",
        "recentchangeslinked-summary": "בדף מיוחד זה רשומים השינויים האחרונים בדפים המקושרים מתוך הדף (או בדפים הכלולים בקטגוריה).\nדפים ב[[Special:Watchlist|רשימת המעקב שלכם]] מוצגים ב'''הדגשה'''.",
        "recentchangeslinked-page": "שם הדף:",
        "recentchangeslinked-to": "הצגת השינויים בדפים המקשרים לדף הנתון במקום זאת",
        "recentchanges-page-removed-from-category": "הדף [[:$1]] הוסר מקטגוריה",
        "recentchanges-page-removed-from-category-bundled": "הדף [[:$1]] הוסר מקטגוריה, [[Special:WhatLinksHere/$1|והוא מוכלל בדפים אחרים]]",
        "autochange-username": "שינוי אוטומטי של מדיה־ויקי",
-       "upload": "העלאת קובץ לשרת",
-       "uploadbtn": "×\94×¢×\9c×\90×\94",
+       "upload": "העלאת קובץ",
+       "uploadbtn": "×\94×¢×\9c×\90ת ×\94ק×\95×\91×¥",
        "reuploaddesc": "ביטול ההעלאה וחזרה לטופס העלאת קבצים לשרת",
        "upload-tryagain": "שליחת התיאור החדש של הקובץ",
        "uploadnologin": "לא נכנסת לחשבון",
        "uploadvirus": "הקובץ מכיל וירוס!\nפרטים:\n<div dir=\"ltr\">$1</div>",
        "uploadjava": "קובץ זה הוא קובץ ZIP שמכיל קובץ &lrm;.class של Java.\nהעלאת קובצי Java אסורה, כיוון שהם יכולים לגרום לעקיפת מגבלות האבטחה.",
        "upload-source": "קובץ המקור",
-       "sourcefilename": "ש×\9d ×\94ק×\95×\91×¥:",
+       "sourcefilename": "ש×\9d ×§×\95×\91×¥ ×\94×\9eק×\95ר:",
        "sourceurl": "כתובת URL של המקור:",
        "destfilename": "שמירת הקובץ בשם:",
        "upload-maxfilesize": "גודל הקובץ המרבי: $1",
        "upload-form-label-infoform-description-tooltip": "תיאור קצר של כל העובדות החשובות על הקובץ.\nאם הקובץ הוא תמונה, יש לציין את הדברים העיקריים המתוארים בתמונה, את האירוע, או את המיקום.",
        "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": "ההעלאה מבוצעת בהתאם לתנאי השירות ולמדיניות הרישיונות ב{{grammar:תחילית|{{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|דף העלאת הקבצים ב{{grammar:תחילית|{{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|דף העלאת הקבצים ב{{grammar:תחילית|{{SITENAME}}}}]], אם ניתן להעלות את הקובץ הזה לשם לפי מדיניות האתר.",
+       "upload-form-label-own-work": "אני יצרתי את הקובץ",
+       "upload-form-label-infoform-categories": "קטגוריות",
+       "upload-form-label-infoform-date": "תאריך",
+       "upload-form-label-own-work-message-local": "ההעלאה מבוצעת בהתאם לתנאי השירות ולמדיניות הרישיונות ב{{grammar:תחילית|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "אם אין באפשרותך להעלות את הקובץ הזה לפי המדיניות של {{SITENAME}}, עליך לסגור את התיבה הנוכחית ולנסות שיטה אחרת.",
+       "upload-form-label-not-own-work-local-local": "באפשרותך לנסות להשתמש ב[[Special:Upload|דף ברירת המחדל להעלאת קבצים]].",
+       "upload-form-label-own-work-message-default": "ידוע לי שאני מעלה את הקובץ הזה למאגר משותף. ההעלאה מבוצעת בהתאם לתנאי השירות ולמדיניות הרישיונות שם.",
+       "upload-form-label-not-own-work-message-default": "אם אין באפשרותך להעלות את הקובץ הזה לפי המדיניות של המאגר המשותף, עליך לסגור את התיבה הנוכחית ולנסות שיטה אחרת.",
+       "upload-form-label-not-own-work-local-default": "באפשרותך לנסות להשתמש ב[[Special:Upload|דף העלאת הקבצים ב{{grammar:תחילית|{{SITENAME}}}}]], אם ניתן להעלות את הקובץ הזה לשם לפי מדיניות האתר.",
+       "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 תנאי השימוש].",
+       "upload-form-label-not-own-work-message-shared": "אם זכויות היוצרים על הקובץ הזה אינן בבעלותך, או שברצונך לשחרר אותו תחת רישיון אחר, באפשרותך להשתמש ב[https://commons.wikimedia.org/wiki/Special:UploadWizard אשף ההעלאה לוויקישיתוף].",
+       "upload-form-label-not-own-work-local-shared": "באפשרותך לנסות להשתמש ב[[Special:Upload|דף העלאת הקבצים ב{{grammar:תחילית|{{SITENAME}}}}]], אם ניתן להעלות את הקובץ הזה לשם לפי מדיניות האתר.",
        "backend-fail-stream": "לא הייתה אפשרות להזרים את הקובץ \"$1\".",
        "backend-fail-backup": "לא הייתה אפשרות לגבות את הקובץ \"$1\".",
        "backend-fail-notexists": "הקובץ \"$1\" אינו קיים.",
        "ntransclusions": "בשימוש {{PLURAL:$1|בדף אחד|ב־$1 דפים}}",
        "specialpage-empty": "אין תוצאות.",
        "lonelypages": "דפים יתומים",
-       "lonelypagestext": "×\94×\93פ×\99×\9d ×\94×\91×\90×\99×\9d ×\90×\99× ×\9d ×\9eק×\95שר×\99×\9d ×\9e×\93פ×\99×\9d ×\90×\97ר×\99×\9d ×\91×\90תר ×\96×\94 ×\95×\90×\99× ×\9d ×\9e×\95×\9b×\9c×\9c×\99×\9d ×\91×\94×\9d.",
+       "lonelypagestext": "×\94×\93פ×\99×\9d ×\94×\91×\90×\99×\9d ×\90×\99× ×\9d ×\9eק×\95שר×\99×\9d ×\95×\90×\99× ×\9d ×\9e×\95×\9b×\9c×\9c×\99×\9d ×\91×\93פ×\99×\9d ×\90×\97ר×\99×\9d ×\91×\90תר {{SITENAME}}.",
        "uncategorizedpages": "דפים חסרי קטגוריה",
        "uncategorizedcategories": "קטגוריות חסרות קטגוריה",
        "uncategorizedimages": "קבצים חסרי קטגוריה",
        "deadendpages": "דפים ללא קישורים",
        "deadendpagestext": "הדפים הבאים אינם מקשרים לדפים אחרים באתר {{SITENAME}}.",
        "protectedpages": "דפים מוגנים",
-       "protectedpages-indef": "×\94×\92× ×\95ת ×\9c×\96×\9e×\9f ×\91×\9cת×\99 ×\9e×\95×\92×\91×\9c בלבד",
+       "protectedpages-indef": "×\94×\92× ×\95ת ×\9c×\9c×\90 ×\94×\92×\91×\9cת ×\96×\9e×\9f בלבד",
        "protectedpages-summary": "בדף זה רשומים הדפים הקיימים שמוגנים כרגע. לרשימת הכותרות שמוגנות מפני יצירה, ראו [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "הגנות מדורגות בלבד",
        "protectedpages-noredirect": "הסתרת הפניות",
        "protectedpages-page": "דף",
        "protectedpages-expiry": "זמן פקיעה",
        "protectedpages-performer": "הוגן על־ידי",
-       "protectedpages-params": "פר×\9e×\98ר×\99×\9d ×\9cהגנה",
+       "protectedpages-params": "ר×\9eת ×\94הגנה",
        "protectedpages-reason": "סיבה",
        "protectedpages-submit": "הצגת דפים",
        "protectedpages-unknown-timestamp": "לא ידוע",
        "listgrouprights-rights": "הרשאות",
        "listgrouprights-helppage": "Help:הרשאות",
        "listgrouprights-members": "(רשימת חברים)",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($2)</code></span>",
        "listgrouprights-addgroup": "הוספת {{PLURAL:$2|הקבוצה|הקבוצות}}: $1",
        "listgrouprights-removegroup": "הסרת {{PLURAL:$2|הקבוצה|הקבוצות}}: $1",
        "listgrouprights-addgroup-all": "הוספת כל הקבוצות",
        "emailccsubject": "העתק של הודעתך למשתמש $1: $2",
        "emailsent": "הדואר נשלח",
        "emailsenttext": "הודעת הדואר האלקטרוני שלך נשלחה.",
-       "emailuserfooter": "$1 {{GENDER:$1|ש×\9c×\97|ש×\9c×\97×\94}} ×\90ת ×\94×\93×\95×\90\"×\9c ×\94×\96×\94 ×\9c{{GRAMMAR:ת×\97×\99×\9c×\99ת|$2}} ×\91×\90×\9eצע×\95ת ×¤×¢×\95×\9cת \"{{int:emailuser}}\" ב{{GRAMMAR:תחילית|{{SITENAME}}}}.",
+       "emailuserfooter": "$1 {{GENDER:$1|ש×\9c×\97|ש×\9c×\97×\94}} ×\90ת ×\94×\93×\95×\90\"×\9c ×\94×\96×\94 ×\9c{{GRAMMAR:ת×\97×\99×\9c×\99ת|$2}} ×\91×\90×\9eצע×\95ת ×\94ת×\9b×\95× ×\94 \"{{int:emailuser}}\" ב{{GRAMMAR:תחילית|{{SITENAME}}}}.",
        "usermessage-summary": "השארת הודעת מערכת.",
        "usermessage-editor": "שולח הודעות המערכת",
        "watchlist": "רשימת המעקב",
        "excontent": "התוכן היה: \"$1\"",
        "excontentauthor": "התוכן היה: \"$1\", {{GENDER:$2|והתורם היחיד היה|והתורמת היחידה הייתה}} \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|שיחה]])",
        "exbeforeblank": "התוכן לפני שרוקן היה: \"$1\"",
-       "delete-confirm": "מחיקת \"$1\"",
+       "delete-confirm": "מחיקת הדף \"$1\"",
        "delete-legend": "מחיקה",
        "historywarning": "<strong>אזהרה:</strong> לדף שאתם עומדים למחוק יש היסטוריית שינויים של {{PLURAL:$1|גרסה אחת|$1 גרסאות}}:",
        "historyaction-submit": "הצגה",
        "changecontentmodel-submit": "שינוי",
        "changecontentmodel-success-title": "מודל התוכן שוּנה",
        "changecontentmodel-success-text": "מודל התוכן של [[:$1]] שוּנה.",
-       "changecontentmodel-cannot-convert": "×\94ת×\95×\9b×\9f ×\91×\93×£ [[:$1]] ×\90×\99× ×\95 ×\99×\9b×\95×\9c ×\9c×\94×\99×\95ת ×\9e×\95×\9eר ×\9cס×\95×\92 ×©×\9c $2.",
+       "changecontentmodel-cannot-convert": "×\9c×\90 × ×\99ת×\9f ×\9c×\94×\9e×\99ר ×\90ת ×\94ת×\95×\9b×\9f ×©×\9c [[:$1]] ×\9cס×\95×\92 $2.",
        "changecontentmodel-nodirectediting": "מודל התוכן $1 אינו תומך בעריכה ישירה",
+       "changecontentmodel-emptymodels-title": "לא קיים מודל תוכן מתאים",
+       "changecontentmodel-emptymodels-text": "לא ניתן להמיר את התוכן של [[:$1]] לאף סוג.",
        "log-name-contentmodel": "יומן שינויי מודל תוכן",
        "log-description-contentmodel": "אירועים שקשורים למודל תוכן של דפים",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|יצר|יצרה}} את הדף $3 תוך שימוש במודל התוכן \"$5\" השונה ממודל ברירת המחדל",
        "protect-level-autoconfirmed": "רק משתמשים ותיקים מורשים",
        "protect-level-sysop": "רק מפעילי מערכת מורשים",
        "protect-summary-cascade": "מדורג",
-       "protect-expiring": "פוקעת $1 (UTC)",
-       "protect-expiring-local": "פוקעת $1",
+       "protect-expiring": "פוקעת ב{{GRAMMAR:תחילית|$1}} (UTC)",
+       "protect-expiring-local": "פוקעת ב{{GRAMMAR:תחילית|$1}}",
        "protect-expiry-indefinite": "בלתי מוגבלת בזמן",
        "protect-cascade": "הגנה על כל הדפים המוכללים בדף זה (הגנה מדורגת)",
        "protect-cantedit": "אין באפשרותך לשנות את רמת ההגנה על דף זה כיוון שאין לך הרשאה לערוך אותו.",
        "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": "ר×\9eת ×\94×\94×\92×\91×\9cה:",
+       "restriction-level": "ר×\9eת ×\94×\94×\92× ה:",
        "minimum-size": "גודל מינימלי",
        "maximum-size": "גודל מרבי:",
        "pagesize": "(בבתים)",
        "undeletedrevisions-files": "{{PLURAL:$1|גרסה אחת|$1 גרסאות}} ו{{PLURAL:$2|קובץ אחד|־$2 קבצים}} שוחזרו",
        "undeletedfiles": "{{PLURAL:$1|שוחזר קובץ אחד|שוחזרו $1 קבצים}}",
        "cannotundelete": "השחזור נכשל:\n$1",
-       "undeletedpage": "'''הדף $1 שוחזר בהצלחה.'''\n\nראו את [[Special:Log/delete|יומן המחיקות]] לרשימה של מחיקות ושחזורים אחרונים.",
+       "undeletedpage": "<strong>הדף $1 שוחזר</strong>\n\nראו את [[Special:Log/delete|יומן המחיקות]] לרשימה של המחיקות והשחזורים שבוצעו לאחרונה.",
        "undelete-header": "ראו את [[Special:Log/delete|יומן המחיקות]] לדפים שנמחקו לאחרונה.",
        "undelete-search-title": "חיפוש דפים שנמחקו",
        "undelete-search-box": "חיפוש דפים שנמחקו",
        "sp-contributions-newonly": "הצגת עריכות שהן יצירות של דפים בלבד",
        "sp-contributions-submit": "חיפוש",
        "whatlinkshere": "דפים המקושרים לכאן",
-       "whatlinkshere-title": "דפים המקשרים לדף $1",
+       "whatlinkshere-title": "דפים המקשרים לדף \"$1\"",
        "whatlinkshere-page": "דף:",
        "linkshere": "הדפים שלהלן מקושרים לדף '''[[:$1]]''':",
        "nolinkshere": "אין דפים המקושרים לדף '''[[:$1]]'''.",
        "whatlinkshere-prev": "{{PLURAL:$1|הקודם|$1 הקודמים}}",
        "whatlinkshere-next": "{{PLURAL:$1|הבא|$1 הבאים}}",
        "whatlinkshere-links": "→ קישורים",
-       "whatlinkshere-hideredirs": "$1 הפניות",
-       "whatlinkshere-hidetrans": "$1 הכללות",
-       "whatlinkshere-hidelinks": "$1 קישורים",
-       "whatlinkshere-hideimages": "$1 קישורים לקובץ",
+       "whatlinkshere-hideredirs": "הסתרת הפניות",
+       "whatlinkshere-hidetrans": "הסתרת הכללות",
+       "whatlinkshere-hidelinks": "הסתרת קישורים",
+       "whatlinkshere-hideimages": "הסתרת קישורי קבצים",
        "whatlinkshere-filters": "מסננים",
        "whatlinkshere-submit": "הצגה",
        "autoblockid": "חסימה אוטומטית #$1",
        "blocklist-rangeblocks": "הסתרת חסימות טווחים",
        "blocklist-timestamp": "זמן",
        "blocklist-target": "יעד",
-       "blocklist-expiry": "פקיעה",
+       "blocklist-expiry": "×\96×\9e×\9f ×¤×§×\99×¢×\94",
        "blocklist-by": "מפעיל חוסם",
        "blocklist-params": "הגדרות חסימה",
        "blocklist-reason": "סיבה",
        "ipblocklist-submit": "חיפוש",
        "ipblocklist-localblock": "חסימה מקומית",
        "ipblocklist-otherblocks": "{{PLURAL:$1|חסימה אחרת|חסימות אחרות}}",
-       "infiniteblock": "×\91×\9cת×\99 ×\9e×\95×\92×\91×\9c ×\91זמן",
-       "expiringblock": "פ×\95קע ×\91Ö¾$2, $1",
+       "infiniteblock": "×\9c×\9c×\90 ×\94×\92×\91×\9cת זמן",
+       "expiringblock": "×\94×\97ס×\99×\9e×\94 ×¤×\95קעת ×\91{{GRAMMAR:ת×\97×\99×\9c×\99ת|$1}} ×\91שע×\94 $2",
        "anononlyblock": "משתמשים אנונימיים בלבד",
        "noautoblockblock": "חסימה אוטומטית מבוטלת",
        "createaccountblock": "יצירת חשבונות נחסמה",
        "lockdbsuccesstext": "בסיס הנתונים ננעל.<br />\nיש לזכור [[Special:UnlockDB|לשחרר את הנעילה]] לאחר שפעולת התחזוקה תסתיים.",
        "unlockdbsuccesstext": "שוחררה הנעילה של בסיס הנתונים",
        "lockfilenotwritable": "קובץ נעילת בסיס הנתונים אינו ניתן לכתיבה. כדי שאפשר יהיה לנעול את בסיס הנתונים או לבטל את נעילתו, שרת האינטרנט צריך לקבל הרשאות לכתוב אליו.",
+       "databaselocked": "בסיס הנתונים כבר נעול.",
        "databasenotlocked": "בסיס הנתונים אינו נעול.",
        "lockedbyandtime": "(על־ידי $1 ב־$3, $2)",
-       "move-page": "העברת $1",
+       "move-page": "העברת הדף \"$1\"",
        "move-page-legend": "העברת דף",
        "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אנא ודאו שאתם מבינים את השלכות המעשה לפני שאתם ממשיכים.",
        "cant-move-category-page": "אין לך הרשאה להעביר דפי קטגוריה.",
        "cant-move-to-category-page": "אין לך הרשאה להעביר דף לדף קטגוריה.",
        "newtitle": "השם החדש:",
-       "move-watch": "מעקב אחר דף המקור ואחר דף היעד",
+       "move-watch": "מעקב אחרי דף המקור ואחרי דף היעד",
        "movepagebtn": "העברה",
        "pagemovedsub": "ההעברה הושלמה בהצלחה",
        "movepage-moved": "הדף \"$1\" הועבר לשם \"$2\".",
        "articleexists": "קיים כבר דף באותו שם, או שהשם שבחרת אינו תקין.\nנא לבחור שם אחר.",
        "cantmove-titleprotected": "אין לך הרשאה להעביר את הדף לכאן, כי השם החדש מוגן מפני יצירה.",
        "movetalk": "העברה גם של דף השיחה",
-       "move-subpages": "×\94×¢×\91רת ×\9b×\9c ×\93פ×\99 ×\94×\9eשנ×\94 (×¢×\93 $1)",
-       "move-talk-subpages": "×\94×¢×\91רת ×\9b×\9c ×\93פ×\99 ×\94×\9eשנ×\94 ×©×\9c ×\93×£ ×\94ש×\99×\97×\94 (×¢×\93 $1)",
+       "move-subpages": "העברת דפי המשנה (עד $1)",
+       "move-talk-subpages": "העברת דפי המשנה של דף השיחה (עד $1)",
        "movepage-page-exists": "הדף $1 קיים כבר ולא ניתן לדרוס אותו אוטומטית.",
        "movepage-page-moved": "הדף $1 הועבר לשם $2.",
        "movepage-page-unmoved": "לא ניתן להעביר את הדף $1 לשם $2.",
        "import-comment": "הערה:",
        "importtext": "נא לייצא את הקובץ מאתר המקור באמצעות ב[[Special:Export|כלי הייצוא]].\nשמרו אותו למחשב שלכם והעלו אותו לכאן.",
        "importstart": "ייבוא דפים...",
-       "import-revision-count": "{{PLURAL:$1|גרסה אחת|$1 גרסאות}}",
+       "import-revision-count": "&rlm;{{PLURAL:$1|גרסה אחת|$1 גרסאות}}",
        "importnopages": "אין דפים לייבוא.",
        "imported-log-entries": "{{PLURAL:$1|יובאה פעולת יומן אחת|יובאו $1 פעולות יומן}}.",
        "importfailed": "הייבוא נכשל: <nowiki>$1</nowiki>",
        "tooltip-pt-mytalk": "דף השיחה שלך",
        "tooltip-pt-anontalk": "שיחה על תרומות המשתמש האנונימי",
        "tooltip-pt-preferences": "ההעדפות שלך",
-       "tooltip-pt-watchlist": "רשימת הדפים שאתם עוקבים אחרי השינויים בהם",
+       "tooltip-pt-watchlist": "רשימת הדפים ש{{GENDER:|אתה עוקב|את עוקבת}} אחרי השינויים בהם",
        "tooltip-pt-mycontris": "רשימת התרומות שלך",
        "tooltip-pt-anoncontribs": "רשימת העריכות שנעשו מכתובת ה־IP הזאת",
        "tooltip-pt-login": "מומלץ להיכנס לחשבון; עם זאת, אין חובה לעשות זאת",
        "tooltip-ca-nstab-category": "צפייה בדף הקטגוריה",
        "tooltip-minoredit": "סימון עריכה זו כמשנית",
        "tooltip-save": "שמירת השינויים שלך",
+       "tooltip-publish": "פרסום השינויים שלך",
        "tooltip-preview": "תצוגה מקדימה של השינויים שלך. נא להשתמש באפשרות זו לפני השמירה.",
-       "tooltip-diff": "צפ×\99×\99×\94 ×\91ש×\99× ×\95×\99×\99×\9d ×©×¢×¨×\9bת×\9d בטקסט",
+       "tooltip-diff": "×\94צ×\92ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\91×\99צעת בטקסט",
        "tooltip-compareselectedversions": "צפייה בהשוואת שתי גרסאות של דף זה",
        "tooltip-watch": "הוספת דף זה לרשימת המעקב שלך",
        "tooltip-watchlistedit-normal-submit": "הסרת הדפים",
        "anonymous": "{{PLURAL:$1|משתמש אנונימי|משתמשים אנונימיים}} של {{SITENAME}}",
        "siteuser": "משתמש {{SITENAME}} $1",
        "anonuser": "משתמש אנונימי של {{SITENAME}} $1",
-       "lastmodifiedatby": "דף זה שונה לאחרונה ב־$2, $1 על־ידי $3.",
+       "lastmodifiedatby": "דף זה שוּנה לאחרונה ב־$2, $1 על־ידי $3.",
        "othercontribs": "מבוסס על העבודה של $1.",
        "others": "אחרים",
        "siteusers": "{{PLURAL:$2|{{GENDER:$1|משתמש}}|משתמשי}} {{SITENAME}} $1",
        "spam_blanking": "כל הגרסאות כוללות קישורים ל־$1, מרוקן את הדף",
        "spam_deleting": "כל הגרסאות כוללות קישורים ל־$1, מוחק את הדף",
        "simpleantispam-label": "בדיקת אנטי־ספאם.\n<strong>אל</strong> תמלאו שדה זה!",
-       "pageinfo-title": "מידע על \"$1\"",
+       "pageinfo-title": "מידע על הדף \"$1\"",
        "pageinfo-not-current": "מצטערים, לא ניתן להציג את המידע הזה לגרסאות ישנות.",
        "pageinfo-header-basic": "מידע בסיסי",
        "pageinfo-header-edits": "היסטוריית עריכות",
        "filedelete-old-unregistered": "גרסת הקובץ \"$1\" אינה רשומה בבסיס הנתונים.",
        "filedelete-current-unregistered": "הקובץ \"$1\" אינו רשום בבסיס הנתונים.",
        "filedelete-archive-read-only": "השרת אינו יכול לכתוב לתיקיית הארכיון \"$1\".",
-       "previousdiff": "â\86\92 ×\9e×¢×\91ר ×\9c×\94ש×\95×\95×\90ת ×\94×\92רס×\90×\95ת הקודמת",
-       "nextdiff": "×\9e×¢×\91ר ×\9c×\94ש×\95×\95×\90ת ×\94×\92רס×\90×\95ת הבאה ←",
+       "previousdiff": "â\86\92 ×\94ער×\99×\9b×\94 הקודמת",
+       "nextdiff": "×\94ער×\99×\9b×\94 הבאה ←",
        "mediawarning": "<strong>אזהרה:</strong> סוג קובץ זה עלול להכיל קוד זדוני.\nהרצת הקוד עלולה לסכן את המחשב שלך.",
        "imagemaxsize": "גודל תמונה מרבי:<br /><em>(בדפי תיאור של קבצים)</em>",
        "thumbsize": "גודל של תמונות ממוזערות:",
        "logentry-import-upload": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 באמצעות העלאת קובץ",
        "logentry-import-upload-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 באמצעות העלאת קובץ ({{PLURAL:$4|גרסה אחת|$4 גרסאות}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 מאתר ויקי אחר",
-       "logentry-import-interwiki-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 מ־$5&rlm; ({{PLURAL:$4|גרסה אחת|$4 גרסאות}})&rlm;",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 מ־$5&rlm; ({{PLURAL:$4|גרסה אחת|$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 בלי להשאיר הפניה",
        "logentry-protect-modify": "$1 {{GENDER:$2|שינה|שינתה}} את רמת ההגנה של הדף $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|שינה|שינתה}} את רמת ההגנה של הדף $3 $4 [מדורג]",
        "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של {{GENDER:$6|$3}} מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}",
-       "logentry-rights-rights-legacy": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3&rlm;",
+       "logentry-rights-rights-legacy": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3",
        "logentry-rights-autopromote": "$1 קודם אוטומטית מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|העלה|העלתה}} גרסה חדשה של $3",
        "feedback-useragent": "User agent:",
        "searchsuggest-search": "חיפוש",
        "searchsuggest-containing": "כולל...",
+       "api-error-autoblocked": "כתובת ה־IP שלך נחסמה אוטומטית, כי היא הייתה בשימוש על־ידי משתמש חסום.",
        "api-error-badaccess-groups": "אינך מורשה להעלות קבצים לאתר הוויקי הזה.",
        "api-error-badtoken": "שגיאה פנימית: אסימון שבור.",
+       "api-error-blocked": "נחסמת מעריכה.",
        "api-error-copyuploaddisabled": "העלאה לפי כתובת כובתה בשרת זה.",
        "api-error-duplicate": "כבר יש באתר הזה {{PLURAL:$1|קובץ אחר|קבצים אחרים}} עם אותו תוכן.",
        "api-error-duplicate-archive": "כבר {{PLURAL:$1|היה|היו}} באתר הזה {{PLURAL:$1|קובץ|קבצים}} עם אותו תוכן, אבל {{PLURAL:$1|הוא נמחק|הם נמחקו}}.",
        "api-error-nomodule": "שגיאה פנימית: מודול ההעלאה אינו מוגדר.",
        "api-error-ok-but-empty": "שגיאה פנימית: אין תשובה מהשרת.",
        "api-error-overwrite": "לא מותרת החלפת קובץ קיים.",
+       "api-error-ratelimited": "ניסית להעלות בזמן קצר יותר קבצים מהכמות המירבית המותרת באתר הוויקי הזה.\nנא לנסות שוב בעוד מספר דקות.",
        "api-error-stashfailed": "שגיאה פנימית: השרת נכשל באחסון הקובץ הזמני.",
        "api-error-publishfailed": "שגיאה פנימית: השרת נכשל בפרסום הקובץ הזמני.",
        "api-error-stasherror": "הייתה שגיאה בהעלאת הקובץ לסליק.",
index b5f461d..eb11fb4 100644 (file)
        "upload-form-label-infoform-description-tooltip": "छोटे रूप में बतायें इस के उलेखनीयता के बारे में। \n चित्र हेतु, जो मुख्य वस्तु नहीं दिखाया गया है आदि के स्थान।",
        "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 Commons Upload Wizard] का उपयोग करें।",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "यदि आप चाहें तो आप [[Special:Upload|{{SITENAME}} के पृष्ठ]] पर फ़ाइल डाल सकते हैं, यदि यह फ़ाइल वहाँ के नियम के अंतर्गत हो तो।",
+       "upload-form-label-own-work": "यह मेरा कार्य है",
+       "upload-form-label-infoform-categories": "श्रेणियाँ",
+       "upload-form-label-infoform-date": "दिनांक",
+       "upload-form-label-own-work-message-local": "मैं यह सत्यापित करता हूँ कि मेरे द्वारा डाला गया फ़ाइल {{SITENAME}} सेवा के शर्तों और अधिकार नियम के अनुकूल है।",
+       "upload-form-label-not-own-work-message-local": "यदि आप {{SITENAME}} के नियमों के अंतर्गत फ़ाइल नहीं डाल सकते, तो आप इसे हटा कर किसी दूसरे विधि का उपयोग करें।",
+       "upload-form-label-not-own-work-local-local": "आप [[Special:Upload|मूल डालने वाले पृष्ठ]] का भी उपयोग कर सकते हो।",
+       "upload-form-label-own-work-message-default": "मैं यह समझता हूँ कि यहाँ सभी फ़ाइल सांझा होते हैं। मैं यह सत्यापित करता हूँ कि में सेवा के शर्तों और नियम के अनुरूप ही कार्य कर रहा हूँ।",
+       "upload-form-label-not-own-work-message-default": "यदि आप इस नियम के अंतर्गत फ़ाइल नहीं डालना चाहते तो अभी इसे बन्द कर दें और कोई दूसरे विधि को खोजें।",
+       "upload-form-label-not-own-work-local-default": "यदि आप चाहें तो आप [[Special:Upload|{{SITENAME}} के पृष्ठ]] पर फ़ाइल डाल सकते हैं, यदि यह फ़ाइल वहाँ के नियम के अंतर्गत हो तो।",
+       "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 विकि उपयोग की शर्तों] का भी पालन करता है।",
+       "upload-form-label-not-own-work-message-shared": "यदि आपके पास इस फ़ाइल का प्रतिकृति अधिकार नहीं है और आप इसे किसी और अधिकार के तहत प्रदर्शित करना चाहते हैं तो आप [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] का उपयोग करें।",
+       "upload-form-label-not-own-work-local-shared": "यदि आप चाहें तो आप [[Special:Upload|{{SITENAME}} के पृष्ठ]] पर फ़ाइल डाल सकते हैं, यदि यह फ़ाइल वहाँ के नियम के अंतर्गत हो तो।",
        "backend-fail-stream": "फ़ाइल $1 स्ट्रीम नहीं हो पाई।",
        "backend-fail-backup": "फ़ाइल $1 बैकअप नहीं हो पाई।",
        "backend-fail-notexists": "फ़ाइल $1 मौजूद नहीं है।",
index 0c33094..fa1b19f 100644 (file)
        "thursday": "četvrtak",
        "friday": "petak",
        "saturday": "subota",
-       "sun": "Ned",
-       "mon": "Pon",
-       "tue": "Uto",
-       "wed": "Sri",
-       "thu": "Ä\8cet",
-       "fri": "Pet",
-       "sat": "Sub",
+       "sun": "ned",
+       "mon": "pon",
+       "tue": "uto",
+       "wed": "sri",
+       "thu": "Ä\8det",
+       "fri": "pet",
+       "sat": "sub",
        "january": "siječnja",
        "february": "veljače",
        "march": "ožujka",
        "upload-form-label-infoform-description": "Opis",
        "upload-form-label-usage-title": "Korištenje",
        "upload-form-label-usage-filename": "Ime datoteke",
-       "foreign-structured-upload-form-label-own-work": "Ovo je moje djelo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Možete pokušati [[Special:Upload|postaviti datoteku na projektu {{SITENAME}}]], pod uvjetom da može biti tamo postavljena, sukladno pravilima projekta.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava ove datoteke i slažem se da je nepozivo postavljam na Zajednički poslužitelj pod licencijom  [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], i pristajem na [https://wikimediafoundation.org/wiki/Terms_of_Use Uvjete uporabe].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku, ili je želite objaviti pod drugom licencijom, razmislite o uporabi [https://commons.wikimedia.org/wiki/Special:UploadWizard Čarobnjaka za postavljanje] na Zajedničkom poslužitelju.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Možete pokušati [[Special:Upload|postaviti datoteku na projektu {{SITENAME}}]], pod uvjetom da je dopušteno postavljanje ove datoteke, sukladno pravilima projekta.",
+       "upload-form-label-own-work": "Ovo je moje djelo",
+       "upload-form-label-infoform-categories": "Kategorije",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-not-own-work-local-default": "Možete pokušati [[Special:Upload|postaviti datoteku na projektu {{SITENAME}}]], pod uvjetom da može biti tamo postavljena, sukladno pravilima projekta.",
+       "upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava ove datoteke i slažem se da je nepozivo postavljam na Zajednički poslužitelj pod licencijom  [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], i pristajem na [https://wikimediafoundation.org/wiki/Terms_of_Use Uvjete uporabe].",
+       "upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku, ili je želite objaviti pod drugom licencijom, razmislite o uporabi [https://commons.wikimedia.org/wiki/Special:UploadWizard Čarobnjaka za postavljanje] na Zajedničkom poslužitelju.",
+       "upload-form-label-not-own-work-local-shared": "Možete pokušati [[Special:Upload|postaviti datoteku na projektu {{SITENAME}}]], pod uvjetom da je dopušteno postavljanje ove datoteke, sukladno pravilima projekta.",
        "backend-fail-stream": "Ne mogu prikazati datoteku $1.",
        "backend-fail-backup": "Izrada sigurnosne kopije datoteke \"$1\" nije uspjela.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
index 0a51bcd..140f56a 100644 (file)
@@ -9,10 +9,11 @@
                        "아라",
                        "Tisave",
                        "Bfpage",
-                       "Macofe"
+                       "Macofe",
+                       "Lucas"
                ]
        },
-       "tog-underline": "Souliyen lyen yo :",
+       "tog-underline": "Souliyen lyen yo&nbsp;:",
        "tog-hideminor": "Kache tout modifikasyon resan yo ki tou piti",
        "tog-hidepatrolled": "Kache modifikasyon yo ki fèk fèt pou moun ki ap veye yo",
        "tog-newpageshidepatrolled": "Kache paj ki siveye yo nan mitan lis nouvo paj yo",
@@ -27,7 +28,7 @@
        "tog-watchmoves": "Ajoute paj mwen deplase yo nan lis swivi mwen",
        "tog-watchdeletion": "Ajoute paj mwen efase yo nan lis swivi mwen",
        "tog-watchrollback": "Ajoute paj kote mwen ranvèse chanjman yo nan lis swivi mwen",
-       "tog-minordefault": "Make tout modifikasyon mwen yo \"tou piti\" pa defo",
+       "tog-minordefault": "Make tout modifikasyon kòm «&nbsp;tou piti&nbsp;» pa defo",
        "tog-previewontop": "Montre kout je anvan zòn modifikasyon",
        "tog-previewonfirst": "Montre kout je pou chak premye modifikasyon",
        "tog-enotifwatchlistpages": "Voye yon imèl ban mwen lè youn nan paj m ap swiv yo chanje",
        "morenotlisted": "Lis sa a pa konplè.",
        "mypage": "Paj",
        "mytalk": "Diskisyon",
-       "anontalk": "Paj diskisyon pou adrès IP sa",
+       "anontalk": "Diskite",
        "navigation": "Navigasyon",
        "and": "&#32;epi",
        "qbfind": "Chache",
        "versionrequired": "Vèsion $1 de MediaWiki nesesè",
        "versionrequiredtext": "Vèzion $1 de MediaWiki nesesè pou itilize paj sa. Wè [[Special:Version|version page]].",
        "ok": "OK",
-       "retrievedfrom": "Rekipere depi « $1 »",
+       "retrievedfrom": "Rekipere depi «&nbsp;$1&nbsp;»",
        "youhavenewmessages": "Ou genyen $1 ($2).",
        "youhavenewmessagesmanyusers": "Ou gen $2 de plizyè itilizatè $2.",
        "youhavenewmessagesmulti": "Ou genyen nouvo mesaj sou $1.",
        "viewsourceold": "Wè kòd paj la",
        "editlink": "modifye",
        "viewsourcelink": "wè kòd paj la",
-       "editsectionhint": "Modifye seksyon : $1",
+       "editsectionhint": "Modifye seksyon&nbsp;: $1",
        "toc": "Kontni yo",
        "showtoc": "montre",
        "hidetoc": "kache",
        "confirmable-yes": "Wi",
        "confirmable-no": "Non",
        "thisisdeleted": "Ou vle wè oubyen restore $1 ?",
-       "viewdeleted": "Wè $1 ?",
+       "viewdeleted": "Wè $1&nbsp;?",
        "restorelink": "{{PLURAL:$1|yon revizion efase|$1 revizion efase yo}}",
        "feedlinks": "Fil:",
        "feed-invalid": "Kalite fil sa envalid.",
        "virus-scanfailed": "Rechèch an pa ritounen pyès rezilta (kòd $1)",
        "virus-unknownscanner": "antiviris nou pa konnen :",
        "logouttext": "'''Ou dekonekte kounye a.'''\n\nOu mèt kontinye itilize {{SITENAME}} san ou pa idantifye, oubyen ou ka <span class='plainlinks'>[$1 rekonekte]</span> w ankò ak menm non an oubyen yon lòt.\nNote ke kèk paj gendwa afiche tankou ou te toujou konekte tank ou pa efase kach nan navigatè ou.",
+       "welcomeuser": "Byenveni, $1&nbsp;!",
        "yourname": "Non itilizatè ou an :",
        "userlogin-yourname": "Non itilizatè",
        "userlogin-yourname-ph": "Rantre non itilizatè w",
        "resetpass-submit-cancel": "Anile",
        "resetpass-wrong-oldpass": "Mopas sa pa bon ditou; li te mèt mopas ou an kounye a oubyen yon mopas tanporè.\nGendwa ou te deja modifye li oubyen ou te mande yon nouvo mopas tanporè.",
        "resetpass-temp-password": "Mopas tanporè yo ba ou an:",
+       "passwordreset-username": "Non itilizatè&nbsp;:",
        "bold_sample": "Tèks fonse",
        "bold_tip": "Tèks fonse",
        "italic_sample": "Tèks italik",
        "allpagesprefix": "Montre paj yo ki ap komanse pa prefiks sa a :",
        "categories": "Kategori yo",
        "categoriespagetext": "Kategori ki ap swiv {{PLURAL:$1|la|yo}} gen lòt paj oubien medya nan yo.\n[[Special:UnusedCategories|Kategori ki pa itilize]] pa parèt la.\nGade tou [[Special:WantedCategories|kategori moun mande]].",
-       "special-categories-sort-count": "klase pa valè",
-       "special-categories-sort-abc": "klase alfabetikalman",
        "linksearch": "Lyen andeyò",
        "listgrouprights-members": "(lis manm yo)",
        "emailuser": "Voye yon mesaj (imèl) pou itilizatè sa a",
+       "noemailtext": "Itilizatè sa pa te espesifye yon adrès imel ki valab.",
        "watchlist": "Lis swivi mwen",
        "mywatchlist": "Lis swivi mwen",
        "addedwatchtext": "Paj « [[:$1]] » te byen ajoute nan [[Special:Watchlist|lis swivi ou an]].\nDepi kounye a, tout modifikasyon nan paj sa a ak nan paj diskisyon li pral parèt <b>fonse</b> nan [[Special:RecentChanges|lis chanjman ki fèk fèt]] pou ou ka wè yo pi byen.",
index 621b567..5e56627 100644 (file)
@@ -62,6 +62,7 @@
        "tog-watchdefault": "Az általam szerkesztett lapok és fájlok felvétele a figyelőlistámra",
        "tog-watchmoves": "Az általam átnevezett lapok és fájlok felvétele a figyelőlistámra",
        "tog-watchdeletion": "Az általam törölt lapok és fájlok felvétele a figyelőlistámra",
+       "tog-watchuploads": "Általam feltöltött új fájlok hozzáadása a figyelőlistámhoz",
        "tog-watchrollback": "Az általam visszaállított lapok felvétele a figyelőlistámra",
        "tog-minordefault": "Alapértelmezetten minden szerkesztésemet jelölje aprónak",
        "tog-previewontop": "Előnézet megjelenítése a szerkesztőablak előtt",
        "upload-form-label-infoform-description-tooltip": "Röviden írj le minden említésre méltót a műről.\nFénykép esetén említsd meg a főbb látható dolgokat, a készítés alkalmát vagy helyszínét.",
        "upload-form-label-usage-title": "Használat",
        "upload-form-label-usage-filename": "Fájlnév",
-       "foreign-structured-upload-form-label-own-work": "Ez a saját munkám",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategóriák",
-       "foreign-structured-upload-form-label-infoform-date": "Dátum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Kijelentem, hogy a fájlt a(z) {{SITENAME}} következő felhasználási feltételei és licencirányelvei alapján töltöm fel.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Ha nem tudod feltölteni a fájlt a(z) {{SITENAME}} irányelvei értelmében, zárd be ezt a panelt és próbálkozz egy másik módszerrel.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Az [[Special:Upload|alapértelmezett feltöltőoldalt]] is kipróbálhatod.",
-       "foreign-structured-upload-form-label-own-work-message-default": "Megértettem, hogy a megosztott tárhelyre töltöm fel a fájlt. Kijelentem, hogy az ottani felhasználási feltételek és licencirányelvek szerint teszem ezt.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Ha nem tudod feltölteni a fájlt a megosztott tárhely irányelvei értelmében, zárd be ezt a panelt és próbálkozz egy másik módszerrel.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Megpróbálhatod használni [[Special:Upload|a(z) {{SITENAME}} feltöltési lapját]] is, ha ezt a fájlt fel lehet tölteni az itteni irányelvek szerint.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Igazolom, hogy én birtoklom a fájl szerzői jogait, és egyetértek azzal, hogy visszavonhatatlanul közzéteszem a fájlt a Wikimédia Commonson a [https://creativecommons.org/licenses/by-sa/4.0/deed.hu Creative Commons Nevezd meg! – Így add tovább! 4.0] licenc alatt, és egyetértek a [https://wikimediafoundation.org/wiki/Terms_of_Use felhasználási feltételekkel].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Ha nem birtoklod a fájl szerzői jogait vagy más licenc alatt szeretnéd közzétenni, fontold meg a [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Feltöltésvarázslójának] használatát.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Megpróbálhatod használni [[Special:Upload|a(z) {{SITENAME}} feltöltési lapját]] is, ha ezt a fájlt fel lehet tölteni az itteni irányelvek szerint.",
+       "upload-form-label-own-work": "Ez a saját munkám",
+       "upload-form-label-infoform-categories": "Kategóriák",
+       "upload-form-label-infoform-date": "Dátum",
+       "upload-form-label-own-work-message-local": "Kijelentem, hogy a fájlt a(z) {{SITENAME}} következő felhasználási feltételei és licencirányelvei alapján töltöm fel.",
+       "upload-form-label-not-own-work-message-local": "Ha nem tudod feltölteni a fájlt a(z) {{SITENAME}} irányelvei értelmében, zárd be ezt a panelt és próbálkozz egy másik módszerrel.",
+       "upload-form-label-not-own-work-local-local": "Az [[Special:Upload|alapértelmezett feltöltőoldalt]] is kipróbálhatod.",
+       "upload-form-label-own-work-message-default": "Megértettem, hogy a megosztott tárhelyre töltöm fel a fájlt. Kijelentem, hogy az ottani felhasználási feltételek és licencirányelvek szerint teszem ezt.",
+       "upload-form-label-not-own-work-message-default": "Ha nem tudod feltölteni a fájlt a megosztott tárhely irányelvei értelmében, zárd be ezt a panelt és próbálkozz egy másik módszerrel.",
+       "upload-form-label-not-own-work-local-default": "Megpróbálhatod használni [[Special:Upload|a(z) {{SITENAME}} feltöltési lapját]] is, ha ezt a fájlt fel lehet tölteni az itteni irányelvek szerint.",
+       "upload-form-label-own-work-message-shared": "Igazolom, hogy én birtoklom a fájl szerzői jogait, és egyetértek azzal, hogy visszavonhatatlanul közzéteszem a fájlt a Wikimédia Commonson a [https://creativecommons.org/licenses/by-sa/4.0/deed.hu Creative Commons Nevezd meg! – Így add tovább! 4.0] licenc alatt, és egyetértek a [https://wikimediafoundation.org/wiki/Terms_of_Use felhasználási feltételekkel].",
+       "upload-form-label-not-own-work-message-shared": "Ha nem birtoklod a fájl szerzői jogait vagy más licenc alatt szeretnéd közzétenni, fontold meg a [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Feltöltésvarázslójának] használatát.",
+       "upload-form-label-not-own-work-local-shared": "Megpróbálhatod használni [[Special:Upload|a(z) {{SITENAME}} feltöltési lapját]] is, ha ezt a fájlt fel lehet tölteni az itteni irányelvek szerint.",
        "backend-fail-stream": "Nem sikerült sugározni ezt a fájlt: $1.",
        "backend-fail-backup": "Nem lehet elmenteni ezt a fájlt: $1.",
        "backend-fail-notexists": "Ez a fájl nem létezik: $1 .",
        "tags-edit-revision-legend": "Címkék hozzáadás vagy eltávolítása {{PLURAL:$1|ehhez a változathoz|mind a(z) $1 változathoz}}",
        "tags-edit-logentry-legend": "Címkék hozzáadás vagy eltávolítása {{PLURAL:$1|ehhez a napló bejegyzéshez|mind a(z) $1 napló bejegyzéshez}}",
        "tags-edit-existing-tags": "Létező címkék:",
-       "tags-edit-existing-tags-none": "„Nincs”",
+       "tags-edit-existing-tags-none": "<em>Nincs</em>",
        "tags-edit-new-tags": "Új címkék:",
        "tags-edit-add": "Alábbi címkék hozzáadása:",
        "tags-edit-remove": "Alábbi címkék eltávolítása:",
        "tags-edit-reason": "Ok:",
        "tags-edit-revision-submit": "Változások alkalmazás {{PLURAL:$1|ehhez a|$1}} változathoz",
        "tags-edit-logentry-submit": "Változások alkalmazás {{PLURAL:$1|ehhez a|$1}} napló bejegyzéshez",
-       "tags-edit-success": "A változások sikeresen alkalmazva.",
+       "tags-edit-success": "A változások alkalmazva.",
        "tags-edit-failure": "A változásokat nem sikerült alkalmazni:\n$1",
        "tags-edit-nooldid-title": "Érvénytelen változat",
        "tags-edit-nooldid-text": "Nem adtál meg a változatot, vagy a megadott változat nem létezik.",
index ed8b068..65e4c76 100644 (file)
@@ -44,6 +44,7 @@
        "tog-watchdefault": "Ավելացնել իմ խմբագրած էջերը և նիշքերը իմ հսկացանկում",
        "tog-watchmoves": "Ավելացնել իմ վերնավանած էջերը և նիշքերը իմ հսկացանկում",
        "tog-watchdeletion": "Ավելացնել իմ ջնջած էջերը և նիշքերը իմ հսկացանկում",
+       "tog-watchuploads": "Իմ բեռնած նիշքերը ավելացնել իմ հսկացանկում",
        "tog-watchrollback": "Իմ հետ շրջած էջերն ավելացնել իմ հսկացանկում",
        "tog-minordefault": "Բոլոր խմբագրումները լռելյայն կերպով նշել որպես չնչին",
        "tog-previewontop": "Ցույց տալ նախադիտումը խմբագրման դաշտից առաջ",
        "october-date": "Հոկտեմբերի $1",
        "november-date": "Նոյեմբերի $1",
        "december-date": "Դեկտեմբերի $1",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Կատեգորիա|Կատեգորիաներ}}",
        "category_header": "«$1» կատեգորիայի հոդվածները",
        "subcategories": "Ենթակատեգորիաներ",
        "view-pool-error": "Ներեցեք, սերվերները գերբեռնված են այս պահին։\nՇատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը կրկին դիտելու համար։\n\n$1",
        "generic-pool-error": "Ներեցեք, սերվերները գերբեռնված են այս պահին։\nՇատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը կրկին դիտելու համար։",
        "pool-errorunknown": "Անհայտ սխալ",
+       "poolcounter-usage-error": "Օգտագործման սխալ՝ $1",
        "aboutsite": "{{grammar:genitive|{{SITENAME}}}} մասին",
        "aboutpage": "Project:Էությունը",
        "copyright": "Կայքի բովանդակությունը թողարկված է $1 թույլատրագրով, եթե այլ բան նշված չէ։",
        "pagetitle": "$1 — {{SITENAME}}",
        "retrievedfrom": "Ստացված է «$1» էջից",
        "youhavenewmessages": "Դուք ունեք $1 ($2)։",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Դուք ունեք}} $1 {{PLURAL:$3|այլ մասնակից|$3 մասնակցից}} ($2):",
        "youhavenewmessagesmanyusers": "Դուք ունեք $1 մի քանի օգտագործողից ($2)։",
        "newmessageslinkplural": "{{PLURAL:$1|նոր հաղորդագրություն|999=նոր հաղորդագրություններ}}",
        "newmessagesdifflinkplural": "վերջին {{PLURAL:$1|փոփոխում|999=փոփոխումներ}}",
        "filerenameerror": "Չհաջողվեց «$1» նիշքը վերանվանել «$2»։",
        "filedeleteerror": "Չհաջողվեց ջնջել «$1» ֆայլը։",
        "directorycreateerror": "Չհաջողվեց ստեղծել «$1» պանակը։",
+       "directoryreadonlyerror": "$1 թղթապանակը միայն ընթերցելու համար է:",
        "filenotfound": "Չհաջողվեց գտնել «$1» ֆայլը։",
        "unexpected": "Անսպասելի արժեք. «$1»=«$2»։",
        "formerror": "Սխալ. չհաջողվեց փոխանցել տվյալները",
        "customjsprotected": "Դուք չեք կարող խմբագրել այս ՋավաՍկրիպտ էջը, քանի որ այն պարունակում է այլ մասնակցի անձնական նախընտրանքներ։",
        "mycustomcssprotected": "Դուք բավարար իրավունքներ չունեք այս CSS էջը խմբագրելու համար։",
        "mycustomjsprotected": "Դուք բավարար իրավունքներ չունեք այս JavaScript էջը խմբագրելու համար։",
+       "myprivateinfoprotected": "Դուք իրավասու չեք խմբագրել Ձեր անձնական տեղեկությունը:",
        "mypreferencesprotected": "Դուք բավարար իրավունքներ չունեք Ձեր նախընտրությունները խմբագրելու համար։",
        "ns-specialprotected": "«{{ns:special}}» անվանատարածքի էջերը չեն կարող խմբագրվել։",
        "titleprotected": "Այս անվանմամբ էջի ստեղծումը արգելվել է [[User:$1|$1]] մասնակցի կողմից։\nՏրված պատճառն է՝ <em>$2</em>։",
        "virus-scanfailed": "զննման սխալ (կոդ $1)",
        "virus-unknownscanner": "անծանոթ հակավիրուս՝",
        "logouttext": "<strong>Դուք դուրս եկաք համակարգից։</strong>\n\nԻ նկատի ունեցեք, որ որոշ էջեր կարող են ցուցադրվել այնպես՝ ինչպես եթե դեռ համակարգում լինեիք մինչև որ չջնջեք ձեր զննարկիչի հիշապահեստը։",
+       "cannotlogoutnow-title": "Այժմ դուրս գալ անհնար է",
+       "cannotlogoutnow-text": "$1 օգտագործելիս դուրս գալն անհնար է:",
        "welcomeuser": "Բարի գալո՜ւստ, $1",
        "welcomecreation-msg": "Ձեր հաշիվն ստեղծված է։\nՉմոռանաք փոփոխել ձեր [[Special:Preferences|նախընտրությունները]]։",
        "yourname": "Մասնակցի անուն՝",
        "remembermypassword": "Հիշել իմ մուտքը այս դիտարկչում ($1 {{PLURAL:$1|օրից}} ոչ ավել ժամկետով)",
        "userlogin-remembermypassword": "Մուտք գործած մնալ",
        "userlogin-signwithsecure": "Օգտագործել անվտանգ միացում",
+       "cannotloginnow-title": "Այժմ դուրս գալ անհնար է",
+       "cannotloginnow-text": "$1 օգտագործելիս դուրս գալն անհնար է:",
        "yourdomainname": "Ձեր դոմենը՝",
        "password-change-forbidden": "Այս վիքիում չեք կարող փոխել գաղտնաբառ։",
        "externaldberror": "Տեղի է ունեցել վավերացման արտաքին տվյալների բազայի սխալ, կամ դուք չունեք բավարար իրավունքներ ձեր արտաքին հաշվի փոփոխման համար։",
        "wrongpassword": "Մուտքագրված գաղտնաբառը սխալ էր։ Խնդրում ենք կրկին փորձել։",
        "wrongpasswordempty": "Մուտքագրված գաղտնաբառը դատարկ էր։ Խնդրում ենք կրկին փորձել։",
        "passwordtooshort": "Գաղտնաբառը պետք է պարունակի առնվազն {{PLURAL:$1|1 սիմվոլ|$1 սիմվոլ}}։",
+       "passwordtoolong": "Ծածկագիրը չի կարող գերազանցել {{PLURAL:$1|1 նիշը|$1 նիշը}}:",
        "password-name-match": "Գաղտնաբառը պետք է տարբեր լինել ձեր մասնակցի անունից։",
        "password-login-forbidden": "Այս ծածկանվան և գաղտնաբառի օգտագործումն արգելված է",
        "mailmypassword": "Փոխել գաղտնաբառը",
        "noemailprefs": "Այս հնարավորության գործածման համար անհրաժեշտ է նշել էլ-փոստի հասցե։",
        "emailconfirmlink": "Վավերացնել ձեր էլ-փոստի հասցեն",
        "invalidemailaddress": "Նշված էլ-փոստի հասցեն անընդունելի է, քանի որ այն ունի անթույլատրելի ֆորմատ։ Խնդրում ենք նշել ճշմարիտ հասցե կամ այս դաշտը թողնել դատարկ։",
+       "cannotchangeemail": "Այս վիքիում մասնակցային հաշվի էլ.փոստի փոփոխությունն անհնար է:",
        "emaildisabled": "Այս կայքը չի կարող ուղարկել էլ․ նամակներ։",
        "accountcreated": "Հաշիվը ստեղծված է",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|քննարկում]]) մասնակցի հաշիվը ստեղծված է։",
        "createaccount-title": "{{SITENAME}}. մասնակցային հաշվի ստեղծում",
        "createaccount-text": "Ինչ-որ մեկը ստեղծել է «$2» անվանմամբ մասնակցային հաշիվ «$3» գաղտնաբառով {{SITENAME}} ($4) նախագծում՝ նշելով ձեր էլ-հասցեն։ Ձեզ անհրաժեշտ է մտնել համակարգ և փոխել գաղտնաբառը։\n\nԿարող եք անտեսել այս հաղորդագրությունը, եթե հաշիվը ստեղծվել է սխալմամբ։",
        "login-throttled": "Դուք կատարել եք չափից շատ մուտքի փորձ։\nԽնդրում ենք սպասել $1 կրկին փորձելուց առաջ։",
+       "login-abort-generic": "Մուտք գործելը ձախողվեց: Մերժված է:",
+       "login-migrated-generic": "Ձեր մասնակցային հաշիվը տեղափոխվել է, և Ձեր մասնակցային անունն այլևս գոյություն չունի այս վիքիում:",
        "loginlanguagelabel": "Լեզու՝ $1",
        "pt-login": "Մուտք գործել",
        "pt-login-button": "Մտնել",
        "newpassword": "Նոր գաղտնաբառը.",
        "retypenew": "Հաստատեք նոր գաղտնաբառը.",
        "resetpass_submit": "Հաստատել գաղտնաբառը և մտնել համակարգ",
-       "changepassword-success": "Ձեր գաղտնաբառը հաջողությամբ փոխված է։",
+       "changepassword-success": "Ձեր գաղտնաբառը փոփոխվեց։",
+       "botpasswords": "Բոտերի ծածկագրեր",
+       "botpasswords-disabled": "Բոտերի ծածկագրերն անջատված են:",
+       "botpasswords-existing": "Գոյություն ունեցող բոտային ծածկագրերը",
+       "botpasswords-createnew": "Ստեղծել նոր բոտային ծածկագիր",
+       "botpasswords-editexisting": "Խմբագրել առկա բոտային ծածկագիրը",
+       "botpasswords-label-appid": "Բոտի անուն՝",
+       "botpasswords-label-create": "Ստեղծել",
+       "botpasswords-label-update": "Թարմացնել",
+       "botpasswords-label-cancel": "Չեղարկել",
+       "botpasswords-label-delete": "Ջնջել",
+       "botpasswords-label-resetpassword": "Վերականգնել ծածկագիրը",
+       "botpasswords-label-restrictions": "Օգտագործման սահմանափակումներ:",
+       "botpasswords-label-grants-column": "Թույլատրված է",
+       "botpasswords-bad-appid": "\"$1\" բոտի անունն անթույլատրելի է:",
+       "botpasswords-created-title": "Բոտի ծածկագիրը ստեղծվել է",
+       "botpasswords-created-body": "$2 մասնակցի $1 բոտի համար բոտի ծածկագիրը ստեղծվել է:",
+       "botpasswords-updated-title": "Բոտի ծածկագիրը թարմացվել է",
+       "botpasswords-updated-body": "$2 մասնակցի $1 բոտի համար բոտի ծածկագիրը ստեղծվել է:",
+       "botpasswords-deleted-title": "Բոտի ծածկագիրը ջնջված է",
+       "botpasswords-deleted-body": "$2 մասնակցի $1 բոտի համար բոտի ծածկագիրը ջնջվել է:",
        "resetpass_forbidden": "Գաղտնաբառը չի կարող փոխվել",
        "resetpass-no-info": "Այս էջին ուղիղ դիմելու համար անհրաժեշտ է մտնել համակարգ։",
        "resetpass-submit-loggedin": "Փոխել գաղտնաբառը",
        "upload-form-label-infoform-title": "Մանրամասներ",
        "upload-form-label-infoform-name": "Անուն",
        "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": "Ամսաթիվ",
+       "upload-form-label-own-work": "Սա իմ անձնական աշխատանքն է",
+       "upload-form-label-infoform-categories": "Կատեգորիաներ",
+       "upload-form-label-infoform-date": "Ամսաթիվ",
        "upload-curl-error6": "URL-հասցեն անհասանելի է",
        "upload-curl-error6-text": "Նշված URL-հասցեն անհասանելի է։ Խնդրում ենք ստուգել հասցեի ճշգրտությունը և կայքի գործունությունը։",
        "upload-curl-error28": "Բեռնման ժամհատնում",
index ebba631..0f60d82 100644 (file)
        "upload-form-label-infoform-description-tooltip": "Describe brevemente tote le aspectos notabile de iste obra. Pro un photo, mentiona le cosas principal que es representate, le occasion o le loco.",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nomine del file",
-       "foreign-structured-upload-form-label-own-work": "Iste es mi proprie obra",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorias",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Io confirma que io incarga iste file secundo le conditiones de servicio e politicas de licentia de {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Si tu non pote incargar iste file in concordantia con le politicas de {{SITENAME}}, per favor claude iste dialogo e essaya un altere methodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Tu pote etiam essayar [[Special:Upload|le pagina de incargamento normal]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Io comprende que io incarga iste file in un repositorio commun. Io confirma que io lo face secundo le conditiones de servicio e politicas de licentia de illo.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Si tu non pote incargar iste file in concordantia con le politicas del repositorio commun, per favor claude iste dialogo e essaya un altere methodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Tu pote anque probar [[Special:Upload|le pagina de incargamento in {{SITENAME}}]], si le politicas de ille sito permitte incargar iste file.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Io certifica que io possede le derecto de autor sur iste file, io consenti le publication irrevocabile de iste file a Wikimedia Commons sub le licentia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], e io accepta le [https://wikimediafoundation.org/wiki/Terms_of_Use conditiones de uso].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Si tu non possede le derecto de autor sur iste file, o si tu prefere publicar lo sub un altere licentia, considera usar le [https://commons.wikimedia.org/wiki/Special:UploadWizard assistente de incargamento de Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Tu pote anque probar [[Special:Upload|le pagina de incargamento in {{SITENAME}}]], si le politicas de ille sito permitte incargar iste file.",
+       "upload-form-label-own-work": "Iste es mi proprie obra",
+       "upload-form-label-infoform-categories": "Categorias",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Io confirma que io incarga iste file secundo le conditiones de servicio e politicas de licentia de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Si tu non pote incargar iste file in concordantia con le politicas de {{SITENAME}}, per favor claude iste dialogo e essaya un altere methodo.",
+       "upload-form-label-not-own-work-local-local": "Tu pote etiam essayar [[Special:Upload|le pagina de incargamento normal]].",
+       "upload-form-label-own-work-message-default": "Io comprende que io incarga iste file in un repositorio commun. Io confirma que io lo face secundo le conditiones de servicio e politicas de licentia de illo.",
+       "upload-form-label-not-own-work-message-default": "Si tu non pote incargar iste file in concordantia con le politicas del repositorio commun, per favor claude iste dialogo e essaya un altere methodo.",
+       "upload-form-label-not-own-work-local-default": "Tu pote anque probar [[Special:Upload|le pagina de incargamento in {{SITENAME}}]], si le politicas de ille sito permitte incargar iste file.",
+       "upload-form-label-own-work-message-shared": "Io certifica que io possede le derecto de autor sur iste file, io consenti le publication irrevocabile de iste file a Wikimedia Commons sub le licentia [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], e io accepta le [https://wikimediafoundation.org/wiki/Terms_of_Use conditiones de uso].",
+       "upload-form-label-not-own-work-message-shared": "Si tu non possede le derecto de autor sur iste file, o si tu prefere publicar lo sub un altere licentia, considera usar le [https://commons.wikimedia.org/wiki/Special:UploadWizard assistente de incargamento de Commons].",
+       "upload-form-label-not-own-work-local-shared": "Tu pote anque probar [[Special:Upload|le pagina de incargamento in {{SITENAME}}]], si le politicas de ille sito permitte incargar iste file.",
        "backend-fail-stream": "Non poteva transmitter le file $1.",
        "backend-fail-backup": "Non poteva facer un copia de reserva del file $1.",
        "backend-fail-notexists": "Le file $1 non existe.",
index e19b63b..8b0af46 100644 (file)
@@ -63,6 +63,7 @@
        "tog-watchdefault": "Tambahkan halaman yang saya sunting ke daftar pantauan",
        "tog-watchmoves": "Tambahkan halaman yang saya pindahkan ke daftar pantauan",
        "tog-watchdeletion": "Tambahkan halaman yang saya hapus ke daftar pantauan",
+       "tog-watchuploads": "Tambahkan berkas baru yang saya unggah ke daftar pantauan",
        "tog-watchrollback": "Tambahkan halaman yang pernah saya kembalikan ke dalam daftar pantauan saya",
        "tog-minordefault": "Tandai semua suntingan sebagai suntingan kecil secara baku",
        "tog-previewontop": "Perlihatkan pratayang sebelum kotak sunting dan tidak sesudahnya",
        "databaseerror-query": "Kueri: $1",
        "databaseerror-function": "Fungsi: $1",
        "databaseerror-error": "Kesalahan: $1",
+       "transaction-duration-limit-exceeded": "Untuk mencegah penundaan replikasi yang tinggi, pengiriman ini dibatalkan karena durasi tulis ($1) melebihi batas $2 {{PLURAL:$2|detik|detik}}.\nJika Anda ingin mengganti banyak butir sekaligus, cobalah melakukan dalam operasi yang lebih kecil.",
        "laggedslavemode": "Peringatan: Halaman mungkin tidak berisi perubahan terbaru.",
        "readonly": "Basis data dikunci",
        "enterlockreason": "Masukkan alasan penguncian, termasuk perkiraan kapan kunci akan dibuka",
        "noemail": "Tidak ada alamat surel yang tercatat untuk pengguna \"$1\".",
        "noemailcreate": "Anda perlu menyediakan alamat surel yang sah",
        "passwordsent": "Kata sandi baru telah dikirimkan ke alamat surel yang didaftarkan untuk \"$1\".\nSilakan masuk log kembali setelah menerima surel tersebut.",
-       "blocked-mailpassword": "Alamat IP Anda diblokir dari penyuntingan sehingga tidak diizinkan menggunakan fungsi pengingat kata sandi untuk mencegah penyalahgunaan.",
+       "blocked-mailpassword": "Alamat IP Anda diblokir dari penyuntingan. Untuk mencegah penyalahgunaan, Anda tidak diperkenankan untuk memulihkan kata sandi Anda melalui alamat IP ini.",
        "eauthentsent": "Sebuah surel untuk konfirmasi telah dikirim ke alamat surel. Sebelum surel lainnya dikirim ke akun tersebut, Anda harus mengikuti instruksi di dalam surel tersebut, untuk melakukan konfirmasi bahwa alamat tersebut adalah benar kepunyaan Anda.",
        "throttled-mailpassword": "Suatu pengingat kata sandi telah dikirimkan dalam {{PLURAL:$1|$1 jam}} terakhir.\nUntuk menghindari penyalahgunaan, hanya satu kata sandi yang akan dikirimkan setiap {{PLURAL:$1|$1 jam}}.",
        "mailerror": "Kesalahan dalam mengirimkan surel: $1",
        "createaccount-title": "Pembuatan akun untuk {{SITENAME}}",
        "createaccount-text": "Seseorang telah membuat sebuah akun untuk alamat surel Anda di {{SITENAME}} ($4) dengan nama \"$2\" dan kata sandi \"$3\". Anda dianjurkan untuk masuk log dan mengganti kata sandi Anda sekarang.\n\nAnda dapat mengabaikan pesan ini jika akun ini dibuat karena suatu kesalahan.",
        "login-throttled": "Anda sudah terlalu sering mencoba masuk log.\nSilakan menunggu $1 sebelum mencoba lagi.",
-       "login-abort-generic": "Proses masuk Anda tidak berhasil - Dibatalkan",
+       "login-abort-generic": "Proses masuk log Anda tidak berhasil - Dibatalkan",
        "login-migrated-generic": "Akun Anda telah dimigrasi, dan nama pengguna Anda tidak lagi terdaftar di wiki ini.",
        "loginlanguagelabel": "Bahasa: $1",
        "suspicious-userlogout": "Permintaan Anda untuk keluar log ditolak karena tampaknya dikirim oleh penjelajah yang rusak atau proksi penyinggah.",
        "newpassword": "Kata sandi baru:",
        "retypenew": "Ketik ulang kata sandi baru:",
        "resetpass_submit": "Atur kata sandi dan masuk log",
-       "changepassword-success": "Kata sandi Anda telah berhasil diubah!",
+       "changepassword-success": "Kata sandi Anda telah diubah!",
        "changepassword-throttled": "Anda terlalu sering mencoba masuk log.\nMohon tunggu $1 sebelum mencoba lagi.",
        "botpasswords": "Kata sandi bot",
        "botpasswords-disabled": "Kata sandi bot dinonaktifkan.",
        "uploaded-script-svg": "Terdapat elemen terskrip \"$1\" dalam berkas SVG yang diunggah.",
        "uploaded-hostile-svg": "Terdapat CSS yang tidak aman dalam elemen gaya berkas SVG yang diunggah.",
        "uploaded-event-handler-on-svg": "Penetapan atribut <i>event-handler</i> $1=\"$2\" tidak diizinkan dalam berkas SVG.",
+       "uploaded-setting-event-handler-svg": "Penyetelan atribut event-handler diblokir, menemukan <code>&lt;$1 $2=\"$3\"&gt;</code> dalam berkas SVG yang diunggah.",
        "uploadscriptednamespace": "Berkas SVG ini memuat ruang nama ilegal \"$1\"",
        "uploadinvalidxml": "XML dalam berkas yang diunggah tidak bisa diuraikan.",
        "uploadvirus": "Berkas tersebut mengandung virus! Rincian: $1",
        "upload-form-label-infoform-description-tooltip": "Jelaskan dengan singkat hal-hal penting tentang karya ini.\nUntuk foto, sebutkan hal-hal utama yang ditampilkan, kesempatan atau tempat yang ditampilkan di foto.",
        "upload-form-label-usage-title": "Penggunaan",
        "upload-form-label-usage-filename": "Nama berkas",
-       "foreign-structured-upload-form-label-own-work": "Ini adalah karya saya sendiri",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategori",
-       "foreign-structured-upload-form-label-infoform-date": "Tanggal",
+       "upload-form-label-own-work": "Ini adalah karya saya sendiri",
+       "upload-form-label-infoform-categories": "Kategori",
+       "upload-form-label-infoform-date": "Tanggal",
        "backend-fail-stream": "Tidak bisa mengalikan berkas $1.",
        "backend-fail-backup": "Tidak dapat mencadangkan berkas $1.",
        "backend-fail-notexists": "Berkas $1 tidak ada.",
        "mw-widgets-dateinput-placeholder-day": "TTTT-BB-HH",
        "mw-widgets-dateinput-placeholder-month": "TTTT-BB",
        "api-error-blacklisted": "Pilih judul lain yang deskriptif",
-       "randomrootpage": "Halaman dasar sembarang"
+       "randomrootpage": "Halaman dasar sembarang",
+       "log-action-filter-block": "Jenis pemblokiran:",
+       "log-action-filter-block-block": "Blokir",
+       "log-action-filter-suppress-block": "Perahasiaan pengguna menurut pemblokiran"
 }
index e54d6cf..e88379c 100644 (file)
        "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",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Mabalinmo pay a padasen [[Special:Upload|ti kasisigud a pagikargaan a panid]].",
+       "upload-form-label-own-work": "Daytoy ket bukodko nga obra",
+       "upload-form-label-infoform-categories": "Katkategoria",
+       "upload-form-label-infoform-date": "Petsa",
+       "upload-form-label-not-own-work-local-local": "Mabalinmo pay a padasen [[Special:Upload|ti kasisigud a pagikargaan a panid]].",
        "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.",
index 5e2b5fa..ac588bf 100644 (file)
                        "Adam-Yourist"
                ]
        },
-       "tog-underline": "Ð¥Ñ\8cожадеÑ\80га |ок|алÑ\82акадар:",
-       "tog-hideminor": "Ð¥Ñ\8cаÑ\82|аÑ\8fздаÑ\80а Ñ\87Ñ\83 ÐºÐµÑ\80даÑ\87а Ñ\85Ñ\83вÑ\86амаÑ\88a Ð·|амига Ð´Ð¾Ð»Ð° Ñ\85Ñ\83вÑ\86амаÑ\88 ÐºÑ\8aайладаккÑ\85а",
-       "tog-hidepatrolled": "Ð¥Ñ\8cаÑ\82|аÑ\8fздаÑ\80а Ñ\87Ñ\83 ÐºÐµÑ\80даÑ\87а Ñ\85Ñ\83вÑ\86амаÑ\88a Ð´|анийÑ\81адаÑ\8c Ð´Ð¾Ð»Ð° Ñ\85Ñ\83вÑ\86амаÑ\88 ÐºÑ\8aайладаккÑ\85а",
-       "tog-newpageshidepatrolled": "Ð¥Ñ\8cаÑ\82|аÑ\8fздаÑ\80а Ñ\87Ñ\83 ÐºÐµÑ\80даÑ\87а Ñ\85Ñ\83вÑ\86амаÑ\88a Ñ\85Ñ\8cанийÑ\81адаÑ\8c Ð´Ð¾Ð»Ð° Ð¾Ð°Ð³|онаÑ\88 ÐºÑ\8aайлаÑ\8fккÑ\85а",
-       "tog-hidecategorization": "Къайлаяккха оагӀонай категореш",
-       "tog-extendwatchlist": "ШеÑ\80адаÑ\8c Ñ\82еÑ\80кама Ñ\85Ñ\8cаÑ\82|аÑ\8fздаÑ\80, Ð¼Ð°Ñ\81Ñ\81адола Ñ\85Ñ\83вÑ\86амаÑ\88 Ñ\87Ñ\83лоаÑ\86аÑ\88 Ð´Ð¾Ð»Ð°, Ð°Ð»Ñ\85Ñ\85а Ñ\82|еÑ\85Ñ\8cаÑ\80а Ð´Ð°Ñ\8cÑ\80аÑ\88 Ð¼Ð°Ñ\80а Ð° Ð´Ð¾Ð°Ñ\86аÑ\88",
+       "tog-underline": "ТIаÑ\85Ñ\8cожаÑ\8fÑ\80га ÐºIала Ñ\82ака Ñ\85Ñ\8cакÑ\85ар:",
+       "tog-hideminor": "Ð\9aÑ\8aайладаккÑ\85а Ð·|амига Ð´Ð¾Ð»Ð° Ñ\85Ñ\83вÑ\86амаÑ\88 ÐºÐµÑ\80да Ñ\85Ñ\83вÑ\86амаÑ\88Ñ\82а Ñ\8eкÑ\8aеÑ\80а",
+       "tog-hidepatrolled": "Ð\9aÑ\8aайладаккÑ\85а Ñ\85а Ð´ÐµÑ\80а Ñ\87акÑ\85даÑ\8cнна Ð´Ð¾Ð»Ð° Ñ\85Ñ\83вÑ\86амаÑ\88 ÐºÐµÑ\80да Ñ\85Ñ\83вÑ\86амаÑ\88Ñ\82а Ñ\8eкÑ\8aеÑ\80а",
+       "tog-newpageshidepatrolled": "Ð\9aÑ\8aайлаÑ\8fÑ\8cккÑ\85а Ñ\85а Ð´ÐµÑ\80а Ñ\87акÑ\85Ñ\8aÑ\8fнна Ð¹Ð¾Ð»Ð° Ð¾Ð°Ð³IонаÑ\88 ÐºÐµÑ\80да Ð¾Ð°Ð³IонаÑ\88Ñ\82а Ñ\8eкÑ\8aеÑ\80а",
+       "tog-hidecategorization": "Къайлаяха оагӀонай категореш",
+       "tog-extendwatchlist": "Ð¥Ñ\8cаÑ\88еÑ\80Ñ\8aÑ\8fÑ\8c Ð¹Ð¾Ð»Ð° Ð·ÐµÐ¼ Ð±Ð°Ñ\80а Ñ\81пиÑ\81ок, Ð¼Ð°Ñ\81Ñ\81адола Ñ\85Ñ\83вÑ\86амаÑ\88 Ñ\88е Ñ\87Ñ\83лоаÑ\86аÑ\88, Ñ\82|еÑ\85Ñ\8cаÑ\80а Ð´Ð°Ñ\8c Ñ\85Ñ\83вÑ\86амаÑ\88 Ñ\85инна Ñ\86а IеÑ\88.",
        "tog-usenewrc": "Керда хувцамашка а хьат|аяздара зембаккхарга а эргадаккхараш тоабаде (JavaScript эша)",
        "tog-numberheadings": "Керташкашта аланза таьрахьа хотта",
        "tog-showtoolbar": "Г|алатнийcдара г|ирсагартакх хьахьокха (JavaScript)",
@@ -66,7 +66,7 @@
        "thursday": "ера",
        "friday": "пӀаьраска",
        "saturday": "шоатта",
-       "sun": "К|и",
+       "sun": "КIиранди",
        "mon": "Ор",
        "tue": "Шин",
        "wed": "Кха",
        "april": "Тушоли бутт",
        "may_long": "Села бутт",
        "june": "Этинга бутт",
-       "july": "Баьцамеа\\Меа бутт",
+       "july": "Баьцамеа бутт",
        "august": "Мяцхали бутт",
        "september": "Тов\\Михий бутт",
        "october": "Ардарий\\АьрхIий бутт",
        "november": "Лай чилла бутт",
        "december": "Чан-тар бутт",
-       "january-gen": "Ð\9dажгамÑ\81Ñ\85ой бетт",
+       "january-gen": "Ð\90гIой бетт",
        "february-gen": "Саь-кур бетт",
        "march-gen": "Муттхьол бетт",
        "april-gen": "Тушоли бетт",
        "may-gen": "Села бетт",
        "june-gen": "Этинга бетт",
-       "july-gen": "Баьцамеа\\Меа бетт",
+       "july-gen": "Баьцамеа бетт",
        "august-gen": "Мецхали бетт",
        "september-gen": "Тов\\Михий бетт",
        "october-gen": "Ардарий\\АьрхIий бетт",
        "oct": "Ардарий\\АьрхIий",
        "nov": "Лай чилла",
        "dec": "Чан-тар",
-       "january-date": "Ð\9dажгамÑ\81Ñ\85ой $1",
+       "january-date": "Ð\90гIой Ð±Ñ\83Ñ\82Ñ\82 $1",
        "february-date": "Саь-кур бутт $1",
        "march-date": "Муттхьол $1",
        "april-date": "Тушоли $1",
        "period-am": "ДЦ",
        "period-pm": "ДТ",
        "pagecategories": "{{PLURAL:$1|1=Категори|Категореш}}",
-       "category_header": "\"$1\" Катага чура оаг|онаш",
+       "category_header": "«$1» категори чура оагIонаш",
        "subcategories": "Чуракатагаш",
        "category-media-header": "\"$1\" Категори чура файлаш",
-       "category-empty": "''УкÑ\85 ÐºÐ°Ñ\82ага Ñ\87Ñ\83 Ñ\86Ñ\85Ñ\8cаккÑ\85а Ð¾Ð°Ð³|онаÑ\88 Ðµ Ð¿Ð°Ñ\8cлаÑ\88 Ñ\8fÑ\86.''",
+       "category-empty": "''Ð\95Ñ\80 ÐºÐ°Ñ\82егоÑ\80и Ñ\85Ó\80анза Ñ\8fÑ\8cÑ\81Ñ\81а Ñ\8f (Ñ\86Ñ\85Ñ\8cаккÑ\85а Ð¾Ð°Ð³IонаÑ\88 Ðµ Ñ\84айлаÑ\88 Ð¹Ð¾Ð°Ñ\86аÑ\88).''",
        "hidden-categories": "{{PLURAL:$1|1=Къайла категори|Къайла категореш}}",
-       "hidden-category-category": "Ð\9aÑ\8aайла ÐºÐ°Ñ\82агаш",
-       "category-subcat-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82агa Ñ\82|еÑ\85Ñ\8cаÑ\80а Ð±Ñ\83Ñ\85каÑ\82аг Ñ\87Ñ\83лоаÑ\86.|{{PLURAL:$1|1=$1 Ð±Ñ\83Ñ\85каÑ\82аг Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f|$1 Ð±Ñ\83Ñ\85каÑ\82агаÑ\88 Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f}} $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80ex.}}",
-       "category-subcat-count-limited": "УкÑ\85 ÐºÐ°Ñ\82агa Ñ\87Ñ\83 {{PLURAL:$1|1=$1 Ðº|алкаÑ\82аг|$1 Ðº|алкаÑ\82агаÑ\88}}.",
-       "category-article-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82ага Ñ\86Ñ\85Ñ\8cа Ð¾Ð°Ð³|Ñ\83в Ð¼Ð°Ñ\80а Ñ\87Ñ\83лоаÑ\86аÑ\86.|{{PLURAL:$1|1=$1 Ð¾Ð°Ð³|Ñ\83в Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f|$1 Ð¾Ð°Ð³|oнаÑ\88 Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f}} Ñ\83кÑ\85 ÐºÐ°Ñ\82ага $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80\85.}}",
-       "category-article-count-limited": "УкÑ\85 ÐºÐ°Ñ\82ага Ñ\87Ñ\83 {{PLURAL:$1|1=$1 Ð¾Ð°Ð³|Ñ\83в|$1 Ð¾Ð°Ð³|oнаÑ\88}}.",
+       "hidden-category-category": "Ð\9aÑ\8aайла ÐºÐ°Ñ\82егоÑ\80еш",
+       "category-subcat-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 Ñ\8f Ñ\83кÑ\85ан ÐºIалÑ\85аÑ\80а ÐºÐ°Ñ\82егоÑ\80и.|УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 Ñ\8f $1 {{PLURAL:$1|кIалÑ\85аÑ\80а ÐºÐ°Ñ\82егоÑ\80и|кIалÑ\85аÑ\80а ÐºÐ°Ñ\82егоÑ\80еÑ\88}} $2 Ð¼Ð°Ñ\81Ñ\81айолÑ\87аÑ\80еÑ\85.}}",
+       "category-subcat-count-limited": "УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 {{PLURAL:$1|кIалÑ\85аÑ\80а ÐºÐ°Ñ\82егоÑ\80и|$1 ÐºIалÑ\85аÑ\80а ÐºÐ°Ñ\82егоÑ\80еÑ\88}} Ñ\8f.",
+       "category-article-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 Ñ\86аI Ð¼Ð°Ñ\80а Ð¾Ð°Ð³IÑ\83в Ñ\8fÑ\86.|УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 Ñ\8f $2 Ð¾Ð°Ð³Ó\80Ñ\83в, Ñ\86аÑ\80еÑ\85 Ð¾Ð°Ð³Ó\80онгаÑ\85Ñ\8c {{PLURAL:$1|Ñ\85Ñ\8cагойÑ\82а $1 Ð¾Ð°Ð³Ó\80Ñ\83в}}}}",
+       "category-article-count-limited": "УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 {{PLURAL:$1|$1 Ð¾Ð°Ð³Ó\80Ñ\83в Ñ\8f|1=Ñ\86аI Ð¾Ð°Ð³Ó\80Ñ\83в Ð¼Ð°Ñ\80а Ñ\8fÑ\86}}.",
        "category-file-count": "{{PLURAL:$2|Укх катагори чу цаI мара файл яц.|{{PLURAL:$1|1=$1 файл хьахьокхаш я|$1 файл хьахьокхаш я}} укх категори $2 долачарeх.}}",
-       "category-file-count-limited": "УкÑ\85 ÐºÐ°Ñ\82ага Ñ\87Ñ\83 {{PLURAL:$1|1=$1 Ð»Ñ\83Ñ\80даÑ\80|$1 Ð»Ñ\83Ñ\80даÑ\80аÑ\88}}.",
-       "listingcontinuesabbrev": "д|ахо",
-       "index-category": "Ð\94|аÑ\85Ñ\8cожама Ð¾Ð°Ð³|онаш",
-       "noindex-category": "Ð\94|аÑ\85Ñ\8cожаманза Ð¾Ð°Ð³|онаш",
-       "broken-file-category": "Ð\9fаÑ\8cла Ñ\85Ñ\8cожадеÑ\80гаÑ\88Ñ\86а Ð±Ð¾Ð»Ñ\85беÑ\88 Ð¹Ð¾Ð°Ñ\86а Ð¾Ð°Ð³|онаш",
-       "about": "Ð\9bоаÑ\86ам",
+       "category-file-count-limited": "УкÑ\85 ÐºÐ°Ñ\82егоÑ\80и Ñ\87Ñ\83 {{PLURAL:$1|$1 Ñ\84айл|$1 Ñ\84айлаÑ\88|1=Ñ\86аI Ð¼Ð°Ñ\80а Ñ\84айл Ñ\8fÑ\86}}.",
+       "listingcontinuesabbrev": "(дIахо)",
+       "index-category": "Ð\98ндекÑ\81 Ð¾Ñ\82Ñ\82аеÑ\88 Ð¾Ð°Ð³Iонаш",
+       "noindex-category": "Ð\98ндекÑ\81 Ñ\86а Ð¾Ñ\82Ñ\82аеÑ\88 Ð¾Ð°Ð³Iонаш",
+       "broken-file-category": "Файла Ñ\82IаÑ\85Ñ\8cожаÑ\8fÑ\80гаÑ\88 Ð±Ð¾Ð»Ñ\85беÑ\88 Ð¹Ð¾Ð°Ñ\86а Ð¾Ð°Ð³Iонаш",
+       "about": "СÑ\83Ñ\80Ñ\82 Ð¾Ñ\82Ñ\82адаÑ\80",
        "article": "Йоазув",
-       "newwindow": "(кердача коре)",
+       "newwindow": "&nbsp;(керда кора чу)",
        "cancel": "Эшац",
-       "moredotdotdot": "Д|ахо",
-       "morenotlisted": "Ер |ояздар хьалдиззанз да.",
-       "mypage": "Oаг|ув",
-       "mytalk": "Дувцам",
-       "anontalk": "Дувцар",
+       "moredotdotdot": "ДIахо...",
+       "morenotlisted": "Ер список хьалйиза яц.",
+       "mypage": "ОагIув",
+       "mytalk": "Дувца оттадар",
+       "anontalk": "Дувца оттадар",
        "navigation": "Навигаци",
        "and": "&#32;а",
        "qbfind": "Лахар",
-       "qbbrowse": "Б|аргтасса",
-       "qbedit": "Ð¥Ñ\83вÑ\86а",
-       "qbpageoptions": "Оаг|он оттамаш",
+       "qbbrowse": "БIаргтохар",
+       "qbedit": "Ð\9dиÑ\81Ñ\8aе",
+       "qbpageoptions": "ОагIон оттамаш",
        "qbmyoptions": "Са оттамаш",
        "faq": "КТХ",
        "faqpage": "Project:КТХ",
-       "actions": "Ð¥|амдаÑ\80аш",
+       "actions": "Ð\90Ñ\80дамаш",
        "namespaces": "ЦIерий мотташ",
-       "variants": "Ð\9aеÌ\81паш",
+       "variants": "Ð\92аÑ\80ианÑ\82аш",
        "navigation-heading": "Навигацен меню",
-       "errorpagetitle": "Г|алат",
-       "returnto": "цу $1 оаг|он т|а юхаг|о",
+       "errorpagetitle": "ГӀалат",
+       "returnto": "Укх $1 оагIона тIа юхагӀо.",
        "tagline": "Кечал укхазара: {{grammar:genitive|{{SITENAME}}}}",
-       "help": "Ð\93Ó\80о",
+       "help": "Ð\9dовкÑ\8a\81Ñ\82ал",
        "search": "Лахаp",
        "searchbutton": "Хьалáха",
-       "go": "Дехьа г|о",
+       "go": "Дехьавала",
        "searcharticle": "Дехьавала",
        "history": "Истори",
        "history_short": "Истори",
-       "updatedmarker": "Со Ñ\85анаÑ\87а Ð´ÐµÐ½Ñ\86а Ñ\85Ñ\83вÑ\86амаÑ\88 Ñ\85иннaд",
+       "updatedmarker": "Со Ñ\82IеÑ\85Ñ\85Ñ\8cаÑ\80а Ñ\83кÑ\85аз Ñ\85иннаÑ\87Ñ\83л Ñ\82IеÑ\85Ñ\8cагIа ÐºÐµÑ\80дадаÑ\8cккÑ\85ад",
        "printableversion": "Зарба тохара верси",
-       "permalink": "Даиман латташ йола хьожаярг",
-       "print": "Ð\9aепаÑ\82оÑ\85аÑ\80",
+       "permalink": "Ð\94аиман Ð»Ð°Ñ\82Ñ\82аÑ\88 Ð¹Ð¾Ð»Ð° Ñ\82IаÑ\85Ñ\8cожаÑ\8fÑ\80г",
+       "print": "Ð\97аÑ\80ба Ñ\82оÑ\85а",
        "view": "Хьажар",
-       "view-foreign": "Ð\9cазаоаг|он Ñ\87Ñ\83 $1 хьажа",
+       "view-foreign": "УкÑ\85 $1 Ñ\81айÑ\82а Ñ\87Ñ\83 хьажа",
        "edit": "Нийсде",
        "edit-local": "Хувца локальни йоазонца сурт оттадар",
-       "create": "Ð¥Ñ\8cаде",
+       "create": "Ð¥Ñ\8cакÑ\85олла",
        "create-local": "ТIатоха локальни йоазонца сурт оттадар",
-       "editthispage": "Ð\95Ñ\80 Ð¾Ð°Ð³|Ñ\83в Ñ\85Ñ\83вÑ\86а",
-       "create-this-page": "Ep oаг|ув хьае",
-       "delete": "Д|аяккха",
-       "deletethispage": "Ð\95Ñ\80 Ð¾Ð°Ð³|Ñ\83в Ð´|аÑ\8fÑ\8cккÑ\85а",
-       "undeletethispage": "Ð\95Ñ\80 Ð¾Ð°Ð³|Ñ\83в Ð´|аÑ\8fккÑ\85анз Ð¹Ð¸Ñ\82а",
-       "undelete_short": "Ð\9cеÑ\82Ñ\82аоÑ\82Ñ\82ае {{PLURAL:$1|1=Ñ\85Ñ\83вÑ\86ам|$1 Ñ\85Ñ\83вÑ\86амаÑ\88}}",
-       "viewdeleted_short": "Б|аргтасса {{PLURAL:$1|1=д|адаьккха хувцам|$1 д|адаьккха хувцамаш}}",
-       "protect": "Ð\9bоÑ\80аде",
+       "editthispage": "Ð\9dийÑ\81Ñ\8aе ÐµÑ\80 Ð¾Ð°Ð³IÑ\83в",
+       "create-this-page": "Хьакхолла ер оагӀув",
+       "delete": "ДӀаяккха",
+       "deletethispage": "Ð\94Ó\80аÑ\8fккÑ\85а ÐµÑ\80 Ð¾Ð°Ð³Ó\80Ñ\83в",
+       "undeletethispage": "ЮÑ\85амеÑ\82Ñ\82аоÑ\82Ñ\82ае ÐµÑ\80 Ð¾Ð°Ð³Ó\80Ñ\83в",
+       "undelete_short": "ЮÑ\85амеÑ\82Ñ\82аоÑ\82Ñ\82ае {{PLURAL:$1|$1 Ð½Ð¸Ð¹Ñ\81даÑ\80|$1 Ð½Ð¸Ð¹Ñ\81даÑ\80аÑ\88|1=нийÑ\81даÑ\80}}",
+       "viewdeleted_short": "{{PLURAL:$1|$1 дIадаьккха нийсдарга|дIадаьккха нийсдарга|$1 дIадаьккха нийсдарашга}} хьажар",
+       "protect": "Ð\93Iо Ð´Ð°Ñ\80",
        "protect_change": "хувца",
-       "protectthispage": "Ð\9bоÑ\80ае ÐµÑ\80 Ð¾Ð°Ð³|Ñ\83в",
-       "unprotect": "Ð\9bоÑ\80ам хувца",
-       "unprotectthispage": "Ð\9bоÑ\80ам хувца",
+       "protectthispage": "Ð\93Iо Ð´Ðµ Ñ\83кÑ\85 Ð¾Ð°Ð³Iон",
+       "unprotect": "Ð\93Iо хувца",
+       "unprotectthispage": "УкÑ\85 Ð¾Ð°Ð³Iон Ð³Iо хувца",
        "newpage": "Керда оагӀув",
-       "talkpage": "УкÑ\85 Ð¾Ð°Ð³|он Ñ\82|а Ð´Ñ\83вÑ\86ам Ð±Ðµ",
+       "talkpage": "Ð\95Ñ\80 Ð¾Ð°Ð³IÑ\83в Ñ\8eвÑ\86а",
        "talkpagelinktext": "дувца оттадар",
-       "specialpage": "Ð\93\83лакÑ\85адаÑ\80а Ð¾Ð°Ð³|ув",
+       "specialpage": "Ð\91алÑ\85а Ð¾Ð°Ð³Ó\80ув",
        "personaltools": "Доакъашхочун гӀирсаш",
        "articlepage": "Йоазон т|а б|аргтасса",
        "talk": "Дувца оттадар",
        "aboutsite": "{{grammar:genitive|{{SITENAME}}}} лаьца",
        "aboutpage": "Project:Лоацам",
        "copyright": "$1 чулоацамаца тIакхоачаш да.",
-       "copyrightpage": "{{ns:project}}:ЯздаÑ\8cÑ\87Ñ\83нна Ð±Ð¾ÐºÑ\8aо",
+       "copyrightpage": "{{ns:project}}:Ð\90вÑ\82оÑ\80а Ð±Ð¾ÐºÑ\8aонаÑ\88",
        "currentevents": "ХӀанзара хинна хIамаш",
        "currentevents-url": "Project:ХӀанзара хинна хIамаш",
        "disclaimers": "Бехктокхам хьацаэцар",
        "disclaimerpage": "Project:Бехктокхам хьацаэцар",
-       "edithelp": "Хувцама гӀо",
+       "edithelp": "Хувцам бара новкъостал",
        "helppage-top-gethelp": "ГӀо",
        "mainpage": "Кертера оагӀув",
        "mainpage-description": "Кертера оагӀув",
        "nstab-main": "Йоазув",
        "nstab-user": "Дакъалаьцархо",
        "nstab-media": "Медифаг",
-       "nstab-special": "Ð\93Ó\80Ñ\83лакха оагӀув",
+       "nstab-special": "Ð\91алха оагӀув",
        "nstab-project": "Проектах лаьца",
        "nstab-image": "Файл",
        "nstab-mediawiki": "Хоам",
-       "nstab-template": "Ð\9aеп",
+       "nstab-template": "Ð\9bо",
        "nstab-help": "ГӀо",
        "nstab-category": "Категори",
        "mainpage-nstab": "Кертера оагӀув",
        "internalerror_info": "Чура гӀалат: $1",
        "cannotdelete-title": "ОагIув дIаяккха йиш яц \"$1\"",
        "badtitle": "Мегаш йоаца цӀи",
-       "badtitletext": "Езаш йола оагӀува цӀи нийса яц, яьсса я, е харцахь я меттаюкъара цIи е интервики цӀи. Иштта, цӀера юкъе оттаде мегаш доаца хьаракъаш нийсаденна хила тарлуш да.",
-       "viewsource": "Ð\91IаÑ\80гÑ\82аÑ\81Ñ\81ам",
+       "badtitletext": "Езаш йола оагӀон цӀи нийса яц, яьсса я, е харцахь йоалаяй меттай юкъера цIи е интервики цӀи. Иштта, цӀера юкъе оттаде мегаш доаца хьаракъаш нийсаденна хила тарлуш да.",
+       "viewsource": "Ð¥Ñ\8cажаÑ\80",
        "actionthrottled": "Сихален овзамал",
        "protectedpagetext": "Ер оаг|ув къайла я хувцамаш дергдоацаш е кхы дола х|амдараш.",
        "virus-unknownscanner": "довзашдоаца мазаундохьалург:",
        "userlogin-yourname-ph": "Чуйоалае доакъашхочун цӀи",
        "createacct-another-username-ph": "Чуйоалае доакъашхочун цӀи",
        "yourpassword": "КъайладIоагӀа:",
+       "userlogin-yourpassword": "Пароль",
        "yourpasswordagain": "КъайладIоагӀа юха Ӏоязаде:",
        "remembermypassword": "(укх $1 {{PLURAL:$1|1=ден|деношкахь}}) мара са чувалара/чуялара дагалоаца дезаш дац",
        "yourdomainname": "Шун цӀеноагӀув:",
        "emailconfirmlink": "Доаржален хоамни хьожадорг дIачIоагIаде",
        "loginlanguagelabel": "Мотт: $1",
        "pt-login": "Чувала/яла",
-       "pt-createaccount": "Учёта яздар кхолла",
+       "pt-createaccount": "Учёта яздар хьакхолла",
        "pt-userlogout": "Аравала/яла",
        "changepassword": "КъайладIоaгIа дIахувцар",
        "oldpassword": "Къаьна къайладIоагӀа:",
        "summary": "Хувцамий белгалдер",
        "subject": "БӀагал/кортале:",
        "minoredit": "ЗӀамига хувцам",
-       "watchthis": "УкÑ\85 Ð¾Ð°Ð³Ó\80Ñ\83ва Ñ\82еÑ\80кам Ð±Ðµ",
-       "savearticle": "ОагӀув хьаязъе",
+       "watchthis": "Ð\97ем Ð±Ðµ Ñ\83кÑ\85 Ð¾Ð°Ð³Ó\80он",
+       "savearticle": "ОагӀув дIаязъе",
        "preview": "Хьалхе бӀаргтассар",
-       "showpreview": "Хьалхе бӀаргтaссам",
+       "showpreview": "Хьалххе хьажар",
        "showdiff": "Даь хувцамаш",
-       "anoneditwarning": "Зем хила! Шо кхы чудаьннадац. Шун IP-моттиг укх хийца оагӀув искаречу дӀаяздаь хургья.",
+       "anoneditwarning": "<strong>Теркам бе!</strong> Хьо автор хинна система чуваьннавац. Нагахьа санна Iа моллагIа хувцам бой, Хьа IP-адрес дийла массанен бIаргагуш хургда. Нагахьа санна Хьо <strong>[$1 хьачувоале]</strong> е <strong>[$2 учёта яздар хьакхолле]</strong>, нийсдараш (хувцамаш) бувзам болаш хургда Хьа доакъашхой цIерца, иштта кхыдола толажагIи гIойленагIи дола дикаьш хургда Хьона.",
        "summary-preview": "Лоацам ба:",
        "subject-preview": "Кортале хургья:",
        "blockedtitle": "Дакъалаьцархо чӀега бела ва/я",
        "loginreqpagetext": "Кхыйола оагӀувнашка хьожаргдолаш, оаш $1 де деза.",
        "accmailtitle": "КъайладIоагӀа дӀадахьийтад",
        "newarticle": "(Kерда)",
-       "newarticletext": "Шо хьожаяргаца дехьадаьннад йоаца оагӀув тӀа.\nИз кхолларгьйолаш кӀалхагӀа доала корачу текст Iочуязаде (нагахьа кхетаде хала дале [$1 новкъосталан оагӀувага] хьажа).\nЦа ховш укхаза нийсденнадале, шоай браузера кнопка '''Юха''' тӀа пӀелга тоӀабе.",
+       "newarticletext": "Шо хьожаяргаца дехьадаьннад йоаца оагӀон тӀа.\nИз кхолларгьйолаш кӀалхагӀа доала корачу текст Iочуязаде (нагахьа кхетаде хала дале [$1 новкъосталан оагӀонга] хьажа).\nЦа ховш укхаза нийсденнадале, шоай браузера '''Юха''' (назад) кнопка тӀа пӀелга тоӀабе.",
        "noarticletext": "ХIанз укх оагӀув тӀа текст яц.\nШун аьттув ба [[Special:Search/{{PAGENAME}}|цу тайпара цӀи хьоаяр кораде]] кхыйола йоазуваш чу, иштта\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тара дола тептарий яздаьраш], е\n'''[{{fullurl:{{FULLPAGENAME}}|action=edit}} изза мо цӀи йолаш оагӀув кхолла]'''</span>.",
        "noarticletext-nopermission": "ХIанз укх оагӀув тӀа яздам дац.\nШун йиш я, кхыдола йоазувнашках [[Special:Search/{{PAGENAME}}|дола цӀерий хаттам корае]] е <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} нийсамий тептара йоазувнаш корае].</span>",
        "note": "'''ХӀамоалар:'''",
        "previewnote": "'''Хьалхе б|аргтассам мара бац.'''\nЯздам кхы яздаь дац!",
        "editing": "Хувцам: $1",
-       "editingsection": "Хувцам: $1 (оагӀува дáкъа)",
+       "editingsection": "Хувцам: $1 (оагӀон дáкъа)",
        "editingcomment": "ГӀалатнийсдар $1 (керда декъам)",
        "editconflict": "ГӀалатнийсдара къовсам: $1",
        "yourtext": "Хьа яздам",
        "copyrightwarning": "Теркам бе, $2 ($1 хьажа) бокъонаца лорадеш, тӀахьежама кӀала уллаш, оаш мел чуяккхаш дола хоамаш, яздамаш долга.\nНаггахь санна шоай яздамаш пурам доацаш мала волашву саго хувца е кхы дола моттиге яздердолаш, безам беци, укхаз Ӏочуцаяздеча, дикаьгӀа да.<br />\nОаш дош лу, даь дола хувцама да волга/йолга, е оаш пурам долаш Ӏочуяздеш да кхычера меттигара шоай яздамаш/хоамаш.\n'''Яздархой бокъоца лорадеш дола хӀамаш, цара пурам доацаш, Ӏочумаязаде!'''",
-       "templatesused": "УкÑ\85 Ð±Ó\80аÑ\80гоагÓ\80Ñ\83вни Ð¾Ð°Ð³Ó\80Ñ\83в Ñ\82Ó\80а Ð»ÐµÐ»Ð°Ñ\8fÑ\8c {{PLURAL:$1|1=Ð\9aÑ\83Ñ\86кеп|Ð\9aÑ\83Ñ\86кепаш}}:",
+       "templatesused": "УкÑ\85 Ð¾Ð°Ð³Iон Ñ\82Iа {{PLURAL:$1|1=пайда Ñ\8dÑ\86а Ð\9bо|пайда Ñ\8dÑ\86а Ð\9bонаш}}:",
        "templatesusedpreview": "Хьалхе бӀаргтассама оагӀув тӀа леладеш дола {{PLURAL:$1|1=Куцкеп|Куцкепаш}}:",
        "template-protected": "(лорадаь да)",
-       "template-semiprotected": "(дакъа-лорам)",
-       "hiddencategories": "Ер оагӀув укх {{PLURAL:$1|1=къайла цатегаца|къайла цатегашца}} дакъа лоаца:",
-       "permissionserrorstext-withaction": "$2 де бокъо яц {{PLURAL:$1|1=из бахьан долаш|из бахьанаш долаш}}:",
+       "template-semiprotected": "(цхьа долча даькъе гIо оттадаь да)",
+       "hiddencategories": "Ер оагIув {{PLURAL:$1|$1 къайла категориех|1=цаI къайла категорех}} я:",
+       "permissionserrorstext-withaction": "Ер $2 де Хьа бокъо яц {{PLURAL:$1|1=из бахьан долаш|из бахьанаш долаш}}:",
        "recreate-moveddeleted-warn": "'''Зем бе! Шо хьалххе дIайоаккхаш хинна оагӀув хьае гӀерта.'''\n\nХьажа, бокъонцахь езаш йолга.\nКӀалхагIа укх оагӀуви дӀадаккхами цӀи хувцами тептараш хьекха да.",
-       "moveddeleted-notice": "Ер оагӀув дӀаяккха хиннай.\nНовкъостала, кӀалха хьахьекха да дӀадаккхама а хувцама а тептарашкара яздараш.",
+       "moveddeleted-notice": "Ер оагӀув дӀаяккха хиннай.\nНовкъостала, кӀалха хьахьекха да дӀадаккхама а хувцама а тептарашкара дIаяздараш.",
        "log-fulllog": "Деррига таптара бӀаргтасса",
        "edit-conflict": "Хувцамий къовсам.",
        "post-expand-template-inclusion-warning": "Зембаккхам: жамIан чIабалаш чулоаца дустам геттара доккха да.\nЦхьадола чIабалаш чулоацалургдац.",
        "viewpagelogs": "Укх оагӀон тептараш хьокха",
        "currentrev-asof": "тӀеххьара верси $1",
        "revisionasof": "Верси $1",
-       "revision-info": "$1; $2 хувцам",
+       "revision-info": "Верси $1; {{GENDER:$6|$2}}$7",
        "previousrevision": "← Xьалхарча",
        "nextrevision": "ТIехьайоагIараш →",
        "currentrevisionlink": "ХIанзара верси",
-       "cur": "хӀанз.",
+       "cur": "хӀанза.",
        "next": "тӀехь.",
-       "last": "хьалх.",
+       "last": "хьалха.",
        "page_first": "хьалхара",
        "page_last": "тӀехьара",
        "histlegend": "Кхетам: (хӀанз.) = хӀанза йолачунна бӀаргоагӀувни хьакъоастам ба; (хьалх.) = хьалха хинначунна бӀаргоагӀувни хьакъоастам ба; '''зӀ''' = зӀамига хьахувцам ба.",
        "searchresults": "Лахар чакхдоалаш корадаьр",
        "searchresults-title": "«$1» лахар",
        "notextmatches": "ОагIувнаша яздамий вIашагIакхетараш дац",
-       "prevn": "{{PLURAL:$1|хьалхйоагlар $1|хьалхйоагlараш $1|хьалхйоагlараш $1}}",
+       "prevn": "{{PLURAL:$1|1=хьалхайогIар|хьалхайогIараш}} $1",
        "nextn": "{{PLURAL:$1|1=тIехьайоагIар|тIехьайоагIараш}} $1",
        "prevn-title": "{{PLURAL:$1|1=$1 хьалхара йоазув|$1 хьалхара йоазувнаш}}",
-       "nextn-title": "{{PLURAL:$1|1=$1 тIехьара йоазув|$1 тIехьара йоазувнаш}}",
+       "nextn-title": "{{PLURAL:$1|ТIадоагIа $1 яздар|ТIадоагIа $1 яздараш}}",
        "shown-title": "Хьóкха $1 {{PLURAL:$1|даь йоазо|даь йоазонаш}} укх оáгIувна тIа",
-       "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) хьажа",
+       "viewprevnext": "ДIахьажа ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Укх масса-хьахьоадайтамач ер оаг|ув \"[[:$1]]\" я'''",
        "searchmenu-new": "<strong>Кхолла оагIув «[[:$1]]» укх вики-проекте!</strong>\n{{PLURAL:$2|0=|Иштта хьажа хьай лийха оагIувнага.|Иштта хьажа хьай лахара хьахиннарашка.}}",
        "searchprofile-articles": "Кертера оагIонаш",
        "searchprofile-advanced-tooltip": "Iочуязаяь цIераренашках лаха",
        "search-result-size": "$1 ({{PLURAL:$2|$2 дош|$2 дешаш}})",
        "search-result-category-size": "{{PLURAL:$1|1=$1 дакъа|$1 дакъаш}} ({{PLURAL:$2|1=$2 кIалцатег|$2 кIалцатегаш}}, {{PLURAL:$3|1=$3 паьла|$3 паьлий}})",
-       "search-redirect": "($1 дехьачуяьккхар)",
+       "search-redirect": "(дIа-сахьожадар $1 тIара)",
        "search-section": " (дакъа $1)",
        "search-suggest": "Хьона эшар ер хила мега: $1",
        "search-interwiki-caption": "Гаргалон хьахьоадайтамаш",
        "search-relatedarticle": "шоайл дола",
        "searchrelated": "гаргара",
        "searchall": "деррига",
-       "search-nonefound": "Ð\94IаÑ\85аÑ\82Ñ\82ама Ð½Ð¸Ð¹Ñ\81амаÑ\88 корадаьдац.",
+       "search-nonefound": "Ð¥Ñ\8cа Ð´ÐµÑ\85аÑ\80 Ð´Ð°Ñ\80а Ð²IаÑ\88и Ð½Ð¸Ð¹Ñ\81а Ð´Ð¾Ð°Ð³IаÑ\88 Ñ\85илаÑ\80 корадаьдац.",
        "powersearch-legend": " Доккха тахкар",
        "powersearch-ns": " ЦIерий аренашкахь лахар",
        "powersearch-toggleall": "Деррига",
        "nchanges": "$1 {{PLURAL:$1|1=хувцам|хувцамаш}}",
        "enhancedrc-history": "истори",
        "recentchanges": "Керда хувцамаш",
-       "recentchanges-legend": "Ð\9aеÑ\80да Ñ\85Ñ\83вÑ\86амий оттамаш",
+       "recentchanges-legend": "Ð\9aеÑ\80да Ñ\85Ñ\83вÑ\86амай оттамаш",
        "recentchanges-summary": "КIалхагIа лоарамий доаламе тIехьара оагIувний хувцамаш дIаязадаь да {{grammar:genitive|{{SITENAME}}}}.",
        "recentchanges-feed-description": "Укх ларамца тIехьара массахувцамашт теркам бе.",
        "recentchanges-label-newpage": "Укх хувцамаца керда оагIув кхелла хиннай",
        "recentchanges-label-minor": "Ер зIамига хувцам ба",
        "recentchanges-label-bot": "Ер хувцам ботаца баь ба",
-       "recentchanges-label-unpatrolled": "Ð\95Ñ\80 Ñ\85Ñ\83вÑ\86ам Ñ\88ий Ð¼Ð¾Ñ\82Ñ\82иге ÐºÑ\85Ñ\8b Ð´IадеÑ\85Ñ\8cаÑ\8fÑ\8cккÑ\85аÑ\8fц.",
+       "recentchanges-label-unpatrolled": "УкÑ\85 Ñ\85Ñ\83вÑ\86ама Ñ\85Iанза Ñ\86Ñ\85Ñ\8cанно Ñ\85а (паÑ\82Ñ\80Ñ\83лиÑ\80оваÑ\82Ñ\8c) Ð´Ð°Ñ\8c Ð´Ð°ц.",
        "recentchanges-label-plusminus": "байташкахь боарам хувцар",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIувнашка]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIонашка]])",
        "rcnotefrom": "КIалхагIа хувцамаш хьахьекха я <strong>$2</strong> денза (<strong>$1</strong> кхачалца).",
-       "rclistfrom": "$3 $2 тIара хувцамаш хьахьокха",
-       "rcshowhideminor": "$1 зIамига хувцамаш",
+       "rclistfrom": "$3 $2 денза даь хувцамаш хьахьокха",
+       "rcshowhideminor": "$1 зIамига нийсдараш",
        "rcshowhideminor-hide": "Къайлдаккха",
        "rcshowhidebots": "$1 боташ",
        "rcshowhidebots-show": "Хьахьокха",
        "rcshowhideliu": "$1 бовзийтарчара доакъашхой",
-       "rcshowhideliu-hide": "Ð\9aÑ\8aайлдаккха",
-       "rcshowhideanons": "$1 цIияьккханза дакъалаьцархой",
+       "rcshowhideliu-hide": "Ð\9aÑ\8aайлабаха",
+       "rcshowhideanons": "$1 цIияккханза доакъашхой",
        "rcshowhideanons-show": "Хьахьокха",
-       "rcshowhideanons-hide": "Ð\9aÑ\8aайлдаккха",
+       "rcshowhideanons-hide": "Ð\9aÑ\8aайлабаха",
        "rcshowhidepatr": "$1 теркам даь хувцамаш",
-       "rcshowhidemine": "$1 Ñ\81ай Ñ\85Ñ\83вÑ\86амаш",
+       "rcshowhidemine": "$1 Ñ\85Ñ\8cа Ð½Ð¸Ð¹Ñ\81даÑ\80аш",
        "rcshowhidemine-hide": "Къайлдаккха",
-       "rclinks": "$2 динах<br />$3 $1 хинна тIехьара хувцамаш хьахьокха",
+       "rclinks": "Хьахьокха $2 дийнахь даь хинна тIеххьара $1 хувцамаш\n<br />$3",
        "diff": "башхало",
        "hist": "истори",
        "hide": "Къайлдаккха",
        "recentchangeslinked": "Гаргалон хувцамаш",
        "recentchangeslinked-feed": "Гаргалон хувцамаш",
        "recentchangeslinked-toolbox": "Укханца вIашагIдувзаденна хувцамаш",
-       "recentchangeslinked-title": "$1ца хьалаьца хувцамаш",
+       "recentchangeslinked-title": "$1ца вIашидувзаденна хувцамаш",
        "recentchangeslinked-summary": "Ер, Iинк яь йола оагIув (е укх цатегачу чуйоагIараш), дукха ха йоацаш хьийца оагIувнашкий дагарле я.\n[[Special:Watchlist|Шун теркама дагарленашках]] чуйоагIа оагIувнаш '''белгалаяь я'''.",
        "recentchangeslinked-page": "ОагIува цIи",
        "recentchangeslinked-to": "ОагIувнаш тIа хувцамаш хьахьокха, хьахьекха йола оагIув тIа Iинкаш еш йола.",
        "filehist-dimensions": "Файлан боарам",
        "filehist-filesize": "Паьла юстарал",
        "filehist-comment": "Белгалдаккхар",
-       "imagelinks": "Файла пайда эцар",
+       "imagelinks": "Файлах пайда эцар",
        "linkstoimage": "{{PLURAL:$1|1=ТIехьайоагIача $1 оагIуво тIахьожаву|ТIехьайоагIача $1 оагIувнаша тIахьожаву}} укх файла тIа:",
        "nolinkstoimage": "Йола паьла тIа  Iинк ю оагIувнаш дац",
        "sharedupload": "Ер паьла $1чера я, кхыча хьахьоадайтамча хьахайраде йийшайолаш я.",
        "brokenredirects-delete": "дIадаккха",
        "withoutinterwiki-submit": "Хьахьокха",
        "nbytes": "$1 {{PLURAL:$1|байт}}",
-       "nmembers": "$1 {{PLURAL:$1|1=дакъалаьцархо|дакъалаьцархой}}",
+       "nmembers": "$1 {{PLURAL:$1|объект}}",
        "prefixindex": "ОагIувнаший хьалхера цIи хьагойтар",
        "shortpages": "Лоаца оагIувнаш",
        "longpages": "Доккхий оагIувнаш",
        "move": "ЦIи хувца",
        "movethispage": "Укх оагIува цIи хувца",
        "pager-newer-n": "{{PLURAL:$1|кердагIа дара|кердагIа дараш|кердагIа долачаьрахь}} $1",
-       "pager-older-n": "{{PLURAL:$1|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð°Ñ\80а|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð°Ñ\80аÑ\88|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð¾Ð»aÑ\87аÑ\8cÑ\80аÑ\85Ñ\8c}} $1",
+       "pager-older-n": "{{PLURAL:$1|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð°Ñ\80а|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð°Ñ\80аÑ\88|кÑ\8aаÑ\8cнаÑ\80а Ð´Ð¾Ð»aÑ\87аÑ\80еÑ\85}} $1",
        "booksources": "Джейнай хьасташ (источники)",
        "booksources-search-legend": "Джейнах лаьца хоам лахар",
        "booksources-search": "Хьалáха",
        "invert": "Харжар юхадаккха",
        "namespace_association": "Ювзаенна мотт",
        "blanknamespace": "(Кертера)",
-       "contributions": "{{GENDER:$1|Доакъашхочунна}} къахьегам",
+       "contributions": "{{GENDER:$1|Доакъашхочун}} къахьегам",
        "contributions-title": "$1 дакъалаьцархочунна къахьегам",
        "mycontris": "Са къахьегам",
+       "anoncontribs": "Къахьегам",
        "contribsub2": "{{GENDER:$3|$1}} ($2) баь болх",
        "uctop": "(xIанзара)",
        "month": "Укх бетт (кхы хьалхагIа)",
        "istemplate": "юкъейоалаяр",
        "isimage": "Файлан хьожаярг",
        "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIа|хьалхайоагIараш}} $1",
-       "whatlinkshere-next": "{{PLURAL:$1|1=тIехьайоагIа|тIехьайоагIараш}} $1",
+       "whatlinkshere-next": "{{PLURAL:$1|1=тIехьайоагIар|тIехьайоагIараш}} $1",
        "whatlinkshere-links": "← хьожаяргаш",
        "whatlinkshere-hideredirs": "$1 дIа-хьа чуяьккхамаш",
        "whatlinkshere-hidetrans": "$1 чуяьккхамаш",
        "thumbnail-more": "Доккха де",
        "thumbnail_error": "ЗIамигасуртанчий кхеллама гIалат: $1",
        "import-upload-filename": "ПаьлацIи:",
-       "tooltip-pt-userpage": "Дакъалаьцархочунна оагIув",
-       "tooltip-pt-mytalk": "Шун дувцамий оагIув",
-       "tooltip-pt-preferences": "Шун оттамаш",
+       "tooltip-pt-userpage": "{{GENDER:|Хьа}} доакъашхочунна оагIув",
+       "tooltip-pt-mytalk": "{{GENDER:|Хьа}} дувца оттадара оагIув",
+       "tooltip-pt-preferences": "{{GENDER:|Хьа оттамаш}}",
        "tooltip-pt-watchlist": "ОоагIувна дагарле, шо бIаргалокхаш йола",
-       "tooltip-pt-mycontris": "Шун хувцамаш",
+       "tooltip-pt-mycontris": "{{GENDER:|хьа}} хувцамаш",
        "tooltip-pt-login": "Укхаза хьай цIи аьле чувала/яла йиша я, амма из параз дац",
        "tooltip-pt-logout": "Аравала/яла",
        "tooltip-pt-createaccount": "Хьа бокъо я учёта яздар кхелла система чу вала, амма параз долаш дац из.",
        "tooltip-ca-talk": "ОагIон чулоацам дувца оттадар",
        "tooltip-ca-edit": "Нийсъе ер оагIув",
        "tooltip-ca-addsection": "Керда дакъа хьаде",
-       "tooltip-ca-viewsource": "Ð\95Ñ\80 Ð¾Ð°Ð³IÑ\83в Ñ\85Ñ\83вÑ\86амаÑ\85 Ð»Ð¾Ñ\80аÑ\8fÑ\8c Ñ\8f, Ð°Ð¼Ð¼Ð° Ñ\88Ñ\83н Ñ\86Ñ\83нна Ð³IÑ\83вамага Ñ\85Ñ\8cажа бокъо я.",
+       "tooltip-ca-viewsource": "Ð\95Ñ\80 Ð¾Ð°Ð³IÑ\83в Ñ\85Ñ\83вÑ\86амбаÑ\80аÑ\85 Ð³Iо Ñ\82еÑ\85а (лоÑ\80аÑ\8f) Ñ\8f, Ð°Ð¼Ð¼Ð° Ñ\86Ñ\83нна Ð´IадолалÑ\83 Ñ\82екÑ\81Ñ\82ага Ñ\85Ñ\8cажа Ð°, Ð¸Ð· Ñ\82IеÑ\80Ñ\85Ñ\8cаÑ\8fзÑ\8aе а бокъо я.",
        "tooltip-ca-history": "Укх оагIон даь хувцамаш тIа дола тептар",
        "tooltip-ca-protect": "Eр оагIув лорае",
        "tooltip-ca-delete": "Ер оагIув дIаяькха",
        "tooltip-ca-nstab-special": "Ер гIулакха оагIув я, из хувца бокъо яц",
        "tooltip-ca-nstab-project": "Проектан оагIув",
        "tooltip-ca-nstab-image": "Файлан оагӀув",
-       "tooltip-ca-nstab-template": "Ð\9aепан оагIув",
+       "tooltip-ca-nstab-template": "Ð\9bон оагIув",
        "tooltip-ca-nstab-help": "ГӀон оагIув",
        "tooltip-ca-nstab-category": "Категорий оагӀув",
        "tooltip-minoredit": "Ер хувцар башха доаца санна белгалде",
-       "tooltip-save": "Ð¥Ñ\83вÑ\86амаÑ\88 ÐºÑ\85оде",
-       "tooltip-preview": "Ð\9eагIÑ\83в Ñ\82Iа Ñ\85Ñ\8cалÑ\85е Ð±IаÑ\80гÑ\82аÑ\81Ñ\81аÑ\80, Ð´ÐµÑ\85аÑ\80 Ð´Ð°, Ð¾Ð°Ð³IÑ\83в Ð´IаÑ\8fзÑ\8aелаÑ\8cÑ\85, Ñ\86Ñ\83н Ñ\82еÑ\80кам Ð±Ðµ.",
-       "tooltip-diff": "Яздам Ñ\82Iа Ñ\8fÑ\8c Ð¹Ð¾Ð»Ð° хувцамаш хьахьокха",
+       "tooltip-save": "Ð¥Ñ\8cай Ñ\85Ñ\83вÑ\86амаÑ\88 Ð»Ð¾Ñ\80адеÑ\88 Ð´IаÑ\8fзаде",
+       "tooltip-preview": "Ð\94еÑ\85аÑ\80 Ð´Ð°, Ð¾Ð°Ð³Ó\80Ñ\83в Ð»Ð¾Ñ\80аеÑ\88Ñ\8c Ð´IаÑ\8fзаелеÑ\85Ñ\8c Ð¸Ð· Ð¼Ð¸Ñ\88Ñ\82а Ñ\8f Ñ\82аÑ\85ка Ñ\85Ñ\8cалÑ\85Ñ\85е Ñ\85Ñ\8cажаÑ\80аÑ\85 Ð¿Ð°Ð¹Ð´Ð° Ñ\8dÑ\86аÑ\88!",
+       "tooltip-diff": "Ð\94IадолалÑ\83 Ñ\82екÑ\81Ñ\82аÑ\86а Ð´Ð°Ñ\8c хувцамаш хьахьокха",
        "tooltip-compareselectedversions": "Укх оагIувни шин доржамаш тIа юкъера хувцамаш зе.",
        "tooltip-watch": "Ер оагIув теркам беча каьхата тIа яькха",
        "tooltip-rollback": "Цкъа пIелг тоIабе дIадаккха тIехьара редакторас даь хувцамаш",
        "tooltip-undo": "Даь хувцар дIадаьккха, хьалххе хьажар хьахьокха, дIадаккхара бахьан Iочуязаде аьттув болаш.",
-       "tooltip-summary": "Лоаца чулоацам Iочуязаде",
+       "tooltip-summary": "Лоаца йоазонца сурт оттадар Iочуязаде",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|1=Къайла категори|Къайла категореш}} ($1)",
        "pageinfo-toolboxlink": "ОагIонах бола хоам",
        "previousdiff": "← Хьалхара нийсдар",
        "nextdiff": "ТIайоагIа нийсъар",
        "ilsubmit": "Хьалáха",
        "bad_image_list": "Бустам цу тайпара хила беза:\n\nДагарлен хьаракъаш мара лоарх|аш хургьяц (укх тамагIалгацa * дувлашду мугIараш).\nМугIарен хьалхара Iинк, сурт Iоттае пурам доаца Iинка, хила еза. \nЦу мугIара тIехьайоагIа Iинкаш, арадаккхар мо лоарх|аш хургья, вешта аьлча, йоазувашка чуIоттаде мегаш дола сурт санна ларх|а мега.",
        "metadata": "Метахоамаш",
-       "metadata-help": "Ð\9fаÑ\8cлаÑ\81 Ñ\87Ñ\83лоаÑ\86а, ÐºÑ\85Ñ\8bдола Ñ\85IамаÑ\88, Ñ\82аÑ\8cÑ\80аÑ\85Ñ\8cа Ñ\81Ñ\83Ñ\80Ñ\82доакÑ\85аÑ\80гÑ\86а Ðµ Ñ\82IагIолладоакÑ\85аÑ\80гÑ\86а Ñ\87Ñ\83дакÑ\85аÑ\88 Ð´Ð¾Ð»Ð°. Ð¥Ñ\8cаÑ\8fÑ\8c Ð¿Ð°Ñ\8cл, Ð³IалаÑ\82аÑ\85Ñ\8c Ð¼Ñ\83кÑ\8aадаÑ\8cкÑ\85а Ñ\85инна Ð´Ð°Ð»Ðµ, Ñ\85Ñ\8cаÑ\85Ñ\8cокÑ\85аÑ\88 Ð´Ð¾Ð»Ð° Ñ\81Ñ\83Ñ\80Ñ\82, Ð´ÐµÑ\80Ñ\80ига Ñ\85IамаÑ\88 Ñ\87Ñ\83лоаÑ\86аÑ\80гдаÑ\86.",
+       "metadata-help": "ФайлаÑ\81 ÐºÑ\85Ñ\8bдола Ñ\85оамаÑ\88 Ñ\87Ñ\83лоаÑ\86а, Ñ\86иÑ\84Ñ\80овой Ñ\81Ñ\83Ñ\80Ñ\82доакÑ\85аÑ\80го Ðµ Ñ\81канеÑ\80о Ñ\82IаÑ\82оÑ\85аÑ\88 Ð´Ð¾Ð»Ð°. Ð\9dагаÑ\85Ñ\8cа Ñ\84айл Ñ\87Ñ\83Ñ\8fкÑ\85аÑ\87Ñ\83л Ñ\82IеÑ\85Ñ\8cа Ñ\85ийÑ\86а Ñ\85инна Ð´Ð°Ð»Ðµ, Ñ\86Ñ\85Ñ\8cаÑ\86Ñ\86айола Ð¿Ð°Ñ\80амеÑ\82Ñ\80аÑ\88 Ñ\85IанзаÑ\80а Ñ\81Ñ\83Ñ\80Ñ\82а Ñ\82аÑ\80а Ð¹Ð¾Ð°Ñ\86аÑ\88 Ñ\85ила Ð¼ÐµÐ³Ð°Ñ\88 Ñ\8f.",
        "metadata-expand": "Кхыдола хIамаш хьахьокха",
        "metadata-collapse": "Кхыдола хIамаш къайладаккха",
        "metadata-fields": "Укх списке дагaрадаь суртай метахоамай йистош, хьахьекха хургда суртан оагIон тIа, метахоамай таблица хьоарчая йолаш. Юхедиса йистош къайла хургда.\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-artist": "Яздархо",
        "exif-exifversion": "Верси Exif",
        "exif-colorspace": "Басара аре",
-       "exif-pixelxdimension": "СÑ\83Ñ\80Ñ\82а Ñ\88ерал",
+       "exif-pixelxdimension": "СÑ\83Ñ\80Ñ\82а Ñ\88орал",
        "exif-pixelydimension": "Сурта лакхал",
        "exif-datetimedigitized": "Оцифровк яь таьрахь а, ха а",
        "exif-writer": "Яздама да",
        "watchlisttools-view": "Дагарчера оагIувнаш тIа хувцамаш",
        "watchlisttools-edit": "Дагарче хьажа/хувца",
        "watchlisttools-raw": "Яздам мо хувца",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|дувца оттадар]])",
        "duplicate-defaultsort": "Зем бе. Сатийна дIа-хьа хьоржама доагI \"$2\" хьалхара сатийна дIа-хьа хьоржама доагI \"$1\" хьахьоржа.",
        "version": "Доржам",
-       "version-specialpages": "Ð\93\83лакÑ\85ий Ð¾Ð°Ð³IÑ\83внаш",
+       "version-specialpages": "Ð\91алÑ\85а Ð¾Ð°Ð³Ó\80онаш",
        "version-version": "($1)",
        "version-software-version": "Доржам",
        "fileduplicatesearch-filename": "ПаьлацIи:",
index 8e3c46f..325f6ad 100644 (file)
        "noemail": "Það er ekkert netfang skráð fyrir notandan \"$1\".",
        "noemailcreate": "Þú verður að skrá gilt netfang",
        "passwordsent": "Nýtt lykilorð var sent á netfangið sem er skráð á „$1“.\nSkráðu þig inn á ný þegar þú hefur móttekið það.",
-       "blocked-mailpassword": "Þér er ekki heimilt að gera breytingar frá þessu netfangi og  því getur þú ekki fengið nýtt lykilorð í pósti.  Þetta er gert til þess að koma í veg fyrir skemmdarverk.",
+       "blocked-mailpassword": "IP-vistfangið þitt hefur verið útilokað frá því að gera breytingar. Til þess að koma í veg fyrir misnotkun er því ekki hægt að nýta sér endurheimtingu lykilorðs frá þessu IP-vistfangi.",
        "eauthentsent": "Staðfestingarpóstur hefur verið sendur á uppgefið netfang. Þú verður að fylgja leiðbeiningunum í póstinum til þess að virkja netfangið og staðfesta að það sé örugglega þitt.",
        "throttled-mailpassword": "Tölvupóstur til að endursetja lykilorðið hefur þegar verið sent, innan við $1 {{PLURAL:$1|síðasta klukkutímans|síðustu klukkutímanna}}.\nTil að koma í veg fyrir misnotkun, er aðeins einn tölvupóstur sendur {{PLURAL:$1|hvern $1 klukkutíma|hverja $1 klukkutíma}}.",
        "mailerror": "Upp kom villa við sendingu tölvupósts: $1",
        "resetpass_submit": "Skrifaðu aðgangsorðið og skráðu þig inn",
        "changepassword-success": "Það tókst að breyta lykilorðinu þínu!",
        "changepassword-throttled": "Þú hefur gert of margar tilraunir til innskráningar að undanförnu.\nBíddu í $1 áður en þú reynir aftur.",
+       "botpasswords": "Lykilorð róbóta",
        "botpasswords-label-create": "Búa til",
        "botpasswords-label-update": "Uppfæra",
        "botpasswords-label-cancel": "Hætta við",
        "minoredit": "Þetta er minniháttar breyting",
        "watchthis": "Vakta þessa síðu",
        "savearticle": "Vista síðu",
+       "publishpage": "Gefa út síðu",
        "preview": "Forskoða",
        "showpreview": "Forskoða",
        "showdiff": "Sýna breytingar",
        "upload-form-label-infoform-description-tooltip": "Lýstu stuttlega öllu því sem er markvert um verkið.\nFyrir ljósmyndir, nefndu aðalatriði myndarinnar, tilefni eða staðsetningu.",
        "upload-form-label-usage-title": "Notkun",
        "upload-form-label-usage-filename": "Skráarheiti",
-       "foreign-structured-upload-form-label-own-work": "Það er mitt eigið verk",
-       "foreign-structured-upload-form-label-infoform-categories": "Flokkar",
-       "foreign-structured-upload-form-label-infoform-date": "Dagsetning",
-       "foreign-structured-upload-form-label-own-work-message-local": "Ég skil að ég sé að hlaða inn skrá samkvæmt notkunarskilmálum og leyfisskilmálum {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Ef þú getur ekki hlaðið inn þessari skrá samkvæmt reglum {{SITENAME}}, lokaðu þá þessum glugga og reyndu aðra aðferð.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Þú gætir einnig prófað að nota [[Special:Upload|sjálfgefnu innhleðslusíðuna]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Ég skil að ég sé að hlaða inn skrá á sameiginlegt vefsvæði. Ég staðfesti að ég sé að gera það samkvæmt notkunarskilmálum og leyfisskilmálum þess.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Ef þú getur ekki hlaðið inn þessari skrá samkvæmt reglum sameiginlega vefsvæðisins, lokaðu þá þessum glugga og reyndu aðra aðferð.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Þú gætir einnig prófað að nota [[Special:Upload|innhleðslusíðuna á {{SITENAME}}]], ef það má hlaða þessari skrá inn samkvæmt reglum þeirra.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Ég staðfesti að ég eigi höfundarréttinn að þessari skrá og samþykki óafturkræft að gefa þessa skrá til Wikimedia Commons undir  [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] leyfi. Ég samþykki [https://wikimediafoundation.org/wiki/Terms_of_Use notendaskilmálana].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Ef þú átt ekki höfundarréttinn að þessari skrá, eða þú vilt gefa það út undir öðru leyfi, prófaðu  [https://commons.wikimedia.org/wiki/Special:UploadWizard Innsendingaálfinn á Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Þú gætir einnig prófað að nota [[Special:Upload|innhleðslusíðuna á {{SITENAME}}]], ef það má hlaða þessari skrá inn samkvæmt reglum þeirra.",
+       "upload-form-label-own-work": "Það er mitt eigið verk",
+       "upload-form-label-infoform-categories": "Flokkar",
+       "upload-form-label-infoform-date": "Dagsetning",
+       "upload-form-label-own-work-message-local": "Ég skil að ég sé að hlaða inn skrá samkvæmt notkunarskilmálum og leyfisskilmálum {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Ef þú getur ekki hlaðið inn þessari skrá samkvæmt reglum {{SITENAME}}, lokaðu þá þessum glugga og reyndu aðra aðferð.",
+       "upload-form-label-not-own-work-local-local": "Þú gætir einnig prófað að nota [[Special:Upload|sjálfgefnu innhleðslusíðuna]].",
+       "upload-form-label-own-work-message-default": "Ég skil að ég sé að hlaða inn skrá á sameiginlegt vefsvæði. Ég staðfesti að ég sé að gera það samkvæmt notkunarskilmálum og leyfisskilmálum þess.",
+       "upload-form-label-not-own-work-message-default": "Ef þú getur ekki hlaðið inn þessari skrá samkvæmt reglum sameiginlega vefsvæðisins, lokaðu þá þessum glugga og reyndu aðra aðferð.",
+       "upload-form-label-not-own-work-local-default": "Þú gætir einnig prófað að nota [[Special:Upload|innhleðslusíðuna á {{SITENAME}}]], ef það má hlaða þessari skrá inn samkvæmt reglum þeirra.",
+       "upload-form-label-own-work-message-shared": "Ég staðfesti að ég eigi höfundarréttinn að þessari skrá og samþykki óafturkræft að gefa þessa skrá til Wikimedia Commons undir  [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] leyfi. Ég samþykki [https://wikimediafoundation.org/wiki/Terms_of_Use notendaskilmálana].",
+       "upload-form-label-not-own-work-message-shared": "Ef þú átt ekki höfundarréttinn að þessari skrá, eða þú vilt gefa það út undir öðru leyfi, prófaðu  [https://commons.wikimedia.org/wiki/Special:UploadWizard Innsendingaálfinn á Commons].",
+       "upload-form-label-not-own-work-local-shared": "Þú gætir einnig prófað að nota [[Special:Upload|innhleðslusíðuna á {{SITENAME}}]], ef það má hlaða þessari skrá inn samkvæmt reglum þeirra.",
        "backend-fail-stream": "Gat ekki streymt skránni „$1“.",
        "backend-fail-backup": "Öryggisafritun skrárinnar $1 mistókst.",
        "backend-fail-notexists": "Skráin $1 er ekki til.",
index 3c1eed2..14da229 100644 (file)
@@ -95,7 +95,8 @@
                        "Wim b",
                        "V6rg",
                        "JackLantern",
-                       "Mpiva"
+                       "Mpiva",
+                       "Urielejh"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "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-watchlistreloadautomatically": "Ricarica automaticamente l'elenco degli osservati speciali ogni volta che si modifica un 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",
        "protect_change": "cambia",
        "protectthispage": "Proteggi questa pagina",
        "unprotect": "Cambia la protezione",
-       "unprotectthispage": "Cambia la protezione a questa pagina",
+       "unprotectthispage": "Modifica la protezione di questa pagina",
        "newpage": "Nuova pagina",
        "talkpage": "Pagina di discussione",
        "talkpagelinktext": "Discussione",
        "minoredit": "Questa è una modifica minore",
        "watchthis": "Aggiungi agli osservati speciali",
        "savearticle": "Salva la pagina",
+       "publishpage": "Pubblica pagina",
        "preview": "Anteprima",
        "showpreview": "Visualizza anteprima",
        "showdiff": "Mostra modifiche",
        "userpage-userdoesnotexist": "L'account \"$1\" non corrisponde a un utente registrato.\nVerificare che si intenda davvero creare o modificare questa pagina.",
        "userpage-userdoesnotexist-view": "L'utenza \"$1\" non è registrata.",
        "blocked-notice-logextract": "Questo utente è attualmente bloccato.\nL'ultimo elemento del registro dei blocchi è riportato di seguito per informazione:",
-       "clearyourcache": "<strong>Nota:</strong> dopo aver salvato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti. \n*<strong>Firefox / Safari:</strong> tenere premuto il tasto delle maiuscole <em>Shift</em> e fare clic su <em>Ricarica</em>, oppure premere <em>Ctrl-F5</em> o <em>Ctrl-R</em> (<em>⌘-R</em> su Mac)\n*<strong>Google Chrome:</strong> premere <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> su un Mac)\n*<strong>Internet Explorer:</strong> tenere premuto il tasto <em>Ctrl</em> e fare clic su <em>Aggiorna</em>, oppure premere <em>Ctrl-F5</em>\n*<strong>Opera:</strong> svuotare completamente la cache dal menu <em>Strumenti → Preferenze</em>",
+       "clearyourcache": "<strong>Nota:</strong> dopo aver salvato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti. \n*<strong>Firefox / Safari:</strong> tenere premuto il tasto delle maiuscole <em>Shift</em> e fare clic su <em>Ricarica</em>, oppure premere <em>Ctrl-F5</em> o <em>Ctrl-R</em> (<em>⌘-R</em> su Mac)\n*<strong>Google Chrome:</strong> premere <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> su un Mac)\n*<strong>Internet Explorer:</strong> tenere premuto il tasto <em>Ctrl</em> e fare clic su <em>Aggiorna</em>, oppure premere <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Vai nel <em>Menu → Impostazioni</em> (<em>Opera → Preferenze</em> su un Mac) e poi in <em>Privacy & sicurezza → Pulisci dati del browser → Immagini e file nella cache</em>.",
        "usercssyoucanpreview": "'''Suggerimento:''' usa il pulsante 'Visualizza anteprima' per provare il tuo nuovo CSS prima di salvarlo.",
        "userjsyoucanpreview": "'''Suggerimento:''' usa il pulsante 'Visualizza anteprima' per provare il tuo nuovo JavaScript prima di salvarlo.",
        "usercsspreview": "'''Questa è solo un'anteprima del proprio CSS personale. Le modifiche non sono ancora state salvate!'''",
        "upload-form-label-infoform-description-tooltip": "Descrivi sinteticamente tutto quanto sia degno di nota a proposito di quest'opera.\nPer le foto, indica le cose principali che vi sono rappresentate, l'occasione e/o il luogo in cui sono state scattate.",
        "upload-form-label-usage-title": "Utilizzo",
        "upload-form-label-usage-filename": "Nome del file",
-       "foreign-structured-upload-form-label-own-work": "Questo è un mio lavoro",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorie",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confermo che sto caricando questo file seguendo le condizioni di servizio e le politiche sulle license di {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Se non si è in grado di caricare il file in base alle politiche di {{SITENAME}}, chiudi questa finestra e prova un altro metodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Puoi anche provare la [[Special:Upload|pagina di caricamento predefinita]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Ho capito che sto caricando questo file in un archivio condiviso. Confermo che lo sto facendo secondo le condizioni di servizio e le politiche sulle license di lì.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Se non si è in grado di caricare il file in base alle politiche dell'archivio condiviso, chiudi questa finestra e prova un altro metodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Puoi anche provare ad usare la [[Special:Upload|pagina di caricamento su {{SITENAME}}]], se questo file può essere caricato in base alle sue politiche.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Attesto che possiedo i diritti d'autore su questo file, e accetto irrevocabilmente il rilascio di questo file su Wikimedia Commons in base alla licenza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribuzione-Condividi allo stesso modo 4.0], e accetto le [https://wikimediafoundation.org/wiki/Terms_of_Use Condizioni d'uso].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Se non possiedi i diritti d'autore su questo file, o se lo vuoi rilasciare con una licenza diversa, usa il [https://commons.wikimedia.org/wiki/Special:UploadWizard caricamento guidato di Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Puoi anche provare ad usare la [[Special:Upload|pagina di caricamento su {{SITENAME}}]], se il sito consente il caricamento di questo file in base alle sue politiche.",
+       "upload-form-label-own-work": "Questo è un mio lavoro",
+       "upload-form-label-infoform-categories": "Categorie",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Confermo che sto caricando questo file seguendo le condizioni di servizio e le politiche sulle license di {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Se non si è in grado di caricare il file in base alle politiche di {{SITENAME}}, chiudi questa finestra e prova un altro metodo.",
+       "upload-form-label-not-own-work-local-local": "Puoi anche provare la [[Special:Upload|pagina di caricamento predefinita]].",
+       "upload-form-label-own-work-message-default": "Ho capito che sto caricando questo file in un archivio condiviso. Confermo che lo sto facendo secondo le condizioni di servizio e le politiche sulle license di lì.",
+       "upload-form-label-not-own-work-message-default": "Se non si è in grado di caricare il file in base alle politiche dell'archivio condiviso, chiudi questa finestra e prova un altro metodo.",
+       "upload-form-label-not-own-work-local-default": "Puoi anche provare ad usare la [[Special:Upload|pagina di caricamento su {{SITENAME}}]], se questo file può essere caricato in base alle sue politiche.",
+       "upload-form-label-own-work-message-shared": "Attesto che possiedo i diritti d'autore su questo file, e accetto irrevocabilmente il rilascio di questo file su Wikimedia Commons in base alla licenza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribuzione-Condividi allo stesso modo 4.0], e accetto le [https://wikimediafoundation.org/wiki/Terms_of_Use Condizioni d'uso].",
+       "upload-form-label-not-own-work-message-shared": "Se non possiedi i diritti d'autore su questo file, o se lo vuoi rilasciare con una licenza diversa, usa il [https://commons.wikimedia.org/wiki/Special:UploadWizard caricamento guidato di Commons].",
+       "upload-form-label-not-own-work-local-shared": "Puoi anche provare ad usare la [[Special:Upload|pagina di caricamento su {{SITENAME}}]], se il sito consente il caricamento di questo file in base alle sue politiche.",
        "backend-fail-stream": "Impossibile trasmettere il file $1.",
        "backend-fail-backup": "Impossibile eseguire il backup del file $1 .",
        "backend-fail-notexists": "Il file $1 non esiste.",
        "changecontentmodel-success-text": "Il tipo di contenuto di [[:$1]] è stato modificato.",
        "changecontentmodel-cannot-convert": "Il contenuto di [[:$1]] non può essere convertito in tipo $2.",
        "changecontentmodel-nodirectediting": "Il modello di contenuto $1 non supporta la modifica diretta",
+       "changecontentmodel-emptymodels-title": "Nessun modello di contenuto disponibile",
+       "changecontentmodel-emptymodels-text": "Il contenuto di [[:$1]] non può essere convertito in alcun tipo.",
        "log-name-contentmodel": "Modifiche del modello contenuti",
        "log-description-contentmodel": "Eventi relativi al modello di contenuto di una pagina",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|ha creato}} la pagina $3 utilizzando un modello di contenuto non predefinito \"$5\"",
        "whatlinkshere-prev": "{{PLURAL:$1|precedente|precedenti $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|successivo|successivi $1}}",
        "whatlinkshere-links": "← collegamenti",
-       "whatlinkshere-hideredirs": "$1 redirect",
-       "whatlinkshere-hidetrans": "$1 inclusioni",
-       "whatlinkshere-hidelinks": "$1 collegamenti",
-       "whatlinkshere-hideimages": "$1 link da file",
+       "whatlinkshere-hideredirs": "Nascondi redirect",
+       "whatlinkshere-hidetrans": "Nascondi inclusioni",
+       "whatlinkshere-hidelinks": "Nascondi collegamenti",
+       "whatlinkshere-hideimages": "Nascondi collegamenti da file",
        "whatlinkshere-filters": "Filtri",
        "whatlinkshere-submit": "Vai",
        "autoblockid": "Autoblocco #$1",
        "lockdbsuccesstext": "Il database è stato bloccato.<br />\nRicordare di [[Special:UnlockDB|rimuovere il blocco]] dopo aver terminato le operazioni di manutenzione.",
        "unlockdbsuccesstext": "Il database è stato sbloccato.",
        "lockfilenotwritable": "Impossibile scrivere sul file di ''lock'' del database. L'accesso in scrittura a tale file da parte del server web è necessario per bloccare e sbloccare il database.",
+       "databaselocked": "Il database è già bloccato.",
        "databasenotlocked": "Il database non è bloccato.",
        "lockedbyandtime": "(da $1 il $2 alle $3)",
        "move-page": "Spostamento di $1",
        "tooltip-ca-nstab-category": "Vedi la pagina della categoria",
        "tooltip-minoredit": "Contrassegna questa modifica come minore",
        "tooltip-save": "Salva le modifiche",
+       "tooltip-publish": "Pubblica le tue modifiche",
        "tooltip-preview": "Anteprima delle modifiche (consigliata prima di salvare)",
        "tooltip-diff": "Guarda le modifiche apportate al testo",
        "tooltip-compareselectedversions": "Guarda le differenze tra le due versioni selezionate di questa pagina.",
        "autoredircomment": "Redirect alla pagina [[$1]]",
        "autosumm-new": "Creata pagina con \"$1\"",
        "autosumm-newblank": "Creata pagina vuota",
-       "size-bytes": "$1 byte",
+       "size-bytes": "$1 {{PLURAL:$1|byte}}",
        "lag-warn-normal": "Le modifiche apportate {{PLURAL:$1|nell'ultimo secondo|negli ultimi $1 secondi}} potrebbero non apparire in questa lista.",
        "lag-warn-high": "A causa di un eccessivo ritardo nell'aggiornamento del server di database, le modifiche apportate {{PLURAL:$1|nell'ultimo secondo|negli ultimi $1 secondi}} potrebbero non apparire in questa lista.",
        "watchlistedit-normal-title": "Modifica osservati speciali",
        "feedback-useragent": "Agente utente:",
        "searchsuggest-search": "Ricerca",
        "searchsuggest-containing": "contenente...",
+       "api-error-autoblocked": "Il tuo indirizzo IP è stato bloccato automaticamente, perché è stato utilizzato da un utente bloccato.",
        "api-error-badaccess-groups": "Non sei autorizzato a caricare documenti su questa wiki.",
        "api-error-badtoken": "Errore interno: token errato.",
+       "api-error-blocked": "Sei stato bloccato, non puoi fare modifiche.",
        "api-error-copyuploaddisabled": "Il caricamento tramite URL è disabilitato su questo server.",
        "api-error-duplicate": "Sul sito {{PLURAL:$1|c'è già un altro documento|ci sono già altri documenti}} con lo stesso contenuto.",
        "api-error-duplicate-archive": "{{PLURAL:$1|C'era un altro file|C'erano altri file}} già nel sito con lo stesso contenuto, ma {{PLURAL:$1|è stato cancellato|sono stati cancellati}}.",
        "api-error-unknownerror": "Errore sconosciuto: \"$1\".",
        "api-error-uploaddisabled": "Il caricamento è disabilitato su questa wiki.",
        "api-error-verification-error": "Questo file potrebbe essere danneggiato, o avere l'estensione sbagliata.",
+       "api-error-was-deleted": "Un file con lo stesso nome è stato precedentemente caricato e successivamente eliminato.",
        "duration-seconds": "$1 {{PLURAL:$1|secondo|secondi}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuto|minuti}}",
        "duration-hours": "$1 {{PLURAL:$1|ora|ore}}",
index 1546fb8..1cdd9dc 100644 (file)
        "tog-ccmeonemails": "他の利用者に送信したメールの控えを自分にも送信",
        "tog-diffonly": "差分の下にページ内容を表示しない",
        "tog-showhiddencats": "隠しカテゴリを表示",
-       "tog-norollbackdiff": "巻き戻し後の差分を表示しない",
+       "tog-norollbackdiff": "ロールバック後の差分を表示しない",
        "tog-useeditwarning": "変更を保存せずに編集画面から離れようとしたら警告",
        "tog-prefershttps": "ログインする際、常に安全な接続を使用する",
        "underline-always": "常に付ける",
        "minoredit": "細部の編集",
        "watchthis": "このページをウォッチ",
        "savearticle": "ページを保存",
+       "publishpage": "ページを公開",
        "preview": "プレビュー",
        "showpreview": "プレビューを表示",
        "showdiff": "差分を表示",
        "recentchangeslinked-page": "ページ名:",
        "recentchangeslinked-to": "このページへのリンク元での変更の表示に切り替え",
        "recentchanges-page-added-to-category": "[[:$1]]をカテゴリに追加",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]]ã\81¨ä»\96[[Special:WhatLinksHere/$1|{{PLURAL:$2|1ã\83\9aã\83¼ã\82¸|$2ã\83\9aã\83¼ã\82¸}}]]ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81«è¿½å\8a ",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]]ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81«è¿½å\8a ã\80\82[[Special:WhatLinksHere/$1|ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81¯ä»\96ã\81®ã\83\9aã\83¼ã\82¸ã\81«å\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82]]",
        "recentchanges-page-removed-from-category": "[[:$1]]をカテゴリから除外",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]]ã\81¨ä»\96 [[Special:WhatLinksHere/$1|{{PLURAL:$2|1ã\83\9aã\83¼ã\82¸|$2ã\83\9aã\83¼ã\82¸}}]]ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81\8bã\82\89é\99¤å¤\96",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]]ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81\8bã\82\89é\99¤å¤\96ã\80\82[[Special:WhatLinksHere/$1|ã\81\93ã\81®ã\83\9aã\83¼ã\82¸ã\81¯ä»\96ã\81®ã\83\9aã\83¼ã\82¸ã\81«å\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99]]",
        "autochange-username": "メディアウィキ自動変更",
        "upload": "ファイルをアップロード",
        "uploadbtn": "ファイルをアップロード",
        "upload-form-label-infoform-description-tooltip": "この作品に対して特筆すべきことをすべて説明します。\n写真であれば、主に何が写っているのか、いつ、どこで撮ったものなのかについて述べてください。",
        "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|the upload page on {{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 Terms of Use] に同意します。",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "このファイルの著作権を所有していない場合、または別のライセンスの下でそれをリリースしたい場合には、 [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] を使用することを検討してください。",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "もしサイトが、それらの方針の下にて、このファイルのアップロードを許可している場合は、[[Special:Upload|{{SITENAME}}上でのアップロードページ]]の利用も検討できます。",
+       "upload-form-label-own-work": "これはあなた自身による作業です",
+       "upload-form-label-infoform-categories": "カテゴリ",
+       "upload-form-label-infoform-date": "日付",
+       "upload-form-label-own-work-message-local": "私は {{SITENAME}} 上での以下の利用規約とライセンス方針で、このファイルをアップロードしていることを確認します。",
+       "upload-form-label-not-own-work-message-local": "もし、あなたは {{SITENAME}} の方針の下で、このファイルをアップロードすることができない場合には、このダイアログを閉じて、別の方法をお試しください。",
+       "upload-form-label-not-own-work-local-local": "また、[[Special:Upload|デフォルトのアップロードページ]]を試してみてください。",
+       "upload-form-label-own-work-message-default": "私は共有リポジトリにこのファイルをアップロードしていることを理解しています。私は、そこにサービスやライセンス方針を以下のようにやっていることを、確認します。",
+       "upload-form-label-not-own-work-message-default": "もし、あなたは共有リポジトリの方針の下で、このファイルをアップロードすることができない場合には、このダイアログを閉じて、別の方法をお試しください。",
+       "upload-form-label-not-own-work-local-default": "このファイルはその方針の下でそこにアップロードすることができれば、また、 [[Special:Upload|the upload page on {{SITENAME}}]]を使用してみてください",
+       "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 Terms of Use] に同意します。",
+       "upload-form-label-not-own-work-message-shared": "このファイルの著作権を所有していない場合、または別のライセンスの下でそれをリリースしたい場合には、 [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] を使用することを検討してください。",
+       "upload-form-label-not-own-work-local-shared": "もしサイトが、それらの方針の下にて、このファイルのアップロードを許可している場合は、[[Special:Upload|{{SITENAME}}上でのアップロードページ]]の利用も検討できます。",
        "backend-fail-stream": "ファイル $1 をストリームできませんでした。",
        "backend-fail-backup": "ファイル $1 をバックアップできませんでした。",
        "backend-fail-notexists": "ファイル $1 は存在しません。",
        "ipb-unblock": "利用者またはIPアドレスのブロックを解除",
        "ipb-blocklist": "現在有効なブロックを表示",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}}の投稿の一覧",
+       "ipb-blocklist-duration-left": "残り $1",
        "unblockip": "ブロックを解除",
        "unblockiptext": "以下のフォームで利用者またはIPアドレスのブロックを解除できます。",
        "ipusubmit": "このブロックを解除",
index 7982dbb..a20bb2f 100644 (file)
                        "Matma Rex"
                ]
        },
-       "tog-underline": "Garisen ngisoré pranala:",
-       "tog-hideminor": "Dhelikaké besutan cilik ing owah-owahan pungkasan",
-       "tog-hidepatrolled": "Dhelikaké besutan awasan ing owah-owahan pungkasan",
-       "tog-newpageshidepatrolled": "Dhelikaké kaca kapanto saka daptar kaca anyar",
-       "tog-hidecategorization": "Dhelikaké kategorisasi kaca",
-       "tog-extendwatchlist": "Jembaraké daptar pangawasan kanggo nuduhaké kabèh owahan, ora mung sing paling anyar",
-       "tog-usenewrc": "Owah-owahané paguyuban miturut kaca nèng owah-owahan anyar lan daptar panto",
-       "tog-numberheadings": "Wènèhana nomer judul secara otomatis",
+       "tog-underline": "Nggaris ngisori pranala:",
+       "tog-hideminor": "Dhelikaké besutan cilik saka owah-owahan pungkasan",
+       "tog-hidepatrolled": "Dhelikaké besutan ingawasan saka owah-owahan pungkasan",
+       "tog-newpageshidepatrolled": "Dhelikaké kaca ingawasan saka pratélaning kaca anyar",
+       "tog-hidecategorization": "Dhelikaké gegebengan kaca",
+       "tog-extendwatchlist": "Ambakaké pawawangan nedya nuduhaké kabèh owahan, ora mung sing paling anyar",
+       "tog-usenewrc": "Golongaké owah-owahan miturut kaca ing owah-owahan anyar lan pawawangan",
+       "tog-numberheadings": "Wènèhi angkaning sesirah kanthi otomatis",
        "tog-showtoolbar": "Tuduhaké wilah piranti sarana besut",
        "tog-editondblclick": "Besut kaca sarana ngeklik pindho",
-       "tog-editsectiononrightclick": "Fungsèkna panyuntingan sub-bagian mawa klik-tengen ing judul bagian (mbutuhaké JavaScript)",
-       "tog-watchcreations": "Tambahaké kaca sing tak gawé lan berkas sing tak unggah nèng daptar pangawasan",
-       "tog-watchdefault": "Tambahaké kaca lan berkas sing tak sunting nèng daptar pangawasan",
-       "tog-watchmoves": "Tambahaké kaca lan berkas sing tak pindhahaké nèng daptar pangawasan",
-       "tog-watchdeletion": "Tambahaké kaca lan berkas sing tak busak nèng daptar pangawasan",
-       "tog-watchuploads": "Tambahaké barkas anyar sing tak unggah nyang pawawanganku",
-       "tog-watchrollback": "Tambahaké kaca sing tak wurungaké nyang pawawanganku",
-       "tog-minordefault": "Tandhanana kabèh suntingan dadi suntingan cilik secara baku",
-       "tog-previewontop": "Tuduhna pratayang sadurungé kothak sunting lan ora sawisé",
-       "tog-previewonfirst": "Tuduhna pratayang ing suntingan kapisan",
-       "tog-enotifwatchlistpages": "Kirimi kula layang èlèktronik yèn ana kaca utawa berkas nèng daptar pangawasanku sing diowah",
-       "tog-enotifusertalkpages": "Kirimana aku layang e-mail yèn kaca dhiskusiku owah",
-       "tog-enotifminoredits": "Kirimi kula layang èlèktronik uga yèn ana suntingan cilik saka kaca lan berkas",
-       "tog-enotifrevealaddr": "Kirimana aku layang e-mail ing layang notifikasi",
-       "tog-shownumberswatching": "Tuduhna cacahé pangawas",
-       "tog-oldsig": "Tapak asma sing ana:",
-       "tog-fancysig": "Anggepen tapak asta minangka teks wiki (tanpa pranala otomatis)",
+       "tog-editsectiononrightclick": "Idinaké mbesut pérangan sarana klik tengen ing sesirahing pérangan",
+       "tog-watchcreations": "Wuwuh kaca gawéanku lan barkas unggahanku nyang pawawanganku",
+       "tog-watchdefault": "Wuwuh kaca lan barkas besutanku nyang pawawanganku",
+       "tog-watchmoves": "Wuwuh kaca lan barkas lih-lihanku nyang pawawanganku",
+       "tog-watchdeletion": "Wuwuh kaca lan barkas busakanku nyang pawawanganku",
+       "tog-watchuploads": "Wuwuh barkas anyar unggahanku nyang pawawanganku",
+       "tog-watchrollback": "Wuwuh kaca sing tak wurungaké nyang pawawanganku",
+       "tog-minordefault": "Tengeri kabèh besutan minangka besutan cilik sacara baku",
+       "tog-previewontop": "Deleng prawuryan sadurungé besut kothak",
+       "tog-previewonfirst": "Tuduhaké prawuryan nalika mbesut pisanan",
+       "tog-enotifwatchlistpages": "Kirimi aku layangtronik yèn ana kaca utawa barkas ing pawawanganku sing diowah",
+       "tog-enotifusertalkpages": "Kirimi aku layangtronik yèn kaca gegunemanku diowah",
+       "tog-enotifminoredits": "Uga kirimi aku layangtronik yèn ana besutan cilik ing kaca lan barkas",
+       "tog-enotifrevealaddr": "Singkab alamat layangtronikku ing layang pawarta",
+       "tog-shownumberswatching": "Tuduhaké cacah wong sing ngawasi",
+       "tog-oldsig": "Tandha tangan sing ana:",
+       "tog-fancysig": "Anggep tandha tangan minangka tulisan wiki (tanpa pranala otomatis)",
        "tog-uselivepreview": "Trapaké prawuryan langsung",
        "tog-forceeditsummary": "Élingna aku menawa kothak ringkesan suntingan isih kosong",
-       "tog-watchlisthideown": "Delikna suntinganku ing daftar pangawasan",
+       "tog-watchlisthideown": "Dhelikaké besutanku saka pawawangan",
        "tog-watchlisthidebots": "Dhelikaké besutan bot saka pangawasan",
-       "tog-watchlisthideminor": "Delikna suntingan kecil di daftar pangawasan",
-       "tog-watchlisthideliu": "Ngumpetaké suntingan panganggo sing mlebu log seka daftar pangawasan",
+       "tog-watchlisthideminor": "Dhelikaké besutan cilik saka pawawangan",
+       "tog-watchlisthideliu": "Dhelikaké saka pawawangan besutaning wong sing mlebu",
        "tog-watchlistreloadautomatically": "Mot manèh pawawangan kanthi otomanis samangsa panyaring diowah (butuh JavaScript)",
-       "tog-watchlisthideanons": "Ngumpetaké suntingan panganggo anonim seka daftar pangawasan",
-       "tog-watchlisthidepatrolled": "Delikna suntingan sing wis dipatroli saka daftar pangawasan",
+       "tog-watchlisthideanons": "Dhelikaké saka pawawangan besutaning para anonim",
+       "tog-watchlisthidepatrolled": "Dhelikaké besutan ingawasan saka pawawangan",
        "tog-watchlisthidecategorization": "Dhelikaké kategorisasi kaca",
-       "tog-ccmeonemails": "Kirimana aku salinan layang e-mail sing tak-kirimaké menyang wong liya",
-       "tog-diffonly": "Aja dituduhaké isi kaca ing ngisor bédané suntingan",
-       "tog-showhiddencats": "Tuduhna kategori sing didelikaké",
-       "tog-norollbackdiff": "Lirwaaké prabédan sawusé nglakokaké sawijining pambalikan.",
-       "tog-useeditwarning": "Ã\88lingaké kula yèn kula ninggalaké suntingan sing durung kasimpen",
-       "tog-prefershttps": "Panggah sarana sambungan aman nalika mlebu",
-       "underline-always": "Mesthi",
+       "tog-ccmeonemails": "Kirimi aku salinan layangtronik sing tak kirim nyang wong liya",
+       "tog-diffonly": "Aja dituduhaké isining kaca ing ngisor bédané suntingan",
+       "tog-showhiddencats": "Tuduhaké kategori sing didhelikaké",
+       "tog-norollbackdiff": "Aja tuduhaké prabédan sawisé mbalèkaké.",
+       "tog-useeditwarning": "Ã\89lingaké kula yèn kula ninggalaké suntingan sing durung kasimpen",
+       "tog-prefershttps": "Tansah nganggo sambungan aman nalika mlebu",
+       "underline-always": "Tansah",
        "underline-never": "Ora tau",
-       "underline-default": "Kulit atau penjelajah bawaan",
-       "editfont-style": "Modhèl aksara (font) ing kotak suntingan:",
-       "editfont-default": "Standar panjelajah wèb",
+       "underline-default": "Baku kulit utawa pangluron",
+       "editfont-style": "Gagrag fon ing pambesutan:",
+       "editfont-default": "Baku pangluron",
        "editfont-monospace": "Fon monospasi",
        "editfont-sansserif": "Fon tansèrif",
        "editfont-serif": "Fon sèrif",
@@ -95,9 +95,9 @@
        "september": "Sèptèmber",
        "october": "Oktober",
        "november": "Nopèmber",
-       "december": "Désèmber",
+       "december": "Dhésèmber",
        "january-gen": "Januari",
-       "february-gen": "bruari",
+       "february-gen": "bruari",
        "march-gen": "Maret",
        "april-gen": "April",
        "may-gen": "Mèi",
        "september-gen": "Sèptèmber",
        "october-gen": "Oktober",
        "november-gen": "Nopèmber",
-       "december-gen": "Désèmber",
+       "december-gen": "Dhésèmber",
        "jan": "Jan",
        "feb": "Pèb",
        "mar": "Mar",
        "sep": "Sèp",
        "oct": "Okt",
        "nov": "Nop",
-       "dec": "Dès",
+       "dec": "D",
        "january-date": "Januari $1",
        "february-date": "Pèbruari $1",
        "march-date": "Maret $1",
        "august-date": "Agustus $1",
        "september-date": "$1 Sèptèmber",
        "october-date": "Oktober $1",
-       "november-date": "$1 Novèmber",
-       "december-date": "$1 Dèsèmber",
+       "november-date": "$1 Nopèmber",
+       "december-date": "$1 Dsèmber",
        "period-am": "Isuk-Awan",
        "period-pm": "Soré-Wengi",
        "pagecategories": "{{PLURAL:$1|Kategori|Kategori}}",
        "category_header": "Kaca sajeroning kategori \"$1\"",
-       "subcategories": "Subkategori",
+       "subcategories": "Anak kategori",
        "category-media-header": "Médhia sajeroning kategori \"$1\"",
-       "category-empty": "''Kategori iki saiki ora ngandhut artikel utawa média.''",
-       "hidden-categories": "{{PLURAL:$1|Kategori kadhelikaké|Kategori kadhelikaké}}",
+       "category-empty": "<em>Kategori iki lagi ora ngandhut artikel utawa médhia.</em>",
+       "hidden-categories": "{{PLURAL:$1|Kategori kadhelikan}}",
        "hidden-category-category": "Kategori kadhelikan",
-       "category-subcat-count": "{{PLURAL:$2|Kategori iki mung ngandhut subkategori ngisor iki.|Kategori iki ngandhut {{PLURAL:$1|subkategori|$1 subkategori}} ngisor iki saka gunggung $2 subkategori.}}",
-       "category-subcat-count-limited": "Kategori iki ora duwé {{PLURAL:$1|subkategori|$1 subkategori}} ''berikut''.",
+       "category-subcat-count": "{{PLURAL:$2|Kategori iki mung ngandhut saanak kategori ngisor iki.|Kategori iki ngandhut {{PLURAL:$1|anak kategori|$1 anak kategori}} ngisor iki saka gunggung $2 anak kategori.}}",
+       "category-subcat-count-limited": "Kategori iki duwé {{PLURAL:$1|anak kategori|$1 anak kategori}} kaya ngisor iki.",
        "category-article-count": "{{PLURAL:$2|Kategori iki mung ngandhut kaca ngisor iki.|{{PLURAL:$1|Kaca|$1 kaca}} ngisor iki ana ing kategori iki saka gunggung $2 kaca.}}",
        "category-article-count-limited": "Kategori iki ngandhut {{PLURAL:$1|kaca|$1 kaca-kaca}} sing kapacak ing ngisor iki.",
        "category-file-count": "{{PLURAL:$2|Kategori iki mung isi barkas iki.|{{PLURAL:$1|Barkas|$1 barkas}} iki ana sajeroning kategori iki saka $2 gunggungé.}}",
        "moredotdotdot": "Liyané...",
        "morenotlisted": "Pratélan iki ora jangkep.",
        "mypage": "Kaca",
-       "mytalk": "Wicara",
-       "anontalk": "Rembug",
+       "mytalk": "Geguneman",
+       "anontalk": "Geguneman",
        "navigation": "Napigasi",
        "and": "&#32;lan",
        "qbfind": "Golèk",
        "searchbutton": "Golèk",
        "go": "Menyang",
        "searcharticle": "Menyang",
-       "history": "Sajarah kaca",
+       "history": "Babading kaca",
        "history_short": "Babad",
        "updatedmarker": "wis inganyaran kawit tekaku sing pungkasan",
        "printableversion": "Cara cithakan",
        "deletethispage": "Busak kaca iki",
        "undeletethispage": "Wurungaké pambusaking kaca iki",
        "undelete_short": "Batal busak {{PLURAL:$1|sabesutan|$1 besutan}}",
-       "viewdeleted_short": "Pirsani {{PLURAL:$1|suntingan|suntingan}} ingkang sampun kabusak",
+       "viewdeleted_short": "Deleng {{PLURAL:$1|sabesutan sing kabusak|$1 besutan sing kabusak}}",
        "protect": "Reksa",
        "protect_change": "owah",
        "protectthispage": "Reksa kaca iki",
        "talkpage": "Rembug kaca iki",
        "talkpagelinktext": "gunem",
        "specialpage": "Kaca mirunggan",
-       "personaltools": "Piranti pribadhi",
+       "personaltools": "Piranti priangga",
        "articlepage": "Deleng kaca isi",
-       "talk": "Rembug",
+       "talk": "Rerembugan",
        "views": "Praèn",
        "toolbox": "Piranti",
        "userpage": "Deleng kaca panganggo",
        "otherlanguages": "Ing basa liya",
        "redirectedfrom": "(Dilih saka $1)",
        "redirectpagesub": "Alih kaca",
-       "redirectto": "Malih nyang:",
+       "redirectto": "Ngalih menyang:",
        "lastmodifiedat": "Kaca iki pungkasan diowah kala $1, tabuh $2.",
-       "viewcount": "Kaca iki wis tau diaksès cacahé ping {{PLURAL:$1|siji|$1}}.",
+       "viewcount": "Kaca iki wis diaksès ping {{PLURAL:$1|siji|$1}}.",
        "protectedpage": "Kaca kareksa",
        "jumpto": "Jujug:",
        "jumptonavigation": "napigasi",
        "aboutpage": "Project:Bab",
        "copyright": "Kabèh isi kasedyakaké miturut $1.",
        "copyrightpage": "{{ns:project}}:Hak cipta",
-       "currentevents": "Kadadéan saiki",
-       "currentevents-url": "Project:Kadadéan saiki",
+       "currentevents": "Kadadian saiki",
+       "currentevents-url": "Project:Kadadian saiki",
        "disclaimers": "Sélakan",
        "disclaimerpage": "Project:Sélakan umum",
        "edithelp": "Pitulung besut",
        "policy-url": "Project:Kabijakan",
        "portal": "Gapura paguyuban",
        "portal-url": "Project:Garupa paguyuban",
-       "privacy": "Niti pripasi",
+       "privacy": "Niti priangga",
        "privacypage": "Project:Niti pripasi",
        "badaccess": "Aksès ora olèh",
        "badaccess-group0": "Panjenengan ora pareng nglakokaké tindhakan sing panjenengan gayuh.",
        "laggedslavemode": "Pènget: Kaca iki mbokmenawa isiné dudu pangowahan pungkasan.",
        "readonly": "Umpak data kagembok",
        "enterlockreason": "Lebokna alesan panguncèn, kalebu uga prakiran kapan kunci bakal dibuka",
-       "readonlytext": "Database lagi dikunci marang panampan anyar. Pangurus sing ngunci mènèhi katrangan kaya mangkéné: <p>$1",
+       "readonlytext": "Juru administrasi sistem sing ngunci iku medhar mangkéné: $1",
        "missing-article": "Basis data ora bisa nemokaké tèks kaca sing kuduné ana, yaiku \"$1\" $2.\nBab iki bisasané disebabaké déning pranala daluwarsa menyang revisi sadurungé kaca sing wis dibusak.\nYèn dudu iki panyebabé, panjenengan manawa bisa nemokaké kasalahan (''bug'') jroning piranti alus (''software''). Mangga dilapuraké bab iki menyang [[Special:ListUsers/sysop|administrator]], kanthi nyebutaké alamat URL sing dituju",
        "missingarticle-rev": "(owahan#: $1)",
        "missingarticle-diff": "(Béda: $1, $2)",
        "cannotdelete-title": "Ora bisa mbusak kaca \"$1\"",
        "delete-hook-aborted": "Pambusakan dibatalaké déning ''hook''.\nOra ana alesané.",
        "no-null-revision": "Ora isa nggawe revisi 'null' anyar kanggo kaca \"$1\"",
-       "badtitle": "Sésirah ala",
-       "badtitletext": "Judhul kaca sing panjenengan ora bisa dituduhaké, kosong, utawa dadi judhul antar-basa utawa judhul antar-wiki. Iku bisa uga ana  sawijining utawa luwih aksara sing ora bisa didadèkaké judhul.",
+       "badtitle": "Sesirah ala",
+       "badtitletext": "Sesirahing kaca sing dikarepaké ora sah, suwung, utawa salah nggayut nyang sesirah antarabasa utawa antarawiki.\nIku mungkin ngandhut pralambang siji utawa luwih sing ora kena dianggo tumrap sesirah iki.",
        "perfcached": "Data iki mung dijupuk saka papan singgahan lan mungkin ora kaanyaran. Maksimum {{PLURAL:$1|sak asil|$1 asil}} sumadhiya nèng papan singgahan.",
        "perfcachedts": "Data iki mung dijupuk saka papan singgahan lan mungkin dianyari pungkasan $1. Maksimum {{PLURAL:$4|sak asil|$4 asil}} sumadhiya nèng papan singgahan.",
        "querypage-no-updates": "Update saka kaca iki lagi dipatèni. Data sing ana ing kéné saiki ora bisa bakal dibalèni unggah manèh.",
        "actionthrottled": "Tindakan diwatesi",
        "actionthrottledtext": "Minangka sawijining pepesthèn anti-spam, panjenengan diwatesi nglakoni tindhakan iki sing cacahé kakèhan ing wektu cendhak.\nMangga dicoba manèh ing sawetara menit.",
        "protectedpagetext": "Kaca iki wis digembok supaya ora bisa disunting lan diapa-apakaké.",
-       "viewsourcetext": "Panjenengan bisa mirsani utawa nulad sumber kaca iki:",
-       "viewyourtext": "Sampéyan bisa ndelok lan nyalin sumber '''suntingan Sampéyan''' nèng kaca iki:",
+       "viewsourcetext": "Sampéyan bisa ndeleng lan nyalin sumbering kaca iki.",
+       "viewyourtext": "Sampéyan bisa ndeleng lan nyalin sumbering <strong>besutaning sampéyan</strong> ing kaca iki.",
        "protectedinterface": "Kaca iki isiné tèks antarmuka sing dienggo software lan wis dikunci kanggo menghindari kasalahan.",
        "editinginterface": "'''Pènget:''' Panjenengan nyunting kaca sing dianggo nyedyakaké tèks antarmuka kanggo piranti alus.\nPangowahan kaca iki bakal awèh pangaruh marang tampilan antarmuka panganggo kanggoné panganggo liya.\nKanggo terjemahan, mangga nganggo [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], proyèk lokalisasi MediaWiki.",
        "cascadeprotected": "Kaca iki wis direksa saka panyuntingan amerga disertakaké ing {{PLURAL:$1|kaca|kaca-kaca}} ngisor iki sing wis direksa mawa opsi \"runtun\" diaktifaké:\n$2",
        "welcomecreation-msg": "Akun panjenengan wis kacipta. Aja lali nata konfigurasi [[Special:Preferences|preferensi {{SITENAME}}]] panjenengan.",
        "yourname": "Jeneng panganggo:",
        "userlogin-yourname": "Jeneng panganggo",
-       "userlogin-yourname-ph": "Isi jeneng panganggo Sampéyan",
+       "userlogin-yourname-ph": "Isi jeneng panganggoning sampéyan",
        "createacct-another-username-ph": "Isi jeneng panganggo",
        "yourpassword": "Tembung wadi:",
        "userlogin-yourpassword": "Tembung wadi",
        "createacct-submit": "Gawé akun sampéyan",
        "createacct-another-submit": "Gawé akun",
        "createacct-benefit-heading": "{{SITENAME}} digawé déning wong-wong kaya déné sampéyan.",
-       "createacct-benefit-body1": "{{PLURAL:$1|besutan|besutan}}",
-       "createacct-benefit-body2": "{{PLURAL:$1|kaca|kaca}}",
-       "createacct-benefit-body3": "{{PLURAL:$1|panyumbang|panyumbang}} pungkasan",
+       "createacct-benefit-body1": "{{PLURAL:$1|besutan}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|kaca}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|sing nyumbang}} pungkasan",
        "badretype": "Sandhi panjenengan ora gathuk",
        "usernameinprogress": "Panggawéning akun tumrap jeneng panganggo iki tembé lumaku.\nEntèni sadhéla.",
        "userexists": "Jeneng panganggo sing dilebokaké lagi dianggo.\nMangga pilih jeneng liya.",
        "createaccount-title": "Gawé rékening kanggo {{SITENAME}}",
        "createaccount-text": "Ana wong sing nggawé sawijining akun utawa rékening kanggo alamat e-mail panjenengan ing {{SITENAME}} ($4) mawa jeneng \"$2\" lan tembung sandi \"$3\". Panjenengan disaranaké kanggo mlebu log lan ngganti tembung sandi panjenengan saiki.\n\nPanjenengan bisa nglirwakaké pesen iki yèn akun utawa rékening iki digawé déné sawijining kaluputan.",
        "login-throttled": "Panjenengan wis kakèhan njajal mlebu log.\nTulung nunggu dhisik $1 sadurungé njajal manèh.",
-       "login-abort-generic": "Sampéyan ora suksès mlebu log - Dibatalaké",
+       "login-abort-generic": "Sampéyan ora bisa mlebu - Kawurungan",
        "loginlanguagelabel": "Basa: $1",
        "suspicious-userlogout": "Panjaluk panjenengan supaya metu ditolak amarga katoné panjlajah internt utawa proksi panyinggah.",
        "createacct-another-realname-tip": "Jeneng asli ora kudu dilebokake.\n\nYen sampeyan milih nglebokake jeneng asli, jeneng kuwi bakal dinggo ngwenehi atribusi kanggo karya-karyane.",
        "user-mail-no-addy": "Njajal ngirim layang èlèktronik tanpa alamat layang èlèktronik.",
        "user-mail-no-body": "Nyoba ngirim layang e-mail, tapi isine kosong.",
        "changepassword": "Ganti tembung wadi",
-       "resetpass_announce": "Panjenengan wis mlebu log mawa kodhe sementara sing dikirim mawa e-mail. Menawa kersa nglanjutaké, panjenengan kudu milih tembung sandhi anyar ing kéné:",
+       "resetpass_announce": "Kanggo ngrampungaké lelakoning lumebu, sampéyan kudu masang tembung wadi anyar.",
        "resetpass_text": "<!-- Tambahaké teks ing kéné -->",
        "resetpass_header": "Ganti tembung wadining akun",
        "oldpassword": "Tembung wadi lawas:",
        "newpassword": "Tembung wadi anyar:",
        "retypenew": "Tik manèh tembung wadi anyaré:",
        "resetpass_submit": "Nata tembung sandhi lan mlebu log",
-       "changepassword-success": "Tembung sandhi panjenengan wis suksès diowahi!",
+       "changepassword-success": "Tembung wadining sampéyan kasil diowah!",
        "botpasswords": "Tembung wadi bot",
        "botpasswords-label-appid": "Jeneng bot:",
        "botpasswords-label-create": "Gawé",
        "passwordreset-emailtext-ip": "Ana uwong (mbok menawa Sampéyan, mawa angka IP $1) njaluk ganti tembung sandhiné Sampéyan ana ing {{SITENAME}} ($4). {{PLURAL:$3|Rèkèning|Rèkèning-rèkèning}} ngisor iki magepokan karo padunungané layang èlèktronik iki:\n\n$2\n\n{{PLURAL:$3|Tembung sandhi sawetara iki}} bakal kedaluwarsa ing {{PLURAL:$5|sak dina|$5 dina}}.\nSampéyan kudu mlebu log lan milih siji tembung sandhi anyar saiki. Yèn wong liya sing njaluk iki, utawa yèn Sampéyan jebul wis kèlingan tembung sandhiné sing lawas saéngga ora ana niyat kanggo ngganti, Sampéyan bisa ngejaraké wara-wara iki lan bacutaké nganggo tembung sandhiné lawas Sampéyan.",
        "passwordreset-emailtext-user": "Panganggo $1 seka {{SITENAME}} njaluk ganti tembung sandhiné Sampéyan ana ing {{SITENAME}} ($4). {{PLURAL:$3|Rèkèning|Rèkèning-rèkèning}} ngisor iki magepokan karo padunungané layang èlèktronik iki:\n\n$2\n\n{{PLURAL:$3|Tembung sandhi sawetara iki}} bakal kedaluwarsa ing {{PLURAL:$5|sak dina|$5 dina}}.\nSampéyan kudu mlebu log lan milih siji tembung sandhi anyar saiki. Yèn wong liya sing njaluk iki, utawa yèn Sampéyan jebul wis kèlingan tembung sandhiné sing lawas saéngga ora ana niyat kanggo ngganti, Sampéyan bisa ngejaraké wara-wara iki lan bacutaké nganggo tembung sandhiné lawas Sampéyan.",
        "passwordreset-emailelement": "Jeneng panganggo: \n$1\n\nTembung wadi sauntara: \n$2",
-       "passwordreset-emailsentemail": "Layang èlèktronik kanggo mbalèkaké tembung sandhi wis dikirim.",
+       "passwordreset-emailsentemail": "Yèn layang èlèktronik iki nggayut akuning sampéyan, layang kanggo salin tembung wadi bakal dikirim.",
        "passwordreset-emailsent-capture": "Layang èlèktronik kanggo mbalèkaké tembung sandhi wis dikirim, bisa didelok ngisor iki.",
        "passwordreset-emailerror-capture": "Layang èlèktronik pangèling tembung sandhi wis digawe, yaiku sing ditampilaké nèng ngisor iki, nanging ora kasil dikirim ing {{GENDER:$2|panganggo}}: $1",
-       "changeemail": "Ganti alamat layang èlèktronik",
+       "changeemail": "Owah utawa busak alamat layang èlèktronik",
        "changeemail-header": "Ganti alamat layang èlèktronik akun",
        "changeemail-no-info": "Sampéyan kudu mlebu log kanggo ngaksès kaca iki langsung.",
        "changeemail-oldemail": "Alamat layang èlèktronik saiki:",
        "resettokens-done": "Reset token.",
        "resettokens-resetbutton": "Reset token sing dipilih",
        "bold_sample": "Tulisan kandel",
-       "bold_tip": "Tulisann kandel",
-       "italic_sample": "Tulisan miring",
+       "bold_tip": "Tulisan kandel",
+       "italic_sample": "Tulisan dhoyong",
        "italic_tip": "Tulisan dhoyong",
        "link_sample": "Sesirah pranala",
        "link_tip": "Pranala njero",
        "extlink_tip": "Pranala jaba (élinga ater-ater http://)",
        "headline_sample": "Tulisan sesirah",
        "headline_tip": "Sesirah tataran 2",
-       "nowiki_sample": "Tèks iki ora bakal diformat",
+       "nowiki_sample": "Isi nganggo tulisan tanpa format ing kéné",
        "nowiki_tip": "Aja nganggo format wiki",
        "image_sample": "Conto.jpg",
-       "image_tip": "Mènèhi gambar/berkas",
+       "image_tip": "Barkas sisipan",
        "media_sample": "Conto.ogg",
        "media_tip": "Pranala barkas",
        "sig_tip": "Tandha tangan sampéyan mawa tandha wayah",
        "hr_tip": "Garis horisontal",
        "summary": "Tingkesan:",
-       "subject": "Subyek/judhul:",
+       "subject": "Jejer:",
        "minoredit": "Iki besutan cilik",
        "watchthis": "Awasi kaca iki",
        "savearticle": "Simpen kaca",
        "missingcommenttext": "Tulung lebokna komentar ing ngisor iki.",
        "missingcommentheader": "'''Pangéling:''' Sampéyan durung nyadhiyakaké judhul/jejer kanggo tanggepan iki.\nYèn Sampéyan klik \"{{int:savearticle}}\" manèh, suntingan Sampéyan bakal kasimpen tanpa kuwi.",
        "summary-preview": "Prawuryan tingkesan:",
-       "subject-preview": "Pratayang subyèk/judhul:",
+       "subject-preview": "Prawuryaning jejer:",
        "blockedtitle": "Panganggo kapalangan",
        "blockedtext": "'''Asma panganggo utawa alamat IP panjenengan diblokir.'''\n\nBlokir iki sing nglakoni $1.\nAlesané ''$2''.\n\n* Diblokir wiwit: $8\n* Kadaluwarsa pemblokiran ing: $6\n* Sing arep diblokir: $7\n\nPanjenengan bisa ngubungi $1 utawa [[{{MediaWiki:Grouppage-sysop}}|pangurus liyané]] kanggo ngomongaké prakara iki.\n\nPanjenengan ora bisa nggunakaké fitur 'Kirim layang e-mail panganggo iki' kejaba panjenengan wis nglebokaké alamat e-mail sing sah ing [[Special:Preferences|préferènsi]] panjenengan.\n\nAlamat IP panjenengan iku $3, lan ID pamblokiran iku #$5.\nTulung kabèh informasi ing ndhuwur iki disertakaké ing saben pitakon panjenengan.",
        "autoblockedtext": "Alamat IP panjenangan wis diblokir minangka otomatis amerga dienggo déning panganggo liyané. Pamblokiran dilakoni déning $1 mawa alesan:\n\n:''$2''\n\n* Diblokir wiwit: $8\n* Blokir kadaluwarsa ing: $6\n* Sing dikarepaké diblokir: $7\n\nPanjenengan bisa ngubungi $1 utawa [[{{MediaWiki:Grouppage-sysop}}|pangurus liyané]] kanggo ngomongaké perkara iki.\n\nPanjenengan ora bisa nganggo fitur \"kirim e-mail panganggo iki\" kejaba panjenengan wis nglebokaké alamat e-mail sing sah ing [[Special:Preferences|préferènsi]] panjenengan lan panjenengan wis diblokir kanggo nggunakaké.\n\nID pamblokiran panjenengan iku #$5 lan alamat IP panjenengan iku $3. Tulung sertakna informasi ing dhuwur kabèh iki saben ngajokaké pitakonan panjenengan. Matur nuwun.",
        "blockednoreason": "ora ana alesan sing diwènèhaké",
-       "whitelistedittext": "Panjenengan kudu $1 supaya bisa nyunting artikel.",
+       "whitelistedittext": "Sampéyan kudu $1 murih bisa mbesut kaca.",
        "confirmedittext": "Panjenengan kudu ndhedhes alamat e-mail dhisik sadurungé pareng nyunting sawijining kaca. Mangga nglebokaké lan validasi alamat e-mail panjenengan sadurungé nglakoni panyuntingan. Alamat e-mail sawisé bisa diowahi liwat [[Special:Preferences|kaca préférènsi]]",
        "nosuchsectiontitle": "Pérangan ora katemu",
        "nosuchsectiontext": "Panjenengan nyoba nyunting sawijining bagéan sing ora ana.\nBagéan iki manawa wis dipindhah utawa dibusak nalika panjenengan buka.",
        "templatesusedsection": "{{PLURAL:$1|Cithakan}} sing dienggo ding bagian iki:",
        "template-protected": "(kareksa)",
        "template-semiprotected": "(semu kareksa)",
-       "hiddencategories": "Kaca iki sawijining anggota saka {{PLURAL:$1|1 kategori ndelik|$1 kategori-kategori ndelik}}:",
+       "hiddencategories": "Kaca iki anggotaning {{PLURAL:$1|1 kategori wadi|$1 kategori wadi}}:",
        "edittools": "<!-- Tèks ing ngisor iki bakal ditudhuhaké ing ngisoring isènan suntingan lan pangemotan.-->",
        "nocreatetext": "Situs iki ngwatesi kemampuan kanggo nggawé kaca anyar. Panjenengan bisa bali lan nyunting kaca sing wis ana, utawa mangga [[Special:UserLogin|mlebua log utawa ndaftar]]",
        "nocreate-loggedin": "Panjenengan ora kagungan idin kanggo nggawé kaca anyar.",
        "permissionserrorstext": "Panjengan ora kagungan idin kanggo nglakoni sing panjenengan gayuh amerga {{PLURAL:$1|alesan|alesan-alesan}} iki:",
        "permissionserrorstext-withaction": "Panjenengan ora duwé hak aksès kanggo $2, amarga {{PLURAL:$1|alasan|alasan}} ing ngisor iki:",
        "recreate-moveddeleted-warn": "'''Pènget: Panjenengan gawé manèh sawijining kaca sing wis tau dibusak.'''\n\nMangga digagas manèh apa pantes nerusaké nyunting kaca iki.\nIng ngisor iki kapacak log pambusakan lan pamindhahan saka kaca iki:",
-       "moveddeleted-notice": "Kaca iki wis dibusak.\nCathetan busakan lan lihlihan kaca ana ing ngisor minangka rujukan.",
+       "moveddeleted-notice": "Kaca iki wis dibusak.\nCathetan busakan lan lih-lihan kaca ana ing ngisor minangka rujukan.",
        "log-fulllog": "Deleng cathetan wutuh",
        "edit-hook-aborted": "Suntingan dibatalaké déning kait parser\nTanpa ana katrangan.",
        "edit-gone-missing": "Ora bisa nganyari kaca.\nKatoné kaca iki wis dibusak.",
        "undo-success": "Suntingan iki bisa dibatalaké. Tulung priksa prabandhingan ing ngisor iki kanggo mesthèkaké yèn prakara iki pancèn sing bener panjenengan pèngin lakoni, banjur simpenen pangowahan iku kanggo ngrampungaké pambatalan suntingan.",
        "undo-failure": "Suntingan iki ora bisa dibatalakén amerga ana konflik panyuntingan antara.",
        "undo-norev": "Suntingan iki ora bisa dibatalaké amerga ora ana utawa wis dibusak.",
-       "undo-summary": "←Mbatalaké revisi $1 déning [[Special:Contributions/$2|$2]] ([[User talk:$2|Dhiskusi]])",
+       "undo-summary": "Balèkaké owahan $1 déning [[Special:Contributions/$2|$2]] ([[User talk:$2|gunem]])",
        "undo-summary-username-hidden": "Batalna revisi $1 saking panganggo kang didhelikake",
        "cantcreateaccounttitle": "Akun ora bisa digawé",
        "cantcreateaccount-text": "Saka alamat IP iki ('''$1''') ora diparengaké nggawé akun utawa rékening. Sing mblokir utawa ora marengaké iku [[User:$3|$3]].\n\nAlesané miturut $3 yaiku ''$2''",
        "logdelete-failure": "'''Aturan pandhelikan ora bisa disèt:'''\n$1",
        "revdel-restore": "Ngowahi visiblitas (pangatonan)",
        "pagehist": "Babading kaca",
-       "deletedhist": "Babad kabusakan",
+       "deletedhist": "Babad kabusak",
        "revdelete-hide-current": "Gagal ndhelikaké révisi tanggal $2, $1: iki arupa révisi paling anyar.\nRévisi iki ora bisa didhelikaké.",
        "revdelete-show-no-access": "Gagal nampilaké révisi tanggal $1, jam $2: révisi iki wis ditandhani \"kawates\".\nPanjenengan ora nduwèni aksès menyang révisi iki.",
        "revdelete-modify-no-access": "Gagal ngowahi révisi tanggal $1, jam $2: révisi iki wis ditandhani \"kawates\".\nPanjenengan ora nduwèni aksès menyang révisi iki.",
        "revdelete-reason-dropdown": "*Alasan penghapusan yang umum\n** Pelanggaran hak cipta\n** Komentar atau informasi pribadi yang tidak pantas\n** Nama pengguna yang tidak pantas\n** Berpotensi mencemarkan nama baik",
        "revdelete-otherreason": "Alesan liya/tambahan:",
        "revdelete-reasonotherlist": "Alesan liya",
-       "revdelete-edit-reasonlist": "Sunting alesan pambusakan",
+       "revdelete-edit-reasonlist": "Besut jalaraning pambusak",
        "revdelete-offender": "Juru pangriptaning owahan:",
        "suppressionlog": "Log barang-barang sing didelikaké (''oversight'')",
        "suppressionlogtext": "Ngisor iki daptar apa-apa waé sing wis dibusak lan diblokir kalebu kontèn sing didhelikaké saka para pangurus.\nDelok [[Special:BlockList|daptar blokiran]] sing isiné daptar apa-apa waé sing lagi dilarang lan diblokir.",
        "mergelog": "Gabung log",
        "revertmerge": "Batalna panggabungan",
        "mergelogpagetext": "Ing ngisor iki kapacak daftar panggabungan sajarah kaca ing kaca liyané.",
-       "history-title": "Riwayat rèvisi saka \"$1\"",
+       "history-title": "Babad owahaning \"$1\"",
        "difference-title": "Prabéda antara owahan \"$1\"",
        "difference-title-multipage": "Prabédhan antara kaca \"$1\" lan \"$2\"",
        "difference-multipage": "(Prabédhan antar kaca)",
        "searchmenu-exists": "'''Ana kaca kanthi jeneng \"[[$1]]\" ing wiki iki'''",
        "searchmenu-new": "<strong>Gawéa kaca \"[[:$1]]\" nyang wiki iki!</strong> {{PLURAL:$2|0=|Uga delenga kaca sing katemu sarana panggolèking sampéyan.|Uga delenga kasiling panggolèk.}}",
        "searchprofile-articles": "Kaca isi",
-       "searchprofile-images": "Sarwasarana",
+       "searchprofile-images": "Sarwamadya",
        "searchprofile-everything": "Samubarang",
        "searchprofile-advanced": "Lungidan",
        "searchprofile-articles-tooltip": "Golèkan ing $1",
        "search-external": "Panggolèkan èkstèrnal",
        "searchdisabled": "Sawetara wektu iki panjenengan ora bisa nggolèk mawa fungsi golèk {{SITENAME}}. Kanggo saiki mangga panjenengan bisa golèk nganggo Google. Nanging isi indèks Google kanggo {{SITENAME}} bisa waé lawas lan durung dianyari.",
        "search-error": "Ana kasalahan wektu nggoleki: $1",
-       "preferences": "Preferensi (pilihan)",
-       "mypreferences": "Préferènsi",
+       "preferences": "Pilihan",
+       "mypreferences": "Pilihan",
        "prefs-edits": "Gunggung besutan:",
        "prefsnologintext2": "Tulung $1 kanggo ngganti preferensi sampeyan.",
        "prefs-skin": "Kulit",
-       "skin-preview": "Pratilik",
-       "datedefault": "Ora ana préferènsi",
+       "skin-preview": "Prawuryan",
+       "datedefault": "Ora ana pilihan",
        "prefs-labs": "Piranti lab",
-       "prefs-user-pages": "Kaca panganggo",
-       "prefs-personal": "Profil panganggo",
+       "prefs-user-pages": "Kacaning sing nganggo",
+       "prefs-personal": "Panjèrènging sing nganggo",
        "prefs-rc": "Owah-owahan pungkasan",
-       "prefs-watchlist": "Dhaftar pangawasan",
+       "prefs-watchlist": "Pawawangan",
+       "prefs-editwatchlist": "Besut pawawangan",
+       "prefs-editwatchlist-label": "Besut isining pawawanganing sampéyan",
+       "prefs-editwatchlist-edit": "Deleng lan busak sesirah ing pawawanganing sampéyan",
+       "prefs-editwatchlist-raw": "Besut pawawangan lakaran",
+       "prefs-editwatchlist-clear": "Resiki pawawanganing sampéyan",
        "prefs-watchlist-days": "Cacahé dina sing dituduhaké ing dhaftar pangawasan:",
        "prefs-watchlist-days-max": "Maksimum $1 {{PLURAL:$1|dina|dina}}",
        "prefs-watchlist-edits": "Cacahé suntingan maksimum sing dituduhaké ing dhaftar pangawasan sing luwih jangkep:",
        "prefs-watchlist-edits-max": "Gunggung maksimum: 1000",
-       "prefs-watchlist-token": "Token pantauan:",
+       "prefs-watchlist-token": "Tokening pawawangan:",
        "prefs-misc": "Liya-liya",
        "prefs-resetpass": "Ganti tembung sandi",
-       "prefs-changeemail": "Ganti alamat layang èlèktronik",
+       "prefs-changeemail": "Owah utawa busak alamat layangtronik",
        "prefs-setemail": "Setèl alamat layang èlèktronik",
        "prefs-email": "Opsi layang-e",
        "prefs-rendering": "Tampilan",
        "columns": "Kolom:",
        "searchresultshead": "Panggolèkan",
        "stub-threshold": "Ambang wates kanggo format <a href=\"#\" class=\"stub\">pranala rintisan</a>:",
+       "stub-threshold-sample-link": "pralampita",
        "stub-threshold-disabled": "Dipatèni",
        "recentchangesdays": "Cacahé dina sing dituduhaké ing owah-owahan pungkasan:",
        "recentchangesdays-max": "(maksimum $1 {{PLURAL:$1|dina|dina}})",
        "prefs-help-recentchangescount": "Iki klebu owah-owahan pungkasan, kaca sajarah, lan log.",
        "prefs-help-watchlist-token2": "Ini adalah kunci rahasia (token) ke web feed dari daftar pantauan Anda.\nSiapa saja yang tahu akan dapat melihat daftar pantauan Anda, jadi jangan dibagikan.\n[[Special:ResetTokens|Klik di sini jika Anda perlu menyetel ulang]].",
        "savedprefs": "Préferènsi Panjenengan wis disimpen",
+       "savedrights": "Haking panganggo {{GENDER:$1|$1}} wis kasimpen.",
        "timezonelegend": "Zona wektu:",
        "localtime": "Wektu saenggon:",
        "timezoneuseserverdefault": "Anggo gawan wiki ($1)",
        "prefs-namespaces": "Ruang jeneng / Bilik jeneng",
        "default": "baku",
        "prefs-files": "Berkas",
-       "prefs-custom-css": "CSS pribadi",
-       "prefs-custom-js": "JS pribadi",
+       "prefs-custom-css": "CSS priangga",
+       "prefs-custom-js": "JavaScript priangga",
        "prefs-common-css-js": "CSS/JS didumaké kanggo kabèh kulit:",
        "prefs-reset-intro": "Panjenengan bisa migunakaké kaca iki kanggo mbalèkaké préferensi panjenengan marang setèlan baku situs.\nPembalikan ora bisa dibatalaké.",
        "prefs-emailconfirm-label": "Konfirmasi layang-e:",
        "prefs-help-signature": "Komentar ing kaca wicara kudu ditapak astani nganggo \"<nowiki>~~~~</nowiki>\" sing bakal dikonvèrsi dadi tapak asta panjenengan lan tanggal wektu.",
        "badsig": "Tapak astanipun klèntu; cèk rambu HTML.",
        "badsiglength": "Tapak asta panjenengan kedawan.\nAja luwih saka {{PLURAL:$1|karakter|karakter}}.",
-       "yourgender": "Jinis kelamin:",
-       "gender-unknown": "Ora dinyatakaké",
-       "gender-male": "Lanang",
-       "gender-female": "Wadon",
+       "yourgender": "Kepiyé sampéyan medhar priangganing sampéyan?",
+       "gender-unknown": "Nalika nyebut sampéyan, piranti alus iku bakal nganggo tembung sing nétral jèndher sabisané",
+       "gender-male": "Dhèwèké mbesut kaca wiki",
+       "gender-female": "Dhèwèké mbesut kaca wiki",
        "prefs-help-gender": "Opsional: Dipigunakaké kanggo panyebutan jinis kelamin sing bener déning piranti alus.\nInformasi iki bakal kabuka kanggo publik.",
-       "email": "Layang élèktronik (E-mail)",
-       "prefs-help-realname": "* <strong>Asma asli</strong> (ora wajib): menawa panjenengan maringi, asma asli panjenengan bakal digunakaké kanggo mènèhi akrédhitasi kanggo kasil karya tulis panjenengan.",
+       "email": "Layangtronik",
+       "prefs-help-realname": "Jeneng asli manasuka.\nMenawa diisi, iku bakal kanggo ngatribusi sampéyan awit karyaning sampéyan.",
        "prefs-help-email": "Alamat layang èlèktronik sipaté mung pilihan, nanging dibutuhaké kanggo nyetèl ulang tembung sandhi yèn Sampéyan lali.",
        "prefs-help-email-others": "Sampéyan uga bisa milih kanggo ngidinaké wong liya ngubungi Sampéyan liwat layang èlèktronik sing ana ing kaca panganggo utawa kaca guneman.\nAlamat layang èlèktronik Sampéyan ora dituduhaké nalika wong liya ngubungi Sampéyan.",
        "prefs-help-email-required": "Alamat layang-e dibutuhaké.",
-       "prefs-info": "Informasi dhasar",
+       "prefs-info": "Katerangan pokok",
        "prefs-i18n": "Internasionalisasi",
        "prefs-signature": "Tapak asma",
        "prefs-dateformat": "Format tanggal",
        "userrights": "Manajemen hak panganggo",
        "userrights-lookup-user": "Ngatur kelompok panganggo",
        "userrights-user-editname": "Lebokna jeneng panganggo:",
-       "editusergroup": "Sunting kelompok panganggo",
+       "editusergroup": "Besut golongan {{GENDER:$1|panganggo}}",
        "editinguser": "Ngganti hak panganggo '''[[User:$1|$1]]''' $2",
-       "userrights-editusergroup": "Sunting kelompok panganggo",
+       "userrights-editusergroup": "Besut golongan panganggo",
        "saveusergroups": "Simpen kelompok panganggo",
        "userrights-groupsmember": "Anggota saka:",
        "userrights-groupsmember-auto": "Anggota implisit saka:",
        "grouppage-suppress": "{{ns:project}}:Oversight",
        "right-read": "Maca kaca-kaca",
        "right-edit": "Besut kaca",
-       "right-createpage": "Nggawé kaca (sing dudu kaca dhiskusi)",
-       "right-createtalk": "Nggawé kaca dhiskusi",
+       "right-createpage": "Gawé kaca (sing dudu kaca rerembugan)",
+       "right-createtalk": "Gawé kaca rerembugan",
        "right-createaccount": "Nggawé rékening (akun) panganggo anyar",
        "right-minoredit": "Tandhani minangka besutan cilik",
-       "right-move": "Pindhahna kaca",
+       "right-move": "Ngalih kaca",
        "right-move-subpages": "Pindhahaké kaca lan kabèh anak-kacané",
        "right-move-rootuserpages": "Ngalih kaca panganggo oyod",
        "right-movefile": "Mindhah berkas",
        "right-bot": "Anggepen minangka prosès otomatis",
        "right-nominornewtalk": "Suntingan sithik (''minor'') ora ngwetokaké prompt pesen anyar",
        "right-apihighlimits": "Nganggo wates sing luwih dhuwur ing kwéri API",
-       "right-writeapi": "Migunakaké API panulisan",
+       "right-writeapi": "Nganggo API tulis",
        "right-delete": "Busak kaca-kaca",
        "right-bigdelete": "Busak kaca-kaca mawa sajarah panyuntingan sing gedhé",
        "right-deletelogentry": "Busak lan batalaké mbusak isi log spésipik",
        "right-protect": "Ganti undhaking pangreksan lan owah kaca-kaca sing direksa",
        "right-editprotected": "Owah kaca-kaca sing direksa (tanpa pangreksan runtun)",
        "right-editsemiprotected": "Owah kaca-kaca sing direksa dadi \"{{int:protect-level-autoconfirmed}}\"",
-       "right-editinterface": "Sunting interface (antarmuka) panganggo",
-       "right-editusercssjs": "Sunting berkas-berkas CSS lan JS panganggo liya",
-       "right-editusercss": "Sunting berkas-berkas CSS panganggo liya",
-       "right-edituserjs": "Sunting berkas-berkas JS panganggo liya",
+       "right-editinterface": "Besut antarmuka panganggo",
+       "right-editusercssjs": "Besut barkas-barkas CSS lan JavaScript panganggo liya",
+       "right-editusercss": "Besut barkas-barkas CSS panganggo liya",
+       "right-edituserjs": "Besut barkas-barkas JavaScript panganggo liya",
        "right-editmyusercss": "Owahi berkas CSS panganggo sampeyan",
        "right-editmyuserjs": "Owahi berkas JavaScript panganggo sampeyan",
        "right-viewmywatchlist": "Dheleng daftar pangawasan sampeyan",
        "right-viewmyprivateinfo": "Dheleng data pribadi sampeyan (kayata alamat layang elektronik, jeneng asli)",
        "right-editmyprivateinfo": "Owahi data pribadi sampeyan (kayata alamat layang elektronik, jeneng asli)",
        "right-editmyoptions": "Owahi preferensi sampeyan",
-       "right-rollback": "Sacara gelis mbalèkaké panganggo pungkasan sing nyunting kaca tartamtu",
+       "right-rollback": "Balèkaké kanthi gelis besutaning panganggo pungkasan sing mbesut kaca tinamtu",
        "right-markbotedits": "Tandhani besutan kawurungan minangka besutan bot",
        "right-noratelimit": "Ora dipengaruhi déning wates cacahing suntingan.",
        "right-import": "Impor kaca-kaca saka wiki liya",
        "right-unwatchedpages": "Tuduhna daftar kaca-kaca sing ora diawasi",
        "right-mergehistory": "Gabungna sajarah kaca-kaca",
        "right-userrights": "Besut kabèh hak panganggo",
-       "right-userrights-interwiki": "Sunting hak-hak para panganggo ing situs-situs wiki liya",
+       "right-userrights-interwiki": "Besut hak-haking panganggo asal wiki jaba",
        "right-siteadmin": "Kunci lan buka kunci basis data",
        "right-override-export-depth": "Èkspor kaca klebu kaca kagandhèng nganti tataran/''depth'' 5",
        "right-sendemail": "Ngirim layang listrik (e-mail) menyang panganggo liya",
        "action-move": "alihna kaca iki",
        "action-move-subpages": "mindahaké kaca iki, lan kabèh anak-kacané",
        "action-move-rootuserpages": "ngalih kaca panganggo oyod",
-       "action-movefile": "pindhahna berkas iki",
+       "action-movefile": "lih barkas iki",
        "action-upload": "ngunggahaké berkas iki",
        "action-reupload": "nindhih berkas sing wis ana",
        "action-reupload-shared": "nindhih berkas sing wis ana ing papan panyimpanan berkas sing dianggo bebarengan",
        "filehist-deleteone": "busaken iki",
        "filehist-revert": "balèkna",
        "filehist-current": "saiki",
-       "filehist-datetime": "Surya/Tabuh",
+       "filehist-datetime": "Tanggal/Tabuh",
        "filehist-thumb": "Gambar cilik",
        "filehist-thumbtext": "Gambar cilik kanggo owahan $1",
        "filehist-nothumb": "Ora ana miniatur",
        "filehist-dimensions": "Alang ujur",
        "filehist-filesize": "Gedhené berkas",
        "filehist-comment": "Tanggapan",
-       "imagelinks": "Panganggoan berkas",
+       "imagelinks": "Panganggoning barkas",
        "linkstoimage": "{{PLURAL:$1|Kaca|$1 kaca}} ngisor iki nggayut barkas iki:",
        "linkstoimage-more": "Luwih saka $1 {{PLURAL:$1|kaca|kaca-kaca}} nduwèni pranala menyang berkas iki.\nDhaftar ing ngisor nuduhaké {{PLURAL:$1|kaca pisanan kanthi pranala langsung|$1 kaca kanthi pranala langsung}} menyang berkas iki.\n[[Special:WhatLinksHere/$2|dhaftar pepak]] uga ana.",
-       "nolinkstoimage": "Ora ana kaca sing nyambung menyang berkas iki.",
+       "nolinkstoimage": "Ora ana kaca sing nggayut menyang barkas iki.",
        "morelinkstoimage": "Ndeleng [[Special:WhatLinksHere/$1|luwih akèh pranala]] menyang berkas iki.",
        "linkstoimage-redirect": "$1 (alihan berkas) $2",
        "duplicatesoffile": "{{PLURAL:$1|berkas ing ngisor arupa duplikat|$1 berkas ing ngisor arupa duplikat}} saka berkas iki ([[Special:FileDuplicateSearch/$2|luwih rinci]]):",
        "filedelete-otherreason": "Alesan tambahan/liya:",
        "filedelete-reason-otherlist": "Alesan liya",
        "filedelete-reason-dropdown": "*Alesan pambusakan\n** Nglanggar hak cipta\n** Berkas duplikat",
-       "filedelete-edit-reasonlist": "Sunting alesan pambusakan",
+       "filedelete-edit-reasonlist": "Busak jalaraning pambusak",
        "filedelete-maintenance": "Pambusakan lan pambalikan berkas kanggo sawetara dipatèni salawas ana pangruwatan.",
        "filedelete-maintenance-title": "Ora bisa mbusak berkas",
        "mimesearch": "Panggolèkan MIME",
        "newpages-username": "Asma panganggo:",
        "ancientpages": "Kaca-kaca langkung sepuh",
        "move": "Pindhahen",
-       "movethispage": "Pindhahna kaca iki",
+       "movethispage": "Lih kaca iki",
        "unusedimagestext": "Berkas-berkas sing kapacak iki ana nanging ora dienggo ing kaca apa waé.\nTulung digatèkaké yèn situs wèb liyané mbok-menawa bisa nyambung ing sawijining berkas sacara langsung mawa URL langsung, lan berkas-berkas kaya mengkéné iku mbok-menawa ana ing daftar iki senadyan ora dienggo aktif manèh.",
        "unusedcategoriestext": "Kategori iki ana senadyan ora ana artikel utawa kategori liyané sing nganggo.",
        "notargettitle": "Ora ana sasaran",
        "addedwatchtext": "Kaca \"[[:$1]]\" wis ditambahaké menyang [[Special:Watchlist|daftar pangawasan]].\nOwah-owahan sing dumadi ing tembé ing kaca iku lan kaca dhiskusi sing kagandhèng, bakal dipacak ing kéné.",
        "removewatch": "Singkiraké saka daptar pangawasan",
        "removedwatchtext": "Kaca \"[[:$1]]\" wis dibusak saka [[Special:Watchlist|daftar pangawasan]].",
-       "watch": "Awati",
+       "watch": "Awasi",
        "watchthispage": "Periksa kaca iki",
        "unwatch": "Ora usah ngawasaké manèh",
        "unwatchthispage": "Batalna olèhé ngawasi kaca iki",
        "deleteotherreason": "Alesan liya utawa tambahan:",
        "deletereasonotherlist": "Alesan liya",
        "deletereason-dropdown": "*Alesan pambusakan\n** Spam\n** Vandalisme\n** Nglanggar hak cipta\n** Disuwun sing nulis\n** Pangalihan rusak",
-       "delete-edit-reasonlist": "Sunting alesan pambusakan",
+       "delete-edit-reasonlist": "Besut jalaraning pambusak",
        "delete-toobig": "Kaca iki ndarbèni sajarah panyuntingan sing dawa, yaiku ngluwihi $1 {{PLURAL:$1|revision|révisi}}.\nPambusakan kaca sing kaya mangkono mau wis ora diparengaké kanggo menggak anané karusakan ing {{SITENAME}}.",
        "delete-warning-toobig": "Kaca iki duwé sajarah panyuntingan sing dawa, luwih saka $1 {{PLURAL:$1|révisi|révisi}}.\nMbusak kaca iki bisa ngrusak operasi basis data ing {{SITENAME}};\nkudu ngati-ati.",
        "deleting-backlinks-warning": "'''Awas:''' Kaca liyane mungkin ana sing nautake ing kaca sing arep sampeyan busak.",
        "cantrollback": "Ora bisa mbalèkaké suntingan; panganggo pungkasan iku siji-sijiné penulis artikel iki.",
        "alreadyrolled": "Ora bisa mbalèkaké suntingan pungkasan [[:$1]] déning [[User:$2|$2]] ([[User talk:$2|Wicara]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); wong liya wis nyunting utawa mbalèkaké kaca artikel iku.\n\nSuntingan pungkasan dilakoni déning [[User:$3|$3]] ([[User talk:$3|Wicara]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Ringkesan suntingan yaiku: <em>$1</em>.",
-       "revertpage": "Suntingan [[Special:Contributions/$2|$2]] ([[User talk:$2|dhiskusi]]) dipunwangsulaken dhateng ing vèrsi pungkasan déning [[User:$1|$1]]",
+       "revertpage": "Besutan sing dibalèkaké [[Special:Contributions/$2|$2]] ([[User talk:$2|gunem]]) bab owahan pungkasan déning [[User:$1|$1]]",
        "revertpage-nouser": "Suntingan déning panganggo sing didhelikake, dibalèkaké nèng benahan pungkasan déning [[User:$1|$1]]",
        "rollback-success": "Suntingan dibalèkaké déning $1;\ndiowahi bali menyang vèrsi pungkasan déning $2.",
        "sessionfailure-title": "Sèsi gagal",
        "protect-otherreason": "Alesan liya/tambahan:",
        "protect-otherreason-op": "Alesan liya",
        "protect-dropdown": "*Alesan umum pangreksan\n** Vandalisme makaping-kaping\n** Spam makaping-kaping\n** Perang suntingan\n** Kaca kerep disunting",
-       "protect-edit-reasonlist": "Nyunting alesan reksan",
+       "protect-edit-reasonlist": "Mbesut jalaraning pangreksa",
        "protect-expiry-options": "1 jam:1 hour,1 dina:1 day,1 minggu:1 week,2 minggu:2 weeks,1 sasi:1 month,3 sasi:3 months,6 sasi:6 months,1 taun:1 year,tanpa wates:infinite",
        "restriction-type": "Pangreksan:",
        "restriction-level": "Tingkatan pambatesan:",
        "namespace": "Lowah aran:",
        "invert": "Balèkaké pilihan",
        "tooltip-invert": "Centhang kothak iki kanggo ndhelikaké owahan saka kaca-kaca nèng njero bilik jeneng kapilih (lan bilik jeneng kakait yèn dicenthang)",
-       "namespace_association": "Bilik jeneng kakait",
+       "namespace_association": "Lowah aran magepokan",
        "tooltip-namespace_association": "Centhang kothak iki kanggo nglebokaké uga bilik jeneng gumenan utawa subyèk sing kakait karo bilik jeneng kapilih",
        "blanknamespace": "(Pokok)",
        "contributions": "Sumbangan {{GENDER:$1|panganggo}}",
        "linkshere": "Kaca-kaca iki nduwé pranala menyang '''[[:$1]]''':",
        "nolinkshere": "Ora ana kaca sing nduwé pranala menyang '''[[:$1]]'''.",
        "nolinkshere-ns": " Ora ana kaca sing nduwé pranala menyang '''[[:$1]]''' ing bilik jeneng sing kapilih.",
-       "isredirect": "kaca lihlihan",
+       "isredirect": "kaca lih-lihan",
        "istemplate": "karo cithakan",
-       "isimage": "pranala berkas",
+       "isimage": "pranala barkas",
        "whatlinkshere-prev": "{{PLURAL:$1|sadurungé|$1 sadurungé}}",
        "whatlinkshere-next": "{{PLURAL:$1|sabanjuré|$1 sabanjuré}}",
        "whatlinkshere-links": "← pranala",
-       "whatlinkshere-hideredirs": "$1 pangalihan-pangalihan",
+       "whatlinkshere-hideredirs": "$1 lih-lihan",
        "whatlinkshere-hidetrans": "$1 transklusi",
        "whatlinkshere-hidelinks": "pranala-pranala $1",
        "whatlinkshere-hideimages": "$1 pranala berkas",
        "ipbother": "Wektu liya",
        "ipboptions": "2 jam:2 hours,1 dina:1 day,3 dina:3 days,1 minggu:1 week,2 minggu:2 weeks,1 sasi:1 month,3 sasi:3 months,6 sasi:6 months,1 taun:1 year,tanpa wates:infinite",
        "ipbhidename": "Delikna jeneng panganggo saka suntingan lan pratélan",
-       "ipbwatchuser": "Ngawasi kaca panganggo lan kaca-kaca dhiskusi panganggo iki",
+       "ipbwatchuser": "Wasi kaca panganggoning lan kaca gegunemaning panganggo iki",
        "ipb-disableusertalk": "Alangi panganggo iki nyunting kaca gunemané nalika diblokir",
        "ipb-change-block": "Blokir manèh panganggo kanthi sèting iki",
        "ipb-confirm": "Pesthèkaké blokir",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] wis diblokir.<br />\nDelok [[Special:BlockList|daptar blokir]] kanggo ninjo blokiran.",
        "ipb-blockingself": "Sampéyan arep mblokir Sampéyan dhéwé! Sampéyan yakin arep nglakoni kuwi?",
        "ipb-confirmhideuser": "Sampéyan arep mblokir panganggo mawa piranti \"dhelikaké panganggo\" isih murub. Iki bakal nyegah jeneng panganggo ana ing kabèh daptar lan èntri log. Sampéyan yakin arep nglakoni kuwi?",
-       "ipb-edit-dropdown": "Sunting alesan pamblokiran",
+       "ipb-edit-dropdown": "Besut jalaraning pamalang",
        "ipb-unblock-addr": "Ilangna blokir $1",
        "ipb-unblock": "Ilangna blokir sawijining panganggo utawa alamat IP",
        "ipb-blocklist": "Ndeleng blokir sing lagi ditrapaké",
        "noautoblockblock": "pamblokiran otomatis dipatèni",
        "createaccountblock": "ndamelipun akun dipunblokir",
        "emailblock": "layang e-mail diblokir",
-       "blocklist-nousertalk": "ora éntuk nyunting kaca gunemané dhéwé",
+       "blocklist-nousertalk": "ora kena mbesut kaca guneman dhéwé",
        "ipblocklist-empty": "Daftar pamblokiran kosong.",
        "ipblocklist-no-results": "alamat IP utawa panganggo sing disuwun ora diblokir.",
        "blocklink": "palang",
        "block-log-flags-nocreate": "opsi nggawé akun utawa rékening dipatèni",
        "block-log-flags-noautoblock": "blokir otomatis dipatèni",
        "block-log-flags-noemail": "e-mail diblokir",
-       "block-log-flags-nousertalk": "ora éntuk nyunting kaca gunemané dhéwé",
+       "block-log-flags-nousertalk": "ora kena mbesut kaca guneman dhéwé",
        "block-log-flags-angry-autoblock": "paningkatan sistem pamblokiran otomatis wis diaktifaké",
        "block-log-flags-hiddenname": "jeneng panganggo didhelikaké",
        "range_block_disabled": "Fungsi pamblokir blok IP kanggo para opsis dipatèni.",
        "lockfilenotwritable": "Berkas kunci basis data ora bisa ditulis. Kanggo ngunci utawa mbuka basis data, berkas iki kudu ditulis déning server wèb.",
        "databasenotlocked": "Basis data ora dikunci.",
        "lockedbyandtime": "(déning {{GENDER:$1|$1}} tanggal $2 wanci $3)",
-       "move-page": "Pindhahna $1",
+       "move-page": "Ngalih $1",
        "move-page-legend": "Mindhah kaca",
        "movepagetext": "Formulir ing ngisor iki bakal ngowahi jeneng sawijining kaca, mindhah kabèh sajarahé menyang kaca sing anyar. Irah-irahan utawa judhul sing lawas bakal dadi kaca pangalihan menyang irah-irahan sing anyar. Pranala menyang kaca sing lawas ora bakal diowahi; dadi pastèkna dhisik mriksa pangalihan [[Special:DoubleRedirects|dobel]] utawa [[Special:BrokenRedirects|pangalihan sing rusak]] sawisé pamindhahan. Panjenengan sing tanggung jawab mastèkaké menawa kabèh pranala-pranala tetep nyambung ing kaca panujon kaya samesthiné.\n\nGatèkna yèn kaca iki '''ora''' bakal dipindhah yèn wis ana kaca liyané sing nganggo irah-irahan sing anyar, kejaba kaca iku kosong utawa ora nduwé sajarah panyuntingan. Dadi tegesé panjenengan bisa ngowahi jeneng kaca iku manèh kaya sedyakala menawa panjenengan luput, lan panjenengan ora bisa nimpani kaca sing wis ana.\n\n'''PÈNGET!'''\nPerkara iki bisa ngakibataké owah-owahan sing drastis lan ora kaduga kanggo kaca-kaca sing populèr;\npastekaké dhisik panjenengan ngerti konsekwènsi saka panggayuh panjenengan sadurungé dibanjuraké.",
        "movepagetext-noredirectfixer": "Formulir di bawah ini digunakan untuk mengubah nama suatu halaman dan memindahkan semua data sejarah ke nama baru.\nJudul yang lama akan menjadi halaman peralihan menuju judul yang baru.\nPastikan untuk memeriksa pengalihan [[Special:DoubleRedirects|ganda]] atau [[Special:BrokenRedirects|rusak]].\nAnda bertanggung jawab untuk memastikan bahwa pranala terus menyambung ke halaman yang seharusnya.\n\nPerhatikan bahwa halaman '''tidak''' akan dipindah apabila telah ada halaman yang menggunakan judul yang baru, kecuali bila halaman tersebut kosong atau merupakan halaman peralihan dan tidak mempunyai sejarah penyuntingan.\nIni berarti Anda dapat mengubah nama halaman kembali seperti semula apabila Anda membuat kesalahan, dan Anda tidak dapat menimpa halaman yang telah ada.\n\n'''Peringatan:'''\nHal ini dapat mengakibatkan perubahan yang tak terduga dan drastis bagi halaman yang populer;\nPastikan Anda mengerti konsekuensi dari perbuatan ini sebelum melanjutkan.",
-       "movepagetalktext": "Kaca dhiskusi sing kagandhèng uga bakal dipindhahaké sacara otomatis '''kejaba yèn:'''\n\n*Sawijining kaca dhiskusi sing ora kosong wis ana sangisoring irah-irahan (judhul) anyar, utawa\n*Panjenengan ora maringi tandha cèk ing kothak ing ngisor iki.\n\nIng kasus-kasus iku, yèn panjenengan gayuh, panjenengan bisa mindhahaké utawa nggabung kaca iku sacara manual.",
+       "movepagetalktext": "Menawa sampéyan nyénthang kothak iki, kaca geguneman sing magepokan bakal otomatis dilih nyang sesirah anyar, kajaba kaca gegunemané wis ana isiné sadurungé.\n\nYèn mangkéné, sampéyan kudu ngalih utawa nggabung kaca-kaca iku kanthi manual.",
        "moveuserpage-warning": "'''Pèngetan:''' Sampéyan arep mindhahaké kaca panganggo. Mangga cathet yèn namung kaca sing bakal dipindhahaké lan panganggo '''ora''' bakal diganti jenengé.",
        "movenologintext": "Panjenengan kudu dadi panganggo sing wis ndaftar lan wis [[Special:UserLogin|mlebu log]] kanggo mindhah kaca.",
        "movenotallowed": "Panjenengan ora pareng ngalihaké kaca.",
        "cant-move-to-user-page": "Panjenengan ora nduwèni hak aksès kanggo mindhahaké kaca menyang sawijining kaca panganggoa (kajaba menyang anak-kaca panganggo).",
        "newtitle": "Menyang irah-irahan utawa judhul anyar:",
        "move-watch": "Awasna kaca iki",
-       "movepagebtn": "Pindhahna kaca",
+       "movepagebtn": "Ngalih kaca",
        "pagemovedsub": "Bisa kasil dipindhahaké",
        "movepage-moved": "'''\"$1\" dipindhahaké menyang \"$2\".'''",
        "movepage-moved-redirect": "Kaca pengalihan wis kacipta.",
        "movepage-moved-noredirect": "Kanggo gawé pengalihan wis ditahan.",
        "articleexists": "Satunggalipun kaca kanthi asma punika sampun wonten, utawi asma ingkang panjenengan pendhet mboten leres. Sumangga nyobi asma sanèsipun.",
        "cantmove-titleprotected": "Panjenengan ora bisa mindhahaké kaca iki menyang lokasi iki, amerga irah-irahan tujuan lagi direksa; ora olèh digawé",
-       "movetalk": "Pindahna kaca dhiskusi sing ana gandhèngané.",
-       "move-subpages": "Pindhahna anak-kaca (nganti $1)",
-       "move-talk-subpages": "Pindhahna anak-kaca saka kaca wicara (nganti $1)",
+       "movetalk": "Lih kaca geguneman sing magepokan",
+       "move-subpages": "Lih anak kaca (tekan $1)",
+       "move-talk-subpages": "Lih anak kaca saka kaca geguneman (tekan $1)",
        "movepage-page-exists": "Kaca $1 wis ana lan ora bisa ditindhes sacara otomatis.",
        "movepage-page-moved": "Kaca $1 wis dipindhah menyang $2.",
        "movepage-page-unmoved": "Kaca $1 ora bisa dialihaké menyang $2.",
        "movepage-max-pages": "Paling akèh $1 {{PLURAL:$1|kaca|kaca}} wis dialihaké lan ora ana manèh sing bakal dialihaké sacara otomatis.",
-       "movelogpage": "Cathetan lihlihan",
+       "movelogpage": "Cathetan lih-lihan",
        "movelogpagetext": "Ing ngisor iki kapacak log pangalihan kaca.",
        "movesubpage": "{{PLURAL:$1|Anak-kaca|Anak-kaca}}",
        "movesubpagetext": "Kaca iki nduwèni $1 {{PLURAL:$1|anak-kaca|anak-kaca}} kaya kapacak ing ngisor.",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|révisi}} saka $2",
        "javascripttest": "Panjajalan JavaScript",
        "javascripttest-qunit-intro": "Delok [dhokumèntasi panjajalan $1] nèng mediawiki.org.",
-       "tooltip-pt-userpage": "Kaca {{GENDER:|panganggo sampéyan}}",
+       "tooltip-pt-userpage": "Kaca {{GENDER:|panganggoning sampéyan}}",
        "tooltip-pt-anonuserpage": "Kaca panganggo IP panjenengan",
-       "tooltip-pt-mytalk": "Kaca paguneman {{GENDER:|sampéyan}}",
-       "tooltip-pt-anontalk": "Dhiskusi perkara suntingan saka alamat IP iki",
-       "tooltip-pt-preferences": "Pamiji {{GENDER:|sampéyan}}",
-       "tooltip-pt-watchlist": "Daftar kaca sing tak-awasi.",
+       "tooltip-pt-mytalk": "Kaca gegunemaning {{GENDER:|sampéyan}}",
+       "tooltip-pt-anontalk": "Rerembugan bab besutan-besutan saka alamat IP iki",
+       "tooltip-pt-preferences": "Pilihaning {{GENDER:|sampéyan}}",
+       "tooltip-pt-watchlist": "Pratélaning kaca sing sampéyan awasi owah-owahané",
        "tooltip-pt-mycontris": "Pratélaning sumbanganing {{GENDER:|sampéyan}}",
        "tooltip-pt-login": "Sampéyan prayogané mlebu masiya ora kudu",
        "tooltip-pt-logout": "Metu",
        "tooltip-pt-createaccount": "Sampéyan prayogané gawé akun lan mlebu masiya ora kudu",
-       "tooltip-ca-talk": "Parembuganing kaca isi",
+       "tooltip-ca-talk": "Rerembuganing kaca isi",
        "tooltip-ca-edit": "Besut kaca iki",
        "tooltip-ca-addsection": "Miwiti pérangan anyar",
        "tooltip-ca-viewsource": "Kaca iki direksa. \nSampéyan bisa ndeleng sumberé",
        "tooltip-ca-unprotect": "Ganti panjagan kaca iki",
        "tooltip-ca-delete": "Busak kaca iki",
        "tooltip-ca-undelete": "Balèkna suntingan ing kaca iki sadurungé kaca iki dibusak",
-       "tooltip-ca-move": "Aliha kaca iki",
+       "tooltip-ca-move": "Lih kaca iki",
        "tooltip-ca-watch": "Tambahaké kaca iki nyang pawawangan sapéyan",
        "tooltip-ca-unwatch": "Busak kaca iki saka daftar pangawasan panjenengan",
        "tooltip-search": "Golèk nyang {{SITENAME}}",
        "file-info-size": "$1 × $2 piksel, ukuran barkas: $3, jinis MIME: $4",
        "file-info-size-pages": "$1 × $2 piksel, gedhéné berkas: $3, jinisé MIME: $4, $5 {{PLURAL:$5|kaca|kaca}}",
        "file-nohires": "Ora ana résolusi sing luwih dhuwur.",
-       "svg-long-desc": "Berkas SVG, nominal $1 × $2 piksel, gedhené berkas: $3",
+       "svg-long-desc": "Barkas SVG, nominal $1 × $2 piksel, gedhéning barkas: $3",
        "svg-long-desc-animated": "Berkas SVG, nominal $1 × $2 piksel, gedhené berkas: $3",
        "svg-long-error": "Berkas SVG ora sah: $1",
        "show-big-image": "Barkas asli",
-       "show-big-image-preview": "Gedhéné pratayang iki: $1",
+       "show-big-image-preview": "Gedhéning prawuryan iki: $1",
        "show-big-image-other": "{{PLURAL:$2|Résolusi|Résolusi}} liya: $1.",
        "show-big-image-size": "$1 × $2 piksel",
        "file-info-gif-looped": "mubeng",
        "exif-primarychromaticities": "Kromatisitas werna primer",
        "exif-ycbcrcoefficients": "Koèfisièn matriks transformasi papan werna",
        "exif-referenceblackwhite": "Wiji réferènsi pasangan ireng putih",
-       "exif-datetime": "Tanggal lan wektu pangowahan berkas",
+       "exif-datetime": "Tanggal lan tabuh owahing barkas",
        "exif-imagedescription": "Judhul gambar",
        "exif-make": "Produsèn kamera",
        "exif-model": "Modhèl kaméra",
        "autosumm-new": "Gawé kaca sing isi '$1'",
        "lag-warn-normal": "Owah-owahan pungkasan sing luwih anyar tinimbang $1 {{PLURAL:$1|detik|detik}} mbokmanawa ora metu ing pratélan iki.",
        "lag-warn-high": "Amarga gedhéné ''lag'' basis data server, owah-owahan pungkasan sing luwih anyar saka $1 {{PLURAL:$1|detik|detik}} mbokmanawa ora metu ing daftar iki.",
-       "watchlistedit-normal-title": "Sunting daftar pangawasan",
+       "watchlistedit-normal-title": "Besut pawawangan",
        "watchlistedit-normal-legend": "Busak irah-irahan saka daftar pangawasan",
        "watchlistedit-normal-explain": "Irah-irahan utawa judhul ing daftar pangawasan panjenengan kapacak ing ngisor iki.\nKanggo mbusak sawijining irah-irahan, kliken kothak ing pinggiré, lan banjur kliken \"Busak judhul\".\nPanjenengan uga bisa [[Special:EditWatchlist/raw|nyunting daftar mentah]].",
        "watchlistedit-normal-submit": "Busak irah-irahan",
        "watchlistedit-normal-done": "Irah-irahan {{PLURAL:$1|siji|$1}} wis dibusak saka daftar pangawasan panjenengan:",
-       "watchlistedit-raw-title": "Sunting daftar mentah",
-       "watchlistedit-raw-legend": "Sunting daftar mentah",
+       "watchlistedit-raw-title": "Besut pawawangan wantahan",
+       "watchlistedit-raw-legend": "Besut pawawangan wantahan",
        "watchlistedit-raw-explain": "Irah-irahan ing daftar pangawasan panjenengan kapacak ing ngisor iki, lan bisa diowahi mawa nambahaké utawa mbusak daftar; sairah-irahan saban barisé.\nYèn wis rampung, anyarana kaca daftar pangawasan iki.\nPanjenengan uga bisa [[Special:EditWatchlist|nganggo éditor standar panjenengan]].",
        "watchlistedit-raw-titles": "Irah-irahan:",
        "watchlistedit-raw-submit": "Anyarana daftar pangawasan",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} ditambahaké:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} diwetokaké:",
        "watchlisttools-view": "Tuduhna owah-owahan sing ana gandhèngané",
-       "watchlisttools-edit": "Tuduhna lan sunting daftar pangawasan",
-       "watchlisttools-raw": "Sunting daftar pangawasan mentah",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|wicara]])",
+       "watchlisttools-edit": "Deleng lan besut pawawangan",
+       "watchlisttools-raw": "Besut pawawangan wantahan",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|geguneman]])",
        "duplicate-defaultsort": "Pènget: Kunci pilih asal (''Default sort key'') \"$2\" nggantèkaké kunci pilih asal sadurungé \"$1\".",
        "version": "Versi",
        "version-extensions": "Èkstènsi sing wis diinstalasi",
        "intentionallyblankpage": "Kaca iki disengajakaké kosong",
        "external_image_whitelist": " #Umbarna larikan iki apa anané<pre>\n#Pigunakaké fragmèn èksprèsi regular (mung bagéyan ing antara //) ing ngisor\n#Fragmèn ini bakal dicocogaké karo URL saka gambar-gambar èksternal\n#Fragmèn sing cocog bakal ditampilaké minangka gambar, yèn ora mung pranala menyang gambar waé sing ditampilaké\n#Larikan sing diwiwiti nganggo # dianggep minangka komentar\n#Iki ora mbédakaké aksara gedhé/cilik\n#Dèlèhna kabèh fragmèn èksprèsi regular sadhuwuré larikan iki. Umbarna larikan iki apa anané</pre>",
        "tags": "Tag pangowahan sing absah",
-       "tag-filter": "Panyaringan [[Special:Tags|tandha]]:",
+       "tag-filter": "Panyaringan [[Special:Tags|tenger]]:",
        "tag-filter-submit": "Penyaring",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tenger|Tenger}}]]: $2)",
        "tags-title": "Tag",
        "revdelete-uname-unhid": "jeneng panganggo dituduhaké",
        "revdelete-restricted": "rèstriksi ditrapaké marang para opsis",
        "revdelete-unrestricted": "rèstriksi marang para opsis dijabel",
-       "logentry-move-move": "$1 {{GENDER:$2|mindhahaké}} kaca $3 nèng $4",
+       "logentry-move-move": "$1 {{GENDER:$2|ngalih}} kaca $3 nyang $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|mindhahaké}} kaca $3 nèng $4 tanpa ninggalaké pangalihan",
        "logentry-move-move_redir": "$1 {{GENDER:$2|mindhahaké}} kaca $3 nèng $4 nindesi pangalihan liyane",
        "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|mindhahaké}} kaca $3 nèng $4 nindesi pangalihan liyane tanpa nginggalaké pangalihan",
        "feedback-cancel": "Batal",
        "feedback-close": "Rampung",
        "feedback-error1": "Kasalahan: Asil ora dikenal saka API",
-       "feedback-error2": "Kasalahan: Gagal nyunting",
+       "feedback-error2": "Cacad: Gagal mbesut",
        "feedback-error3": "Kasalahan: Ora ana tanggepan saka API",
        "feedback-message": "Layang:",
        "feedback-subject": "Jejer:",
index 6685cc6..d6f3dfb 100644 (file)
        "upload-form-label-infoform-description-tooltip": "მოკლედ აღწერეთ ამ ნამუშევრის შესახებ ყველაფერი მნიშვნელოვანი.\nფოტოსათვის, მიუთითეთ რა არის გამოსახული, სად არის გადაღებული, რა ვითარებაში.",
        "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": "თუ ვერ ტვირთავთ ამ ფაილს {{SITENAME}}-ის წესების დაცვით, გთხოვთ დახურეთ ეს ფანჯარა და სცადეთ სხვა მეთოდი.",
-       "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/deed.ka 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}}-ზე]], თუ ამ ფაილის ატვირთვა დაშვებულია მათი პოლიტიკის შესაბამისად.",
+       "upload-form-label-own-work": "ეს ჩემი პირადი ნამუშევარია",
+       "upload-form-label-infoform-categories": "კატეგორიები",
+       "upload-form-label-infoform-date": "თარიღი",
+       "upload-form-label-own-work-message-local": "ვადასტურებ, რომ ვტვირთავვ ამ ფაილს მომსახურების პირობებისა და ლიცენსიის პოლიტიკის შესაბამისად {{SITENAME}}-ზე.",
+       "upload-form-label-not-own-work-message-local": "თუ ვერ ტვირთავთ ამ ფაილს {{SITENAME}}-ის წესების დაცვით, გთხოვთ დახურეთ ეს ფანჯარა და სცადეთ სხვა მეთოდი.",
+       "upload-form-label-not-own-work-local-local": "შეგიძლიათ სცადოთ [[Special:Upload|მთავარი ატვირთვის გვერდი]].",
+       "upload-form-label-own-work-message-default": "ვიცი, რომ ამ ფაილს ვტვირთავ საზიარო ბაზაში. ვადასტურებ, რომ ამას ვაკეთებ მომსახურების პირობებისა და ლიცენზიის პოლიტიკის შესაბამისად.",
+       "upload-form-label-not-own-work-message-default": "თუ ვერ ტვირთავთ ამ ფაილს {{SITENAME}}-ის წესების დაცვით, გთხოვთ დახურეთ ეს ფანჯარა და სცადეთ სხვა მეთოდი.",
+       "upload-form-label-not-own-work-local-default": "შეგიძლიათ ასევე სცადოთ [[Special:Upload|ატვირთვის გვერდი {{SITENAME}}-ზე]], თუ ამ ფაილის ატვირთვა დაშვებულია მათი პოლიტიკის მიხედვით.",
+       "upload-form-label-own-work-message-shared": "მე ვადასტურებ, რომ ამ ფაილზე საავტორო უფლებების მფლობელი ვარ და ვთანხმდები ამ ფაილის შეუქცევადად განთავსებაზე ვიკისაწყობში [https://creativecommons.org/licenses/by-sa/4.0/deed.ka Creative Commons Attribution-ShareAlike 4.0] ლიცენზიით, აგრეთვე ვეთანხმები [https://wikimediafoundation.org/wiki/Terms_of_Use გამოყენების წესებს].",
+       "upload-form-label-not-own-work-message-shared": "თუ თქვენ არ ხართ საავტორო უფლებებს ამ ფაილზე, ან გსურთ გაუშვათ განსხვავებული ლიცენზიით, გთხოვთ გამოიყენეთ [https://commons.wikimedia.org/wiki/Special:UploadWizard ვიკისაწყობის ატვირთვის ფუნქცია].",
+       "upload-form-label-not-own-work-local-shared": "შეგიძლიათ ასევე სცადოთ [[Special:Upload|ატვირთვის გვერდი {{SITENAME}}-ზე]], თუ ამ ფაილის ატვირთვა დაშვებულია მათი პოლიტიკის შესაბამისად.",
        "backend-fail-stream": "ფაილი $1 ტრანსლირება ვერ მოხერხდა.",
        "backend-fail-backup": "ფაილი $1 სარეზერვო ასლის გაკეთება ვერ მოხერხდა.",
        "backend-fail-notexists": "ფაილი $1 არ არსებობს.",
index 2fe53e9..9eb5e96 100644 (file)
        "yournick": "Leqeme:",
        "badsig": "İmza kala nêvêrdiye.\nEtiketê ''HTML''i qontrol ke.",
        "badsiglength": "İmza to zaf derga.\nA gunê ebe $1 {{PLURAL:$1|herfe|herfu}} ra jêde mebo.",
-       "yourgender": "Cınsiyet:",
+       "yourgender": "Şeklê xitabi?",
        "gender-male": "Cüamêrd",
        "gender-female": "Cüanıke",
        "email": "E-poste",
        "rclistfrom": "$3 $2 ra hata nıka vurnaisunê newu bıasne",
        "rcshowhideminor": "$1 vurnaisê qızkeki",
        "rcshowhidebots": "Botu $1",
-       "rcshowhideliu": "Karberunê qeydbiyayu $1",
+       "rcshowhideliu": "karberê qeydbiyayeyi $1",
        "rcshowhideanons": "$1 karberê anonimi",
        "rcshowhidepatr": "Vurnayışê cıyê vênıtey $1",
        "rcshowhidemine": "Vurnayisanê mı $1",
index f839f94..f88289d 100644 (file)
        "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-shared": "Мен осы файлдың авторы екенінімді растаймын және бұл файлды Wikimedia Commons ортаққорына [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}} жобасындағы жүктеу бетін]] қолданып көргіңіз келетін шығар.",
+       "upload-form-label-own-work": "Бұл менің өз туындым",
+       "upload-form-label-infoform-categories": "Санаттар",
+       "upload-form-label-infoform-date": "Ай-күні",
+       "upload-form-label-own-work-message-shared": "Мен осы файлдың авторы екенінімді растаймын және бұл файлды Wikimedia Commons ортаққорына [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] лицензиясы аясында қайтымсыз жариялауға келісемін, сонымен бірге [https://wikimediafoundation.org/wiki/Terms_of_Use Қолдану шарттарына] да келісемін.",
+       "upload-form-label-not-own-work-message-shared": "Егер сіз осы файлдың авторы өзіңіз болмасаңыз немесе оны сіз басқа лицензия аясында жариялағыңыз келсе [https://commons.wikimedia.org/wiki/Special:UploadWizard Ортаққор Жүктеу шеберін] қолданыңыз.",
+       "upload-form-label-not-own-work-local-shared": "Егер сайт бұл файлды жүктеуге өзінің ережелері аясында рұқсат беретін болса, сіз сондай-ақ [[Special:Upload|{{SITENAME}} жобасындағы жүктеу бетін]] қолданып көргіңіз келетін шығар.",
        "backend-fail-stream": "«$1» файлы ақпады.",
        "backend-fail-backup": "«$1» файлының сақтық есесі жасалмады.",
        "backend-fail-notexists": "$1 файлы бар емес.",
index 95a8fee..6612f1a 100644 (file)
        "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": "កាលបរិច្ឆេទ",
+       "upload-form-label-own-work": "នេះជាការងារផ្ទាល់ខ្លួនរបស់ខ្ញុំ",
+       "upload-form-label-infoform-categories": "ចំណាត់ថ្នាក់ក្រុម",
+       "upload-form-label-infoform-date": "កាលបរិច្ឆេទ",
        "backend-fail-notexists": "គ្មានឯកសារ \"$1\" ទេ។",
        "backend-fail-notsame": "ឯកសារដែលមិនដូចគ្នាបេះបិទមួយមានរួចហើយនៅ \"$1\"។",
        "backend-fail-delete": "មិនអាចលុបឯកសារ \"$1\" បានទេ។",
index 63d53ef..e9a314c 100644 (file)
@@ -60,7 +60,8 @@
                        "Joolee0104",
                        "Mooozi",
                        "Ellif",
-                       "HDNua"
+                       "HDNua",
+                       "Ykhwong"
                ]
        },
        "tog-underline": "링크에 밑줄:",
@@ -78,6 +79,7 @@
        "tog-watchdefault": "내가 편집하는 문서와 파일을 주시문서 목록에 추가",
        "tog-watchmoves": "내가 이동하는 문서와 파일을 주시문서 목록에 추가",
        "tog-watchdeletion": "내가 삭제하는 문서와 파일을 주시문서 목록에 추가",
+       "tog-watchuploads": "내가 올린 파일을 주시문서 목록에 추가",
        "tog-watchrollback": "내가 되돌리기 기능을 사용한 문서를 주시문서 목록에 추가",
        "tog-minordefault": "모든 편집에 기본적으로 사소한 편집을 표시",
        "tog-previewontop": "편집 상자 앞에 미리 보기 보이기",
        "tog-watchlistreloadautomatically": "필터가 수정될 때마다 주시문서 목록 자동으로 새로 고치기 (자바스크립트 필요)",
        "tog-watchlisthideanons": "주시문서 목록에서 익명 사용자의 편집을 숨기기",
        "tog-watchlisthidepatrolled": "주시문서 목록에서 점검한 편집을 숨기기",
-       "tog-watchlisthidecategorization": "페이지 류 숨기기",
+       "tog-watchlisthidecategorization": "페이지 류 숨기기",
        "tog-ccmeonemails": "이메일을 보낼 때 내 이메일로 복사본을 보내기",
        "tog-diffonly": "편집 차이를 비교할 때 문서 내용을 보지 않기",
        "tog-showhiddencats": "숨은 분류 보이기",
        "december-date": "12월 $1일",
        "period-am": "오전",
        "period-pm": "오후",
-       "pagecategories": "{{PLURAL:$1|분류}}",
+       "pagecategories": "{{PLURAL:$1|분류|분류}}",
        "category_header": "\"$1\" 분류에 속하는 문서",
        "subcategories": "하위 분류",
        "category-media-header": "\"$1\" 분류에 속하는 미디어",
        "category-empty": "이 분류에 속하는 문서나 자료가 없습니다.",
-       "hidden-categories": "{{PLURAL:$1|숨은 분류}}",
+       "hidden-categories": "{{PLURAL:$1|숨은 분류|숨은 분류}}",
        "hidden-category-category": "숨은 분류",
        "category-subcat-count": "{{PLURAL:$2|이 분류에는 하위 분류 1개만이 속해 있습니다.|다음은 이 분류에 속하는 {{PLURAL:$1|하위 분류}} $2개 가운데 $1개입니다.}}",
        "category-subcat-count-limited": "이 분류에 {{PLURAL:$1|하위 분류가|하위 분류 $1개가}} 있습니다.",
        "badaccess-group0": "요청한 명령을 실행할 권한이 없습니다.",
        "badaccess-groups": "요청한 명령은 {{PLURAL:$2|다음|다음 중 하나의}} 권한을 가진 사용자에게 제한됩니다: $1.",
        "versionrequired": "미디어위키 $1 버전 필요",
-       "versionrequiredtext": "이 문서를 사용하려면 $1 버전 미디어위키가 필요합니다.\n[[Special:Version|설치된 미디어위키 버전]]을 참조하세요.",
+       "versionrequiredtext": "이 문서를 사용하려면 $1 버전 미디어위키가 필요합니다.\n[[Special:Version|설치된 미디어위키 버전]]을 참조하세요.",
        "ok": "확인",
        "retrievedfrom": "원본 주소 \"$1\"",
        "youhavenewmessages": "다른 사용자로부터의 $1가 {{PLURAL:$3|있습니다}}. ($2)",
        "youhavenewmessagesfromusers": "{{PLURAL:$3|다른 사용자로|사용자 $3명으로}}부터의 $1가 {{PLURAL:$4|있습니다}}. ($2)",
        "youhavenewmessagesmanyusers": "여러 사용자로부터의 $1가 있습니다. ($2)",
-       "newmessageslinkplural": "{{PLURAL:$1|새 메시지}}",
-       "newmessagesdifflinkplural": "마지막으로 {{PLURAL:$1|바뀐 내용}}",
+       "newmessageslinkplural": "{{PLURAL:$1|새 메시지|999=새 메시지}}",
+       "newmessagesdifflinkplural": "마지막으로 {{PLURAL:$1|바뀐 내용|999=바뀐 내용}}",
        "youhavenewmessagesmulti": "다른 사용자가 $1에 남긴 새 메시지가 있습니다",
        "editsection": "편집",
        "editold": "편집",
        "nstab-category": "분류",
        "mainpage-nstab": "대문",
        "nosuchaction": "이러한 명령이 없습니다",
-       "nosuchactiontext": "URL에 지정한 명령이 올바르지 않습니다.\nURL을 잘못 입력했거나, 올바르지 않은 링크를 따라갔을 수 있습니다.\n{{SITENAME}}에 사용하는 소프트웨어의 버그가 있을 수 있습니다.",
+       "nosuchactiontext": "URL에 지정한 명령이 올바르지 않습니다.\nURL을 잘못 입력했거나, 올바르지 않은 링크를 따라갔을 수 있습니다.\n{{SITENAME}}에 사용하는 소프트웨어의 버그일 수도 있습니다.",
        "nosuchspecialpage": "해당하는 특수 문서가 없습니다",
        "nospecialpagetext": "<strong>요청한 특수 문서가 존재하지 않습니다.</strong>\n\n특수 문서의 목록은 [[Special:SpecialPages|여기]]에서 볼 수 있습니다.",
        "error": "오류",
        "databaseerror": "데이터베이스 오류",
-       "databaseerror-text": "데이터베이스 쿼리에 오류가 발생했습니다.\n소프트웨어에 버그가 있을 수 있습니다.",
-       "databaseerror-textcl": "데이터베이스 쿼리 오류가 발생했습니다.",
+       "databaseerror-text": "데이터베이스 쿼리 오류가 발생했습니다.\n소프트웨어의 버그일 수 있습니다.",
+       "databaseerror-textcl": "데이터베이스 쿼리 오류가 발생했습니다.",
        "databaseerror-query": "쿼리: $1",
        "databaseerror-function": "함수: $1",
        "databaseerror-error": "오류: $1",
+       "transaction-duration-limit-exceeded": "쓰기 시간($1)이 $2 초 제한을 초과하였으므로 이 트랜잭션은 중단되었습니다. 이는 높은 수준의 반복 지연을 피하기 위해서입니다.\n한번에 수많은 항목을 변경하려면, 작업을 여러 작은 단위로 나누어 시도하십시오.",
        "laggedslavemode": "<strong>경고:</strong> 문서가 최근에 바뀐 내용을 포함하지 않을 수도 있습니다.",
        "readonly": "데이터베이스 잠김",
        "enterlockreason": "데이터베이스를 잠그는 이유와 예상되는 기간을 적어 주세요.",
-       "readonlytext": "데이터베이스가 잠겨 있어서 문서를 편집할 수 없습니다. 데이터베이스 관리가 끝난 후에는 정상으로 돌아올 것입니다.\n\n관리자가 데이터베이스를 잠글 때 남긴 메시지는 다음과 같습니다: $1",
+       "readonlytext": "데이터베이스가 잠겨 있어서 문서를 편집할 수 없습니다. 데이터베이스 관리가 끝난 후에는 정상으로 돌아올 것입니다.\n\n시스템 관리자가 데이터베이스를 잠글 때 남긴 메시지는 다음과 같습니다: $1",
        "missing-article": "데이터베이스에서 \"$1\" 문서의 $2 텍스트를 찾지 못했습니다.\n\n삭제된 문서의 오래된 차이나 역사 링크를 보려고 시도할 때 이러한 문제가 발생할 수 있습니다.\n\n그렇지 않다면, 소프트웨어에 버그가 발생했을 수도 있습니다.\n[[Special:ListUsers/sysop|관리자]]에게 URL을 참조하여 알려주세요.",
-       "missingarticle-rev": "(판번호: $1)",
+       "missingarticle-rev": "(판 번호: $1)",
        "missingarticle-diff": "(차이: $1, $2)",
-       "readonly_lag": "슬레이브 데이터베이스가 마스터 서버의 자료를 새로 고치는 중입니다. 데이터베이스가 자동으로 잠겨져 있습니다",
+       "readonly_lag": "슬레이브 데이터베이스 서버들이 마스터 서버와 동기화되고 있습니다. 그 동안 데이터베이스가 자동으로 잠겨져 있습니다.",
        "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP 헤더가 붙어있지만 API 쓰기 모듈에 대한 요청을 했습니다.",
        "internalerror": "내부 오류",
        "internalerror_info": "내부 오류: $1",
        "cannotdelete": "\"$1\" 문서나 파일을 삭제할 수 없습니다.\n이미 삭제되었을 수도 있습니다.",
        "cannotdelete-title": "\"$1\" 문서를 삭제할 수 없습니다.",
        "delete-hook-aborted": "훅이 삭제를 중단했습니다.\n아무런 설명도 주어지지 않았습니다.",
-       "no-null-revision": "\"$1\" 문서에 대한 새 빈 판을 만들 수 없습니다",
+       "no-null-revision": "\"$1\" 문서에 대한 빈 판을 새로 만들 수 없습니다.",
        "badtitle": "잘못된 제목",
        "badtitletext": "요청한 문서 제목이 잘못되었거나, 비어있거나, 잘못된 인터위키 제목으로 링크했습니다.\n문서 제목에 사용할 수 없는 문자를 사용했을 수 있습니다.",
-       "title-invalid-empty": "요청한 페이지의 제목이 비거나 이름공간밖에 안 들어있습니다.",
+       "title-invalid-empty": "요청한 페이지의 제목이 비어있거나 이름공간의 이름만 포함하고 있습니다.",
        "title-invalid-utf8": "요청한 페이지 제목에 잘못된 UTF-8 글자가 있습니다.",
        "title-invalid-interwiki": "요청한 페이지 제목에 제목에는 사용될 수 없는 위키간 링크가 있습니다.",
        "title-invalid-talk-namespace": "요청한 페이지 제목이 존재하지 않는 토론 문서를 가리킵니다.",
        "title-invalid-characters": "요청된 문서 제목이 잘못된 문자를 포함하고 있습니다: \"$1\".",
        "title-invalid-relative": "제목에 상대 경로가 있습니다. 제목에 상대 경로를 쓰는 것은 적절하지 않습니다. 제목에 붙은 상대 경로는 사용자 브라우저에서 제대로 인식하지 못할 수도 있습니다.",
        "title-invalid-magic-tilde": "요청한 문서의 제목에 적절하지 못한 특수 물결 문자열(magic tilde sequence; <nowiki>~~~</nowiki>)이 들어있습니다.",
-       "title-invalid-too-long": "페이지 제목이 너무 깁니다. 페이지 제목 길이는 최대 $1 까지 설정할 수 있습니다.",
-       "title-invalid-leading-colon": "페이지 제목에 잘못된 문자가 포함되어 있습니다.",
+       "title-invalid-too-long": "요청된 페이지 제목이 너무 깁니다. 길이는 UTF-8 인코딩 기준 최대 $1 바이트까지 설정할 수 있습니다.",
+       "title-invalid-leading-colon": "요청된 페이지 제목 처음에 잘못된 콜론 문자가 포함되어 있습니다.",
        "perfcached": "다음 자료는 캐시된 것이며 최신이 아닐 수 있습니다. 캐시에 최대 {{PLURAL:$1|결과 한 개|결과 $1개}}가 있습니다.",
        "perfcachedts": "다음 자료는 캐시된 것으로, $1에 마지막으로 업데이트되었습니다. 캐시에 최대 {{PLURAL:$4|결과 한 개|결과 $4개}}가 있습니다.",
-       "querypage-no-updates": "ì\9d´ ë¬¸ì\84\9cì\9d\98 ê°±ì\8b ì\9d´ í\98\84ì\9e¬ ì¤\91ì§\80ë\90\98ì\96´ ì\9e\88ì\8aµë\8b\88ë\8b¤.\nì\9e\90ë£\8cê°\80 ì\9e ì\8b\9c 갱신되지 않을 것입니다.",
+       "querypage-no-updates": "ì\9d´ ë¬¸ì\84\9cì\9d\98 ê°±ì\8b ì\9d´ í\98\84ì\9e¬ ì¤\91ì§\80ë\90\98ì\96´ ì\9e\88ì\8aµë\8b\88ë\8b¤.\nì§\80ê¸\88ì\9d\80 ì\9e\90ë£\8cê°\80 갱신되지 않을 것입니다.",
        "viewsource": "원본 보기",
        "viewsource-title": "$1 문서 원본 보기",
        "actionthrottled": "동작 중지",
-       "actionthrottledtext": "악용을 막기 위해 짧은 시간 동안 이 작업을 너무 많이 수행하는 것을 ë§\89ê³  ì\9e\88ì\8aµë\8b\88ë\8b¤.\nì \9cí\95\9cì\9d\84 ë\84\98ì\97\88ì\9c¼ë\8b\88 ëª\87 ë¶\84 ë\92¤ì\97\90 ì\83\88ë¡\9c ì\8b\9cë\8f\84í\95\98ì\84¸ì\9a\94.",
+       "actionthrottledtext": "악용을 막기 위해 짧은 시간 동안 이 작업을 너무 많이 수행하는 것을 ì \9cí\95\9cí\95\98ê³  ì\9e\88ì\8aµë\8b\88ë\8b¤.\nì \9cí\95\9cì\9d\84 ë\84\98ì\97\88ì\9c¼ë\8b\88 ëª\87 ë¶\84 ë\92¤ì\97\90 ë\8b¤ì\8b\9c ì\8b\9cë\8f\84í\95\98ì\84¸ì\9a\94.",
        "protectedpagetext": "이 문서는 편집하거나 다른 명령을 할 수 없도록 보호되어 있습니다.",
        "viewsourcetext": "문서의 원본을 보거나 복사할 수 있습니다.",
-       "viewyourtext": "이 문서로의 <strong>당신의 편집</strong>의 원본을 보고 복사할 수 있습니다.",
+       "viewyourtext": "이 문서에 속한 <strong>당신의 편집</strong>의 원본을 보고 복사할 수 있습니다.",
        "protectedinterface": "이 문서는 이 위키의 소프트웨어 인터페이스에 쓰이는 문서로, 부정 행위를 막기 위해 보호되어 있습니다.\n모든 위키에 대한 번역을 추가하거나 바꾸려면 미디어위키 지역화 프로젝트인 [//translatewiki.net/wiki/Main_Page?setlang=ko translatewiki.net]에 참여하시기 바랍니다.",
        "editinginterface": "<strong>경고:</strong> 소프트웨어 인터페이스에 쓰이는 문서를 고치고 있습니다.\n이 문서에 있는 내용을 바꾸면 이 위키에 있는 모든 사용자에게 영향을 끼칩니다.",
        "translateinterface": "모든 위키를 위해 번역을 추가하거나 바꾸려면, 미디어위키 지역화 프로젝트인 [//translatewiki.net/ translatewiki.net]을 사용해 주시기 바랍니다.",
        "cascadeprotected": "이 문서는 다음 \"연쇄적\" 보호가 걸린 {{PLURAL:$1|문서|문서들}}에 포함되어 있어 함께 보호됩니다:\n$2",
-       "namespaceprotected": "<strong>$1</strong> 이름공간의 문서를 편집할 수 있는 권한이 없습니다.",
+       "namespaceprotected": "<strong>$1</strong> 이름공간의 문서를 편집할 권한이 없습니다.",
        "customcssprotected": "여기에는 다른 사용자의 개인 설정이 포함되어 있기 때문에 이 CSS 문서를 편집할 수 없습니다.",
        "customjsprotected": "여기에는 다른 사용자의 개인 설정이 포함되어 있기 때문에 이 자바스크립트 문서를 편집할 수 없습니다.",
        "mycustomcssprotected": "이 CSS 문서를 편집할 권한이 없습니다.",
        "mypreferencesprotected": "내 환경 설정을 편집할 권한이 없습니다.",
        "ns-specialprotected": "특수 문서는 편집할 수 없습니다.",
        "titleprotected": "[[User:$1|$1]] 사용자가 문서 만들기를 금지했습니다.\n이유는 다음과 같습니다. <em>$2</em>",
-       "filereadonlyerror": "\"$2\" 파일 저장소가 읽기 전용이기 때문에 \"$1\" 파일을 바꿀 수 없습니다.\n\n저장소 관리자가 파일 저장소를 잠근 이유에 대한 설명을 남겼습니다: \"$3\".",
+       "filereadonlyerror": "\"$2\" 파일 저장소가 읽기 전용이기 때문에 \"$1\" 파일을 바꿀 수 없습니다.\n\n파일 저장소를 잠근 시스템 관리자가 다음과 같은 설명을 남겼습니다: \"$3\".",
        "invalidtitle-knownnamespace": "제목 오류: \"$2\" 이름공간과 \"$3\" 텍스트",
-       "invalidtitle-unknownnamespace": "제목 오류: 알 수 없는 $1 이름공간 번호와, \"$2\" 텍스트",
+       "invalidtitle-unknownnamespace": "제목 오류: 알 수 없는 $1 이름공간 번호와 \"$2\" 텍스트",
        "exception-nologin": "로그인하지 않음",
        "exception-nologin-text": "이 문서에 접근하거나 이 동작을 수행하려면 로그인하세요.",
        "exception-nologin-text-manual": "이 문서에 접근하거나 이 명령을 수행하려면 $1하세요.",
        "virus-scanfailed": "검사 실패 (코드 $1)",
        "virus-unknownscanner": "알 수 없는 안티 바이러스:",
        "logouttext": "<strong>이제 로그아웃했습니다.</strong>\n\n브라우저 캐시를 지울 때까지 일부 문서에서 아직 로그인이 되어 있는 것처럼 보일 수 있음에 유의하세요.",
-       "cannotlogoutnow-title": "지금 로그아웃 할 수 없습니다",
+       "cannotlogoutnow-title": "지금 로그아웃할 수 없습니다",
        "cannotlogoutnow-text": "$1 사용 중에는 로그아웃이 불가능합니다.",
        "welcomeuser": "$1님, 환영합니다!",
-       "welcomecreation-msg": "계정이 만들어졌습니다.\n[[Special:Preferences|{{SITENAME}} 사용자 환경 설정]]을 바꿀 수 있습니다.",
+       "welcomecreation-msg": "계정이 만들어졌습니다.\n{{SITENAME}}의 사용자 [[Special:Preferences|환경 설정]]을 바꿀 수 있습니다.",
        "yourname": "사용자 이름:",
-       "userlogin-yourname": "사용자 계정 이름",
-       "userlogin-yourname-ph": "사용자 계정 이름을 입력하세요",
-       "createacct-another-username-ph": "사용자 계정 이름을 입력하세요",
+       "userlogin-yourname": "사용자 이름",
+       "userlogin-yourname-ph": "사용자 이름을 입력하세요",
+       "createacct-another-username-ph": "사용자 이름을 입력하세요",
        "yourpassword": "비밀번호:",
        "userlogin-yourpassword": "비밀번호",
        "userlogin-yourpassword-ph": "비밀번호를 입력하세요",
        "yourpasswordagain": "비밀번호 다시 입력:",
        "createacct-yourpasswordagain": "비밀번호 확인",
        "createacct-yourpasswordagain-ph": "비밀번호를 다시 입력하세요",
-       "remembermypassword": "이 브라우저에서 로그인 상태를 저장하기 (최대 $1{{PLURAL:$1|일}})",
+       "remembermypassword": "이 브라우저에 로그인 상태 저장하기 (최대 $1일)",
        "userlogin-remembermypassword": "로그인 상태를 유지하기",
        "userlogin-signwithsecure": "보안 연결 사용",
-       "cannotloginnow-title": "지금 로그인 할 수 없습니다.",
+       "cannotloginnow-title": "지금 로그인할 수 없습니다.",
        "cannotloginnow-text": "$1 사용 중에는 로그인이 불가능합니다.",
        "yourdomainname": "도메인 이름:",
        "password-change-forbidden": "이 위키에서 비밀번호를 바꿀 수 없습니다.",
-       "externaldberror": "바깥 인증 데이터베이스에 오류가 있거나 바깥 계정을 새로 고칠 권한이 없습니다.",
+       "externaldberror": "인증 데이터베이스에 오류가 있거나 바깥 계정을 새로 고칠 권한이 없습니다.",
        "login": "로그인",
        "nav-login-createaccount": "로그인 / 계정 만들기",
        "userlogin": "로그인 / 계정 만들기",
        "createacct-emailoptional": "이메일 주소 (선택 사항)",
        "createacct-email-ph": "이메일 주소를 입력하세요",
        "createacct-another-email-ph": "이메일 주소를 입력하세요",
-       "createaccountmail": "ì\9e\84ì\8b\9c ì\9e\84ì\9d\98 비밀번호를 이메일로 보내기",
+       "createaccountmail": "ì\9e\84ì\9d\98ì\9d\98 ì\9e\84ì\8b\9c 비밀번호를 이메일로 보내기",
        "createacct-realname": "실명 (선택 사항)",
        "createaccountreason": "이유:",
        "createacct-reason": "이유",
        "userexists": "입력한 사용자 계정 이름이 이미 사용되고 있습니다.\n다른 이름을 선택하세요.",
        "loginerror": "로그인 오류",
        "createacct-error": "계정 만들기 오류",
-       "createaccounterror": "계정을 만들수 없습니다: $1",
-       "nocookiesnew": "사용자 계정을 만들었지만, 아직 로그인하고 있지 않습니다.\n{{SITENAME}}에서는 로그인 정보를 저장하기 위해 쿠키를 사용합니다.\n지금 사용하는 웹 브라우저는 쿠키를 사용하지 않도록 설정되어 있습니다.\n로그인하기 전에 웹 브라우저에서 쿠키를 사용하도록 설정해주세요.",
+       "createaccounterror": "계정을 만들 수 없습니다: $1",
+       "nocookiesnew": "사용자 계정을 만들었지만, 로그인되어 있지 않습니다.\n{{SITENAME}}에서는 로그인을 위해 쿠키를 사용합니다.\n사용자는 쿠키를 사용하지 않도록 설정되어 있습니다.\n쿠키를 사용하도록 설정한 다음 새로운 사용자 이름과 비밀번호로 로그인하세요.",
        "nocookieslogin": "{{SITENAME}}에서는 로그인을 위해 쿠키를 사용합니다.\n쿠키가 비활성되어 있습니다.\n쿠키 사용을 활성화한 다음 다시 시도하세요.",
        "nocookiesfornew": "요청의 출처를 확인할 수 없기 때문에 사용자 계정이 만들어지지 않았습니다.\n쿠키를 활성화한 것을 확인하고, 이 문서를 새로 고치고 나서 다시 시도하세요.",
        "noname": "사용자 계정 이름이 올바르지 않습니다.",
        "noemail": "\"$1\" 사용자는 이메일 주소를 등록하지 않았습니다.",
        "noemailcreate": "올바른 이메일 주소를 제공해야 합니다.",
        "passwordsent": "\"$1\" 계정의 새로운 비밀번호를 이메일로 보냈습니다.\n비밀번호를 받고 다시 로그인해 주세요.",
-       "blocked-mailpassword": "당신의 IP 주소는 편집을 할 수 없게 차단되어 있어서 악용하지 못하도록 비밀번호 되살리기 기능 사용이 금지됩니다.",
+       "blocked-mailpassword": "사용 중인 IP 주소는 편집을 할 수 없도록 차단되어 있습니다. 악용 방지를 위해 비밀번호 되살리기 기능의 사용은 금지됩니다.",
        "eauthentsent": "입력한 이메일로 확인 이메일을 보냈습니다.\n다른 모든 형태의 이메일을 당신의 계정으로 보내기 전에, 계정이 정말 당신의 것인지 확인하기 위해 이메일 내용의 지시대로 계정 확인 절차를 실행해 주셔야 합니다.",
        "throttled-mailpassword": "비밀번호 재설정 이메일을 이미 최근 {{PLURAL:$1|$1시간}} 안에 보냈습니다.\n악용을 방지하기 위해 비밀번호 재설정 메일은 {{PLURAL:$1|$1시간}}마다 오직 하나씩만 보낼 수 있습니다.",
        "mailerror": "메일을 보내는 중 오류: $1",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|토론]]) 사용자 계정이 만들어졌습니다.",
        "createaccount-title": "{{SITENAME}} 계정 만들기",
        "createaccount-text": "누군가가 {{SITENAME}} ($4)에서 사용자 이름 \"$2\", 비밀번호 \"$3\"로 당신의 이메일 주소가 등록된 계정을 만들었습니다. \n지금 로그인하여 비밀번호를 바꾸십시오.\n\n실수로 계정을 잘못 만들었다면 이 메시지는 무시해도 됩니다.",
-       "login-throttled": "로그인에 연속으로 실패하였습니다.\n$1 기다렸다가 다시 시도하세요.",
+       "login-throttled": "최근 너무 많이 로그인을 시도했습니다.\n$1 뒤에 다시 시도하세요.",
        "login-abort-generic": "로그인에 실패했습니다 - 중지됨",
        "login-migrated-generic": "당신의 계정이 마이그레이션되었으며, 당신의 사용자 이름이 더 이상 이 위키에 존재하지 않습니다.",
        "loginlanguagelabel": "언어: $1",
        "changepassword-success": "비밀번호가 바뀌었습니다!",
        "changepassword-throttled": "최근 너무 많이 로그인을 시도했습니다.\n$1 뒤에 다시 시도하세요.",
        "botpasswords": "봇 비밀번호",
+       "botpasswords-summary": "'''봇 비밀번호'''는 사용자의 기본 로그인 정보를 이용하지 않고 API를 통한 사용자 계정으로의 접근을 허용합니다. 봇 비밀번호를 이용하여 로그인할 때 이용 가능한 사용자 권한은 제한될 수 있습니다.\n\n이 기능을 이용할 이유가 없다면 굳이 이용하지 않으셔도 됩니다. 누구도 이 비밀번호의 생성을 사용자에게 요청할 수 없으며, 이를 수락하여 전달하지 말아 주십시오.",
        "botpasswords-disabled": "봇 비밀번호가 비활성화되었습니다.",
+       "botpasswords-no-central-id": "봇 비밀번호를 사용하려면 통합 계정으로 로그인해야 합니다.",
        "botpasswords-existing": "기존의 봇 비밀번호",
        "botpasswords-createnew": "새로운 봇 비밀번호 만들기",
        "botpasswords-editexisting": "기존의 봇 비밀번호 편집하기",
        "botpasswords-label-delete": "삭제",
        "botpasswords-label-resetpassword": "비밀번호 재설정",
        "botpasswords-label-grants": "적용할 수 있는 부여:",
+       "botpasswords-help-grants": "개개의 부여 기능은 사용자 계정이 이미 소유하고 있는 사용자 권한에 대한 접근을 제공합니다. 자세한 사항은 [[Special:ListGrants|부여 목록]]을 확인해 주십시오.",
        "botpasswords-label-restrictions": "사용 제한:",
        "botpasswords-label-grants-column": "승인됨",
        "botpasswords-bad-appid": "\"$1\"이라는 봇 이름은 유효하지 않습니다.",
        "botpasswords-newpassword": "<strong>$1</strong> 계정의 비밀번호가 <strong>$2</strong>로 변경되었습니다. <em>잊어버리지 않도록 기록해두시기 바랍니다.</em>",
        "botpasswords-no-provider": "'BotPasswordsSessionProvider'는 이용할 수 없습니다.",
        "botpasswords-restriction-failed": "봇 비밀번호 제한으로 인해 로그인할 수 없습니다.",
+       "botpasswords-invalid-name": "지정된 사용자 이름은 봇 비밀번호 구분자(\"$1\")를 포함하고 있지 않습니다.",
        "botpasswords-not-exist": "\"$1\" 사용자가 이름이 \"$2\"인 봇의 비밀번호를 가지고 있지 않습니다.",
        "resetpass_forbidden": "비밀번호를 바꿀 수 없습니다",
-       "resetpass-no-info": "ì\9d´ í\8a¹ì\88\98 ë¬¸ì\84\9cì\97\90 ì§\81ì \91 ì \91ê·¼í\95\98려면 ë°\98ë\93\9cì\8b\9c 로그인해야 합니다.",
+       "resetpass-no-info": "ì\9d´ í\8e\98ì\9d´ì§\80ì\97\90 ì§\81ì \91 ì \91ê·¼í\95\98려면 로그인해야 합니다.",
        "resetpass-submit-loggedin": "비밀번호 바꾸기",
        "resetpass-submit-cancel": "취소",
        "resetpass-wrong-oldpass": "비밀번호가 잘못되었거나 현재의 비밀번호와 같습니다.\n이미 비밀번호를 바꾸었거나 새 임시 비밀번호를 요청했을 수 있습니다.",
        "passwordreset-text-many": "{{PLURAL:$1|이메일을 통해 임시 비밀번호를 받으려면 필드 중 하나를 채우세요.}}",
        "passwordreset-disabled": "이 위키에서는 비밀번호를 재설정할 수 없습니다.",
        "passwordreset-emaildisabled": "이 위키에서 이메일 기능이 비활성화되어 있습니다.",
-       "passwordreset-username": "사용자 계정 이름:",
+       "passwordreset-username": "사용자 이름:",
        "passwordreset-domain": "도메인:",
        "passwordreset-capture": "발송 결과 이메일을 보시겠습니까?",
        "passwordreset-capture-help": "이 상자에 체크하면 이메일이 발송된 즉시 임시 비밀번호가 담긴 이메일을 볼 수 있습니다.",
        "changeemail": "이메일 주소를 바꾸거나 제거하기",
        "changeemail-header": "이메일 주소를 바꾸려면 이 양식을 채우세요. 계정에서 이메일 연동을 취소하고 싶다면 양식을 제출할 때 새 이메일 주소를 공란으로 두세요.",
        "changeemail-passwordrequired": "변경을 적용하려면 비밀번호를 입력해야 합니다.",
-       "changeemail-no-info": "ì\9d´ í\8a¹ì\88\98 ë¬¸ì\84\9cì\97\90 ì§\81ì \91 ì \91ê·¼í\95\98려면 ë°\98ë\93\9cì\8b\9c 로그인해야 합니다.",
+       "changeemail-no-info": "ì\9d´ í\8e\98ì\9d´ì§\80ì\97\90 ì§\81ì \91 ì \91ê·¼í\95\98려면 로그인해야 합니다.",
        "changeemail-oldemail": "현재 이메일 주소:",
        "changeemail-newemail": "새 이메일 주소:",
        "changeemail-newemail-help": "이메일 주소를 삭제하고자 한다면 이 칸을 빈칸으로 두세요. 비밀번호 재설정이 불가능해지며, 이메일 주소가 없다면 이메일을 받을 수 없습니다.",
        "changeemail-none": "(없음)",
        "changeemail-password": "{{SITENAME}} 비밀번호:",
        "changeemail-submit": "이메일 주소 바꾸기",
-       "changeemail-throttled": "로그인에 연속으로 너무 많이 실패하였습니다.\n$1 기다렸다가 다시 시도하세요.",
+       "changeemail-throttled": "최근 너무 많이 로그인을 시도했습니다.\n$1 뒤에 다시 시도하세요.",
        "changeemail-nochange": "다른 이메일 주소를 입력해 주세요.",
        "resettokens": "토큰 재설정",
        "resettokens-text": "여기에 당신의 계정과 관련된 특정 개인 데이터에 접근을 허용하는 토큰을 재설정합니다.\n\n토큰이 다른 사람에게 알려졌거나 계정이 침해되었을 때는 재설정해야 합니다.",
        "minoredit": "사소한 편집입니다",
        "watchthis": "이 문서 주시하기",
        "savearticle": "문서 저장",
+       "publishpage": "문서 게시",
        "preview": "미리 보기",
        "showpreview": "미리 보기",
        "showdiff": "차이 보기",
-       "blankarticle": "<strong>경고:</strong> 만들려는 문서가 비어 있습니다.\n\"{{int:savearticle}}\"을 다시 클릭하면, 문서에 내용이 없이 만들어집니다.",
+       "blankarticle": "<strong>경고:</strong> 만들려는 문서가 비어 있습니다.\n\"{{int:savearticle}}\"을 다시 클릭하면, 아무 내용 없이 문서가 만들어집니다.",
        "anoneditwarning": "<strong>경고:</strong> 로그인을 하고 있지 않습니다. 편집을 하게 되면 IP 주소가 공개적으로 보여집니다. <strong>[$1 로그인]</strong>하거나 <strong>[$2 계정을 생성하면]</strong>, 편집 시에 다른 이점과 함께 사용자 이름이 표시됩니다.",
        "anonpreviewwarning": "<em>로그인하고 있지 않습니다. 문서를 저장하면 당신의 IP 주소가 문서의 편집 역사에 남게 됩니다.</em>",
        "missingsummary": "'''알림:''' 편집 요약을 적지 않았습니다.\n이대로 \"{{int:savearticle}}\"을 클릭하면 편집 요약 없이 저장됩니다.",
        "userpage-userdoesnotexist": "\"$1\" 사용자 계정은 등록되어 있지 않습니다.\n이 문서를 만들거나 편집하기 전에 계정이 존재하는지 확인해주세요.",
        "userpage-userdoesnotexist-view": "\"$1\" 사용자 계정은 등록되어 있지 않습니다.",
        "blocked-notice-logextract": "이 사용자는 현재 차단되어 있습니다.\n해당 사용자의 최근 차단 기록을 참조하십시오:",
-       "clearyourcache": "<strong>참고:</strong> 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.\n* <strong>Firefox / Safari</strong>: <em>Shift</em> 키를 누르면서 새로 고침을 클릭하거나, <em>Ctrl-F5</em> 또는 <em>Ctrl-R</em> 을 입력 (Mac에서는 <em>⌘-R</em>)\n* <strong>Google Chrome</strong>: <em>Ctrl-Shift-R</em>키를 입력 (Mac에서는 <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer</strong>: <em>Ctrl</em> 키를 누르면서 새로 고침을 클릭하거나, <em>Ctrl-F5</em>를 입력.\n* <strong>Opera</strong>: <em>도구→설정</em>에서 캐시를 비움",
+       "clearyourcache": "<strong>참고:</strong> 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.\n* <strong>파이어폭스 / 사파리</strong>: <em>Shift</em> 키를 누르면서 새로 고침을 클릭하거나, <em>Ctrl-F5</em> 또는 <em>Ctrl-R</em> 을 입력 (Mac에서는 <em>⌘-R</em>)\n* <strong>구글 크롬</strong>: <em>Ctrl-Shift-R</em>키를 입력 (Mac에서는 <em>⌘-Shift-R</em>)\n* <strong>인터넷 익스플로러</strong>: <em>Ctrl</em> 키를 누르면서 새로 고침을 클릭하거나, <em>Ctrl-F5</em>를 입력.\n* <strong>오페라:</strong> <em>메뉴 → 설정</em>(맥의 경우 <em>오페라 → 환경 설정</em>)으로 이동한 다음 <em>개인 정보 보호 및 보안 → 검색 데이터 지우기 → 캐시한 이미지 및 파일</em>을 누름.",
        "usercssyoucanpreview": "'''안내''': CSS 문서를 저장하기 전에 \"{{int:showpreview}}\" 기능을 통해 작동을 확인해주세요.",
        "userjsyoucanpreview": "'''안내''': 자바스크립트 문서를 저장하기 전에 \"{{int:showpreview}}\" 기능을 통해 작동을 확인해주세요.",
        "usercsspreview": "'''사용자 CSS의 미리 보기입니다.'''\n'''아직 저장하지 않았습니다!'''",
        "note": "<strong>참고:</strong>",
        "previewnote": "'''이 화면은 미리 보기입니다.'''\n편집한 내용은 아직 저장하지 않았습니다!",
        "continue-editing": "편집 영역으로 가기",
-       "previewconflict": "이 미리 보기는 저장할 때의 모습으로 위쪽 편집창의 문서를 반영합니다.",
-       "session_fail_preview": "세션 데이터가 없어져 편집을 저장하지 못했습니다.\n\n로그아웃 되었는지도 모릅니다. <strong>아직 로그인 상태인지 확인하고 다시 시도해주세요</strong>.\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하세요. 그리고 브라우저 설정에서 쿠키 사용을 허용하는지 확인하세요.",
+       "previewconflict": "이 미리 보기는 저장할 때의 모습으로, 위쪽 편집 영역의 텍스트를 반영합니다.",
+       "session_fail_preview": "세션 데이터가 없어져 편집을 저장하지 못했습니다.\n\n로그아웃되었는지도 모릅니다. <strong>아직 로그인 상태인지 확인하고 다시 시도해주세요</strong>.\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하세요. 그리고 브라우저 설정에서 쿠키 사용을 허용하는지 확인하세요.",
        "session_fail_preview_html": "세션 데이터가 없어져 편집을 저장하지 못했습니다.\n\n<em>{{SITENAME}}에서 HTML 입력을 허용하기 때문에, 자바스크립트 공격을 막기 위해 미리 보기는 숨겨져 있습니다.</em>\n\n<strong>적합하게 편집을 시도했다면 다시 시도해주세요.</strong>\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하고, 브라우저가 이 사이트에서 쿠키를 허용하는지 확인하세요.",
        "token_suffix_mismatch": "'''저장하려는 내용의 문장 부호가 망가져 있습니다.'''\n문서 보호를 위해 해당 내용을 저장하지 않습니다.\n버그가 있는 익명 프록시 서비스 등을 사용할 때 이런 문제가 발생할 수 있습니다.",
        "edit_form_incomplete": "'''편집의 일부 내용이 서버에 전달되지 않았습니다. 편집이 손상되지 않았는지 확인하고 다시 시도해 주십시오.'''",
        "explainconflict": "문서를 편집하는 도중에 누군가 이 문서를 고쳤습니다.\n위쪽의 문서가 지금 바뀐 문서이고, 아래쪽의 문서가 당신이 편집한 문서입니다.\n아래쪽의 내용을 위쪽에 적절히 합쳐 주시기 바랍니다.\n\"{{int:savearticle}}\"을 누르면 '''위쪽의 편집 내역만''' 저장됩니다.",
        "yourtext": "당신의 편집",
        "storedversion": "현재 문서",
-       "nonunicodebrowser": "<strong>경고: 웹 브라우저가 유니코드를 완벽하게 지원하지 않습니다.</strong>\n아스키가 아닌 문자가 16진수 코드로 나타날 수 있습니다.",
+       "nonunicodebrowser": "<strong>경고: 브라우저가 유니코드를 지원하지 않습니다.</strong>\n문서를 안전하게 편집할 수 있도록 다음의 우회 방안이 제공됩니다: 편집 상자에서 아스키가 아닌 문자가 16진수 코드로 나타납니다.",
        "editingold": "<strong>경고: 이 문서의 오래된 판을 편집하고 있습니다.</strong>\n이것을 저장하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.",
        "yourdiff": "차이",
        "copyrightwarning": "{{SITENAME}}에서의 모든 기여는 $2 라이선스로 배포된다는 점을 유의해 주세요 (자세한 내용에 대해서는 $1 문서를 읽어주세요).\n만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.<br />\n또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다.\n<strong>저작권이 있는 내용을 허가 없이 저장하지 마세요!</strong>",
        "readonlywarning": "<strong>경고: 데이터베이스가 관리를 위해 잠겨 있습니다. 따라서 문서를 편집한 내용을 지금 저장할 수 없습니다.</strong>\n편집 내용을 복사하여 붙여넣기 등을 사용하여 일단 다른 곳에 저장한 후, 나중에 다시 시도해 주세요.\n\n데이터베이스를 잠근 시스템 관리자가 남긴 설명은 다음과 같습니다: $1",
        "protectedpagewarning": "<strong>경고: 이 문서는 관리자 권한이 있는 사용자만 편집할 수 있도록 보호되어 있습니다.</strong>\n이 문서의 최근 기록을 참조하십시오:",
        "semiprotectedpagewarning": "<strong>참고:</strong> 이 문서는 계정을 등록한 사용자만이 편집할 수 있도록 보호되어 있습니다.\n이 문서의 최근 기록을 참조하십시오:",
-       "cascadeprotectedwarning": "<strong>경고:</strong> 이 문서는 보호되어 있어 관리자만 편집할 수 있습니다. 연쇄적 보호가 걸린 다음 {{PLURAL:$1|문서}}에서 이 문서를 사용하고 있습니다:",
+       "cascadeprotectedwarning": "<strong>경고:</strong> 이 문서는 보호되어 있어 관리자 권한이 있는 사용자만 편집할 수 있습니다. 연쇄적 보호가 걸린 다음 {{PLURAL:$1|문서}}에서 이 문서를 사용하고 있습니다:",
        "titleprotectedwarning": "<strong>경고: 이 문서는 보호되어 있어, 문서를 만드려면 [[Special:ListGroupRights|특정한 권한]]이 필요합니다.</strong>\n아래 문서의 최근 기록을 참조하십시오:",
        "templatesused": "이 문서에서 사용한 {{PLURAL:$1|틀}}:",
        "templatesusedpreview": "이 미리 보기에서 사용하고 있는 {{PLURAL:$1|틀}}:",
        "permissionserrors": "권한 오류",
        "permissionserrorstext": "해당 명령을 수행할 권한이 없습니다. 다음 {{PLURAL:$1|이유}}를 확인해보세요:",
        "permissionserrorstext-withaction": "$2 권한이 없습니다. 다음 {{PLURAL:$1|이유}}를 확인해주세요:",
+       "contentmodelediterror": "사용자는 이 판을 편집할 수 없습니다. 콘텐츠 모델은 <code>$1</code>이며, 이 문서의 현 콘텐츠 모델은 <code>$2</code>이므로 차이가 있습니다.",
        "recreate-moveddeleted-warn": "<strong>경고: 삭제된 문서를 다시 만들고 있습니다.</strong>\n\n이 문서를 계속 편집하는 것이 적합한 것인지 확인해주세요.\n편의를 위해 삭제와 이동 기록을 다음과 같이 제공합니다:",
        "moveddeleted-notice": "이 문서는 삭제되었습니다.\n이 문서의 삭제 및 이동 기록은 다음과 같습니다.",
        "moveddeleted-notice-recent": "죄송합니다, 이 문서는 최근 (24시간 내)에 삭제된 적이 있습니다.\n삭제와 이동 기록이 참고를 위해 남겨져 있습니다.",
        "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": "<strong>경고:</strong> 이 문서는 너무 많은 파서 함수를 포함하고 있습니다.\n\n$2개 보다 적게 {{PLURAL:$2|써야}} 하지만 {{PLURAL:$1|지금은 $1개를 쓰고 있습니다}}.",
-       "expensive-parserfunction-category": "느린 파서 함수 호출을 너무 많이 하는 문서",
+       "expensive-parserfunction-category": "파서 함수 호출을 너무 많이 사용하는 문서",
        "post-expand-template-inclusion-warning": "<strong>경고:</strong> 틀 포함 크기가 너무 큽니다.\n일부 틀은 포함되지 않을 수 있습니다.",
        "post-expand-template-inclusion-category": "사용한 틀의 크기가 지나치게 큰 문서의 목록",
        "post-expand-template-argument-warning": "<strong>경고:</strong> 이 문서는 전개하면 크기가 너무 큰 틀 인수가 하나 이상 포함되어 있습니다.\n이 인수는 생략했습니다.",
        "parser-unstrip-loop-warning": "Unstrip의 반복을 감지했습니다",
        "parser-unstrip-recursion-limit": "Unstrip의 재귀 한도를 초과했습니다 ($1)",
        "converter-manual-rule-error": "언어 변환 규칙을 수동으로 지정하는 도중 오류",
-       "undo-success": "편집을 되돌릴 수 있습니다.\n편집 되돌리기를 완료하려면 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.",
+       "undo-success": "편집을 되돌릴 수 있습니다.\n이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.",
        "undo-failure": "중간의 다른 편집과 충돌하여 이 편집을 되돌릴 수 없습니다.",
        "undo-norev": "문서가 없거나 삭제되었기 때문에 편집을 되돌릴 수 없습니다.",
        "undo-nochange": "편집이 이미 되돌려진 것으로 나타납니다.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|토론]])의 $1판 편집을 되돌림",
        "undo-summary-username-hidden": "숨겨진 사용자가 $1 판을 되돌림",
        "cantcreateaccounttitle": "계정을 만들 수 없습니다",
-       "cantcreateaccount-text": "현재 아이피 주소('''$1''')는 [[User:$3|$3]] 사용자에 의해 계정 만들기가 차단되었습니다.\n\n차단 이유는 다음과 같습니다: $2",
+       "cantcreateaccount-text": "현재 IP 주소('''$1''')는 [[User:$3|$3]] 사용자에 의해 계정 만들기가 차단되었습니다.\n\n차단 이유는 다음과 같습니다: $2",
        "cantcreateaccount-range-text": "당신의 IP 주소(<strong>$4</strong>)가 속해 있는 <strong>$1</strong> 대역에서의 계정 생성을 [[User:$3|$3]] 사용자가 차단하였습니다.\n\n$3 사용자가 제시한 이유는 \"$2\"입니다.",
        "viewpagelogs": "이 문서의 기록 보기",
        "nohistory": "이 문서는 편집 역사가 없습니다.",
        "logdelete-selected": "{{PLURAL:$1|선택한 기록}}:",
        "revdelete-text-text": "삭제된 판은 여전히 문서 역사에 남게 되지만, 그 내용의 일부는 다른 사람들이 접근할 수 없게 됩니다.",
        "revdelete-text-file": "삭제된 파일 버전은 계속 파일 역사에 남게 되지만, 내용의 일부는 다른 사람들이 접근할 수 없게 됩니다.",
-       "logdelete-text": "ì\82­ì \9cë\90\9c ë¡\9cê·¸ ë\82´ì\9a©ì\9d\80 ë¡\9cê·¸ì\97\90 ë³´ì\97¬ì§\80ê² ì§\80ë§\8c, ë\82´ì\9a©ì\9d\98 ì\9d¼ë¶\80ë\8a\94 ë\8b¤ë¥¸ ì\82¬ë\9e\8cë\93¤이 접근할 수 없게 됩니다.",
+       "logdelete-text": "ì\82­ì \9cë\90\9c ë¡\9cê·¸ ë\82´ì\9a©ì\9d\80 ë¡\9cê·¸ì\97\90 ë\82\98í\83\80ë\82\98ì§\80ë§\8c, ë\82´ì\9a© ì¤\91 ì\9d¼ë¶\80ë\8a\94 ì\9d¼ë°\98ì\9d¸이 접근할 수 없게 됩니다.",
        "revdelete-text-others": "다른 관리자는 여전히 숨겨진 내용에 접근할 수 있고 추가 제한이 설정되어 있지 않으면, 다시 되살릴 수 있습니다.",
-       "revdelete-confirm": "ì\9d´ ì\9e\91ì\97\85ì\9d\84 ì\88\98í\96\89í\95\98ë\8a\94 ê²\83ì\9d\98 ê²°ê³¼ë¥¼ ì\95\8cê³  ì\9e\88ì\9c¼ë©°, [[{{MediaWiki:Policy-url}}|ì \95ì±\85]]ì\97\90 ë§\9eë\8a\94 í\96\89ë\8f\99ì\9d¸지 확인해주세요.",
+       "revdelete-confirm": "ì\9d´ ì\9e\91ì\97\85ì\9d\98 ì\88\98í\96\89 ê²°ê³¼ë¥¼ ì\95\8cê³  ì\9e\88ì\9c¼ë©°, ì\9d´ ì\9e\91ì\97\85ì\9d´ [[{{MediaWiki:Policy-url}}|ì \95ì±\85]]ì\97\90 ì\9d\98ê±°í\95\98ë\8a\94지 확인해주세요.",
        "revdelete-suppress-text": "숨기기는 <strong>다음 경우에만</strong> 사용되어야 합니다:\n* 잠재적인 비방 정보\n* 부적절한 개인 정보\n*: 집 주소, 전화번호, 주민등록번호 등",
        "revdelete-legend": "보이기 제한을 설정",
        "revdelete-hide-text": "판 문자열",
        "mergehistory-submit": "판 합치기",
        "mergehistory-empty": "합칠 수 있는 판이 없습니다.",
        "mergehistory-done": "$1 문서의 {{PLURAL:$3|판}} $3개{{PLURAL:$3|가}} [[:$2]]에 성공적으로 합쳐졌습니다.",
-       "mergehistory-fail": "역사 합치기를 수행할 수 없습니다, 문서와 시간 변수를 다시 확인하세요.",
-       "mergehistory-fail-bad-timestamp": "타임스탬프(timestamp)가 적절하지 않습니다.",
+       "mergehistory-fail": "역사 합치기를 수행할 수 없습니다. 문서와 시간 변수를 다시 확인하세요.",
+       "mergehistory-fail-bad-timestamp": "타임스탬프가 적절하지 않습니다.",
        "mergehistory-fail-invalid-source": "원본 문서가 적절하지 않습니다.",
        "mergehistory-fail-invalid-dest": "대상 문서가 적절하지 않습니다.",
+       "mergehistory-fail-no-change": "역사 병합은 모든 판을 병합하지 못했습니다. 문서와 시간 변수를 다시 확인하여 주십시오.",
+       "mergehistory-fail-permission": "역사를 병합할 권한이 부족합니다.",
        "mergehistory-fail-self-merge": "원본과 대상 문서가 같습니다.",
+       "mergehistory-fail-timestamps-overlap": "원본의 판들을 겹치거나 대상이 되는 판들 이후에 오게 할 수 없습니다.",
        "mergehistory-fail-toobig": "이동하려는 {{PLURAL:$1|판}} $1개 제한보다 많이 역사 병합을 수행할 수 없습니다.",
        "mergehistory-no-source": "원본인 $1 문서가 존재하지 않습니다.",
        "mergehistory-no-destination": "대상인 $1 문서가 존재하지 않습니다.",
        "notextmatches": "해당하는 문서 없음",
        "prevn": "이전 {{PLURAL:$1|$1개}}",
        "nextn": "다음 {{PLURAL:$1|$1개}}",
-       "prev-page": "전 페이지",
+       "prev-page": "ì\9d´ì \84 í\8e\98ì\9d´ì§\80",
        "next-page": "다음 페이지",
        "prevn-title": "이전 {{PLURAL:$1|결과}} $1개",
        "nextn-title": "다음 {{PLURAL:$1|결과}} $1개",
        "right-createpage": "문서 만들기 (토론 문서 제외)",
        "right-createtalk": "토론 문서 만들기",
        "right-createaccount": "새 사용자 계정 만들기",
+       "right-autocreateaccount": "외부 사용자 계정으로 자동 로그인",
        "right-minoredit": "사소한 편집으로 표시",
        "right-move": "문서 이동",
        "right-move-subpages": "문서와 하위 문서 이동하기",
        "recentchangeslinked-page": "문서 이름:",
        "recentchangeslinked-to": "해당 문서를 가리키는 문서의 바뀜 보기",
        "recentchanges-page-added-to-category": "[[:$1]]이(가) 분류에 추가되었습니다",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] 문서가 분류에 추가되었습니다. [[Special:WhatLinksHere/$1|이 문서는 다른 문서들에 포함되어 있습니다]]",
        "recentchanges-page-removed-from-category": "[[:$1]]이(가) 분류에서 제거되었습니다",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] 문서가 분류에서 제거되었습니다. [[Special:WhatLinksHere/$1|이 문서는 다른 문서들에 포함되어 있습니다]]",
        "autochange-username": "미디어위키 자동 변경",
        "upload": "파일 올리기",
        "uploadbtn": "파일 올리기",
        "upload-scripted-pi-callback": "XML 스타일시트 프로세싱 명령을 포함하는 파일은 업로드 할 수 없습니다.",
        "uploaded-script-svg": "업로드 된 SVG 파일에서 스크립트로 만들 수 있는 \"$1\" 요소를 발견했습니다.",
        "uploaded-hostile-svg": "업로드 된 SVG 파일의 스타일 요소에 안전하지 못한 CSS가 있습니다.",
+       "uploaded-event-handler-on-svg": "이벤트 핸들러 속성 <code>$1=\"$2\"</code> 설정은 SVG 파일에서 사용할 수 없습니다.",
+       "uploaded-href-attribute-svg": "SVG 파일의 href 속성은 http:// 또는 https:// 대상의 링크만 허용되지만 <code>&lt;$1 $2=\"$3\"&gt;</code>를 발견했습니다.",
+       "uploaded-href-unsafe-target-svg": "안전하지 않은 데이터를 가리키는 href를 발견했습니다: 업로드된 SVG 파일의 URI 대상 <code>&lt;$1 $2=\"$3\"&gt;</code>",
+       "uploaded-animate-svg": "업로드된 SVG 파일에서 \"from\" 속성 <code>&lt;$1 $2=\"$3\"&gt;</code>을 이용 중 \"animate\" 태그가 href를 변경할 수 있음을 발견했습니다.",
+       "uploaded-setting-event-handler-svg": "이벤트 핸들러 속성을 차단으로 설정한 상태에서 <code>&lt;$1 $2=\"$3\"&gt;</code>가 업로드된 SVG 파일에서 발견되었습니다.",
+       "uploaded-setting-href-svg": "부모 요소에 \"href\" 속성을 추가할 목적으로 \"set\" 태그를 사용하는 것은 금지됩니다.",
+       "uploaded-wrong-setting-svg": "원격/데이터/스크립트 대상을 임의의 속성에 추가할 목적으로 \"set\" 태그를 사용하는 것은 금지됩니다. 업로드된 SVG 파일에 <code>&lt;set to=\"$1\"&gt;</code>를 발견했습니다.",
+       "uploaded-setting-handler-svg": "원격/데이터/스크립트와 함께 \"handler\" 속성을 설정한 SVG는 이용이 금지됩니다. 업로드된 SVG 파일에서 <code>$1=\"$2\"</code>를 발견하였습니다.",
        "uploaded-remote-url-svg": "원격 URL로 style 속성이 설정된 SVG파일은 금지됩니다. 업로드된 SVG 파일에서 <code>$1=\"$2\"</code>를 발견하였습니다.",
+       "uploaded-image-filter-svg": "URL에 이미지 필터를 발견했습니다: 업로드된 SVG 파일의 <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploadscriptednamespace": "이 SVG 파일은 사용할 수 없는 이름공간 '$1'을 포함하고 있습니다.",
        "uploadinvalidxml": "업로드된 파일의 XML의 구문을 분석할 수 없습니다.",
        "uploadvirus": "파일이 바이러스를 포함하고 있습니다!\n자세한 설명: $1",
        "upload-options": "올리기 설정",
        "watchthisupload": "이 파일 주시하기",
        "filewasdeleted": "같은 이름을 가진 파일이 올라온 적이 있었고 그 후에 삭제되었습니다.\n올리기 전에 $1을 확인해 주시기 바랍니다.",
+       "filename-thumb-name": "섬네일 제목으로 추정됩니다. 같은 위키에 섬네일 그림을 다시 업로드하지 마십시오. 섬네일이 아니라면 파일 이름을 보다 유의미한 이름으로 수정해 주시고 이름에 섬네일 접두어는 포함하지 마십시오.",
        "filename-bad-prefix": "올리려고 하는 파일 이름이 '''\"$1\"''' 이름으로 시작합니다. \"$1\" 이름은 디지털 사진기가 자동으로 붙이는 의미없는 이름입니다.\n파일에 대해 알기 쉬운 이름을 골라주세요.",
        "filename-prefix-blacklist": " #<!-- 이 줄은 그대로 두십시오 --> <pre>\n# 문법은 다음과 같습니다:\n#   * \"#\" 문자에서 줄의 끝까지는 주석입니다\n#   * 비어 있지 않은 줄은 디지털 카메라에서 자동적으로 부여하는 파일 접두어입니다\nCIMG # 카시오\nDSC_ # 니콘\nDSCF # 후지\nDSCN # 니콘\nDUW # 일부 휴대폰\nIMG # 일반\nJD # 제놉틱\nMGP # 펜탁스\nPICT # 기타\n #</pre> <!-- 이 줄은 그대로 두십시오 -->",
        "upload-proto-error": "잘못된 프로토콜",
        "upload-too-many-redirects": "URL이 너무 많은 넘겨주기를 포함하고 있습니다.",
        "upload-http-error": "HTTP 오류 발생: $1",
        "upload-copy-upload-invalid-domain": "이 도메인에 속하지 않는 웹사이트의 파일을 올릴 수 없습니다.",
+       "upload-foreign-cant-upload": "이 위키는 요청된 외부 파일 저장소에 파일을 업로드할 수 있도록 구성되어 있지 않습니다.",
        "upload-dialog-title": "파일 올리기",
        "upload-dialog-button-cancel": "취소",
        "upload-dialog-button-done": "완료",
        "upload-dialog-button-upload": "올리기",
        "upload-form-label-infoform-title": "자세한 사항",
        "upload-form-label-infoform-name": "이름",
+       "upload-form-label-infoform-name-tooltip": "이 파일을 설명할 수 있는 제목이며, 파일 이름으로 쓰일 것입니다. 띄어쓰기를 포함한 자연어를 쓸 수 있습니다. 파일 확장자는 포함하지 말아 주세요.",
        "upload-form-label-infoform-description": "설명",
+       "upload-form-label-infoform-description-tooltip": "이 작품에 대해 주목할만한 모든 내용을 간략하게 기술합니다.\n사진의 경우 주로 무엇이 찍혀 있는지와 언제 어디서 촬영했는지를 언급합니다.",
        "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-shared": "나는 이 파일에 대한 저작권을 소유하고 있음을 입증하고, 영구히 위키미디어 공용에 이 파일을 [https://creativecommons.org/licenses/by-sa/4.0/ 크리에이티브 커먼즈 저작자표시-동일조건변경허락 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 공용 파일 올리기 마법사]를 사용하는 것을 고려해보세요.",
+       "upload-form-label-own-work": "자작입니다",
+       "upload-form-label-infoform-categories": "분류",
+       "upload-form-label-infoform-date": "날짜",
+       "upload-form-label-own-work-message-local": "사용자는 이 파일을 업로드할 때 {{SITENAME}}의 서비스 조항과 라이선스 정책에 동의하는 것으로 간주합니다.",
+       "upload-form-label-not-own-work-message-local": "이 파일을 {{SITENAME}}의 정책에 따라 업로드할 수 없으면 이 대화 상자를 닫고 다른 방식을 사용하십시오.",
+       "upload-form-label-not-own-work-local-local": "[[Special:Upload|기본 파일 올리기 문서]]를 이용할 수도 있습니다.",
+       "upload-form-label-own-work-message-default": "이 파일을 공유 저장소에 업로드하면 사용자는 서비스 조항과 라이선스 정책에 동의하는 것으로 간주합니다.",
+       "upload-form-label-not-own-work-message-default": "이 파일을 공유 저장소의 정책에 따라 업로드할 수 없으면 이 대화 상자를 닫고 다른 방식을 사용하십시오.",
+       "upload-form-label-not-own-work-local-default": "이 파일이 정책에 따라 업로드가 가능할 경우 [[Special:Upload|{{SITENAME}}의 기본 파일 올리기 문서]]를 이용할 수도 있습니다.",
+       "upload-form-label-own-work-message-shared": "나는 이 파일에 대한 저작권을 소유하고 있음을 입증하고, 영구히 위키미디어 공용에 이 파일을 [https://creativecommons.org/licenses/by-sa/4.0/ 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0]에 따라 배포하는 데 동의하며, [https://wikimediafoundation.org/wiki/Terms_of_Use 이용 약관]에 동의합니다.",
+       "upload-form-label-not-own-work-message-shared": "이 파일의 저작권을 소유하지 않거나 다른 라이선스로 배포하고 싶다면 [https://commons.wikimedia.org/wiki/Special:UploadWizard 공용 파일 올리기 마법사]를 사용하는 것을 고려해보세요.",
+       "upload-form-label-not-own-work-local-shared": "사이트가 정책에 따라 이 파일의 업로드를 허용할 경우 [[Special:Upload|{{SITENAME}}의 기본 파일 올리기 문서]]를 이용할 수도 있습니다.",
        "backend-fail-stream": "\"$1\" 파일을 스트림할 수 없습니다.",
        "backend-fail-backup": "\"$1\" 파일을 백업할 수 없습니다.",
        "backend-fail-notexists": "$1 파일이 존재하지 않습니다.",
        "apihelp": "API 도움말",
        "apihelp-no-such-module": "\"$1\" 모듈을 찾을 수 없습니다.",
        "apisandbox": "API 실험실",
+       "apisandbox-jsonly": "API 연습장을 이용하려면 자바스크립트가 필요합니다.",
        "apisandbox-api-disabled": "이 사이트에서는 API가 꺼져 있습니다.",
        "apisandbox-intro": "<strong>미디어위키 웹 서비스 API</strong>를 시험해보려면 이 페이지를 이용해보세요. API 용법에 대해서는 [[mw:API:Main page|API 문서]]을 참고하십시오. 예: [//www.mediawiki.org/wiki/API#A_simple_example 대문의 내용 요청하기]. 더 많은 예를 보려면 액션을 선택하세요.\n\n여기가 연습장이라도 이 페이지에서 실행하는 동작때문에 위키를 변경할 수도 있다는 점에 유의하십시오.",
        "apisandbox-fullscreen": "패널 늘리기",
        "apisandbox-fullscreen-tooltip": "브라우저 창에 맞도록 샌드박스 패널 늘리기",
        "apisandbox-unfullscreen": "페이지 보기",
+       "apisandbox-unfullscreen-tooltip": "연습장 틀의 크기를 줄이면 미디어위키 둘러보기 링크들을 이용할 수 있습니다.",
        "apisandbox-submit": "요청하기",
        "apisandbox-reset": "지우기",
        "apisandbox-retry": "재시도",
        "apisandbox-loading": "API 모듈 \"$1\"의 정보 불러오는 중...",
+       "apisandbox-load-error": "API 모듈 \"$1\"의 정보를 가져오는 도중 오류가 발생했습니다: $2",
        "apisandbox-no-parameters": "이 API 모듈은 변수가 없습니다.",
        "apisandbox-helpurls": "도움 링크들",
        "apisandbox-examples": "예시",
        "apisandbox-dynamic-parameters-add-placeholder": "변수 이름",
        "apisandbox-dynamic-error-exists": "\"$1\"이라는 변수 이름은 이미 존재합니다.",
        "apisandbox-deprecated-parameters": "앞으로 제거될 변수",
+       "apisandbox-fetch-token": "토큰 자동 채우기",
        "apisandbox-submit-invalid-fields-title": "부적절한 필드가 있음",
+       "apisandbox-submit-invalid-fields-message": "강조된 필드를 수정한 다음 다시 시도해 주십시오.",
        "apisandbox-results": "결과",
        "apisandbox-sending-request": "API 요청을 보내는 중...",
        "apisandbox-loading-results": "API 결과를 받는 중...",
        "apisandbox-results-error": "API 질의 요청을 로딩하는 도중 에러 발생: $1.",
        "apisandbox-request-url-label": "요청 URL:",
        "apisandbox-request-time": "요청 처리 시간: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "토큰 수정 후 다시 제출",
        "apisandbox-results-fixtoken-fail": "\"$1\" 토크을 가져오는데 실패했습니다.",
        "apisandbox-alert-page": "이 문서에 있는 필드가 유효하지 않습니다.",
        "apisandbox-alert-field": "이 필드의 값이 유효하지 않습니다.",
        "listgrouprights-namespaceprotection-namespace": "이름공간",
        "listgrouprights-namespaceprotection-restrictedto": "사용자가 편집할 수 있는 권한",
        "listgrants": "부여",
-       "listgrants-summary": "다음은 사용자 권한에 관련된 접근 권한을 통해 부여된 부여 목록입니다. 사용자는 자신의 계정에 대해 권한을 부여 할 수 있지만, 사용자가 애플리케이션에 부여한 권한 설정에 따라 제한이 있습니다. 사용자를 대신하여 동작하는 애플리케이션은 사용자가 갖고 있지 않은 권한은 사용할 수 없습니다. \n각각의 권한에 대한 [[{{MediaWiki:Listgrouprights-helppage}}|추가 정보]]가 있습니다.",
+       "listgrants-summary": "다음은 사용자 권한에 관련된 접근 권한을 통해 부여된 부여 목록입니다. 사용자는 자신의 계정에 대해 권한을 부여할 수 있지만, 사용자가 애플리케이션에 부여한 권한 설정에 따라 제한이 있습니다. 사용자를 대신하여 동작하는 애플리케이션은 사용자가 갖고 있지 않은 권한을 사용할 수는 없습니다. \n각각의 권한에 대한 [[{{MediaWiki:Listgrouprights-helppage}}|추가 정보]]가 있습니다.",
        "listgrants-grant": "부여",
        "listgrants-rights": "권한",
        "trackingcategories": "추적용 분류",
        "ipb-unblock": "사용자 또는 IP 주소 차단 해제하기",
        "ipb-blocklist": "현재 차단 기록 보기",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}}의 기여",
+       "ipb-blocklist-duration-left": "남은 기간: $1",
        "unblockip": "사용자 차단 해제",
        "unblockiptext": "아래의 양식에 차단 해제하려는 IP 주소나 사용자 이름을 입력하세요.",
        "ipusubmit": "차단 해제",
        "import-nonewrevisions": "가져온 판 없음(모든 판이 이미 존재하거나 오류로 인해 건너뛰었을 수도 있습니다.)",
        "xml-error-string": "$3단 $2줄 (바이트 $4)에서 $1: $5",
        "import-upload": "XML 데이터 올리기",
-       "import-token-mismatch": "세션 데이터가 손실되었습니다.\n\n로그아웃 되었는지도 모릅니다. <strong>아직 로그인 상태인지 확인하고 다시 시도해주세요</strong>.\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하세요. 그리고 브라우저 설정에서 쿠키 사용을 허용하는지 확인하세요.",
+       "import-token-mismatch": "세션 데이터가 손실되었습니다.\n\n로그아웃되었는지도 모릅니다. <strong>아직 로그인 상태인지 확인하고 다시 시도해주세요</strong>.\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하세요. 그리고 브라우저 설정에서 쿠키 사용을 허용하는지 확인하세요.",
        "import-invalid-interwiki": "해당 위키에서 문서를 가져올 수 없습니다.",
        "import-error-edit": "문서를 편집할 수 없기 때문에 \"$1\" 문서를 가져올 수 없었습니다.",
        "import-error-create": "문서를 만들 수 없기 때문에 \"$1\" 문서를 가져올 수 없었습니다.",
        "tooltip-ca-nstab-category": "분류 문서 보기",
        "tooltip-minoredit": "이 편집을 사소한 편집으로 표시하기",
        "tooltip-save": "바뀐 내용 저장하기",
+       "tooltip-publish": "변경사항 게시",
        "tooltip-preview": "바뀜을 미리 봅니다. 저장하기 전에 미리 보기를 해주세요!",
        "tooltip-diff": "자신이 바꾼 내용 보기",
        "tooltip-compareselectedversions": "이 문서에서 선택한 두 판 간의 차이를 비교",
        "pageinfo-watchers": "문서를 주시하는 사용자 수",
        "pageinfo-visiting-watchers": "이 문서를 최근에 방문한 주시하는 사용자 수",
        "pageinfo-few-watchers": "{{PLURAL:$1|주시하는 사용자}} $1명보다 적음",
+       "pageinfo-few-visiting-watchers": "최근의 편집을 주시하는 사용자가 있을 수도 없을 수도 있습니다",
        "pageinfo-redirects-name": "이 문서의 넘겨주기 수",
        "pageinfo-redirects-value": "$1",
        "pageinfo-subpages-name": "이 문서의 하위 문서 수",
        "confirmemail_body_set": "$1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 지정하였습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을\n활성화하려면 아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
        "confirmemail_invalidated": "이메일 확인이 취소됨",
        "invalidateemail": "이메일 확인 취소",
+       "notificationemail_subject_changed": "{{SITENAME}}의 등록된 이메일 주소가 변경되었습니다",
+       "notificationemail_subject_removed": "{{SITENAME}}의 등록된 이메일 주소가 제거되었습니다",
+       "notificationemail_body_changed": "IP 주소 $1에 속하는 누군가가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 \"$3\"으로 변경하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
+       "notificationemail_body_removed": "IP 주소 $1에 속하는 누군가가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 제거하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
        "scarytranscludedisabled": "[인터위키가 비활성되어 있습니다]",
        "scarytranscludefailed": "[$1 틀을 불러오는 데에 실패했습니다]",
        "scarytranscludefailed-httpstatus": "[$1 틀을 가져오는 데 실패했습니다: HTTP $2]",
        "tags-deactivate": "비활성화",
        "tags-hitcount": "$1개 {{PLURAL:$1|바뀜}}",
        "tags-manage-no-permission": "태그를 변경할 권한이 없습니다.",
+       "tags-manage-blocked": "차단된 상태에서는 변경 태그를 관리할 수 없습니다.",
        "tags-create-heading": "태그 생성",
        "tags-create-explanation": "기본적으로 새로 생성된 태그는 사용자와 봇이 사용할 수 있습니다.",
        "tags-create-tag-name": "태그 이름:",
        "tags-delete-submit": "이 태그를 영구히 삭제",
        "tags-delete-not-allowed": "확장 기능에서 정의된 태그는 확장 기능 설정에서 허용되지 않은 이상 삭제할 수 없습니다.",
        "tags-delete-not-found": "\"$1\" 태그가 존재하지 않습니다.",
+       "tags-delete-too-many-uses": "\"$1\" 태그가 $2개 이상의 판에 적용되어 있으므로 삭제할 수 없습니다.",
+       "tags-delete-warnings-after-delete": "\"$1\" 태그가 삭제되었으나 다음과 같은 $2개의 경고 태그가 발생하였습니다:",
        "tags-activate-title": "태그 활성화",
        "tags-activate-question": "\"$1\" 태그를 활성화하려고 합니다.",
        "tags-activate-reason": "이유:",
        "tags-deactivate-reason": "이유:",
        "tags-deactivate-not-allowed": "\"$1\" 태그를 비활성화할 수 없습니다.",
        "tags-deactivate-submit": "비활성화",
+       "tags-apply-no-permission": "사용자의 변경 사항과 변경 태그를 적용할 권한이 없습니다.",
+       "tags-apply-blocked": "차단된 상태에서는 사용자의 변경 사항과 변경 태그를 적용할 수 없습니다.",
        "tags-apply-not-allowed-one": "\"$1\" 태그를 수동으로 추가하는 것은 허용되지 않습니다.",
        "tags-apply-not-allowed-multi": "다음 {{PLURAL:$2|태그를}} 수동으로 추가하는 것은 허용되지 않습니다: $1",
        "tags-update-no-permission": "태그를 문서 판이나 로그 기록에서 추가하거나 삭제할 권한이 없습니다.",
+       "tags-update-blocked": "차단된 상태에서는 변경 태그를 추가하거나 제거할 수 없습니다.",
        "tags-update-add-not-allowed-one": "\"$1\" 태그를 수동으로 추가하는 것은 허용되지 않습니다.",
        "tags-update-add-not-allowed-multi": "다음 {{PLURAL:$2|태그는}} 수동으로 추가하는 것이 허용되지 않습니다: $1",
        "tags-update-remove-not-allowed-one": "\"$1\" 태그를 제거하는 것은 허용되지 않습니다.",
        "logentry-import-upload": "$1님이 $3 문서를 파일 올리기로 {{GENDER:$2|가져왔습니다}}",
        "logentry-import-upload-details": "$1님이 $3 문서 ({{PLURAL:$4|판}} $4개)를 파일 올리기로 {{GENDER:$2|가져왔습니다}}",
        "logentry-import-interwiki": "$1님이 $3 문서를 다른 위키에서 {{GENDER:$2|가져왔습니다}}",
-       "logentry-import-interwiki-details": "$1님이 $3 문서 ({{PLURAL:$4|판}} $4개)를 다른 위키에서 {{GENDER:$2|가져왔습니다}}",
+       "logentry-import-interwiki-details": "$1님이 $3 문서($4개의 판)를 $5에서 {{GENDER:$2|가져왔습니다}}",
        "logentry-merge-merge": "$1님이 $3 문서를 $4 안에 {{GENDER:$2|병합했습니다}} (판은 $5까지)",
        "logentry-move-move": "$1님이 $3 문서를 $4 문서로 {{GENDER:$2|이동했습니다}}",
        "logentry-move-move-noredirect": "$1님이 $3 문서를 넘겨주기를 만들지 않고 $4 문서로 {{GENDER:$2|이동했습니다}}",
        "logentry-protect-protect-cascade": "$1님이 $3 문서를 {{GENDER:$2|보호했습니다}} $4 [연쇄적]",
        "logentry-protect-modify": "$1님이 $3 문서의 보호 수준을 {{GENDER:$2|바꾸었습니다}} $4",
        "logentry-protect-modify-cascade": "$1님이 $3 문서의 보호 수준을 {{GENDER:$2|바꾸었습니다}} $4 [연쇄적]",
-       "logentry-rights-rights": "$1님이 $3 사용자의 권한을 $4에서 $5(으)로 {{GENDER:$2|바꾸었습니다}}",
+       "logentry-rights-rights": "$1님이 {{GENDER:$6|$3}}을(를) 위해 $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|올렸습니다}}",
        "feedback-useragent": "사용자 에이전트:",
        "searchsuggest-search": "검색",
        "searchsuggest-containing": "다음 문자열 포함...",
+       "api-error-autoblocked": "사용자의 IP 주소는 차단된 사용자에 의해 사용되었으므로 자동으로 차단된 상태입니다.",
        "api-error-badaccess-groups": "이 위키에 파일을 올릴 권한이 없습니다.",
        "api-error-badtoken": "내부 오류: 토큰이 잘못되었습니다.",
+       "api-error-blocked": "편집에서 차단되어 있습니다.",
        "api-error-copyuploaddisabled": "이 서버에서 URL을 통해 파일 올리기가 비활성화되어 있습니다.",
        "api-error-duplicate": "이 위키에 내용이 똑같은 {{PLURAL:$1|다른 파일}}이 있습니다.",
        "api-error-duplicate-archive": "같은 내용을 담고 있던 {{PLURAL:$1|다른 파일}}이 있었지만 이 {{PLURAL:$1|파일}}은 삭제되었습니다.",
        "api-error-nomodule": "내부 오류: 올리기 모듈이 설정되지 않았습니다.",
        "api-error-ok-but-empty": "내부 오류: 서버에서 응답이 없습니다.",
        "api-error-overwrite": "이미 있는 파일을 덮어쓸 수 없습니다.",
+       "api-error-ratelimited": "짧은 시간 안에 위키가 허용하는 것 보다 더 많은 파일을 업로드하려고 합니다.\n몇 분 뒤에 다시 시도해 주십시오.",
        "api-error-stashfailed": "내부 오류: 서버가 임시 파일을 저장하지 못했습니다.",
        "api-error-publishfailed": "내부 오류: 서버가 임시 파일을 게시하지 못했습니다.",
        "api-error-stasherror": "파일을 안전한 곳으로 업로드 하는 동안 오류가 발생했습니다.",
        "api-error-stashzerolength": "서버는 파일을 저장하지 못했는데, 파일의 용량이 0이기 때문입니다.",
        "api-error-stashnotloggedin": "파일을 업로드하기 위해 로그인이 필요합니다.",
        "api-error-stashwrongowner": "저장된 임시 저장소에 존재하는 파일에 접근할 권한이 없습니다.",
+       "api-error-stashnosuchfilekey": "미공개 위치에 접근을 시도한 파일 키는 존재하지 않습니다.",
        "api-error-timeout": "서버가 제 시간 내에 응답하지 않았습니다.",
        "api-error-unclassified": "알 수 없는 오류가 발생했습니다.",
        "api-error-unknown-code": "알 수 없는 오류: \"$1\"",
        "api-error-unknownerror": "알 수 없는 오류: \"$1\"",
        "api-error-uploaddisabled": "이 위키에서 파일 올리기가 비활성화되어 있습니다.",
        "api-error-verification-error": "파일이 손상되었거나 잘못된 확장자를 사용하고 있습니다.",
+       "api-error-was-deleted": "이 이름으로 된 파일은 과거에 업로드된 이후 삭제된 적이 있습니다.",
        "duration-seconds": "$1{{PLURAL:$1|초}}",
        "duration-minutes": "$1{{PLURAL:$1|분}}",
        "duration-hours": "$1{{PLURAL:$1|시간}}",
        "expand_templates_generate_xml": "XML 구문 트리 보기",
        "expand_templates_generate_rawhtml": "원본 HTML 보이기",
        "expand_templates_preview": "미리 보기",
+       "expand_templates_preview_fail_html": "<em>{{SITENAME}}에서 순수 HTML 입력을 허용한 상태에서 세션 데이터가 분실되었습니다. 그러므로 자바스크립트 공격을 예방하기 위해 미리 보기는 숨겨져 있습니다.</em>\n\n<strong>적합하게 미리 보기를 시도했다면 다시 시도해 주십시오.</strong>\n그래도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하여 사용자의 브라우저가 이 사이트에서 쿠키를 허용하는지 확인해 주십시오.",
+       "expand_templates_preview_fail_html_anon": "<em>{{SITENAME}}에서 순수 HTML 입력을 허용한 상태에서 사용자는 로그인되어 있지 않습니다. 그러므로 자바스크립트 공격을 예방하기 위해 미리 보기는 숨겨져 있습니다.</em>\n\n<strong>적합하게 미리 보기를 시도했다면 [[Special:UserLogin|로그인]]한 다음 다시 시도해 주십시오.",
        "expand_templates_input_missing": "전개할 내용을 입력해야 합니다.",
        "pagelanguage": "문서 언어 바꾸기",
        "pagelang-name": "문서",
        "special-characters-group-ipa": "IPA 문자",
        "special-characters-group-symbols": "기호",
        "special-characters-group-greek": "그리스 문자",
+       "special-characters-group-greekextended": "그리스어 확장",
        "special-characters-group-cyrillic": "키릴 문자",
        "special-characters-group-arabic": "아랍 문자",
        "special-characters-group-arabicextended": "아랍어 확장",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "쿠키 기반 세션",
        "sessionprovider-nocookies": "브라우저의 쿠키 기능이 꺼져 있는지 확인하십시오. 쿠키 기능을 켠 다음 다시 시작해야 합니다.",
        "randomrootpage": "임의 루트 페이지",
-       "log-action-filter-block": "차단의 유형:"
+       "log-action-filter-block": "차단의 유형:",
+       "log-action-filter-contentmodel": "콘텐츠 모델 수정 분류:",
+       "log-action-filter-delete": "삭제 종류:",
+       "log-action-filter-import": "가져오기 종류:",
+       "log-action-filter-managetags": "태그 관리 동작 종류:",
+       "log-action-filter-move": "이동 종류:",
+       "log-action-filter-newusers": "계정 생성 종류:",
+       "log-action-filter-patrol": "점검 종류:",
+       "log-action-filter-protect": "보호 종류:",
+       "log-action-filter-rights": "권한 변경 종류",
+       "log-action-filter-suppress": "숨기기 종류",
+       "log-action-filter-upload": "업로드 종류:",
+       "log-action-filter-all": "모두",
+       "log-action-filter-block-block": "차단",
+       "log-action-filter-block-reblock": "차단 변경",
+       "log-action-filter-block-unblock": "차단 해제",
+       "log-action-filter-contentmodel-change": "콘텐츠 모델 변경",
+       "log-action-filter-contentmodel-new": "비표준 콘텐츠 모델 문서 생성",
+       "log-action-filter-delete-delete": "문서 삭제",
+       "log-action-filter-delete-restore": "문서 복구",
+       "log-action-filter-delete-event": "로그 삭제",
+       "log-action-filter-delete-revision": "판 삭제",
+       "log-action-filter-import-interwiki": "트랜스위키 가져오기",
+       "log-action-filter-import-upload": "XML 업로드를 통한 가져오기",
+       "log-action-filter-managetags-create": "태그 생성",
+       "log-action-filter-managetags-delete": "태그 삭제",
+       "log-action-filter-managetags-activate": "태그 활성화",
+       "log-action-filter-managetags-deactivate": "태그 비활성화",
+       "log-action-filter-move-move": "넘겨주기를 덮어쓰지 않고 이동",
+       "log-action-filter-move-move_redir": "넘겨주기를 덮어쓰며 이동",
+       "log-action-filter-newusers-create": "익명의 사용자에 의한 생성",
+       "log-action-filter-newusers-create2": "등록된 사용자에 의한 생성",
+       "log-action-filter-newusers-autocreate": "자동 생성",
+       "log-action-filter-newusers-byemail": "이메일로 보낸 비밀번호로 생성",
+       "log-action-filter-patrol-patrol": "수동 점검",
+       "log-action-filter-patrol-autopatrol": "자동 점검",
+       "log-action-filter-protect-protect": "보호",
+       "log-action-filter-protect-modify": "보호 변경",
+       "log-action-filter-protect-unprotect": "보호 해제",
+       "log-action-filter-protect-move_prot": "이동 보호",
+       "log-action-filter-rights-rights": "수동 변경",
+       "log-action-filter-rights-autopromote": "자동 변경",
+       "log-action-filter-suppress-event": "로그 숨기기",
+       "log-action-filter-suppress-revision": "판 숨기기",
+       "log-action-filter-suppress-delete": "문서 숨기기",
+       "log-action-filter-suppress-block": "차단을 통한 사용자 숨기기",
+       "log-action-filter-suppress-reblock": "재차단을 통한 사용자 숨기기",
+       "log-action-filter-upload-upload": "새로 업로드",
+       "log-action-filter-upload-overwrite": "다시 업로드"
 }
index b1b6464..ca96110 100644 (file)
@@ -52,7 +52,7 @@
        "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",
-       "tog-norollbackdiff": "Donn noh „{{int:Rollback}}“ de Ungerscheide nit aanzeije",
+       "tog-norollbackdiff": "Donn noh „{{int:Rollback}}“ de Ongerscheide nit aanzeije",
        "tog-useeditwarning": "Donn mesch warne, wann esch vun en Sigg fott jonn, ih dat esch all ming Änderunge avjeschpeischert hann.",
        "tog-prefershttps": "Jangk emmer övver en verschlößelte Verbendong bei Enlogge",
        "underline-always": "jo, ongershtriishe",
        "minoredit": "Dat es en klein Änderong (mini)",
        "watchthis": "Op di Sigg heh oppaßße",
        "savearticle": "De Sigg Avspeichere",
+       "publishpage": "Veröffentlesche",
        "preview": "Vör-Ansich",
-       "showpreview": "Vör-Aansich zeije",
-       "showdiff": "De Ungerscheide zeije",
+       "showpreview": "Vöraff belohre",
+       "showdiff": "Veränderonge zeije",
        "blankarticle": "<strong>Opjepaß:</strong> Di Sigg, di De jrahd aanlähje wells, es läddesch. Wann De jäz norr_ens op „{{int:savearticle}}“ jehß, weed di Sigg och ohne jät dren aanjelaat.",
        "anoneditwarning": "'''Opjepaß:''' Weil De nit enjelogg bes, weed Ding <i lang=\"en\" xml:lang=\"en\">IP</i>-Adräß en heh dä Sigg ier Leß met de Väsiohne faßjehallde wääde.\nWann De [$1 enlogge deihs] udder [$2 desch aanmällds], dann wääde Ding Änderonge met dingem Nahme als Metmaacher opjevöhrt.",
        "anonpreviewwarning": "''Weil De nit enjlogg bes, weed Ding <code lang=\"en\">IP</code>-Addräß zoamme met dä neue Version faßjehallde, wann de heh di Sigg avspeichere deihß.''",
        "userpage-userdoesnotexist": "Enne Metmaacher „<nowiki>$1</nowiki>“ ham_mer nit, beß De sescher, dat De di Metmaachersigg verhaftesch änndere udder aanlähje wellß?.",
        "userpage-userdoesnotexist-view": "Ene Metmaacher mem Nahme „$1“ hät sesch noch nih aanjemeldt",
        "blocked-notice-logextract": "Dä Metmaacher es jraad jesperrt.\nHeh kütt der neuste Enndraach drövver uss_em Logbooch övver et Metmaacher_Sperre:",
-       "clearyourcache": "'''Opjepass:'''\nNoh em Speichere künnd et sin, datt De Dingem Brauser singe Cache Speicher\növverlisste muss, ih datt De de Änderunge och ze sinn kreß.\n* Beim '''<i lang=\"en\">Mozilla</i>''' un '''<i lang=\"en\">Firefox</i>''' un '''<i lang=\"en\">Safari</i>''', dröck dä Jrußschreffknopp eronger un kleck dann op <i lang=\"en\">Reload</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck <i lang=\"de\">Ctrl+F5</i> / <i lang=\"de\">Strg+F5</i>, udder dröck <i lang=\"en\">Ctrl+R</i> / <i lang=\"de\">Strg+R</i>, obb enem <i lang=\"en\">Macintosh</i> dröck <i lang=\"de\">⌘+R</i>.\n* Beim '''<i lang=\"en\">Google Chrome</i>''', dröck <i lang=\"en\">Ctrl+Jrußschreffknopp+R</i> / <i lang=\"de\">Strg+Jrußschreffknopp+R</i>, obb enem <i lang=\"en\">Macintosh</i> dröck <i lang=\"de\">⌘+Jrußschreffknopp+R</i>.\n* Beim '''<i lang=\"en\">Internet Explorer</i>''', dröck dä Jrußschreffknopp eronger un kleck dann op <i lang=\"en\">Refresh</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck <i lang=\"de\">Ctrl+F5</i> / <i lang=\"de\">Strg+F5</i>,\n* Beim '''<i lang=\"en\">Konqueror</i>''' kleck op <i lang=\"en\">Reload</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck op <i>F5</i>.\n* Beim  '''<i lang=\"en\">Opera</i>''' kanns De övver et Menue jonn un däm janze Zwescheschpeischer singe Enhald övver <i lang=\"en\">Tools → Preferences</i> / <i lang=\"de\">Werkzeug → Einstellungen</i> fottschmieße, neuerdings jeiht et och met <i>Alt+F5</i>.",
+       "clearyourcache": "<strong>Opjepass:</strong>\nNoh em Speichere künnd et sin, datt De Dingem Brauser singe Cache Speicher\növverlisste muss, ih datt De de Änderunge och ze sinn kreß.\n* Beim <strong><i lang=\"en\">Mozilla</i></strong> un <strong><i lang=\"en\">Firefox</i></strong> un <strong><i lang=\"en\">Safari</i></strong>, dröck dä Jrußschreffknopp eronger un kleck dann op <i lang=\"en\">Reload</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck <i lang=\"de\">Ctrl+F5</i> / <i lang=\"de\">Strg+F5</i>, udder dröck <i lang=\"en\">Ctrl+R</i> / <i lang=\"de\">Strg+R</i>, obb enem <i lang=\"en\">Macintosh</i> dröck <i lang=\"de\">⌘+R</i>.\n* Beim <strong><i lang=\"en\">Google Chrome</i></strong>, dröck <i lang=\"en\">Ctrl+Jrußschreffknopp+R</i> / <i lang=\"de\">Strg+Jrußschreffknopp+R</i>, obb enem <i lang=\"en\">Macintosh</i> dröck <i lang=\"de\">⌘+Jrußschreffknopp+R</i>.\n* Beim <strong><i lang=\"en\">Internet Explorer</i></strong>, dröck dä Jrußschreffknopp eronger un kleck dann op <i lang=\"en\">Refresh</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck <i lang=\"de\">Ctrl+F5</i> / <i lang=\"de\">Strg+F5</i>,\n* Beim <strong><i lang=\"en\">Konqueror</i></strong> klegg op <i lang=\"en\">Reload</i> / <i lang=\"de\">Aktualisieren</i>, udder dröck op <i>F5</i>.\n* Beim  <strong><i lang=\"en\">Opera</i></strong> kanns De övver et Menue jonn un däm janze Zwescheschpeischer singe Enhald övver <i lang=\"en\">Tools → Preferences</i> / <i lang=\"de\">Werkzeug → Einstellungen</i> fottschmieße, neuerdings jeiht et och met <i>Alt+F5</i>.",
        "usercssyoucanpreview": "<b>Tipp:</b> Dun met däm <b style=\"padding:2px; background-color:#ddd;\ncolor:black\">Vör-Aansich Zeije</b>-Knopp usprobeere, wat Ding neu\nMetmaacher_CSS/Java_Skripp mäht, ih dat et avspeichere deis!",
        "userjsyoucanpreview": "<b>Tipp:</b> Dun met däm <b style=\"padding:2px; background-color:#ddd;\ncolor:black\">Vör-Aansich Zeije</b>-Knopp usprobeere, wat Ding neu\nMetmaacher_Java_Skripp mäht, ih dat et avspeichere deis!",
        "usercsspreview": "<b>Opjepass: Do bes heh nor am Usprobeere, wat Ding\nMetmaacher_CSS mäht, et es noch nit jesechert!</b>",
        "upload-form-label-infoform-description": "Äkliehrong",
        "upload-form-label-usage-title": "Der Jebruch",
        "upload-form-label-usage-filename": "Dä Dattei iehre Nahme",
-       "foreign-structured-upload-form-label-own-work": "dat es ming eije Wärk",
-       "foreign-structured-upload-form-label-infoform-categories": "Saachjroppe",
-       "foreign-structured-upload-form-label-infoform-date": "Dattum",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Wann De di Dattei nit en de jemeinsamme Sammlong vun Datteule huh lahde kanns un derbei de Rähjelle {{ucfirst:{{GRAMMAR:vun|{{ucfirst:{{SITENAME}}}}}}}} ennhalde, dann maach heh nit wigger, un probehr ene anndere Wähsch.",
-       "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]]",
+       "upload-form-label-own-work": "Dat es ming eije Wärk",
+       "upload-form-label-infoform-categories": "Saachjroppe",
+       "upload-form-label-infoform-date": "Dattum",
+       "upload-form-label-not-own-work-message-local": "Wann De di Dattei nit en de jemeinsamme Sammlong vun Datteule huh lahde kanns un derbei och de Rähjelle {{GRAMMAR:vun|{{ucfirst:{{SITENAME}}}}}} ennhalde, dann maach heh nit wigger, un probehr ene anndere Wähsch.",
+       "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.",
+       "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.",
+       "upload-form-label-not-own-work-message-default": "Wann De di Dattei nit en de jemeinsamme Sammlong vun Datteije huh lahde kanns un derbei de Rähjelle ennhalde, dann maach heh nit wigger, un probehr ene anndere Wähsch.",
+       "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.",
        "whatlinkshere-prev": "de vörijje {{PLURAL:$1||$1|noll}} zeije",
        "whatlinkshere-next": "de nächste {{PLURAL:$1||$1|noll}} zeije",
        "whatlinkshere-links": "← Links",
-       "whatlinkshere-hideredirs": "de Ömleijdonge $1",
+       "whatlinkshere-hideredirs": "De Ömleijdonge verschteijsche",
        "whatlinkshere-hidetrans": "de Oproofe $1",
-       "whatlinkshere-hidelinks": "de nommahle Lengks $1",
+       "whatlinkshere-hidelinks": "De nommahle Lengks verschteijsche",
        "whatlinkshere-hideimages": "$1 de Lengks op Datteihje",
        "whatlinkshere-filters": "Ußsööke",
        "whatlinkshere-submit": "Lohß jonn!",
        "tooltip-ca-nstab-category": "Dun de Saachjropp aanzeije",
        "tooltip-minoredit": "Deit Ding Änderonge als klein Mini-Änderonge markkehre.",
        "tooltip-save": "Deit Ding Änderonge avspeichere.",
+       "tooltip-publish": "Donn Ding Änderonge öffentlesch maache",
        "tooltip-preview": "Liss de Vör-Aanseesch vun dä Sigg un vun Dinge Änderonge, ih datte se avspeijschere deihs!",
        "tooltip-diff": "Zeijsch Ding Änderonge aam Täx aan.",
        "tooltip-compareselectedversions": "Dun de Ungerscheid zwesche dä beids usjewählde Versione zeije.",
        "logentry-protect-protect-cascade": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät di Sigg „$3“ jeschöz: $4 met wiggerjävve",
        "logentry-protect-modify": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät dä Schoz vun dä Sigg „$3“ verändert: $4",
        "logentry-protect-modify-cascade": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät dä Schoz vun dä Sigg „$3“ verändert: $4 met wiggerjävve",
-       "logentry-rights-rights": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} „$1“ hät däm Metmaacher „$3“ sing Jroppe-Räächde vun „$4“ op „$5“ ömjestallt.",
+       "logentry-rights-rights": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} „$1“ hät {{GENDER:$2|däm|däm|däm Metmaacher|dä|däm}} „$3“ {{GENDER:$2|sing|sing|sing|ier|sing}} Jroppe-Räächde vun „$4“ op „$5“ ömjestallt.",
        "logentry-rights-rights-legacy": "{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 hät däm Metmaacher $3 sing Räääschte-Jroppe verändert.",
        "logentry-rights-autopromote": "{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 wood automattesch vum $4 zom $5 jemaat.",
        "logentry-upload-upload": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät di Dattei „$3“ huhjelahe.",
        "searchsuggest-containing": "dren änthallde…",
        "api-error-badaccess-groups": "Do häs nit et Rääsch, Datteije en heh dat Wiki huhzelaade.",
        "api-error-badtoken": "Fähler: et Kännzeijsche (<i lang=\"en\">token</i>) es kappott.",
+       "api-error-blocked": "Do bes föh et Änndere jeschpächt.",
        "api-error-copyuploaddisabled": "Et Huhlaade vun enem <i lang=\"en\">URL</i> es op däm ẞööver heh nit zohjelohße.",
        "api-error-duplicate": "Mer han em Wiki ald {{PLURAL:$1|[en Dattei]|[$1 andere Datteije]|[kein Dattei]}} mem akeraat sellve Enhalldt.",
        "api-error-duplicate-archive": "Mer hatte {{PLURAL:$1|[en ander Dattei]|[ander Datteije]|[kein ander Dattei]}} heh em Wiki mem sellve Enhalt, ävver se {{PLURAL:$1|es|sen|es}} ald fottjeschmeße woode.",
index 60e5995..8277a44 100644 (file)
@@ -24,6 +24,7 @@
        "tog-hideminor": "Guherandinên biçûk ji listêya guherandinên dawî veşêre",
        "tog-hidepatrolled": "Guherandinên hatine kontrolkirin ji nav guherandinên dawî veşêre",
        "tog-newpageshidepatrolled": "Rûpelên hatine kontrolkirin ji lîsteya rûpelên nû veşêre",
+       "tog-hidecategorization": "Kategorîzekirina rûpelan veşêre",
        "tog-extendwatchlist": "Lîsteya şopandinê berfireh bike ji bo dîtina hemû guherandinan, ne tenê yên nû",
        "tog-usenewrc": "Weşandina zêdetir (JavaScript pêwîst e)",
        "tog-numberheadings": "Sernavan otomatîk bihejmêre",
@@ -51,6 +52,7 @@
        "tog-watchlisthideminor": "Guhertinên biçûk ji lîsteya şopandinê veşêre",
        "tog-watchlisthideliu": "Guherandinên bikarhênerên qeydkirî ji lîsteya şopandinê veşêre",
        "tog-watchlisthideanons": "Guherandinên bikarhênerên neqeydkirî ji lîsteya şopandinê veşêre",
+       "tog-watchlisthidecategorization": "Kategorîzekirina rûpelan veşêre",
        "tog-ccmeonemails": "Kopiyên e-nameyên min ji bikarhênerên din re şandî, ji min re jî bişîne.",
        "tog-diffonly": "Li cem guhertinan, naveroka rûpelê nîşan nede",
        "tog-showhiddencats": "Kategoriyên veşartî bibîne",
        "retypenew": "Şîfreya nû careke din binîvîse",
        "resetpass_submit": "Şîfreyê pêkbîne û têkeve",
        "changepassword-success": "Guhertine şîfreya te serkeftî bû!",
+       "botpasswords-label-appid": "Navê bot:",
+       "botpasswords-label-create": "Çêke",
        "botpasswords-label-update": "Rojane bike",
        "botpasswords-label-cancel": "Betal bike",
+       "botpasswords-label-delete": "Jê bibe",
+       "botpasswords-bad-appid": "Navê bot \"$1\" ne derbasdar e.",
        "resetpass_forbidden": "Şîfre nikarin werin guhertin",
        "resetpass-submit-loggedin": "Şîfreyê biguherîne",
        "resetpass-submit-cancel": "Betal bike",
        "editingold": "'''Hişyarî: Tu li ser guhertoyeke kevn a vê rûpelê dixebitî.\nHeke tu qeyd bikî, hemû guhertinên piştî vê revîzyonê winda dibin.\n'''",
        "yourdiff": "Cudahî",
        "copyrightwarning": "Hemû tevkariyên {{SITENAME}} di bin $2 de tên belav kirin (ji bo hûragahiyan li $1 binêre).\nEger tu nexwazî ku nivîsên te bê dilrehmî bên guherandin û li gora keyfa herkesî bên belavkirin, li vir neweşîne.<br />\nTu soz didî ku te ev bi xwe nivîsand an jî ji çavkaniyekê azad an geliyane (''public domain'') girt.\n'''Berhemên mafên wan parastî bê destûr neweşîne!'''",
-       "protectedpagewarning": "'''Hişyarî:  Ev rûpel tê parastin. Bi tenê bikarhênerên ku xwediyên mafên \"koordînatoriyê\" ne, dikarin vê rûpelê biguherînin.'''",
+       "protectedpagewarning": "<strong>Hişyarî: Ev rûpel tê parastin. Tenê bikarhênerên ku xwediyê mafên rêveberiyê ne, dikarin vê rûpelê biguherînin.</strong>",
        "semiprotectedpagewarning": "'''Hişyarî:''' Ev rûpel tê parastin, lewma tenê bikarhênerên tomarkirî dikarin vê biguherînin.\nGuhertina herî dawî bi referansa li jêr hatiye piştrastkirin:",
        "templatesused": "{{PLURAL:$1|Şablona|Şablonên}} ku li ser vê rûpelê {{PLURAL:$1|tê|tên}} bikaranîn:",
        "templatesusedpreview": "{{PLURAL:$1|Şablona|Şablonên}} di vê pêşdîtinê de {{PLURAL:$1|tê|tên}} bikaranîn:",
        "postedit-confirmation-restored": "Ev rûpel hate restorekirin.",
        "postedit-confirmation-saved": "Guhertina te hate tomarkirin.",
        "edit-already-exists": "Nikarî rûpeleka nuh çêke.\nEw berê heye.",
+       "invalid-content-data": "Daneyên naverokê yên nederbasdar",
        "content-model-wikitext": "wîkînivîs",
        "content-model-text": "nivîsê sade",
        "content-model-javascript": "JavaScript",
        "right-userrights": "Hemû mafên bikarhêner biguherîne",
        "right-userrights-interwiki": "Mafên bikarhênerên li ser wîkiyên din biguherîne",
        "right-sendemail": "Ji bikarhênerên di re ename bişîne",
+       "grant-editpage": "Rûpelên ku hene biguherîne",
+       "grant-editprotected": "Rûpelên parastî bigûherîne",
        "newuserlogpage": "Çêkirina hesabê nû",
        "newuserlogpagetext": "Ev têketina hesabên bikarhêneriyê ye ên ku nû hatine afirandin.",
        "rightslog": "Guhertina mafê bikarhêneriyê",
        "rcshowhidemine": "Guherandinên min $1",
        "rcshowhidemine-show": "nîşan bide",
        "rcshowhidemine-hide": "veşêre",
-       "rcshowhidecategorization-show": "Nîşan bide",
-       "rcshowhidecategorization-hide": "Veşêre",
+       "rcshowhidecategorization": "Kategorîzekirina rûpelan $1",
+       "rcshowhidecategorization-show": "nîşan bide",
+       "rcshowhidecategorization-hide": "veşêre",
        "rclinks": "$1 guherandinên di $2 rojên dawî de nîşan bide<br />$3",
        "diff": "cudahî",
        "hist": "dîrok",
        "filewasdeleted": "Data'yek bi vê navê hatibû barkirin û jêbirin. Xêra xwe li $1 seke ku barkirina te hêja ye ya na.",
        "filename-bad-prefix": "Nava wê data'yê, yê tu niha bardikê, bi '''\"$1\"''' destpêdike. Kamêrayên dîjîtal wan navan didin wêneyên xwe. Ji kerema xwe navekî baştir binivisîne ji bo mirov zûtir zanibin ku şayeşê vê wêneyê çî ye.",
        "upload-file-error": "Çewtiya navxweyî",
+       "upload-misc-error": "Çewtiya barkirinê ya nenas",
+       "upload-dialog-title": "Dosyeyê bar bike",
        "upload-dialog-button-cancel": "Betal bike",
        "upload-dialog-button-done": "Çêbû",
        "upload-dialog-button-save": "Tomar bike",
        "upload-form-label-infoform-description": "Danasîn",
        "upload-form-label-usage-title": "Bikaranîn",
        "upload-form-label-usage-filename": "Navê dosyeyê",
-       "foreign-structured-upload-form-label-own-work": "Min ev xebat bi xwe çêkiriye",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorî",
-       "foreign-structured-upload-form-label-infoform-date": "Dîrok",
+       "upload-form-label-own-work": "Min ev xebat bi xwe çêkiriye",
+       "upload-form-label-infoform-categories": "Kategorî",
+       "upload-form-label-infoform-date": "Dîrok",
        "backend-fail-notexists": "Dosye $1 tune ye.",
        "backend-fail-delete": "Dosyeya \"$1\" nikaribû bê jêbirin.",
        "backend-fail-store": "Dosyeya \"$1\" di bin \"$2\" nikaribû bê tomarkirin.",
        "mostcategories": "Rûpelên bi pir kategorî",
        "mostinterwikis": "Rûpelên bi bêhtirîn girêdanên înterwîkiyê",
        "prefixindex": "Hemû rûpelên bi pêşbendik",
+       "prefixindex-submit": "Nîşan bide",
        "shortpages": "Rûpelên kurt",
        "longpages": "Rûpelên dirêj",
        "deadendpages": "Rûpelên bê dergeh",
        "listusers-editsonly": "Tenê bikarhênerên bi guherrandinan nîşan bide",
        "usercreated": "di $1 de, li $2 hate çêkirin",
        "newpages": "Rûpelên nû",
+       "newpages-submit": "Nîşan bide",
        "newpages-username": "Navê bikarhêner:",
        "ancientpages": "Gotarên herî kevin",
        "move": "Hilgire",
        "specialloguserlabel": "Bikarhêner:",
        "speciallogtitlelabel": "Armanc (sernav an bikarhêner)",
        "log": "Têketin",
+       "logeventslist-submit": "Nîşan bide",
        "all-logs-page": "Hemû têketin",
        "alllogstext": "Hemû têketinên {{SITENAME}} li jêr tên nîşandan.\nTu dikarî ji xwe re têketinekê hilbijêrî, navê bikarhêneriyê an navê rûpelekê binivîse û agahiyan li ser wê bibîne.",
        "logempty": "Tiştek di vir de nîne.",
        "log-title-wildcard": "Li sernavên bi vê dest pê dikin bigere",
+       "checkbox-select": "Hilbijêre:$1",
+       "checkbox-all": "Hemû",
        "allpages": "Hemû rûpel",
        "nextpage": "Rûpela pêşî ($1)",
        "prevpage": "Rûpelê berî vê ($1)",
        "allpages-bad-ns": "Namespace'a \"$1\" di {{SITENAME}} da tune ye.",
        "allpages-hide-redirects": "Beralîkirinan veşêre",
        "categories": "Kategorî",
+       "categories-submit": "Nîşan bide",
        "categoriespagetext": "Di van kategoriyan de rûpel an jî medya hene.\n[[Special:UnusedCategories|Kategoriyên nayên bikaranîn]] li vir nayên nîşandan.\nLi [[Special:WantedCategories|kategoriyên xwestî]] binêre.",
        "deletedcontributions": "Beşdariyên bikarhênerekî yê jêbirî",
        "deletedcontributions-title": "Guherandinên bikarhêner yê jêbirî",
        "listgrouprights-members": "(lîsteya endaman)",
        "listgrouprights-addgroup-all": "Hemû koman tevlî bike",
        "listgrouprights-removegroup-all": "Hemû koman jê bibe",
+       "listgrants-rights": "Maf",
        "trackingcategories-name": "Navê peyamê",
        "trackingcategories-nodesc": "Ti danasîn tune ye.",
        "mailnologin": "Navnîşanê neşîne",
        "wlshowlast": "Guhertinên berî $1 saetan, $2 rojan, ya  nîşan bide",
        "watchlist-hide": "Veşêre",
        "watchlist-submit": "Nîşan bide",
+       "wlshowhidebots": "bot",
        "wlshowhideliu": "bikarhênerên tomarkirî",
+       "wlshowhideanons": "bikarhênerên bênav",
        "wlshowhidecategorization": "kategorîzekirina rûpelan",
        "watchlist-options": "Vebijarkên lîsteya şopandinê",
        "watching": "Tê şopandin...",
        "spamprotectiontitle": "Parastina spam",
        "spamprotectiontext": "Rûpela ku tu dixwazî tomar bikî ji ber parastina spamê hate astengkirin.\nJi ber ku girêdaneke derve di wê rûpelê de heye ev pirsgirêk pêk hat.",
        "spamprotectionmatch": "Ev nivîsa parastinê spam vêxist: $1",
+       "pageinfo-title": "Agahiyên bo \"$1\"",
        "pageinfo-header-basic": "Agahiyên sereke",
        "pageinfo-header-edits": "Dîrokê biguherîne",
        "pageinfo-header-restrictions": "Parastina rûpelê",
        "pageinfo-firsttime": "Dema çêkirina rûpelê",
        "pageinfo-lasttime": "Dema guherandina dawî",
        "pageinfo-edits": "Hejmara guherandinan",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|Kategoriya|Kategoriyên}} veşartî ($1)",
        "pageinfo-toolboxlink": "Agahiyên rûpelê",
        "pageinfo-redirectsto-info": "agahî",
        "pageinfo-contentpage-yes": "Erê",
        "exif-usercomment": "Şîroveyên bikarhêner",
        "exif-datetimedigitized": "Dema pencekîkirinê",
        "exif-exposuretime-format": "$1 sanî ($2)",
-       "exif-brightnessvalue": "Zelalî",
+       "exif-brightnessvalue": "Zelaliya APEX",
        "exif-flash": "Flaş",
        "exif-filesource": "Çavkaniya pelê",
        "exif-contrast": "Kontrast",
        "exif-disclaimer": "Ferexetname",
        "exif-unknowndate": "Dîroka nayê zanîn",
        "exif-orientation-1": "Normal",
+       "exif-componentsconfiguration-0": "tune ye",
        "exif-exposureprogram-1": "Manûel",
        "exif-exposureprogram-2": "Programa normal",
        "exif-subjectdistance-value": "$1 metre",
        "confirm-purge-top": "Bîra vê rûpelê jêbîbe ?",
        "confirm-watch-button": "Temam",
        "confirm-unwatch-button": "Baş e",
+       "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← rûpela berî vê",
        "imgmultipagenext": "rûpela din →",
        "imgmultigo": "Here!",
        "imgmultigoto": "Here rûpela $1",
+       "img-lang-default": "(zimanê standart)",
        "table_pager_next": "Rûpela pêş",
        "table_pager_prev": "Rûpela berî",
        "table_pager_first": "Rûpela pêşîn",
        "watchlistedit-clear-titles": "Sernav:",
        "watchlisttools-edit": "Lîsteya şopandinê bibîne û biguherîne",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|gotûbêj]])",
+       "timezone-local": "Herêmî",
        "version": "Versiyon",
        "version-specialpages": "Rûpelên taybet",
        "version-other": "Yên din",
        "version-software-product": "Berhem",
        "version-software-version": "Guherto",
        "version-entrypoints-header-url": "URL",
+       "version-libraries-version": "Guherto",
+       "version-libraries-license": "Destûr",
        "version-libraries-description": "Danasîn",
+       "version-libraries-authors": "Xwedî",
        "fileduplicatesearch-filename": "Navê dosyeyê:",
        "fileduplicatesearch-submit": "Lê bigere",
        "specialpages": "Rûpelên taybet",
        "tags-active-yes": "Erê",
        "tags-active-no": "Na",
        "tags-edit": "biguherîne",
+       "tags-delete": "jê bibe",
        "tags-create-reason": "Sedem:",
        "tags-delete-reason": "Sedem:",
        "tags-activate-reason": "Sedem:",
        "tags-deactivate-reason": "Sedem:",
+       "tags-edit-reason": "Sedem:",
        "comparepages": "Rûpelan bide ber hev",
        "compare-page1": "Rûpel 1",
        "compare-page2": "Rûpel 2",
        "htmlform-selectorother-other": "Yên din",
        "htmlform-no": "Na",
        "htmlform-yes": "Erê",
+       "htmlform-chosen-placeholder": "Vebijarkekê hilbijêre",
+       "htmlform-title-not-exists": "$1 tune ye.",
+       "htmlform-user-not-exists": "<strong>$1</strong> tune ye.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ne navekî derbasdar e.",
        "logentry-delete-delete": "$1 rûpela $3 {{GENDER:$2|jê bir}}",
        "revdelete-content-hid": "naverok veşartî ye",
        "revdelete-uname-hid": "navê bikarhêneriyê yê veşartî",
        "feedback-error-title": "Çewtî",
        "feedback-message": "Peyam:",
        "feedback-subject": "Mijar:",
+       "feedback-submit": "Tomar bike",
        "feedback-thanks-title": "Spas!",
        "searchsuggest-search": "Lêgerîn",
        "searchsuggest-containing": "dihundirîne...",
        "api-error-filename-tooshort": "Navê dosyeyê pir kurt e.",
+       "api-error-unknown-code": "Çewtiya nenas: \"$1\".",
+       "api-error-unknownerror": "Çewtiya nenas: \"$1\".",
+       "duration-years": "$1 {{PLURAL:$1|sal}}",
        "expand_templates_output": "Encam",
        "expand_templates_ok": "Baş e",
        "expand_templates_preview": "Pêşdîtin",
        "pagelanguage": "Zimanê rûpelê biguherîne",
+       "pagelang-name": "Rûpel",
        "pagelang-language": "Ziman",
+       "pagelang-use-default": "Zimanê standart bi kar bîne",
        "pagelang-select-lang": "Zimanekî hilbijêre",
        "pagelang-submit": "Tomar bike",
        "right-pagelang": "Zimanê rûpelê biguherîne",
        "action-pagelang": "zimanê rûpelê biguherîne",
        "log-name-pagelang": "Têketina guherandina ziman",
+       "logentry-pagelang-pagelang": "$1 zimanê $3 ji $4 {{GENDER:$2|guherand}} $5",
        "mediastatistics-header-total": "Hemû dosye",
        "special-characters-group-latin": "Latînî",
        "special-characters-group-latinextended": "Latînî berfirehkirî",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-titleinput-description-new-page": "rûpel hê tune ye",
-       "mw-widgets-titleinput-description-redirect": "beralî bike ber bi $1 ve"
+       "mw-widgets-titleinput-description-redirect": "beralî bike ber bi $1 ve",
+       "log-action-filter-all": "Hemû",
+       "log-action-filter-block-block": "Asteng bike"
 }
index 9e1c92a..374650e 100644 (file)
        "minoredit": "Dëst ass eng kleng Ännerung",
        "watchthis": "Dës Säit iwwerwaachen",
        "savearticle": "Säit späicheren",
+       "publishpage": "Säit publizéieren",
        "preview": "Kucken ouni ofzespäicheren",
        "showpreview": "Kucken ouni ofzespäicheren",
        "showdiff": "Ännerunge weisen",
        "continue-editing": "Gitt weider an de Beräich fir z'änneren",
        "previewconflict": "Dir gesitt an dem ieweschten Textfeld wéi den Text ausgesi wäert, wann Dir späichert.",
        "session_fail_preview": "<strong>Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.</strong>\nVersicht et w.e.g. nach eng Kéier.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.",
-       "session_fail_preview_html": "<strong>Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.</strong>\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.</strong>",
+       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech datt Äre Browser d^Späichere vu Cookieë vun dësem Site zouléisst.",
        "token_suffix_mismatch": "'''Är Ännerung gouf refuséiert, well Äre Browser Zeechen am Ännerungs-Identifiant verännert huet.'''\nD'Ännerung gouf refuséiert, fir ze verhënneren datt den Text op der Säit onliesbar gëtt.\nDëst geschitt heiansdo wann Dir en anonyme Proxy-Service um Internet benotzt.",
        "edit_form_incomplete": "'''En Deel vum Ännerungsformulaire koum net um Server un; iwwerpréift w.e.g ob Är Ännerunge komplett sinn a probéiert nach emol.'''",
        "editing": "Ännere vu(n) $1",
        "upload-form-label-infoform-description": "Beschreiwung",
        "upload-form-label-usage-title": "Benotzung",
        "upload-form-label-usage-filename": "Numm vum Fichier",
-       "foreign-structured-upload-form-label-own-work": "Dëst ass mäin eegent Wierk",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorien",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work": "Dëst ass mäin eegent Wierk",
+       "upload-form-label-infoform-categories": "Kategorien",
+       "upload-form-label-infoform-date": "Datum",
        "backend-fail-stream": "De Fichier $1 konnt net iwwerdroe ginn.",
        "backend-fail-backup": "De Fichier $1 konnt net geséchert ginn.",
        "backend-fail-notexists": "De Fichier $1 gëtt et net.",
        "ipbexpiry": "Gültegkeet:",
        "ipbreason": "Grond:",
        "ipbreason-dropdown": "*Heefeg Ursaache fir Benotzer ze spären:\n**Bewosst falsch Informatiounen an eng oder méi Säite gesat\n**Ouni Grond Inhalt vu Säite geläscht\n**Spam-Verknëppunge mat externe Säiten\n**Topereien an d'Säite gesat\n**Beleidegt oder bedréit aner Mataarbechter\n**Mëssbrauch vu verschiddene Benotzernimm\n**Net akzeptabele Benotzernumm",
-       "ipb-hardblock": "Verhënneren datt ageloggte Benotzer vun dëser IP-Adress aus Ännerunge maache kënnen",
+       "ipb-hardblock": "Verhënneren datt ageloggt Benotzer vun dëser IP-Adress aus Ännerunge maache kënnen",
        "ipbcreateaccount": "Opmaache vun engem Benotzerkont verhënneren",
        "ipbemailban": "Verhënneren datt de Benotzer E-Maile verschéckt",
        "ipbenableautoblock": "Automatesch déi lescht IP-Adress spären déi vun dësem Benotzer benotzt gouf, an all IP-Adresse vun denen dëse Benotzer versicht Ännerunge virzehuelen",
        "tooltip-ca-nstab-category": "Kategoriesäit weisen",
        "tooltip-minoredit": "Dës Ännerung als kleng markéieren.",
        "tooltip-save": "Ännerunge späicheren",
+       "tooltip-publish": "Är Ännerunge publizéieren",
        "tooltip-preview": "Kuckt är Ännerungen ouni ofzespäicheren, Benotzt dëst w.e.g. virum späicheren!",
        "tooltip-diff": "Weist wéi eng Ännerungen Dir beim Text gemaach hutt.",
        "tooltip-compareselectedversions": "D'Ënnerscheeder op dëser Säit tëscht den zwou gewielte Versioune weisen.",
        "feedback-useragent": "User Agent:",
        "searchsuggest-search": "Sichen",
        "searchsuggest-containing": "mat ...",
+       "api-error-autoblocked": "Är IP-Adress gouf automatesch gespaart wëll se vun engem gespaarte Benotzer  benotzt gouf",
        "api-error-badaccess-groups": "Et ass Iech net erlaabt fir Fichieren op dës Wiki eropzelueden.",
        "api-error-badtoken": "Interne Feeler: falschen Token.",
+       "api-error-blocked": "Dir gouft gespaart a  kënnt dofir keng Ännerunge maachen.",
        "api-error-copyuploaddisabled": "D'Eroplueden iwwer eng URL ass op dësem Server desaktivéiert.",
        "api-error-duplicate": "Et gëtt schonn {{PLURAL:$1|en anere Fichier|e puer aner Fichiere}} mat dem selwechten Inhalt op dem Site",
        "api-error-duplicate-archive": "Et gouf schonn {{PLURAL:$1| een anere Fichier|e puer aner Fichieren}} op dem Site mat deemselwechten Inhalt, {{PLURAL:$1|e gouf|se goufen}} awer geläscht.",
index ced7c58..b331307 100644 (file)
@@ -5,7 +5,8 @@
                        "Hosseinblue",
                        "Lakzon",
                        "Mjbmr",
-                       "Macofe"
+                       "Macofe",
+                       "Huji"
                ]
        },
        "tog-underline": "کڕ(خط)کیشائن ژێر پیوندەل:",
        "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}}]] استفاده کنید.",
+       "upload-form-label-own-work": "یة کار ووژمة",
+       "upload-form-label-infoform-categories": "ڕزگەل",
+       "upload-form-label-infoform-date": "تاریخ",
+       "upload-form-label-own-work-message-local": "تائید می کنم که این پرونده را تحت مجوزها و سیاست‌های {{SITENAME}} بارگذاری می‌کنم.",
+       "upload-form-label-not-own-work-message-local": "اگر امکان بارگذاری پرونده تحت سیاست‌های {{SITENAME}} را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "upload-form-label-not-own-work-local-local": "ممکن بخواهید از [[Special:Upload|پنجرهٔ بارگذاری پیش‌فرض]] استفاده کنید.",
+       "upload-form-label-own-work-message-default": "متوجهم که این پرونده را بر روی مخزن مشترک بارگذاری می‌کنم و تائید می‌کنم که تحت سیاست‌ها و مجوزهای آنجا عمل می‌کنم.",
+       "upload-form-label-not-own-work-message-default": "اگر امکان بارگذاری پرونده تحت سیاست‌ها و مجوزهای مخزن اشتراک‌گذاری را ندارید، لطفاً این پنجره را ببندید و از روش‌های دیگر استفاده کنید.",
+       "upload-form-label-not-own-work-local-default": "در صورتی که نمی‌شود پرونده را تحت سیاست‌ها بارگذاری کنید ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
+       "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 سیاست نحوهٔ استفاده] هستم.",
+       "upload-form-label-not-own-work-message-shared": "اگر مالک حق تکثیر این پرونده نیستید یا قصد بارگذاری تحت مجوز دیگری دارید، از [https://commons.wikimedia.org/wiki/Special:UploadWizard جادوگر بارگذاری ویکی‌انبار] استفاده کنید.",
+       "upload-form-label-not-own-work-local-shared": "در صورتی که سایت امکان بارگذاری پرونده را تحت سیاست‌ها بارگذاری می‌دهد ممکن است بخواهید از [[Special:Upload|پنجرهٔ بارگذاری در {{SITENAME}}]] استفاده کنید.",
        "backend-fail-stream": "نمی‌توان پروندهٔ $1 را ارسال کرد.",
        "backend-fail-backup": "نمی‌توان نسخهٔ پشتیبان برای پروندهٔ $1 ایجاد کرد",
        "backend-fail-notexists": "پروندهٔ $1 وجود ندارد.",
        "exbeforeblank": "محتوای صفحه قبل از خالی‌کردن این بود: «$1»",
        "delete-confirm": "حذف «$1»",
        "delete-legend": "حۀذف کردن/پاک کردن",
-       "historywarning": "<strong>هشدار:</strong> صفحه‌ای که در حال پاک‌کردن آن هستید دارای یک تاریخچه همراه $1 {{PLURAL:$1|بازبینی|بازبینی‌ها}} است:",
+       "historywarning": "<strong>هشدار:</strong> صفحه‌ای که در حال پاک‌کردن آن هستید دارای یک تاریخچه همراه $1 {{PLURAL:$1|بازبینی|بازبینی}} است:",
        "historyaction-submit": "نیشان دائن",
        "confirmdeletetext": "شما در حال حذف کردن یک صفحه یا تصویر از پایگاه داده‌ها همراه با تمام تاریخچهٔ آن هستید.\nلطفاً این عمل را تأیید کنید و اطمینان حاصل کنید که عواقب این کار را می‌دانید و این عمل را مطابق با [[{{MediaWiki:Policy-url}}|سیاست‌ها]] انجام می‌دهید.",
        "actioncomplete": "عملكرد كامل بيه",
index a835f91..eab4db5 100644 (file)
@@ -8,7 +8,8 @@
                        "Mjbmr",
                        "Matma Rex",
                        "Lakzon",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Amire80"
                ]
        },
        "tog-underline": "هوم پئیڤأند زیرخأط دار:",
        "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": "گات",
+       "upload-form-label-own-work": "یە کار مئنە",
+       "upload-form-label-infoform-categories": "دأسە یا",
+       "upload-form-label-infoform-date": "گات",
        "backend-fail-stream": "نبوئه جانیا\"$1\" کل بوئه.",
        "backend-fail-backup": "نبوئه سی \"$1\" پشتجا گرت.",
        "backend-fail-notexists": "جانیا $1 وجود ناره.",
        "listgrouprights-rights": "حقوقیا",
        "listgrouprights-helppage": "هومیاری:حقوق گرو",
        "listgrouprights-members": "(نوم گه اندومیا)",
-       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($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",
index 3daa2d9..7caf232 100644 (file)
        "remembermypassword": "Prisiminti prisijungimo duomenis šiame kompiuteryje (daugiausiai $1 {{PLURAL:$1|dieną|dienas|dienų}})",
        "userlogin-remembermypassword": "Įsiminti mane",
        "userlogin-signwithsecure": "Naudoti saugią jungtį",
-       "cannotloginnow-title": "Negalima prisijungti dabar",
+       "cannotloginnow-title": "Dabar negalima prisijungti",
        "cannotloginnow-text": "Prisijungimas negalimas, kai naudojama $1.",
        "yourdomainname": "Jūsų domenas:",
        "password-change-forbidden": "Jus negalite keisti slaptažodžių šioje wiki.",
        "minoredit": "Tai smulkus pataisymas",
        "watchthis": "Stebėti šį puslapį",
        "savearticle": "Išsaugoti puslapį",
+       "publishpage": "Skelbti puslapį",
        "preview": "Peržiūra",
        "showpreview": "Rodyti peržiūrą",
        "showdiff": "Rodyti skirtumus",
        "upload-form-label-infoform-description-tooltip": "Trumpai apibūdinkite viską, kad įsimintina apie šį darbą.\nNuotraukoms paminėkite pagrindinius dalykus, kurie yra pavaizduoti, asociacijas ar vietą.",
        "upload-form-label-usage-title": "Naudojimas",
        "upload-form-label-usage-filename": "Failo pavadinimas",
-       "foreign-structured-upload-form-label-own-work": "Tai yra mano darbas",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorijos",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Patvirtinu, kad įkeliu šį failą su šiomis naudojimosi sąlygomis ir licencijavimo politika į {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Jeigu Jūs negalite įkelti šio failo su {{SITENAME}}  politika, prašome uždaryti dialogą ir pabandyti kitą metodą.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Jūs taip pat galite norėti išbandyti [[Special:Upload|numatytąjį įkėlimo puslapį]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Aš suprantu, kad įkeliu šį failą į dalinimosi repozitoriją. Aš patvirtinu, kad tai darau laikydamasis jų paslaugų teikimo sąlygų ir licencijavimo politikos.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Jeigu negalite įkelti šio failo su dalinimosi repozitorijos politika, prašome uždaryti šį dialogą ir bandyti kitą metodą.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Jūs taip pat galite norėti išbandyti [[Special:Upload|{{SITENAME}} įkėlimo puslapį]], jeigu šis failas gali būti įkeltas su jų politika.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Aš patvirtinu, kad man priklauso šio failo autorinės teisės ir sutinku neatšaukiamai išleisti šį failą į Wikimedia Commons su [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] licencija, ir aš sutinku su [https://wikimediafoundation.org/wiki/Terms_of_Use paslaugų teikimo sąlygomis].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Jeigu Jums nepriklauso šio failo autorinės teisės arba Jūs norite išleisti jį su kitokia licencija, apsvarstykite naudojimą [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons įkėlimo vedlį].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Jūs taip pat galite norėti išbandyti [[Special:Upload|{{SITENAME}} įkėlimo puslapį]], jeigu šis puslapis leidžia failų įkėlimą pagal jų politiką.",
+       "upload-form-label-own-work": "Tai yra mano darbas",
+       "upload-form-label-infoform-categories": "Kategorijos",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Patvirtinu, kad įkeliu šį failą su šiomis naudojimosi sąlygomis ir licencijavimo politika į {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Jeigu Jūs negalite įkelti šio failo su {{SITENAME}}  politika, prašome uždaryti dialogą ir pabandyti kitą metodą.",
+       "upload-form-label-not-own-work-local-local": "Jūs taip pat galite norėti išbandyti [[Special:Upload|numatytąjį įkėlimo puslapį]].",
+       "upload-form-label-own-work-message-default": "Aš suprantu, kad įkeliu šį failą į dalinimosi repozitoriją. Aš patvirtinu, kad tai darau laikydamasis jų paslaugų teikimo sąlygų ir licencijavimo politikos.",
+       "upload-form-label-not-own-work-message-default": "Jeigu negalite įkelti šio failo su dalinimosi repozitorijos politika, prašome uždaryti šį dialogą ir bandyti kitą metodą.",
+       "upload-form-label-not-own-work-local-default": "Jūs taip pat galite norėti išbandyti [[Special:Upload|{{SITENAME}} įkėlimo puslapį]], jeigu šis failas gali būti įkeltas su jų politika.",
+       "upload-form-label-own-work-message-shared": "Aš patvirtinu, kad man priklauso šio failo autorinės teisės ir sutinku neatšaukiamai išleisti šį failą į Wikimedia Commons su [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] licencija, ir aš sutinku su [https://wikimediafoundation.org/wiki/Terms_of_Use paslaugų teikimo sąlygomis].",
+       "upload-form-label-not-own-work-message-shared": "Jeigu Jums nepriklauso šio failo autorinės teisės arba Jūs norite išleisti jį su kitokia licencija, apsvarstykite naudojimą [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons įkėlimo vedlį].",
+       "upload-form-label-not-own-work-local-shared": "Jūs taip pat galite norėti išbandyti [[Special:Upload|{{SITENAME}} įkėlimo puslapį]], jeigu šis puslapis leidžia failų įkėlimą pagal jų politiką.",
        "backend-fail-stream": "Negali būti apdorotas failas $1.",
        "backend-fail-backup": "Negali būti išsaugotas failas $1.",
        "backend-fail-notexists": "Failas $1 neegzistuoja.",
        "ipb-unblock": "Atblokuoti naudotojo vardą arba IP adresą",
        "ipb-blocklist": "Rodyti egzistuojančius blokavimus",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} indėlis",
+       "ipb-blocklist-duration-left": "$1 kairėje",
        "unblockip": "Atblokuoti naudotoją",
        "unblockiptext": "Naudokite šią formą, kad atkurtumėte redagavimo galimybę\nankščiau užblokuotam IP adresui ar naudotojui.",
        "ipusubmit": "Atblokuoti šį adresą",
        "tooltip-ca-nstab-category": "Rodyti kategorijos puslapį",
        "tooltip-minoredit": "Pažymėti keitimą kaip smulkų",
        "tooltip-save": "Išsaugoti pakeitimus",
+       "tooltip-publish": "Skelbti jūsų pakeitimus",
        "tooltip-preview": "Pakeitimų peržiūra, prašome pažiūrėti prieš išsaugant!",
        "tooltip-diff": "Rodo, kokius pakeitimus padarėte tekste",
        "tooltip-compareselectedversions": "Žiūrėti dviejų pasirinktų puslapio versijų skirtumus.",
        "watchlistedit-raw-done": "Jūsų stebimųjų sąrašas buvo atnaujintas.",
        "watchlistedit-raw-added": "$1 {{PLURAL:$1|puslapis buvo pridėtas|puslapiai buvo pridėti|puslapių buvo pridėta}}:",
        "watchlistedit-raw-removed": "$1 {{PLURAL:$1|puslapis buvo pašalintas|puslapiai buvo pašalinti|puslapių buvo pašalinta}}:",
-       "watchlistedit-clear-title": "Išvalytas stebimųjų sąrašas",
+       "watchlistedit-clear-title": "Išvalyti stebimųjų sąrašą",
        "watchlistedit-clear-legend": "Išvalyti stebimųjų sąrašą",
        "watchlistedit-clear-explain": "Visi pavadinimai bus pašalinti iš jūsų stebimųjų sąrašo",
        "watchlistedit-clear-titles": "Pavadinimai:",
        "sessionprovider-generic": "$1 sesijos",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesijos su slapukais",
        "sessionprovider-nocookies": "Slapukai gali būti neaktyvuoti. Įsitikinkite, kad slapukai yra aktyvuoti ir pradėkite vėl.",
-       "randomrootpage": "Atsitiktinis šakninis puslapis"
+       "randomrootpage": "Atsitiktinis šakninis puslapis",
+       "log-action-filter-all": "Visi",
+       "log-action-filter-newusers-autocreate": "Automatinis kūrimas",
+       "log-action-filter-protect-protect": "Apsauga"
 }
index 035bcdd..ddae430 100644 (file)
        "december-date": "दिसम्बर $1",
        "period-am": "पूर्वाह्न",
        "period-pm": "अपराह्न",
-       "pagecategories": "{{PLURAL:$1|शà¥\8dरà¥\87णà¥\80|à¤\95à¤\8fà¤\9fा à¤¶à¥\8dरà¥\87णà¥\80}}",
+       "pagecategories": "{{PLURAL:$1|शà¥\8dरà¥\87णà¥\80|शà¥\8dरà¥\87णà¥\80सभ}}",
        "category_header": "श्रेणी \"$1\" मे पन्ना सभ",
        "subcategories": "उपश्रेणी",
        "category-media-header": "श्रेणी \"$1\" मे मीडिया",
        "delete": "मेटाबी",
        "deletethispage": "ई पन्ना मेटाबी",
        "undeletethispage": "ई पृष्ठके पुनर्स्थापित करी।",
-       "undelete_short": "{{PLURAL:$1|à¤\8fà¤\95 à¤¹à¤\9fाà¤\8fल à¤\97à¤\8fल|$1 à¤¹टाएल गएल}} परिवर्तन आपस आनी",
-       "viewdeleted_short": "देखी {{PLURAL:$1|एकटा मेटाएल सम्पादन|$1 मेटाएल सम्पादन सभ}}",
+       "undelete_short": "{{PLURAL:$1|à¤\8fà¤\95 à¤®à¥\87à¤\9fाà¤\8fल à¤\97à¤\8fल|$1 à¤®à¥\87टाएल गएल}} परिवर्तन आपस आनी",
+       "viewdeleted_short": "देखी {{PLURAL:$1|एकटा मेटाएल सम्पादन|$1 मेटाएल सम्पादन}}",
        "protect": "सुरक्षित करी",
        "protect_change": "बदली",
        "protectthispage": "ई पन्नाक सुरक्षित करी",
        "pool-errorunknown": "अज्ञात भ्रम",
        "pool-servererror": "पुल काउन्टर सेवा उपलब्ध नै अछि ($1)।",
        "poolcounter-usage-error": "उपयोग त्रुटि: $1",
-       "aboutsite": "विषयमे {{SITENAME}}",
+       "aboutsite": "{{SITENAME}}क बारेमे",
        "aboutpage": "Project:विवरण",
        "copyright": "$1क अन्तर्गत विषय सूची उपलब्ध अछि",
        "copyrightpage": "{{ns:project}}:सर्वाधिकार",
        "databaseerror-text": "डाटाबेस अनुरोध त्रुटि भेल अछि।\nसंभवतः सफ्टवेयरमे गड़बड़ी अछि।",
        "databaseerror-textcl": "डाटाबेस अनुरोध त्रुटि भेल अछि।",
        "databaseerror-query": "अनुरोध: $1",
-       "databaseerror-function": "फà¤\82क्सन: $1",
+       "databaseerror-function": "फà¤\99à¥\8dक्सन: $1",
        "databaseerror-error": "त्रुटि: $1",
        "laggedslavemode": "'''चेतौनी:''' पन्नापर सम्भव जे अद्यतन परिवर्तन नै हुअए।",
        "readonly": "दत्तनिधि प्रतिबन्धित",
        "missing-article": "दत्तनिधि पृष्ठक वांछित पाठ्य नै ताकि सकल, माने \"$1\" $2\nएकर कारण कोनो पुरान फाइल चेन्हासी वा ऐतिहासिक लिंकक पाछाँ जाएब अछि, जे मेटा देल गेल छै।\nजौं ई तकर कारण नै अछि,  तखन अहाँकेँ तंत्रांशमे कोनो दोष भेटल अछि।\nएकर खबरि पहुँचाउ [[Special:ListUsers/sysop|administrator]], केँ, अपन सार्वत्रिक विभव संकेत सूचित करैत।",
        "missingarticle-rev": "(संशोधन#: $1)",
        "missingarticle-diff": "(फाइल-अन्तर प्रणाली: $1, $2)",
-       "readonly_lag": "दतà¥\8dताà¤\82शनिधि à¤¸à¥\8dवà¤\9aालित à¤°à¥\82पà¥\87ँ प्रतिबन्धित कएल गेल अछि जा परजीवी दतांशनिधि वितरक मूलक समक्ष नै आबि जाए।",
+       "readonly_lag": "दतà¥\8dताà¤\82शनिधि à¤¸à¥\8dवà¤\9aालित à¤°à¥\82पसँ प्रतिबन्धित कएल गेल अछि जा परजीवी दतांशनिधि वितरक मूलक समक्ष नै आबि जाए।",
        "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action'क एचटिटिपी शीर्षकद्वारा भेजल गएल पर एपिआईमे लेखन मोड्युल अछि।",
        "internalerror": "आन्तरिक भ्रम",
        "internalerror_info": "आन्तरिक भ्रम: $1",
        "cannotdelete": "पन्ना व संचिका \"$1\" मेटाएल नै जा सकल।",
        "cannotdelete-title": "पन्ना \"$1\" नै मेटा सकल",
        "delete-hook-aborted": "सम्पादन नोकसीसँ खतम भेल।\nई कोनो कारण नै देलक।",
-       "no-null-revision": "\"$1\" पृष्ठ के लेल बिना परिवर्तन नब अवतरण बनाबए में असफल।",
+       "no-null-revision": "\"$1\" पृष्ठक लेल बिना परिवर्तन नब अवतरण बनाबैमे असफल।",
        "badtitle": "खराप शीर्षक",
        "badtitletext": "आग्रह कएल पन्नाक शीर्षक गलत, खाली, वा गलत सम्बन्धित अन्तर-न्हाषा अन्तर विकी शीर्षक छी। ई एक वा बेशी कलाकार युक्त भऽ सकैए जे शीर्षकमे प्रयुक्त नै कएल जा सकैए।",
        "title-invalid-empty": "निवेदित पृष्ठक शीर्षक खाली अछि या मात्र नामस्थान राखने अछि।",
-       "title-invalid-utf8": "निवà¥\87दित à¤ªà¥\83षà¥\8dठà¤\95 à¤¶à¥\80रà¥\8dषà¤\95 à¤\85वà¥\88ध à¤¯à¥\82०à¤\9fà¥\80०एफ-८ सँ सिलसिला राखैत अछि।",
-       "title-invalid-interwiki": "निवेदित पृष्ठ के शीर्षक एक अन्तर-विकी जडी राखैत अछि जे शीर्षक में प्रयोग नै कैर सकएत छि।",
+       "title-invalid-utf8": "निवà¥\87दित à¤ªà¥\83षà¥\8dठà¤\95 à¤¶à¥\80रà¥\8dषà¤\95 à¤\85वà¥\88ध à¤¯à¥\81à¤\9fिएफ-८ सँ सिलसिला राखैत अछि।",
+       "title-invalid-interwiki": "निवेदित पृष्ठक शीर्षक एक अन्तर-विकी जडी राखैत अछि जे शीर्षकमे प्रयोग नै करि सकएत अछि।",
        "title-invalid-talk-namespace": "निवेदित पृष्ठक शीर्षक एक वार्ता पृष्ठ सँ सन्दर्भित अछि जे मौजूद नै अछि।",
        "title-invalid-characters": "निवेदित पृष्ठक शीर्षक अवैध क्यारेक्टर: \"$1\" राखैत अछि।",
        "title-invalid-relative": "शीर्षक एक सन्दर्भित मार्ग राखैत अछि। सन्दर्भित पन्ना के शीर्षक (./, ../)अवैध अछि, कियाकी ई अधिकांश रूप पहुँच से बाहर छि जे हुनका उपयोगकर्ता के ब्रौज़र से प्रयोग में लाबई के प्रयास करल जाएत अछि ।",
-       "title-invalid-magic-tilde": "निवेदित पन्ना के शीर्षक अवैध जादूई टिल्ड सिलसिला राखएत अछि (<nowiki>~~~</nowiki>)।",
-       "title-invalid-too-long": "माँग कएल गेल पन्ना कें शीर्षक बहुत नम्हर अछि । एकरा यू०टी०एफ़० कोडिंग मे $1 {{PLURAL:$1|बाइट|बाइट्स}} से बढ़का नए होना चाही आर एकरा यू०टी०एफ़०-८ एनकोडिंग में होना चाही ।",
-       "title-invalid-leading-colon": "निवेदित पन्ना के शीर्षक प्रारंभ में अवैध कोलन रखएत अछि।",
+       "title-invalid-magic-tilde": "निवेदित पन्नाक शीर्षक अवैध जादुई टिल्ड सिलसिला राखएत अछि (<nowiki>~~~</nowiki>)।",
+       "title-invalid-too-long": "माँग कएल गेल पन्नाक शीर्षक बहुत नम्हर अछि। एकरा युटिएफ कोडिङमे $1 {{PLURAL:$1|बाइट|बाइट्स}} से पैग नै होना चाही आर एकरा युटिएफ-८ एनकोडिङमे होना चाही।",
+       "title-invalid-leading-colon": "निवेदित पन्नाक शीर्षक प्रारम्भमे अवैध कोलन रखएत अछि।",
        "perfcached": "ई दत्तांश उपस्मृतिक आधारपर अछि आ भऽ सकैए जे अद्यतन नै हुअए। अधिकतम {{PLURAL:$1|एकटा परिणाम|$1 परिणाम सभ}} क्याचेमे उपलब्ध अछि ।",
        "perfcachedts": "ई दत्तांश उपस्मृतिमे अछि, आ एकर अन्तिम परिवर्धन भेल अछि $1 केँ। A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "querypage-no-updates": "ऐ पन्नाक नवीनीकरण अखन बन्न अछि।\nएतुक्का दत्तांश अखन नवीकरण नै कएल जाएत।",
        "actionthrottled": "कार्य समाप्त करि देल गएल",
        "actionthrottledtext": "अनपेक्षित सन्देश रोक लेल, अहाँक ई क्रियाक कम्मे कालमे सीमासँ बेसीबेर करबासँ रोकल गेल अछि, अहाँ ओ सीमाक पार कऽ गेल छी।\nकृपया किछ काल बाद फेरसँ प्रयास करी।",
        "protectedpagetext": "ई पन्ना सम्पादन रोकबा लेल संरक्षित अछि।",
-       "viewsourcetext": "à¤\85हाà¤\81 à¤\87 पृष्ठक जडिक देख आ अनुकृत कऽ सकै छी:",
+       "viewsourcetext": "à¤\85हाà¤\81 à¤\88 पृष्ठक जडिक देख आ अनुकृत कऽ सकै छी:",
        "viewyourtext": "अहाँ ई पृष्ठमे '''अपन सम्पादन'''क देख आ एतए उतारि सकै छी:",
        "protectedinterface": "ई पन्ना तंत्रांश लेल मध्यस्थ पाठक व्यवस्था करैत अछि, आ अपशब्द रोकबाक ब्योंत करैत अछि।",
        "editinginterface": "'''चेतौनी''' अहाँ एकटा एहेन पन्नाक सम्पादन कऽ रहल छी जे तंत्रांशक मध्यस्थ पन्नाकेँ पाठ देबा लेल प्रयोग भऽ रहल अछि।\nऐ पन्नामे परिवर्तन दोसर प्रयोक्ता लेल प्रयोक्ता मध्यस्थक रूपमे परिवर्तन करत।\nअनुवाद लेल [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net] जाउ, मीडियाविकी स्थानीयकरण परियोजना पर।",
        "mycustomjsprotected": "अहके लेल इ जावास्क्रिप्ट पन्नाके सम्पादित करवाक अधिकार नै अछि।",
        "myprivateinfoprotected": "अहाके अपन व्यक्तिगत जानकारी बदलैक अनुमति नै अछि।",
        "mypreferencesprotected": "अहाके अपन प्राथमिकता बदलैक अनुमति नै अछि।",
-       "ns-specialprotected": "विशेष पन्ना सभकेँ सम्पादित नै कएल जा सकैए।",
-       "titleprotected": "à¤\90 à¤¶à¥\80रà¥\8dषà¤\95à¤\95 à¤¨à¤¿à¤°à¥\8dमाण à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि [[User:$1|$1]] à¤¦à¥\8dवारा।\nà¤\95ारण à¤\8fतऽ à¤¦à¥\87ल अछि <em>$2</em>।",
-       "filereadonlyerror": "\"$1\" à¤«à¤¾à¤\87लà¤\95à¥\87 à¤¬à¤¦à¤²à¥\88लà¥\87ल à¤\85à¤\95à¥\8dषम à¤\95ियाà¤\95 à¤­à¤£à¥\8dडार \"$2\" à¤\87 समय 'मात्र पाठनक लेल' अछि।\n\nजे प्रबन्धक ई प्रबन्ध लगोनै अछि ओ निम्न विवरण प्रदान कएने अछि: \"$3\"।",
+       "ns-specialprotected": "विशेष पन्ना सभक सम्पादित नै कएल जा सकैए।",
+       "titleprotected": "à¤\88 à¤¶à¥\80रà¥\8dषà¤\95à¤\95 à¤¨à¤¿à¤°à¥\8dमाण à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि [[User:$1|$1]] à¤¦à¥\8dवारा।\nà¤\8fà¤\95र à¤²à¥\87ल à¤¨à¤¿à¤®à¥\8dन à¤\95ारण à¤¦à¥\87ल à¤\97à¤\8fल अछि <em>$2</em>।",
+       "filereadonlyerror": "\"$1\" à¤«à¤¾à¤\87लà¤\95à¥\87 à¤¬à¤¦à¤²à¥\88लà¥\87ल à¤\85à¤\95à¥\8dषम à¤\95ियाà¤\95 à¤­à¤£à¥\8dडार \"$2\" à¤\88 समय 'मात्र पाठनक लेल' अछि।\n\nजे प्रबन्धक ई प्रबन्ध लगोनै अछि ओ निम्न विवरण प्रदान कएने अछि: \"$3\"।",
        "invalidtitle-knownnamespace": "\"$2\" नामस्थान आर \"$3\" नाम बला गलत शीर्षक",
        "invalidtitle-unknownnamespace": "अज्ञात नामस्थान संख्या $1 आर नाम \"$2\" वाला गलत शीर्षक",
        "exception-nologin": "सम्प्रवेशित नै",
-       "exception-nologin-text": "à¤\87 à¤ªà¤¨à¥\8dना à¤µà¤¾ à¤\95ाà¤\9cà¤\95à¥\87 à¤¸à¤\95à¥\8dषम à¤\95रवाà¤\95 à¤²à¥\87ल à¤\95à¥\83पया à¤ªà¥\8dरवà¥\87श à¤\95रà¥\81।",
-       "exception-nologin-text-manual": "à¤\87 à¤ªà¤¨à¥\8dना à¤µà¤¾ à¤\95ाà¤\9cà¤\95à¥\87 à¤¸à¤\95à¥\8dषम à¤\95रवाà¤\95 à¤²à¥\87ल à¤\95à¥\83पया $1 à¤\95रà¥\81।",
-       "virus-badscanner": "खराप विन्यास: अज्ञात विषविधि बिम्बक: ''$1''",
+       "exception-nologin-text": "à¤\88 à¤ªà¤¨à¥\8dना à¤µà¤¾ à¤\95ाà¤\9c à¤¸à¤\95à¥\8dषम à¤\95रवाà¤\95 à¤²à¥\87ल à¤\95à¥\83पया à¤ªà¥\8dरवà¥\87श à¤\95रà¥\80।",
+       "exception-nologin-text-manual": "à¤\88 à¤ªà¤¨à¥\8dना à¤µà¤¾ à¤\95ाà¤\9c à¤¸à¤\95à¥\8dषम à¤\95रवाà¤\95 à¤²à¥\87ल à¤\95à¥\83पया $1 à¤\95रà¥\80।",
+       "virus-badscanner": "खराप विन्यास: अज्ञात विषविधि बिम्बक: <em>$1</em>",
        "virus-scanfailed": "बिम्ब विफल (विध्यादेश $1)",
        "virus-unknownscanner": "अज्ञात विषविधि निरोधक",
        "logouttext": "'''अहाँ निष्क्रमण कऽ गेल छी।'''\n\nअहाँ {{अन्तर्जाल}} प्रयोग अनाम भऽ कऽ सकै छी, वा अहाँ <span class='plainlinks'>[$1 log in again]</span> वएह आकि कोनो आन प्रयोक्ताक रूपमे सेहू प्रयोक कऽ सकै छी।\nई मोन राखू जे किछु पन्ना एना देखा पड़ि सकैए जेना अहाँ अखनो सम्प्रवेशित होइ, जावत अहाँ अपन गवेषकक उपस्मृति मेटा नै दै छी।",
        "userlogin-yourname": "प्रयोक्ता:",
        "userlogin-yourname-ph": "अपन प्रयोगकर्तानाम लिखी",
        "createacct-another-username-ph": "प्रयोगकर्तानाम प्रदान करी",
-       "yourpassword": "à¤\95à¥\82टशब्द:",
-       "userlogin-yourpassword": "à¤\95à¥\82टशब्द",
-       "userlogin-yourpassword-ph": "à¤\85पन à¤\95à¥\82टशब्द लिखी",
-       "createacct-yourpassword-ph": "à¤\95à¥\82टशब्द दर्ज करी",
-       "yourpasswordagain": "à¤\95à¥\82टशब्द फेरसँ टाइप करी:",
-       "createacct-yourpasswordagain": "à¤\95à¥\82à¤\9fशबà¥\8dदà¤\95 जाँच करी",
-       "createacct-yourpasswordagain-ph": "à¤\95à¥\82टशब्द पुनः लिखी",
+       "yourpassword": "à¤\95à¥\81टशब्द:",
+       "userlogin-yourpassword": "à¤\95à¥\81टशब्द",
+       "userlogin-yourpassword-ph": "à¤\85पन à¤\95à¥\81टशब्द लिखी",
+       "createacct-yourpassword-ph": "à¤\95à¥\81टशब्द दर्ज करी",
+       "yourpasswordagain": "à¤\95à¥\81टशब्द फेरसँ टाइप करी:",
+       "createacct-yourpasswordagain": "à¤\95à¥\81à¤\9fशबà¥\8dद जाँच करी",
+       "createacct-yourpasswordagain-ph": "à¤\95à¥\81टशब्द पुनः लिखी",
        "remembermypassword": "ई ब्राउजर पर हमर सम्प्रवेश याद राखी (अधिकतम $1 {{PLURAL:$1|दिन|दिनधरि}}क लेल)",
        "userlogin-remembermypassword": "हमरा सम्प्रवेशित राखी",
        "userlogin-signwithsecure": "सुरक्षित कनेक्शनक प्रयोग करी",
        "cannotloginnow-title": "अखन प्रवेश नै भऽ रहल अछि",
        "cannotloginnow-text": "$1 क उपयोग समय प्रवेश नै कएल जा सकएत अछि।",
        "yourdomainname": "अहाँक डोमेन (प्रभावक्षेत्र):",
-       "password-change-forbidden": "à¤\85हाà¤\81 à¤\88 à¤µà¤¿à¤\95िमà¥\87 à¤\95à¥\82टशब्द नै बदल सकैत छी।",
+       "password-change-forbidden": "à¤\85हाà¤\81 à¤\88 à¤µà¤¿à¤\95िमà¥\87 à¤\95à¥\81टशब्द नै बदल सकैत छी।",
        "externaldberror": "या त प्रमाणिकरण डेटाबेसमे त्रुटि भएल अछि या फेर अहाँक अपन बाह्य खाता अपडेट करैक अनुमति नै अछि।",
        "login": "सम्प्रवेश",
        "nav-login-createaccount": "सम्प्रवेश / खाता खोली",
        "noemail": "प्रयोक्ता \"$1\" लेल कोनो ई-पत्र संकेत दर्ज नै अछि।",
        "noemailcreate": "अहाँकेँ एकटा मान्य ई-पत्र संकेत देबऽ पड़त।",
        "passwordsent": "एकटा नव कूटशब्द \"$1\" लेल पंजीकृत ई-पत्र संकेतपर पठाएल गेल अछि।\nजखन अहाँकेँ ई भेटैए तँ फेरसँ सम्प्रवेश करू।",
-       "blocked-mailpassword": "à¤\85हाà¤\81à¤\95 à¤\85निà¤\95à¥\87त à¤¸à¤®à¥\8dपादन à¤²à¥\87ल à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि, à¤\86 à¤¦à¥\81रà¥\81पयà¥\8bà¤\97 à¤°à¥\8bà¤\95बा à¤²à¥\87ल à¤\95à¥\82à¤\9fशबà¥\8dद à¤ªà¥\8dरतà¥\8dयाहरण à¤¸à¥\87वा à¤\90 लेल उपलब्ध नै अछि।",
+       "blocked-mailpassword": "à¤\85हाà¤\81à¤\95 à¤\85निà¤\95à¥\87त à¤¸à¤®à¥\8dपादन à¤²à¥\87ल à¤ªà¥\8dरतिबनà¥\8dधित à¤\85à¤\9bि, à¤\86 à¤¦à¥\81रà¥\81पयà¥\8bà¤\97 à¤°à¥\8bà¤\95बा à¤²à¥\87ल à¤\95à¥\81à¤\9fशबà¥\8dद à¤ªà¥\8dरतà¥\8dयाहरण à¤¸à¥\87वा à¤\88 लेल उपलब्ध नै अछि।",
        "eauthentsent": "एकटा पावती ई-पत्र निर्धारित ई-पत्र संकेतपर पठा देल गेल अछि।\nऐ खातापर कोनो दोसर ई-पत्र पठाएल जएबासँ पहिने, अहाँकेँ ऐ ई-पत्रक निर्देशक पालन करए पड़त, जइसँ ई पुष्ट भऽ सकए जे ई खाता वास्तवमे अहींक अछि।",
        "throttled-mailpassword": "एकटा कूटशब्द स्मारक पहिनहिये पठाएल गेल अछि, {{PLURAL:$1|घण्टा|$1 घण्टा}}क भीतर।\nदुरुपयोग रोकबा लेल, मात्र एकटा कूटशब्द {{PLURAL:$1|घण्टा|$1 घण्टा}}मे पठाएल जाएत।",
        "mailerror": "ई-पत्र पठेबामे त्रुटी: $1",
        "passwordreset-emailsentemail": "एकटा ई-पत्र मोन पाड़बा लेल पठाओल गेल अछि।",
        "passwordreset-emailsent-capture": "एकटा स्मरण ई-पत्र पठाएल गेल अछि, जे नीचाँ देखाएल अछि।",
        "passwordreset-emailerror-capture": "एकटा स्मरण ई-पत्र बनाएल गेल अछि, जे नीचाँ देखाएल अछि, मुदा प्र्योक्ताकेँ एकरा पठेबाक प्रयास विफल भेल: $1",
-       "changeemail": "à¤\88-पतà¥\8dर à¤¸à¤\82à¤\95à¥\87त à¤¬à¤¦à¤²à¥\82",
-       "changeemail-header": "à¤\88-पतà¥\8dर à¤ªà¤¤à¤¾ à¤\96ाता à¤¬à¤¦à¤²à¥\82",
+       "changeemail": "à¤\88-मà¥\87ल à¤ªà¤¤à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतित à¤\95रà¥\80",
+       "changeemail-header": "à¤\85पन à¤\88मà¥\87ल à¤ªà¤¤à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\87तà¥\81 à¤\8fà¤\95रा à¤ªà¥\81रा à¤\95रà¥\80। à¤¯à¤¦à¤¿ à¤\85हाà¤\81 à¤\85पन à¤µà¤°à¥\8dतमान à¤\88मà¥\87ल à¤ªà¤¤à¤¾ à¤¹à¤\9fाबà¥\88लà¥\87ल à¤\9aाहà¥\88त à¤\9bà¥\80, à¤¤à¤\81 à¤\8fà¤\95रा à¤\96ालà¥\80 à¤\9bà¥\8bडि à¤¦à¥\80 à¤\86 à¤\8fà¤\95रा à¤­à¥\87à¤\9cà¥\80।",
        "changeemail-no-info": "अहाँकेँ ऐ पन्नाकेँ सोझे देखबाले सम्प्रवेशित हुअए पड़त।",
        "changeemail-oldemail": "अखुनका ई-पत्र संकेत:",
        "changeemail-newemail": "नव ई-पत्र संकेत:",
        "sig_tip": "अहाँक हस्ताक्षर समयक मोहरक संग",
        "hr_tip": "अक्षांशीय पंक्ति (अल्प उपयोग)",
        "summary": "सारांश:",
-       "subject": "विषय/मुख्यपंक्ति:",
+       "subject": "विषय:",
        "minoredit": "अल्प संपादन",
        "watchthis": "एहि पृष्ठकेँ देखू",
        "savearticle": "पन्नाक रक्षण करू",
        "missingcommenttext": "कृपा कऽ अपन विचार नीचाँ प्रविष्ट करू।",
        "missingcommentheader": "'''स्मरण:''' अहाँ कोनो विषय/ शीर्षक ऐ टिप्पणीक लेल नै देने छी।\nजँ अहाँ फेरसँ क्लिक करब \"{{int:savearticle}}\" , अहाँक सम्पादन बिना एकर संरक्षित भऽ जाएत।",
        "summary-preview": "सारांश पूर्वावलोकन",
-       "subject-preview": "विषय/ शीर्षक पूर्वावलोकन",
+       "subject-preview": "विषयक झलक:",
        "previewerrortext": "आहाँकें परिवर्तन के पूर्वावलोकन करई कें समय एक त्रुटि एल ।",
        "blockedtitle": "प्रयोक्ता प्रतिबन्धित अछि।",
        "blockedtext": "''' अहाँक प्रयोक्तानाम वा अनिकेत प्रतिबन्धित कऽ देल गेल अछि।'''\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ऐ सभ विवरणक उल्लेख अहाँ अपन कोनो कएल जाइबला प्रश्नमे करू।",
        "newarticle": "(नव)",
        "newarticletext": "अहाँ एहेन पन्नाक लिंकक अनुसरण कऽ आएल छी जे पन्ना अखन बनले नै अछि।\nपन्ना बनेबाक लेल नीचाँक बक्शामे टाइप केनाइ शुरू करू (देखू [$1  सहायता पन्ना] विषेष जानकारी लेल)।",
        "anontalkpagetext": "----'' ई एकटा अनाम प्रयोक्ताक लेल वार्ता पन्ना छी जे अखन धरि अपन खाता नै खोलने छथि, वा जे एकर प्रयोग नै करै छथि।\nहमरा सभकेँ तइ लेल अंकीय अनिकेतक प्रयोग हुनका देखार करबा लेल करऽ पड़ि रहल अछि।\nऐ तरहक अनिकेत अनेक प्रयोक्ता द्वारा साझी कएल जा सकैत अछि।\nजँ अहाँ अनाम प्रयोक्ता छी आ बुझै छी जे बिना मतलबक टिप्पणी अहाँ दिस देल जा रहल अछि, तँ कृपा कऽ [[Special:UserLogin/signup|एकटा खाता खोलू]] वा [[Special:UserLogin|सम्प्रवेश]] जइसँ भविष्यमे आन अनाम प्रयोक्तासँ अहाँकेँ दिक्कत नै हो।''",
-       "noarticletext": "à¤\85à¤\96न à¤\90 à¤ªà¤¨à¥\8dनापर à¤\95à¥\8bनà¥\8b à¤ªà¤¾à¤  à¤¨à¥\88 à¤\85à¤\9bि।\nà¤\85हाà¤\81 [[Special:Search/{{PAGENAME}}|à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤¶à¥\80रà¥\8dषà¤\95à¥\87à¤\81 à¤¤à¤¾à¤\95à¥\82]] à¤\86न à¤ªà¤¨à¥\8dनापर,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} à¤¸à¤®à¥\8dबनà¥\8dधà¥\80 à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤¤à¤¾à¤\95à¥\82],\nà¤\86à¤\95ि [{{fullurl:{{FULLPAGENAME}}|action=edit}} à¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 à¤¸à¤®à¥\8dपादित à¤\95रà¥\82]</span>.",
+       "noarticletext": "à¤\85à¤\96न à¤\88 à¤ªà¤¨à¥\8dनापर à¤\95à¥\8bनà¥\8b à¤ªà¤¾à¤  à¤¨à¥\88 à¤\85à¤\9bि।\nà¤\85हाà¤\81 [[Special:Search/{{PAGENAME}}|à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¶à¥\80रà¥\8dषà¤\95 à¤¤à¤¾à¤\95à¥\80]] à¤\86न à¤ªà¤¨à¥\8dनापर,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} à¤¸à¤®à¥\8dबनà¥\8dधà¥\80 à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤¤à¤¾à¤\95à¥\80],\nà¤\86à¤\95ि [{{fullurl:{{FULLPAGENAME}}|action=edit}} à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤¨à¤¿à¤°à¥\8dमाण à¤\95रà¥\80]</span>।",
        "noarticletext-nopermission": "अखन ऐ पन्नापर कोनो पाठ नै अछि।\nअहाँ [[Special:Search/{{PAGENAME}}|ऐ पन्ना शीर्षक लेल ताकू]]",
        "missing-revision": "\"{{FULLPAGENAME}}\" पन्ना के अवतरण #$1 मौजूद नई अछि ।\n\nओन त ई एक हट्याल गेल पन्ना के पुराना कडी पे क्लिक करबाक कारण से होएत अछि।\nअधिक जानकारी के लेल आहाँ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाबै के लॉग] देख सकै अछि।",
        "userpage-userdoesnotexist": "प्रयोक्ता खाता \"<nowiki>$1</nowiki>\" पंजीकृत नै अछि।\nनिश्चय करू जे की अहाँ ई पन्ना बनेबाक/ सम्पादित करबाक इच्छुक छी।",
        "recentchanges-feed-description": "ऐ सूचना-तंत्रांशमे विकीमे भेल सभसँ लगक परिवर्तन ताकू",
        "recentchanges-label-newpage": "ई सम्पादन एकटा नव पन्नाक निर्माण केलक।",
        "recentchanges-label-minor": "ई एकटा लघु सम्पादन छी",
-       "recentchanges-label-bot": "à¤\88 à¤¸à¤®à¥\8dपादन à¤¯à¤¾à¤\82त्रिक छल।",
+       "recentchanges-label-bot": "à¤\88 à¤¸à¤®à¥\8dपादन à¤¯à¤¾à¤¨à¥\8dत्रिक छल।",
        "recentchanges-label-unpatrolled": "ऐ सम्पादनक पुनरीक्षण अखन धरि नै कएल गेल अछि।",
        "recentchanges-label-plusminus": "पन्नाके आकार इ बाइट संख्यासे बदलल गेल",
        "recentchanges-legend-heading": "<strong>कुञ्जी:</strong>",
        "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": "दिनाङ्क",
+       "upload-form-label-own-work": "ई हमर काज छी",
+       "upload-form-label-infoform-categories": "श्रेणीसभ",
+       "upload-form-label-infoform-date": "दिनाङ्क",
        "backend-fail-stream": "\"$1\" केँ नै स्ट्रिम क सकल।",
        "backend-fail-backup": "\"$1\" केँ नै ब्याकअप क सकल।",
        "backend-fail-notexists": "फाइल $1 नै अछि।",
        "tooltip-ca-edit": "ई पन्नाक सम्पादित करी",
        "tooltip-ca-addsection": "नव खण्ड शुरू करू",
        "tooltip-ca-viewsource": "ऐ पन्नापर वरदहस्त छै।\nअहाँ एकर जड़ि देख सकै छी।",
-       "tooltip-ca-history": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤ªà¤¹à¤¿à¤²à¥\81à¤\95ा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनसभ",
+       "tooltip-ca-history": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤ªà¥\81रान à¤\85वतरण",
        "tooltip-ca-protect": "ऐ पन्नाकेँ बचाउ",
        "tooltip-ca-unprotect": "ऐ पन्नाक रक्षा कवच बदलू",
        "tooltip-ca-delete": "ऐ पन्नाकेँ मेटाउ",
        "tooltip-ca-move": "ऐ पृष्ठकेँ हटाउ",
        "tooltip-ca-watch": "ई पन्नाकेँ अपन साकांक्षसूचीमे राखी",
        "tooltip-ca-unwatch": "ऐ पन्नाकेँ हमर साकांक्ष सूचीसँ हटाउ",
-       "tooltip-search": "ताकी {{SITENAME}}",
+       "tooltip-search": "{{SITENAME}}मे ताकी",
        "tooltip-search-go": "पृष्ठपर पहुँची जौं एनमेन पृष्ठ रहए",
        "tooltip-search-fulltext": "ई पाठक लेल पृष्ठसभमे ताकी",
        "tooltip-p-logo": "सम्मुख पन्ना देखी",
-       "tooltip-n-mainpage": "मुख्य पृष्ठकेँ देखी",
+       "tooltip-n-mainpage": "मुख्य पृष्ठ देखी",
        "tooltip-n-mainpage-description": "मुख्य पन्नापर जाए",
        "tooltip-n-portal": "परियोजनाक विषयमे,अहाँ की कए सकैत छी, वस्तु प्राप्ति स्थल",
        "tooltip-n-currentevents": "लगक घटनाक विषयमे आधार सूचना प्राप्त करी।",
        "tooltip-feed-rss": "ऐ पन्ना लेल आर.एस.एस. सूचना",
        "tooltip-feed-atom": "ऐ पन्ना लेल अणु समदिया",
        "tooltip-t-contributions": "ई {{GENDER:$1|प्रयोक्ताक}} योगदानक सूची देखी",
-       "tooltip-t-emailuser": "à¤\90 à¤ªà¥\8dरयà¥\8bà¤\95à¥\8dताà¤\95à¥\87à¤\81 à¤\88-पतà¥\8dर à¤ªà¤ à¤¾à¤\89",
+       "tooltip-t-emailuser": "à¤\88 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95 à¤\88-पतà¥\8dर à¤ªà¤ à¤¾à¤¬à¥\80",
        "tooltip-t-info": "ई पृष्ठ के सम्बन्धमें आर बैंसी जानकारी",
-       "tooltip-t-upload": "à¤\9aितà¥\8dर à¤\86à¤\95ि à¤®à¥\80डिया à¤«à¤¾à¤\87लà¤\95à¥\87à¤\81 अपलोड करी",
+       "tooltip-t-upload": "à¤\9aितà¥\8dर à¤\86à¤\95ि à¤®à¤¿à¤¡à¤¿à¤¯à¤¾ à¤«à¤¾à¤\87ल अपलोड करी",
        "tooltip-t-specialpages": "सभटा विशेष पन्नाक सूची",
        "tooltip-t-print": "ई पृष्ठक छपैबला रूप",
-       "tooltip-t-permalink": "पनà¥\8dनाà¤\95 à¤\90 à¤¸à¤\82वरà¥\8dधनक स्थायी लिङ्क",
-       "tooltip-ca-nstab-main": "विषय à¤¸à¥\82à¤\9aà¥\80बला à¤ªà¤¨à¥\8dना देखी",
+       "tooltip-t-permalink": "पà¥\83षà¥\8dठà¤\95 à¤\88 à¤¸à¤\82सà¥\8dà¤\95रणक स्थायी लिङ्क",
+       "tooltip-ca-nstab-main": "सामà¤\97à¥\8dरà¥\80 à¤µà¤¾à¤²à¤¾ à¤ªà¥\83षà¥\8dठ देखी",
        "tooltip-ca-nstab-user": "प्रयोक्ता पन्नाकेँ देखू",
        "tooltip-ca-nstab-media": "मीडिया पृष्ठ देखू",
        "tooltip-ca-nstab-special": "ई एकटा विशिष्ट पन्ना छी, आ अहाँ एकरा सम्पादित नै कऽ सकै छी",
        "tooltip-watchlistedit-raw-submit": "साकांक्षसूची उद्दतन करू",
        "tooltip-recreate": "पन्ना फेरसँ बनाउ तखनो जँ ई मेटा देल गेल हुअए",
        "tooltip-upload": "उपारोपण करू",
-       "tooltip-rollback": "\"पà¥\8dरतà¥\8dयावरà¥\8dतन\" à¤\90 à¤ªà¤¨à¥\8dनाà¤\95 à¤\85नà¥\8dतिम à¤¯à¥\8bà¤\97दान à¤\95रà¥\88बलाà¤\95 à¤¸à¤®à¥\8dपादन (समà¥\8dपादनसभ)à¤\95à¥\87à¤\81 à¤\8fà¤\95 à¤\95à¥\8dलिà¤\95मà¥\87 à¤ªà¥\81रान à¤\9cà¤\97हपर à¤²à¤½ à¤\9cाà¤\8f",
+       "tooltip-rollback": "\"पà¥\8dरतà¥\8dयावरà¥\8dतन\" à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 à¤\85नà¥\8dतिम à¤¯à¥\8bà¤\97दान à¤\95रà¥\88बलाà¤\95 à¤¸à¤®à¥\8dपादन (समà¥\8dपादनसभ)à¤\95 à¤\8fà¤\95 à¤\95à¥\8dलिà¤\95मà¥\87 à¤ªà¥\81रान à¤\9cà¤\97हपर à¤²à¤½ à¤\9cाà¤\8f।",
        "tooltip-undo": "\"फेरसँ वएह\" सम्पादनकेँ पूर्वस्थितिमे लऽ जाइए आ पूर्वावलोकन अवस्थामे सम्पादन फॉर्म खोलैए। ई सारांशमे कारण जोड़बाक विकल्प दैत अछि।",
        "tooltip-preferences-save": "मोनपसंद के सुरक्षित करू",
        "tooltip-summary": "छोट संक्षेप दिअ",
        "lastmodifiedatby": "ई पन्ना अंतिम बेर संवर्धित भेल $2, $1 द्वारा $3।",
        "othercontribs": "$1 के काजुक तरहे",
        "others": "दोसर, आन",
-       "siteusers": "{{अन्तर्जाल}} {{PLURAL:$2|प्रयोक्ता|प्रयोक्ता सभ}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|प्रयोगकर्ता}}|प्रयोगकर्ता}} $1",
        "anonusers": "{{अन्तर्जाल}} अज्ञात {{PLURAL:$2|प्रयोक्ता|प्रयोक्ता सभ}} $1",
        "creditspage": "पन्नाक श्रेय",
        "nocredits": "अहि पन्नाक लेल क्रेडिट ज़ानकारी नहि अछि",
        "scarytranscludefailed-httpstatus": "[$1 के लेल आकृति नै आइन पेलौ, त्रुटि: HTTP $2]",
        "scarytranscludetoolong": "यूआरएल बड़ पैग अछि",
        "deletedwhileediting": "'''Warning''': अहां जखन सें संपादन शुरू केने छी, ओकर बाद से ई पृष्ठ के मिटा देल गेल अछि.",
-       "confirmrecreate": "पà¥\8dरयà¥\8bà¤\95à¥\8dता [[User:$1|$1]] ([[User talk:$1|वारà¥\8dता]]) à¤\85हाà¤\81à¤\95 à¤\95ारण à¤¸à¤¹à¤¿à¤¤ à¤¸à¤®à¥\8dपादनà¤\95 à¤¬à¤¾à¤¦ à¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 à¤®à¥\87à¤\9fा à¤¦à¥\87लà¤\95:\n: ''$2''\nà¤\95à¥\83पा à¤\95ऽ à¤\85हाà¤\81 à¤¸à¥\81निशà¥\8dà¤\9aित à¤\95रà¥\82 à¤\9cà¥\87 à¤\85हाà¤\81 à¤\90 à¤ªà¤¨à¥\8dनाà¤\95à¥\87à¤\81 फेरसँ बनबऽ चाहै छी।",
+       "confirmrecreate": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता [[User:$1|$1]] ([[User talk:$1|वारà¥\8dता]]) à¤\85हाà¤\81à¤\95 à¤\95ारण à¤¸à¤¹à¤¿à¤¤ à¤¸à¤®à¥\8dपादनà¤\95 à¤¬à¤¾à¤¦ à¤\88 à¤ªà¤¨à¥\8dनाà¤\95à¥\87 à¤®à¥\87à¤\9fाà¤\8f à¤¦à¥\87लà¤\95:\n: ''$2''\nà¤\95à¥\83पा à¤\95ऽ à¤\85हाà¤\81 à¤¸à¥\81निशà¥\8dà¤\9aित à¤\95रà¥\80 à¤\9cà¥\87 à¤\85हाà¤\81 à¤\88 à¤ªà¤¨à¥\8dनाà¤\95 फेरसँ बनबऽ चाहै छी।",
        "confirmrecreate-noreason": "प्रयोक्ता [[User:$1|$1]] ([[User talk:$1|वार्ता]]) अहाँक सम्पादनक बाद ऐ पन्नाकेँ मेटा देलक| कृपा कऽ अहाँ सुनिश्चित करू जे अहाँ ऐ पन्नाकेँ फेरसँ बनबऽ चाहै छी।",
        "recreate": "फेर सें बनाऊ",
        "confirm_purge_button": "ठीक अछि",
        "compare-revision-not-exists": "जे संशोधन अहाँ कहलौं से अछिये नै।",
        "dberr-problems": "दुखी छी! ई जालस्थल तकनीकी समस्या अनुभव कऽ अछि।",
        "dberr-again": "किछु काल बाट ताकू आ फेरसँ भारित करू।",
-       "dberr-info": "(दत्तनिधि वितरकके सम्पर्क नै कऽ सकल: $1)",
-       "dberr-info-hidden": "(दत्तनिधि वितरकके सम्पर्क नै कऽ सकल: $1)",
+       "dberr-info": "(दत्तनिधि वितरकके सम्पर्क नै कऽ सकल: $1)",
+       "dberr-info-hidden": "(दत्तनिधि वितरकके सम्पर्क नै कऽ सकल: $1)",
        "dberr-usegoogle": "ऐ बीचमे अहाँ गूगलसँ खोज कऽ सकै छी।",
        "dberr-outofdate": "मोन राखू जे हमर सामिग्रीक ओकर सूची पुरान भऽ सकैए।",
        "dberr-cachederror": "ई आग्रह कएल पन्नाक उपस्मृति संरक्षित द्वितीयक अछि, आ भऽ सकैए जे अद्यतन नै हुअए।",
index b7a8909..f3c2f52 100644 (file)
        "upload-form-label-infoform-description": "Famisavisana",
        "upload-form-label-usage-title": "Fampiasana",
        "upload-form-label-usage-filename": "Anaran-drakitra",
-       "foreign-structured-upload-form-label-own-work": "Asako ity",
-       "foreign-structured-upload-form-label-infoform-categories": "Sokajy",
-       "foreign-structured-upload-form-label-infoform-date": "Daty",
+       "upload-form-label-own-work": "Asako ity",
+       "upload-form-label-infoform-categories": "Sokajy",
+       "upload-form-label-infoform-date": "Daty",
        "backend-fail-stream": "Tsy afaka mamaky ilay rakitra $1.",
        "backend-fail-backup": "Tsy afaka mitahiry ilay rakitra $1.",
        "backend-fail-notexists": "Tsy misy ilay rakitra $1.",
index 7b6abe6..8d4af20 100644 (file)
        "creditspage": "Panghargaan laman",
        "spam_blanking": "Sado revisi nan ado pautan ka $1, kosong",
        "spam_deleting": "Sado revisi nan ado pautan ka $1, dihapuih",
-       "simpleantispam-label": "Pamarisoan anti-spam.\nMasukan ko '''DILARANG'''!",
+       "simpleantispam-label": "Pamarisoan anti-spam.\n<strong>Jan</strong> diisi!",
        "pageinfo-title": "Informasi untuak \"$1\"",
        "pageinfo-not-current": "Maaf, indak dapek mangagiahan informasi ko ka revisi lamo.",
        "pageinfo-header-basic": "Informasi dasar",
index 902150a..4093966 100644 (file)
        "upload-form-label-infoform-description-tooltip": "Накратко опишете го сето она што е значајно за делото. Ако е фотографија, споменете ги главните нешта што се прикажани на неа, настанот или местото.",
        "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/deed.mk Криејтив комонс Наведи извор-Сподели под исти услови 4.0] и дека се согласувам да се придржувам до [https://wikimediafoundation.org/wiki/Terms_of_Use/mk Условите на употреба].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Доколку вие не сте имател на авторските права на податотекава, или пак сакате да ја објавите под поинаква лиценца, веројатно ќе треба да се послужите со [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=mk Помошникот за подигање].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Можете да се обидете и на [[Special:Upload|страницата за подигање на {{SITENAME}}]], доколку податотеката може да се подигне под тамошните правила.",
+       "upload-form-label-own-work": "Ова е мое дело",
+       "upload-form-label-infoform-categories": "Категории",
+       "upload-form-label-infoform-date": "Датум",
+       "upload-form-label-own-work-message-local": "Потврдувам дека податотекава ја подигам во согласност со уловите на користење и правилата за лиценцирање на {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Ако не сте во можност да ја подигнете податотекава согласно правилата на {{SITENAME}}. Затворете го дијалогов и обидете се на друг начин.",
+       "upload-form-label-not-own-work-local-local": "Можете да ја пробате и [[Special:Upload|стандардната страница за подигање]].",
+       "upload-form-label-own-work-message-default": "Разбирам дека ја подигам податотекава на заедничко складиште. Потврдувам дека со тоа ги почитувам тамошните услови на користење и лиценцните правила.",
+       "upload-form-label-not-own-work-message-default": "Ако не сте во можност да ја подигнете податотекава во склад со правилата на заедничкото складиште, би ве замолиле да го затворите дијалогов и да пробате на друг начин.",
+       "upload-form-label-not-own-work-local-default": "Можете да се обидете и на [[Special:Upload|страницата за подигање на {{SITENAME}}]], доколку податотеката може да се подигне под тамошните правила.",
+       "upload-form-label-own-work-message-shared": "Сведочам дека јас сум имател на авторските права на оваа податотека, дека се согласувам дека неотповикливо ја објавувам на Ризницата под лиценцата [https://creativecommons.org/licenses/by-sa/4.0/deed.mk Криејтив комонс Наведи извор-Сподели под исти услови 4.0] и дека се согласувам да се придржувам до [https://wikimediafoundation.org/wiki/Terms_of_Use/mk Условите на употреба].",
+       "upload-form-label-not-own-work-message-shared": "Доколку вие не сте имател на авторските права на податотекава, или пак сакате да ја објавите под поинаква лиценца, веројатно ќе треба да се послужите со [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=mk Помошникот за подигање].",
+       "upload-form-label-not-own-work-local-shared": "Можете да се обидете и на [[Special:Upload|страницата за подигање на {{SITENAME}}]], доколку податотеката може да се подигне под тамошните правила.",
        "backend-fail-stream": "Не можев да ја емитувам податотеката $1.",
        "backend-fail-backup": "Не можев да направам резерва на податотеката $1.",
        "backend-fail-notexists": "Податотеката $1 не постои.",
index 560ecb0..ac0d9d2 100644 (file)
        "upload-form-label-infoform-description-tooltip": "ഈ കൃതിയെക്കുറിച്ചുള്ള ശ്രദ്ധേയമായ എല്ലാം ചുരുക്കി ചേർക്കുക.\nഒരു ഫോട്ടോയിൽ, പതിഞ്ഞിരിക്കുന്ന പ്രധാന കാര്യം, വേള, സ്ഥലം തുടങ്ങിയ വിവരങ്ങൾ ഉൾപ്പെടുത്താം.",
        "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/ ക്രിയേറ്റീവ് കോമൺസ് ആട്രിബ്യൂഷൻ-ഷെയർഎലൈക് 4.0] ഉപയോഗാനുമതിയിൽ പ്രസിദ്ധീകരിക്കാമെന്നും [https://wikimediafoundation.org/wiki/Terms_of_Use/ml ഉപയോഗനിബന്ധനകൾ] അംഗീകരിക്കുന്നുവെന്നും സാക്ഷ്യപ്പെടുത്തുന്നു.",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "ഈ പ്രമാണത്തിന്റെ പകർപ്പവകാശം താങ്കളുടെ സ്വന്തമല്ലെങ്കിൽ അഥവാ മറ്റൊരു ഉപയോഗാനുമതിയിലാണ് പ്രമാണം പ്രസിദ്ധീകരിക്കാൻ ഉദ്ദേശിക്കുന്നതെങ്കിൽ [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=ml കോമൺസിലെ അപ്‌ലോഡ് സഹായി] ഉപയോഗിക്കുന്നത് പരിഗണിക്കുക.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "ഈ പ്രമാണം അവരുടെ നയങ്ങൾക്കനുസൃതമായി അപ്‌ലോഡ് ചെയ്യാൻ സൈറ്റ് അനുവദിക്കുമെങ്കിൽ [[Special:Upload|{{SITENAME}} സംരംഭത്തിലെ അപ്‌ലോഡ് താൾ]] പരീക്ഷിച്ചു നോക്കാവുന്നതാണ്.",
+       "upload-form-label-own-work": "ഇതെന്റെ സ്വന്തം സൃഷ്ടി ആണ്",
+       "upload-form-label-infoform-categories": "വർഗ്ഗങ്ങൾ",
+       "upload-form-label-infoform-date": "തീയതി",
+       "upload-form-label-own-work-message-local": "{{SITENAME}} സംരംഭത്തിലെ സേവന നിബന്ധനകൾക്കും ഉപയോഗാനുമതി നയങ്ങൾക്കും അനുസരിച്ചാണ് ഈ പ്രമാണം അപ്‌ലോഡ് ചെയ്യുന്നതെന്ന് ഞാൻ സ്ഥിരീകരിക്കുന്നു.",
+       "upload-form-label-not-own-work-message-local": "{{SITENAME}} സംരംഭത്തിലെ നയങ്ങളനുസരിച്ച് താങ്കൾക്ക് ഈ പ്രമാണം അപ്‌ലോഡ് ചെയ്യാൻ കഴിയില്ലെങ്കിൽ, ദയവായി ഇത് അടച്ച് മറ്റൊരു മാർഗ്ഗം ശ്രമിക്കുക.",
+       "upload-form-label-not-own-work-local-local": "താങ്കൾക്ക് [[Special:Upload|സ്വതേ ഉള്ള അപ്‌ലോഡ് താളും]] പരിശോധിക്കാവുന്നതാണ്.",
+       "upload-form-label-own-work-message-default": "ഈ പ്രമാണം പങ്ക് വെയ്ക്കപ്പെട്ടിരിക്കുന്ന ഒരു ശേഖരത്തിലോട്ടാണ് അപ്‌ലോഡ് ചെയ്യുന്നതെന്ന് ഞാൻ മനസ്സിലാക്കുന്നു. അവിടുത്തെ ഉപയോഗ നിബന്ധനകൾക്കും അനുമതി നയങ്ങൾക്കും അനുസൃതമായാണ് ഇത് ചെയ്യുന്നതെന്ന് ഞാൻ സ്ഥിരീകരിക്കുന്നു.",
+       "upload-form-label-not-own-work-message-default": "പങ്ക് വെയ്ക്കപ്പെട്ടിരിക്കുന്ന ശേഖരത്തിന്റെ നയങ്ങളനുസരിച്ച് താങ്കൾക്ക് ഈ പ്രമാണം അപ്‌ലോഡ് ചെയ്യാൻ കഴിയില്ലെങ്കിൽ, ദയവായി ഇത് അടക്കുകയും മറ്റൊരു മാർഗ്ഗം ശ്രമിക്കുകയും ചെയ്യുക.",
+       "upload-form-label-not-own-work-local-default": "ഈ പ്രമാണം അവരുടെ നയങ്ങളുമായി ചേർന്നുപോകുമെങ്കിൽ താങ്കൾക്ക് [[Special:Upload|{{SITENAME}} സംരംഭത്തിലെ അപ്‌ലോഡ് താൾ]] പരീക്ഷിച്ചു നോക്കാവുന്നതാണ്.",
+       "upload-form-label-own-work-message-shared": "ഈ പ്രമാണത്തിന്റെ പകർപ്പവകാശം എനിക്ക് സ്വന്തമാണെന്നും, ഈ പ്രമാണം വിക്കിമീഡിയ കോമൺസിൽ പിന്നീട് മാറ്റാനാവത്തവിധം [https://creativecommons.org/licenses/by-sa/4.0/ ക്രിയേറ്റീവ് കോമൺസ് ആട്രിബ്യൂഷൻ-ഷെയർഎലൈക് 4.0] ഉപയോഗാനുമതിയിൽ പ്രസിദ്ധീകരിക്കാമെന്നും [https://wikimediafoundation.org/wiki/Terms_of_Use/ml ഉപയോഗനിബന്ധനകൾ] അംഗീകരിക്കുന്നുവെന്നും സാക്ഷ്യപ്പെടുത്തുന്നു.",
+       "upload-form-label-not-own-work-message-shared": "ഈ പ്രമാണത്തിന്റെ പകർപ്പവകാശം താങ്കളുടെ സ്വന്തമല്ലെങ്കിൽ അഥവാ മറ്റൊരു ഉപയോഗാനുമതിയിലാണ് പ്രമാണം പ്രസിദ്ധീകരിക്കാൻ ഉദ്ദേശിക്കുന്നതെങ്കിൽ [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=ml കോമൺസിലെ അപ്‌ലോഡ് സഹായി] ഉപയോഗിക്കുന്നത് പരിഗണിക്കുക.",
+       "upload-form-label-not-own-work-local-shared": "ഈ പ്രമാണം അവരുടെ നയങ്ങൾക്കനുസൃതമായി അപ്‌ലോഡ് ചെയ്യാൻ സൈറ്റ് അനുവദിക്കുമെങ്കിൽ [[Special:Upload|{{SITENAME}} സംരംഭത്തിലെ അപ്‌ലോഡ് താൾ]] പരീക്ഷിച്ചു നോക്കാവുന്നതാണ്.",
        "backend-fail-stream": "$1 എന്ന പ്രമാണം സ്ട്രീം ചെയ്യാൻ കഴിഞ്ഞില്ല.",
        "backend-fail-backup": "$1 എന്ന പ്രമാണത്തിന്റെ ബാക്ക്അപ് എടുക്കാൻ കഴിഞ്ഞില്ല.",
        "backend-fail-notexists": "$1 എന്ന പ്രമാണം നിലവിലില്ല.",
index a4e9ab6..ed1ae3c 100644 (file)
        "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": "दिनांक",
+       "upload-form-label-own-work": "हे माझे स्वत:चे काम आहे",
+       "upload-form-label-infoform-categories": "वर्ग",
+       "upload-form-label-infoform-date": "दिनांक",
        "backend-fail-stream": "$1 या संचिकेचा स्त्रोत शोधता आला नाही.",
        "backend-fail-backup": "$1 या संचिकेची आधारप्रत बनविता आली नाही.",
        "backend-fail-notexists": "$1 ही संचिका अस्तित्वात नाही.",
        "logentry-protect-protect-cascade": "$1 ने $3 $4 [निपतन]ला {{GENDER:$2|सुरक्षित केले}}",
        "logentry-protect-modify": "$1 ने $3 $4 ची  सुरक्षा पातळी {{GENDER:$2|बदलली}}",
        "logentry-protect-modify-cascade": "$1 ने $3 $4 [निपतन]ची  सुरक्षा पातळी {{GENDER:$2|बदलली}}",
-       "logentry-rights-rights": "$1 ने $3 साठी $4 वरुन $5 ला गट सदस्यता{{GENDER:$2|बदलली}}",
+       "logentry-rights-rights": "$1 ने {{GENDER:$6|$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 {{GENDER:$2|अपभारीत केली}} $3",
        "api-error-nomodule": "अंतर्गत चूक: module set चढवलेला नाही",
        "api-error-ok-but-empty": "आंतरिक त्रुटी : विदादाता प्रतिक्रिया देत नहीं",
        "api-error-overwrite": "अस्तित्वात असलेल्या संचिकेवर पुनर्लेखन प्रतिबंधित आहे.",
+       "api-error-ratelimited": "आपण, हा विकी परवानगी देत असल्यापेक्षा अधिक संचिका, कमी कालावधीत अपभारणाचा प्रयत्न करीत आहात.\nकाही मिनिटांनी पुन्हा प्रयत्न करा.",
        "api-error-stashfailed": "इन्तरिक त्रुटी : विदादाता तात्पुरत्या स्वरूपाच्या संचिका जमा करण्यात अयशस्वी",
        "api-error-publishfailed": "अंतर्गत त्रुटी:विदादात्यास, या तात्पुरत्या संचिकेच्या प्रकाशनास अपयश आले.",
        "api-error-stasherror": "स्टॅचमध्ये ही संचिका अपभारणात त्रुटी आली.",
index d4b395e..221b3bb 100644 (file)
        "upload-form-label-infoform-description": "Keterangan",
        "upload-form-label-usage-title": "Penggunaan",
        "upload-form-label-usage-filename": "Nama fail",
-       "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]].",
+       "upload-form-label-own-work": "Ini ialah karya saya sendiri",
+       "upload-form-label-infoform-categories": "Kategori",
+       "upload-form-label-infoform-date": "Tarikh",
+       "upload-form-label-own-work-message-local": "Saya mengesahkan bahawa saya memuat naik fail ini dengan mengikut terma perkhidmatan dan dasar perlesenan di {{SITENAME}}.",
+       "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.",
        "backend-fail-notexists": "Fail $1 tidak wujud.",
index ed896a5..6b6edce 100644 (file)
        "badtitle": "M̄-chiâⁿ piau-tê",
        "badtitletext": "Iau-kiû ê piau-tê sī bô-hāu ê, khang ê, a̍h-sī liân-kiat chhò-gō· ê inter-language/inter-wiki piau-tê.",
        "title-invalid-empty": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k sī khang--ê he̍k-chiá kaⁿ-taⁿ hâm liáu miâ-khong-kan.",
-       "title-invalid-utf8": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k hâm liáu bô chiàⁿ-khak ê 1 lia̍t UTF-8 jī.",
+       "title-invalid-utf8": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k hâm liáu bô chiàⁿ-khak ê 1 lia̍t UTF-8 ê jī.",
        "title-invalid-interwiki": "Só͘ iau-kiû ê ia̍h-bīn tê-bo̍k pau-hâm liáu 1-ê bē-tàng ēng ùi tê-bo̍k ê interwiki liân-kiat.",
        "perfcached": "Ē-kha ê chu-liāu tùi lâi--ê, só·-í bô it-tēng sī siōng sin ê. Tī khoài-chhûn-khu siōng chē ē-tàng khǹg{{PLURAL:$1| pit|$1 pit}} chu-liāu.",
        "perfcachedts": "Ē-kha ê chu-liāu tùi lâi--ê, tī $1 keng-sin--koè. Tī khoài-chûn-khu siōng chē ē-tàng khǹg {{PLURAL:$4|pit|$4 pit}} chu-liāu.",
        "sp-contributions-submit": "Chhoē",
        "whatlinkshere": "Tó-ūi liân kàu chia",
        "whatlinkshere-title": "Liân khì \"$1\" ê ia̍h-bīn",
-       "whatlinkshere-page": "頁:",
+       "whatlinkshere-page": "Ia̍h:",
        "linkshere": "Í-hā '''[[:$1]]''' liân kàu chia:",
        "nolinkshere": "Bô poàⁿ ia̍h liân kàu '''[[:$1]]'''.",
        "isredirect": "choán-ia̍h",
        "tooltip-ca-viewsource": "Chit ia̍h pó-hō͘ tiâu leh.\nLí ē-sái khoàⁿ i ê goân-sú-bé.",
        "tooltip-ca-history": "Chit ia̍h ê chá-chêng pán-pún",
        "tooltip-ca-delete": "Thâi chit ia̍h",
-       "tooltip-ca-move": "徙這頁",
+       "tooltip-ca-move": "Sóa chit ia̍h",
        "tooltip-ca-watch": "共這頁加入去你的監視單",
        "tooltip-ca-unwatch": "Lí ê kàm-sī-toaⁿ soá tiàu chit ia̍h.",
        "tooltip-search": "Chhoé {{SITENAME}}",
        "tooltip-diff": "Hián-sī lí tùi bûn-pún só͘ chò ê kái-tōng",
        "tooltip-watch": "共這頁加入去你的監視單",
        "tooltip-rollback": "Ji̍h \"Hoê-choán\" ē-sái thè tńg-khì téng-chi̍t-ê kái ê lâng ê ia̍h.",
-       "tooltip-preferences-save": "保存設定",
+       "tooltip-preferences-save": "Pó-chûn siat-tēng",
        "tooltip-summary": "Siá chi̍t-ê kán-tan soat-bêng",
        "anonymous": "{{SITENAME}} bô kì-miâ ê iōng-chiá",
        "siteuser": "{{SITENAME}} iōng-chiá $1",
index dbd48f3..6d43901 100644 (file)
        "minoredit": "Chisto è nu cagnamiénto piccerillo",
        "watchthis": "Tiene d'uocchio sta paggena",
        "savearticle": "Sarva 'a paggena",
+       "publishpage": "Pubbreca paggena",
        "preview": "Anteprimma",
        "showpreview": "Vire anteprimma",
        "showdiff": "Fa veré 'e cagnamiente",
        "userpage-userdoesnotexist": "'O cunto utente \"<nowiki>$1</nowiki>\" nun è riggistrato. Cuntrolla ca si buò overo crià o cagnà sta paggena.",
        "userpage-userdoesnotexist-view": "'O cunto utente \"$1\" nun è riggistrato.",
        "blocked-notice-logextract": "St'utente è bloccato mò.\nL'urdemo elemento d' 'o riggistro 'e blocche è ripurtato ccà abbascio p'avé nu riferimento:",
-       "clearyourcache": "'''Nota:''' aroppo sarvate putisse necessità 'e pulezzà 'a caché d' 'o navigatóre pe' vedé 'e cagnamiente. \n*'''Firefox / Safari''': sprémme 'o buttóne maiuscole e ffà clic ncopp'a ''Recarreca'', o pure spremme ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' ncopp'a Mac)\n*'''Google Chrome''': spremme ''Ctrl-Shift-R'' (''⌘-Shift-R'' ncopp'a nu Mac)\n*'''Internet Explorer''': spremme 'o buttóne ''Ctrl'' pe' tramente ca faie click ncopp'a ''Refresh'', o pure spremmere ''Ctrl-F5''\n*'''Opera''': sbacanta tutt' 'a cache addò menu ''Strumiente → Preferenze''",
+       "clearyourcache": "<strong>Nota:</strong> aroppo sarvate putisse necessità 'e pulezzà 'a caché d' 'o navigatóre pe' vedé 'e cagnamiente. \n*<strong>Firefox / Safari</strong>: sprémme 'o buttóne maiuscole e ffà clic ncopp'a ''Recarreca'', o pure spremme ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' ncopp'a Mac)\n*<strong>Google Chrome''': spremme ''Ctrl-Shift-R'' (''⌘-Shift-R'' ncopp'a nu Mac)\n*<strong>Internet Explorer</strong>: spremme 'o buttóne ''Ctrl'' pe' tramente ca faie click ncopp'a ''Refresh'', o pure spremmere ''Ctrl-F5''\n* <strong>Opera:</strong> Vaje addò 'o <em>Menu → Mpustaziune</em> (<em>Opera → Mpustaziune</em> ncopp' 'o Mac) e po' ncopp'a <em>Privacy & sicurezza → Pulezza date d' 'o browser → Immaggene e file d' 'a cache</em>.",
        "usercssyoucanpreview": "'''Cunziglio:''' spremme 'o buttone 'Vide anteprimma' pe' pruvà 'o CSS nuovo apprimma d' 'o sarvà.",
        "userjsyoucanpreview": "'''Cunziglio:''' spremme 'o buttone 'Vide anteprimma' pe' pruvà 'o JavaScript nuovo apprimma d' 'o sarvà.",
        "usercsspreview": "'''Arricuordate ca chest'è sulamente n'anteprimma p' 'o CSS perzunale. 'E cagnamiente nun so' state ancora sarvate!'''",
        "upload-form-label-infoform-description-tooltip": "Facite 'a descriziona sintetica 'e tuttuquanto fosse degno 'e nota a proposito 'e st'opera. P' 'e foto, facite assapé 'e ccosi principale ca songo rappresentate, l'accasione e/o luogo dint' 'o quale so' state scattate.",
        "upload-form-label-usage-title": "Aúso",
        "upload-form-label-usage-filename": "Nomme d' 'o file",
-       "foreign-structured-upload-form-label-own-work": "Chest'è fatica mia",
-       "foreign-structured-upload-form-label-infoform-categories": "Categurìe",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Io cunfermo ca songh'io ca carrecanno stu file sto secutanno 'e tiermene 'e servizio e pulitiche 'e licienza dint'a {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Si nun site capace 'e carrecà stu file pe' bbìa d' 'e pulitiche 'e {{SITENAME}}, pe' piacere nchiurete sta casciulella e tentate n'ata maniera.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Forse vulite pure tentà [[Special:Upload|'a paggena 'e carreche predefinita]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Capisco ca sto a carrecà stu file a nu repositorio spartuto. Cunfermo ca facenno chesto sto secutanno 'e tèrmene 'e servizio e licienze llanno.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Si nun site capace 'e carrecà stu file pe' bbìa d' 'e pulitiche d' 'o repusitorio spartuto, pe' piacere nchiurete sta casciulella e tentate n'ata maniera.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Putite pure tentà 'ausà [[Special:Upload|'a paggena 'e carreche 'e {{SITENAME}}]], si stu file nun se putesse carrecà llanno pe' bbìa d' 'e pulitiche.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Faccio attestato ca songo 'o detentore d' 'o copyright 'e stu file, e so' d'accordo 'e lassà irrevocabbelmente stu file a Wikimedia Commons sott'a licienza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribuziona-SparteEguale 4.0], e so' d'accordo cu sti [https://wikimediafoundation.org/wiki/Terms_of_Use Termene d'Uso].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Si nun tenite 'o copyright 'e stu file, o pure 'o vulite lassà libbero cu n'ata licienza, cunziderate 'ausà 'o [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Putite pure tentà 'e ausà [[Special:Upload|'a paggena 'e carreche 'e {{SITENAME}}]], si stu sito ve premmettesse 'e carrecà llanno pe' bbìa d' 'e pulitiche.",
+       "upload-form-label-own-work": "Chest'è fatica mia",
+       "upload-form-label-infoform-categories": "Categurìe",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Io cunfermo ca songh'io ca carrecanno stu file sto secutanno 'e tiermene 'e servizio e pulitiche 'e licienza dint'a {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Si nun site capace 'e carrecà stu file pe' bbìa d' 'e pulitiche 'e {{SITENAME}}, pe' piacere nchiurete sta casciulella e tentate n'ata maniera.",
+       "upload-form-label-not-own-work-local-local": "Forse vulite pure tentà [[Special:Upload|'a paggena 'e carreche predefinita]].",
+       "upload-form-label-own-work-message-default": "Capisco ca sto a carrecà stu file a nu repositorio spartuto. Cunfermo ca facenno chesto sto secutanno 'e tèrmene 'e servizio e licienze llanno.",
+       "upload-form-label-not-own-work-message-default": "Si nun site capace 'e carrecà stu file pe' bbìa d' 'e pulitiche d' 'o repusitorio spartuto, pe' piacere nchiurete sta casciulella e tentate n'ata maniera.",
+       "upload-form-label-not-own-work-local-default": "Putite pure tentà 'ausà [[Special:Upload|'a paggena 'e carreche 'e {{SITENAME}}]], si stu file nun se putesse carrecà llanno pe' bbìa d' 'e pulitiche.",
+       "upload-form-label-own-work-message-shared": "Faccio attestato ca songo 'o detentore d' 'o copyright 'e stu file, e so' d'accordo 'e lassà irrevocabbelmente stu file a Wikimedia Commons sott'a licienza [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribuziona-SparteEguale 4.0], e so' d'accordo cu sti [https://wikimediafoundation.org/wiki/Terms_of_Use Termene d'Uso].",
+       "upload-form-label-not-own-work-message-shared": "Si nun tenite 'o copyright 'e stu file, o pure 'o vulite lassà libbero cu n'ata licienza, cunziderate 'ausà 'o [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
+       "upload-form-label-not-own-work-local-shared": "Putite pure tentà 'e ausà [[Special:Upload|'a paggena 'e carreche 'e {{SITENAME}}]], si stu sito ve premmettesse 'e carrecà llanno pe' bbìa d' 'e pulitiche.",
        "backend-fail-stream": "Nun se può mannà 'o file \"$1\".",
        "backend-fail-backup": "Nun se può ffà 'o backup d' 'o file \"$1\".",
        "backend-fail-notexists": "'O file $1 nun esiste.",
        "tooltip-ca-nstab-category": "Vere a paggena d\"a categurìa",
        "tooltip-minoredit": "Rénne chìsto cagnamiénto cchiù ppiccirìllo.",
        "tooltip-save": "Sàrva 'e cagnamiénte.",
+       "tooltip-publish": "Pubbreca 'e cagnamiente vuoste",
        "tooltip-preview": "Primma 'e sarvà, vìre primma chille ca hê cagnàte!",
        "tooltip-diff": "Fà vedé 'e cagnamiente c'avite fatto ô testo",
        "tooltip-compareselectedversions": "Fà vedé 'e differenze nfra tutt' 'e dduje verziune scigliute 'e sta paggena",
        "feedback-useragent": "Aggente utente:",
        "searchsuggest-search": "Truova",
        "searchsuggest-containing": "tène...",
+       "api-error-autoblocked": "Ll'indirizzo IP d' 'o vuosto è stato bloccato automaticamente, pecché a nu mumento l'ausaje n'utenza bloccata.",
        "api-error-badaccess-groups": "Tun putite carrecà file ncopp' 'a sta wiki.",
        "api-error-badtoken": "Errore interno: 'O token nun è buono.",
+       "api-error-blocked": "Site stato/a bloccato/a, nun putite ffà cagnamiente.",
        "api-error-copyuploaddisabled": "'A funzione carrcà 'e n'URL nun è appicciata dint'a stu server.",
        "api-error-duplicate": "Nce {{PLURAL:$1|sta è n'atu file|stanno ati file}} ncopp' 'o sito ch' 'e cuntenute eguale eguale.",
        "api-error-duplicate-archive": "Nce {{PLURAL:$1|steva n'atu file|stevano ati file}} già ncopp' 'o sito ch' 'e stisse cuntenute, però {{PLURAL:$1|è stato|so' state}} scancellate.",
        "api-error-nomodule": "Errore interno: Nisciuno modulo 'e carreca mpustato.",
        "api-error-ok-but-empty": "Errore interno: Nisciuna resposta 'a 'o server.",
        "api-error-overwrite": "Sovrascrivere nu file ch'esiste già nun è permesso.",
+       "api-error-ratelimited": "Vuje avite tntato 'e carrecà cchiù file dint'a nu mumento curt' 'e tiempo ca sta wiki premmettesse.\nPe' piacere, tentate n'ata vota int'a nu poch' 'e minute.",
        "api-error-stashfailed": "Errore interno: 'O server nun ngarraje a s'astipà 'o file temporaneo.",
        "api-error-publishfailed": "Errore interno: 'O server nun ngarraje a pubbrecà 'o file temporaneo.",
        "api-error-stasherror": "'A carreca d' 'o file 'n stash è asciuta male, ce sta n'errore.",
index d3ec649..575ba2d 100644 (file)
        "upload-form-label-infoform-description": "Beskrivelse",
        "upload-form-label-usage-title": "Bruk",
        "upload-form-label-usage-filename": "Filnavn",
-       "foreign-structured-upload-form-label-own-work": "Dette er mitt eget verk",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorier",
-       "foreign-structured-upload-form-label-infoform-date": "Dato",
-       "foreign-structured-upload-form-label-own-work-message-local": "Jeg bekrefter at jeg ved å laste opp denne filen følger bruksvilkårene og lisensieringspolitikken på {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Hvis filen ikke lar seg laste opp under {{SITENAME}}s politikk må du lukke denne dialogboksen og prøve en annen metode.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Jeg forstår at jeg laster opp denne filen til et delt arkiv. Jeg bekrefter at dette gjøres i tråd med bruksvilkårene og lisensieringspolitikken der.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Hvis filen ikke lar seg laste opp under arkivets politikk må du lukke denne dialogboksen og prøve en annen metode.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden]] på {{SITENAME}} hvis filen kan lastes opp under politikken som gjelder der.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Jeg bekrefter at jeg har opphavsretten til denne filen, samtykker til å ugjenkallelig slippe filen til Wikimedia Commons under lisensen [https://creativecommons.org/licenses/by-sa/4.0/deed.no Creative Commons Navngivelse-DelPåSammeVilkår 4.0], og samtykker til [https://wikimediafoundation.org/wiki/Terms_of_Use bruksvilkårene].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Hvis du ikke sitter på opphavsretten til filen, eller ønsker å slippe den under en annen lisens, prøv [https://commons.wikimedia.org/wiki/Special:UploadWizard Opplastingsveiviseren på Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden på {{SITENAME}}]] hvis filen kan lastes opp under politikken som gjelder der.",
+       "upload-form-label-own-work": "Dette er mitt eget verk",
+       "upload-form-label-infoform-categories": "Kategorier",
+       "upload-form-label-infoform-date": "Dato",
+       "upload-form-label-own-work-message-local": "Jeg bekrefter at jeg ved å laste opp denne filen følger bruksvilkårene og lisensieringspolitikken på {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Hvis filen ikke lar seg laste opp under {{SITENAME}}s politikk må du lukke denne dialogboksen og prøve en annen metode.",
+       "upload-form-label-not-own-work-local-local": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden]].",
+       "upload-form-label-own-work-message-default": "Jeg forstår at jeg laster opp denne filen til et delt arkiv. Jeg bekrefter at dette gjøres i tråd med bruksvilkårene og lisensieringspolitikken der.",
+       "upload-form-label-not-own-work-message-default": "Hvis filen ikke lar seg laste opp under arkivets politikk må du lukke denne dialogboksen og prøve en annen metode.",
+       "upload-form-label-not-own-work-local-default": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden]] på {{SITENAME}} hvis filen kan lastes opp under politikken som gjelder der.",
+       "upload-form-label-own-work-message-shared": "Jeg bekrefter at jeg har opphavsretten til denne filen, samtykker til å ugjenkallelig slippe filen til Wikimedia Commons under lisensen [https://creativecommons.org/licenses/by-sa/4.0/deed.no Creative Commons Navngivelse-DelPåSammeVilkår 4.0], og samtykker til [https://wikimediafoundation.org/wiki/Terms_of_Use bruksvilkårene].",
+       "upload-form-label-not-own-work-message-shared": "Hvis du ikke sitter på opphavsretten til filen, eller ønsker å slippe den under en annen lisens, prøv [https://commons.wikimedia.org/wiki/Special:UploadWizard Opplastingsveiviseren på Commons].",
+       "upload-form-label-not-own-work-local-shared": "Du kan eventuelt forsøke [[Special:Upload|den ordinære opplastingssiden på {{SITENAME}}]] hvis filen kan lastes opp under politikken som gjelder der.",
        "backend-fail-stream": "Kunne ikke strømme filen $1.",
        "backend-fail-backup": "Kunne ikke sikkerhetskopiere filen $1.",
        "backend-fail-notexists": "Filen $1 finnes ikke.",
index 6703121..bee6f50 100644 (file)
        "morenotlisted": "Disse lieste is niet kompleet...",
        "mypage": "Gebrukerszied",
        "mytalk": "Mien overleg",
-       "anontalk": "Overlegzied veur dit IP-adres",
+       "anontalk": "Overleg",
        "navigation": "Navigasie",
        "and": "&#32;en",
        "qbfind": "Zeuken",
        "viewsource": "Brontekste bekieken",
        "viewsource-title": "Bron bekieken van $1",
        "actionthrottled": "Haandeling tegenehöllen",
-       "actionthrottledtext": "As maotregel tegen t plaotsen van ongewunste verwiezingen, is t antal keren da'j disse haandeling in n korte tied uutvoeren kunnen beteund. Je hebben de limiet overschrejen. Probeer t over n antal minuten weer.",
+       "actionthrottledtext": "As maotregel tegen t plaotsen van alderhaande moek, is t antal keren da'j disse haandeling in n korte tied uutvoeren kunnen beteund. Je hebben de limiet overschrejen. Probeer t over n antal minuten weer.",
        "protectedpagetext": "Disse zied is beveiligd. Bewarken of aandere haandelingen bin niet meugelik.",
-       "viewsourcetext": "Je kunnen de brontekste van disse zied bewarken en bekieken:",
-       "viewyourtext": "Je kunnen '''joew bewarkingen''' an de brontekste van disse zied bekieken en kopiëren:",
+       "viewsourcetext": "Je kunnen de brontekste van disse zied bewarken en bekieken.",
+       "viewyourtext": "Je kunnen <strong>joew bewarkingen</strong> an de brontekste van disse zied bekieken en kopiëren.",
        "protectedinterface": "Op disse zied steet tekste die gebruukt wördt veur systeemteksten van disse wiki. Allinnig beheerders kunnen disse zied bewarken.\nUm vertalingen veur alle wiki's derbie te zetten of te wiezigen, gebruuk [//translatewiki.net/ translatewiki.net], t vertaalprojekt veur MediaWiki.",
        "editinginterface": "<strong>Waorschuwing:</strong> je bewarken n zied die gebruukt wörden deur de programmatuur. Wa'j hier wiezigen, is van invleud op de hele wiki. Um vertalingen derbie te zetten of te wiezigen veur alle wiki's, gebruuk [//translatewiki.net/wiki/Main_Page?setlang=nds-nl translatewiki.net], t vertalingsprojekt veur MediaWiki.",
        "cascadeprotected": "Disse zied is beveiligd umdat t veurkömp in de volgende {{PLURAL:$1|zied|ziejen}}, die beveiligd {{PLURAL:$1|is|bin}} mit de \"kaskade\"-opsie:\n$2",
        "mypreferencesprotected": "Je hebben gien rechten um joew veurkeuren an te passen.",
        "ns-specialprotected": "Spesiale ziejen kunnen niet bewarkt wörden.",
        "titleprotected": "t Anmaken van disse zied is beveiligd deur [[User:$1|$1]].\nDe op-egeven reden is <em>$2</em>.",
-       "filereadonlyerror": "Kon t bestaand \"$1\" niet anpassen umdat de bestaandsmap \"$2\" op dit moment op allinnig-lezen steet.\n\nDe beheerder gaf hierveur de volgende reden: \"$3\".",
+       "filereadonlyerror": "Kon t bestaand \"$1\" niet anpassen umdat de bestaandsmap \"$2\" op dit moment op allinnig-lezen steet.\n\nDe op-egeven reden is: \"$3\".",
        "invalidtitle-knownnamespace": "Ongeldige titel mit naamruumte \"$2\" en tekste \"$3\"",
        "invalidtitle-unknownnamespace": "Ongeldige titel mit onbekend naamruumtenummer $1 en tekste \"$2\"",
        "exception-nologin": "Niet an-emeld",
        "createacct-reason": "Reden",
        "createacct-reason-ph": "Waorumme je n aandere gebrukerskonto anmaken",
        "createacct-submit": "Gebrukerskonto anmaken",
-       "createacct-another-submit": "n Aandere gebrukerskonto anmaken",
+       "createacct-another-submit": "Gebrukerskonto anmaken",
        "createacct-benefit-heading": "{{SITENAME}} wörden emaakt deur meensen zo as jie.",
        "createacct-benefit-body1": "bewarking{{PLURAL:$1||en}}",
        "createacct-benefit-body2": "{{PLURAL:$1|zied|ziejen}}",
        "nocookieslogin": "t Anmelden is mislokt umdat de webkieker gien scheumbestaanden (cookies) an hef staon. Probeer t aksepteren van scheumbestaanden an te zetten en daornao opniej an te melden.",
        "nocookiesfornew": "De gebruker is niet an-emaakt, umdat de bron niet bevestigd kon wörden.\nZörg derveur da'j scheumbestaanden (cookies) an hebben staon, herlaoi disse zied en probeer t opniej.",
        "noname": "Je mutten n gebrukersnaam opgeven.",
-       "loginsuccesstitle": "Suksesvol an-emeld",
+       "loginsuccesstitle": "An-emeld",
        "loginsuccess": "Je bin noen an-emeld bie {{SITENAME}} as \"$1\".",
        "nosuchuser": "Der is gien gebruker mit de naam \"$1\".\nGebrukersnamen bin heufdlettergeveulig.\nKiek de schriefwieze effen nao of [[Special:UserLogin/signup|maak n nieje gebruker an]].",
        "nosuchusershort": "Der is gien gebruker mit de naam \"$1\". Kiek de spelling nao.",
        "createaccount-title": "Gebrukers anmaken veur {{SITENAME}}",
        "createaccount-text": "Der hef der ene n gebruker an-emaakt op {{SITENAME}} ($4), mit de naam $2 en t wachtwoord \"$3\". \nMeld je eigen noen an en wiezig t wachtwoord.\n\nNegeer dit bericht as disse gebruker zonder joew toestemming an-emaakt is.",
        "login-throttled": "Je hebben lestens te vake eprobeerd um an te melden mit n verkeerd wachtwoord.\nJe mutten effen $1 wachten veurda'j t opniej proberen.",
-       "login-abort-generic": "Je bin niet an-emeld. De procedure is aofebreuken.",
+       "login-abort-generic": "Je bin niet an-emeld - Aofebreuken",
        "loginlanguagelabel": "Taal: $1",
        "suspicious-userlogout": "Joew verzeuk um of te melden is aofewezen umdat t dernaor uutziet dat t verstuurd is deur n kepotte webkieker of tussenopslagbuffer",
        "createacct-another-realname-tip": "Joew echte naam opgeven is niet verplicht.\nA'j t invullen, dan zu'w t gebruken um erkenning te geven veur joew warkzaamhejen.",
        "passwordreset-emailtext-ip": "Der hef der ene, waorschienlik jie zelf vanaof t IP-adres $1, n anvraag edaon um joew wachtwoord veur {{SITENAME}} ($4) opniej in te stellen.\nDe volgende {{PLURAL:$3|gebruker is|gebrukers bin}} ekoppeld an dit netpostadres:\n\n$2\n\n{{PLURAL:$3|Dit tiejelike wachtwoord vervölt|Disse tiejelike wachtwoorden vervallen}} over {{PLURAL:$5|één dag|$5 dagen}}.\nMeld je eigen noen an en wiezig t wachtwoord. A'j dit verzeuk niet zelf edaon hebben, of a'j t oorspronkelike wachtwoord nog kennen en t niet wiezigen willen, negeer dit bericht dan en blief joew ouwe wachtwoord gebruken.",
        "passwordreset-emailtext-user": "De gebruker $1 van {{SITENAME}} hef n anvraag edaon um joew wachtwoord veur {{SITENAME}} ($4) opniej in te stellen. \nDe volgende {{PLURAL:$3|gebruker is|gebrukers bin}} ekoppeld an dit netpostadres:\n\n$2\n\n{{PLURAL:$3|Dit tiejelike wachtwoord vervölt|Disse tiejelike wachtwoorden vervallen}} over {{PLURAL:$5|één dag|$5 dagen}}.\nMeld je eigen noen an en wiezig t wachtwoord. A'j dit verzeuk niet zelf edaon hebben, of a'j t oorspronkelike wachtwoord nog kennen en t niet wiezigen willen, negeer dit bericht dan en blief joew ouwe wachtwoord gebruken.",
        "passwordreset-emailelement": "Gebrukersnaam: \n$1\n\nTiedelik wachtwoord: \n$2",
-       "passwordreset-emailsentemail": "Der is n bericht verstuurd um t wachtwoord opniej in te stellen.",
+       "passwordreset-emailsentemail": "As dit netpostadres an joew gebrukerskonto ekoppeld is, dan wördt der n netbericht estuurd um joew wachtwoord opniej in te stellen.",
        "passwordreset-emailsent-capture": "Der is n bericht verstuurd um joew wachtwoord opniej in te stellen. Dit ku'j hieronder lezen.",
        "passwordreset-emailerror-capture": "Der is n bericht veur t opniej opstellen van joew wachwoord an-emaakt, dit ku'j hieronder lezen. t Versturen naor de {{GENDER:$2|gebruker}} is mislokt um de volgende reden: $1",
-       "changeemail": "Wiezig netpostadres",
-       "changeemail-header": "Netpostadres wiezigen",
+       "changeemail": "Netpostadres wiezigen of vorthaolen",
+       "changeemail-header": "Vul dit formulier in um joew netpostadres te wiezigen. A'j t netpostadres van disse gebrukerskonto ontkoppelen willen, laot t netpostadres dan leeg a'j t formulier opslaon.",
        "changeemail-no-info": "Je mutten an-emeld ween um drekt toegang te hebben tot disse zied.",
        "changeemail-oldemail": "t Ouwe netpostadres:",
        "changeemail-newemail": "t Nieje netpostadres:",
        "anonpreviewwarning": "''Je bin niet an-emeld.''\n''Deur de bewarking op te slaon wörden joew IP-adres op-esleugen in de ziedgeschiedenisse.''",
        "missingsummary": "'''Herinnering:''' je hebben gien samenvatting op-egeven veur de bewarking. A'j noen weer op ''Opslaon'' klikken wörden de bewarking zonder samenvatting op-esleugen.",
        "missingcommenttext": "Plaots joew opmarking hieronder.",
-       "missingcommentheader": "'''Waorschuwing:''' je hebben der gien onderwarptitel bie ezet. A'j noen weer op \"{{int:savearticle}}\" klikken, dan wörden de bewarking op-esleugen zonder onderwarptitel.",
+       "missingcommentheader": "<strong>Waorschuwing:</strong> je hebben der gien onderwarptitel bie ezet. A'j noen weer op \"{{int:savearticle}}\" klikken, dan wörden de bewarking op-esleugen zonder onderwarptitel.",
        "summary-preview": "Samenvatting naokieken:",
-       "subject-preview": "Onderwarp/kop naokieken:",
+       "subject-preview": "Onderwarp naokieken:",
        "blockedtitle": "Gebruker is eblokkeerd",
        "blockedtext": "'''Joew gebrukersnaam of IP-adres is eblokkeerd.'''\n\nJe bin eblokkeerd deur: $1.\nDe op-egeven reden is: ''$2''.\n\n* Eblokkeerd vanaof: $8\n* Eblokkeerd tot: $6\n* Bedoeld um te blokkeren: $7\n\nJe kunnen kontakt opnemen mit $1 of n aandere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] um de blokkering te bepraoten.\nJe kunnen gien gebruukmaken van de funksie 'een bericht sturen', behalven a'j n geldig netpostadres op-egeven hebben in joew [[Special:Preferences|veurkeuren]] en t gebruuk van disse funksie niet eblokkeerd is.\nt IP-adres da'j noen gebruken is $3 en t blokkeringsnummer is #$5.\nVermeld t allebeie a'j argens op disse blokkering reageren.",
        "autoblockedtext": "Joew IP-adres is automaties eblokkeerd umdat t gebruukt wördt deur n aandere gebruker, die eblokkeerd wördt deur $1.\nDe reden hierveur was:\n\n:''$2''\n\n* Begint: $8\n* Löp of nao: $6\n* Wee eblokkeerd wördt: $7\n\nJe kunnen kontakt opnemen mit $1 of n van de aandere\n[[{{MediaWiki:Grouppage-sysop}}|beheerders]] um de blokkering te bepraoten.\n\nNB: je kunnen de opsie \"n bericht sturen\" niet gebruken, behalven a'j n geldig netpostadres op-egeven hebben in de [[Special:Preferences|gebrukersveurkeuren]] en je niet eblokkeerd bin.\n\nJoew IP-adres is $3 en joew blokkeernummer is $5.\nGeef disse nummers deur a'j kontakt mit ene opnemen over de blokkering.",
        "prefs-watchlist-token": "Volgliestesleutel",
        "prefs-misc": "Overig",
        "prefs-resetpass": "Wachtwoord wiezigen",
-       "prefs-changeemail": "Netpostadres wiezigen",
+       "prefs-changeemail": "Netpostadres wiezigen of vorthaolen",
        "prefs-setemail": "Stel n netpostadres in",
        "prefs-email": "Instellingen veur netpost",
        "prefs-rendering": "Ziedweergave",
        "rows": "Regels",
        "columns": "Kolommen",
        "searchresultshead": "Zeukresultaoten",
-       "stub-threshold": "Verwiezingsformattering van <a href=\"#\" class=\"stub\">beginnetjes</a>:",
+       "stub-threshold": "Verwiezingsformattering van beginnetjes ($1):",
+       "stub-threshold-sample-link": "veurbeeld",
        "stub-threshold-disabled": "uutezet",
        "recentchangesdays": "Antal dagen die \"Leste wiezigingen\" löt zien:",
        "recentchangesdays-max": "(hooguut $1 {{PLURAL:$1|dag|dagen}})",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Beheerder",
        "grouppage-bureaucrat": "{{ns:project}}:Beheerder",
-       "grouppage-suppress": "{{ns:project}}:Toezichte",
+       "grouppage-suppress": "{{ns:project}}:Toezicht",
        "right-read": "Ziejen bekieken",
        "right-edit": "Ziejen bewarken",
        "right-createpage": "Ziejen anmaken",
        "right-move": "Ziejen herneumen",
        "right-move-subpages": "Ziejen samen mit de ziejen die deronder hangen verplaotsen",
        "right-move-rootuserpages": "Gebrukersziejen van t hoogste nivo herneumen",
+       "right-move-categorypages": "Kategorieziejen herneumen",
        "right-movefile": "Bestaanden herneumen",
        "right-suppressredirect": "Gien deurverwiezing anmaken op de ouwe naam as n zied herneumd wörden",
        "right-upload": "Bestaanden opsturen",
        "right-deletedtext": "Bekiek vortedaone tekste en wiezigingen tussen vortedaone versies",
        "right-browsearchive": "Vortedaone ziejen bekieken",
        "right-undelete": "Vortedaone ziejen weerummeplaotsen",
-       "right-suppressrevision": "Verbörgen versies bekieken en weerummeplaotsen",
+       "right-suppressrevision": "Bepaolde versies bekieken, verbargen en weer zichtbaor maken op ziejen van elke gebruker",
        "right-suppressionlog": "Niet-publieke logboeken bekieken",
        "right-block": "Aandere gebrukers de meugelikheid ontnemen um te bewarken",
        "right-blockemail": "n Gebruker t recht ontnemen um berichjes te versturen",
        "right-userrights": "Alle gebrukersrechten bewarken",
        "right-userrights-interwiki": "Gebrukersrechten van gebrukers in aandere wiki's wiezigen",
        "right-siteadmin": "De databanke blokkeren en weer vriegeven",
-       "right-override-export-depth": "Ziejen uutvoeren, oek de ziejen waor naor verwezen wörden, tot n diepte van 5",
+       "right-override-export-depth": "Ziejen exporteren, oek de ziejen waor naor verwezen wördt, tot n diepte van 5",
        "right-sendemail": "Bericht versturen naor aandere gebrukers",
        "right-passwordreset": "Bekiek netpostberichten veur t opniej instellen van joew wachtwoord",
        "newuserlogpage": "Logboek mit anwas",
        "recentchanges-label-plusminus": "Disse ziedgrootte is mit dit antal bytes ewiezigd",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (zie oek de [[Special:NewPages|lieste mit nieje ziejen]])",
+       "recentchanges-submit": "Bekiek",
        "rcnotefrom": "Dit bin de wiezigingen sinds <strong>$2</strong> (maximum van <strong>$1</strong> wiezigingen).",
        "rclistfrom": "Bekiek wiezigingen vanaof $3 $2",
        "rcshowhideminor": "$1 kleine wiezigingen",
        "recentchangeslinked-summary": "Op disse spesiale zied steet n lieste mit de leste wieziginen op ziejen waornaor verwezen wördt. Ziejen op [[Special:Watchlist|joew volglieste]] staon '''vet'''.",
        "recentchangeslinked-page": "Ziednaam:",
        "recentchangeslinked-to": "Bekiek wiezigingen op ziejen mit verwiezingen naor disse zied",
+       "recentchanges-page-added-to-category": "[[:$1]] bie kategorie ezet",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] bie kategorie ezet, [[Special:WhatLinksHere/$1|disse zied zit in aandere ziejen in-esleuten]]",
+       "recentchanges-page-removed-from-category": "[[:$1]] is vortedaon uut kategorie",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] vortedaon uut kategorie, [[Special:WhatLinksHere/$1|disse zied zit in aandere ziejen in-esleuten]]",
+       "autochange-username": "Automatiese wieziging van MediaWiki",
        "upload": "Bestaand opsturen",
        "uploadbtn": "Bestaand opsturen",
        "reuploaddesc": "Weerumme naor de opstuurzied",
        "semiprotectedpagemovewarning": "'''Waorschuwing:''' disse zied kan allinnig deur eregistreerden gebrukers herneumd wörden.\nDe leste logboekregel steet hieronder:",
        "move-over-sharedrepo": "== t Bestaand besteet al ==\n[[:$1]] besteet al in de edeelden mediadatabanke. A'j n bestaand naor disse titel herneumen, dan ku'j  t edeelden bestaand niet gebruken.",
        "file-exists-sharedrepo": "Disse bestaandsnaam besteet al in de edeelden mediadatabanke.\nKies n aandere bestaandsnaam.",
-       "export": "Ziejen uutvoeren",
-       "exporttext": "De tekste en geschiedenisse van n zied of n koppel ziejen kunnen in XML-formaot uutevoerd wörden. Dit bestaand ku'j daornao uutvoeren naor n aandere MediaWiki deur de [[Special:Import|invoerzied]] te gebruken.\n\nZet in t onderstaonde veld de namen van de ziejen die'j uutvoeren willen, één zied per regel, en gif an o'j alle versies mit de bewarkingssamenvatting uutvoeren willen of allinnig de leste versies mit de bewarkingssamenvatting.\n\nA'j dat leste doon willen dan ku'j oek n verwiezing gebruken, bieveurbeeld [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] veur de zied \"[[{{MediaWiki:Mainpage}}]]\".",
-       "exportall": "Alle ziejen uutvoeren",
+       "export": "Ziejen exporteren",
+       "exporttext": "De tekste en geschiedenisse van n zied of n koppel ziejen kunnen in XML-formaot uutevoerd wörden. Dit bestaand ku'j daornao exporteren naor n aandere MediaWiki deur de [[Special:Import|invoerzied]] te gebruken.\n\nZet in t onderstaonde veld de namen van de ziejen die'j exporteren willen, één zied per regel, en geef an o'j alle versies mit de bewarkingssamenvatting exporteren willen of allinnig de leste versies mit de bewarkingssamenvatting.\n\nA'j dat leste doon willen dan ku'j oek n verwiezing gebruken, bieveurbeeld [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] veur de zied \"[[{{MediaWiki:Mainpage}}]]\".",
+       "exportall": "Alle ziejen exporteren",
        "exportcuronly": "Allinnig de actuele versie, niet de veurgeschiedenisse",
-       "exportnohistory": "----\n'''NB:''' t uutvoeren van de hele geschiedenisse is uutezet vanwegen prestasieredens.",
+       "exportnohistory": "----\n'''NB:''' t exporteren van de hele geschiedenisse is uutezet vanwegen prestasieredens.",
        "exportlistauthors": "De hele auteurslieste opnemen veur elke zied",
-       "export-submit": "Uutvoeren",
+       "export-submit": "Exporteren",
        "export-addcattext": "Ziejen derbie doon uut de kategorie:",
        "export-addcat": "Derbie doon",
        "export-addnstext": "Ziejen uut de volgende naamruumte derbie doon:",
index 40f07fd..37e4a51 100644 (file)
        "nstab-template": "Vörlaag",
        "nstab-help": "Hülp",
        "nstab-category": "Kategorie",
+       "mainpage-nstab": "Hööftsiet",
        "nosuchaction": "Disse Aktschoon gifft dat nich",
        "nosuchactiontext": "De in de URL angeven Akschoon warrt nich ünnerstütt.\nVillicht hest du in de URL en Tippfehler oder büst en verkehrten Lenk nagahn.\nDat kann aver ok op en Bug in de Software henwiesen, de op {{SITENAME}} bruukt warrt.",
        "nosuchspecialpage": "Disse Spezialsiet gifft dat nich",
index 470c288..1c581a8 100644 (file)
        "upload-form-label-infoform-description": "वर्णन",
        "upload-form-label-usage-title": "प्रयोग",
        "upload-form-label-usage-filename": "फाइल नाम",
-       "foreign-structured-upload-form-label-infoform-categories": "श्रेणीहरू",
-       "foreign-structured-upload-form-label-infoform-date": "मिति",
+       "upload-form-label-infoform-categories": "श्रेणीहरू",
+       "upload-form-label-infoform-date": "मिति",
        "backend-fail-stream": "फाइल ''$1'' प्रवाह गर्न सकिएन ।",
        "backend-fail-backup": "फाइल ''$1'' जगेडा संग्रह गर्न सकिएन ।",
        "backend-fail-notexists": "फाइल $1 पृष्ठ अस्तित्वमा छैन ।",
index 15f8e89..53573c8 100644 (file)
@@ -76,7 +76,8 @@
                        "Edoderoo",
                        "Nemo bis",
                        "Lemondoge",
-                       "Dinosaur918"
+                       "Dinosaur918",
+                       "Jdforrester"
                ]
        },
        "tog-underline": "Koppelingen onderstrepen:",
        "minoredit": "Dit is een kleine bewerking",
        "watchthis": "Deze pagina volgen",
        "savearticle": "Pagina opslaan",
+       "publishpage": "Pagina publiceren",
        "preview": "Voorvertoning",
        "showpreview": "Bewerking ter controle bekijken",
        "showdiff": "Wijzigingen bekijken",
        "upload-form-label-infoform-description-tooltip": "Beschrijf kort alles wat voor het werk van belang is.\nBenoem voor een afbeelding de belangrijkste zaken die zijn afgebeeld, alsmede de plaats of de gelegenheid.",
        "upload-form-label-usage-title": "Gebruik",
        "upload-form-label-usage-filename": "Bestandsnaam",
-       "foreign-structured-upload-form-label-own-work": "Dit is mijn eigen werk",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorieën",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Ik bevestig dat ik dit bestand upload onder de voorwaarden en het licentiebeleid van {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Als u niet in staat bent dit bestand te uploaden onder het beleid van {{SITENAME}}, sluit dit venster dan alstublieft en kies een andere methode.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "U kunt ook de [[Special:Upload|standaard uploadpagina]] gebruiken.",
-       "foreign-structured-upload-form-label-own-work-message-default": "Ik begrijp dat ik dit bestand upload naar een gedeelde repository. Ik bevestig dat ik voldoe aan de voorwaarden en het licentiebeleid daar.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Als u niet in staat bent dit bestand te uploaden onder het beleid van de gedeelde repository, sluit dit venster dan alstublieft en kies een andere methode.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "U kunt ook proberen de [[Special:Upload|uploadpagina van {{SITENAME}}]] te gebruiken als dit bestand geüpload kan worden onder hun beleid.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Ik verklaar dat ik de auteursrechten bezit op dit bestand en ik ga onherroepbaar akkoord met het vrijgeven van dit bestand aan Wikimedia Commons onder de licentie [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Naamsvermelding-GelijkDelen 4.0] en ik ga akkoord met de [https://wikimediafoundation.org/wiki/Terms_of_Use Gebruiksvoorwaarden].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Als u geen eigenaar bent van de auteursrechten van dit bestand, of als u het onder een andere licentie wilt vrijgeven, overweeg dan gebruik te maken van de [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "U kunt ook de [[Special:Upload|uploadpagina op {{SITENAME}}]] gebruiken, als de site het uploaden van dit bestand onder hun beleid toestaat.",
+       "upload-form-label-own-work": "Dit is mijn eigen werk",
+       "upload-form-label-infoform-categories": "Categorieën",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Ik bevestig dat ik dit bestand upload onder de voorwaarden en het licentiebeleid van {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Als u niet in staat bent dit bestand te uploaden onder het beleid van {{SITENAME}}, sluit dit venster dan alstublieft en kies een andere methode.",
+       "upload-form-label-not-own-work-local-local": "U kunt ook de [[Special:Upload|standaard uploadpagina]] gebruiken.",
+       "upload-form-label-own-work-message-default": "Ik begrijp dat ik dit bestand upload naar een gedeelde repository. Ik bevestig dat ik voldoe aan de voorwaarden en het licentiebeleid daar.",
+       "upload-form-label-not-own-work-message-default": "Als u niet in staat bent dit bestand te uploaden onder het beleid van de gedeelde repository, sluit dit venster dan alstublieft en kies een andere methode.",
+       "upload-form-label-not-own-work-local-default": "U kunt ook proberen de [[Special:Upload|uploadpagina van {{SITENAME}}]] te gebruiken als dit bestand geüpload kan worden onder hun beleid.",
+       "upload-form-label-own-work-message-shared": "Ik verklaar dat ik de auteursrechten bezit op dit bestand en ik ga onherroepbaar akkoord met het vrijgeven van dit bestand aan Wikimedia Commons onder de licentie [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Naamsvermelding-GelijkDelen 4.0] en ik ga akkoord met de [https://wikimediafoundation.org/wiki/Terms_of_Use Gebruiksvoorwaarden].",
+       "upload-form-label-not-own-work-message-shared": "Als u geen eigenaar bent van de auteursrechten van dit bestand, of als u het onder een andere licentie wilt vrijgeven, overweeg dan gebruik te maken van de [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
+       "upload-form-label-not-own-work-local-shared": "U kunt ook de [[Special:Upload|uploadpagina op {{SITENAME}}]] gebruiken, als de site het uploaden van dit bestand onder hun beleid toestaat.",
        "backend-fail-stream": "Het was niet mogelijk het bestand \"$1\" te streamen.",
        "backend-fail-backup": "Het was niet mogelijk een reservekopie van het bestand $1 te maken.",
        "backend-fail-notexists": "Het bestand $1 bestaat niet.",
        "wantedfiles": "Niet-bestaande bestanden met koppelingen",
        "wantedfiletext-cat": "De volgende bestanden worden gebruikt maar bestaan niet. Bestanden van externe repositories kunnen zijn opgenomen in de lijst, ondanks dat ze bestaan. Dergelijke vals positieven worden <del>doorgehaald weergegeven</del>. Pagina's die niet-bestaande bestanden insluiten staan op de pagina [[:$1]].",
        "wantedfiletext-cat-noforeign": "De volgende bestanden zijn in gebruik maar bestaan niet. Daarnaast staan pagina's met niet-bestaande bestanden op [[:$1]].",
-       "wantedfiletext-nocat": "De volgende bestanden worden gebruikt maar bestaan niet. Bestanden van externe repositories kunnen zijn opgenomen in de lijst, ondanks dat ze bestaan. Dergelijke vals positieven worden <del>doorgehaald weergegeven</del>.",
+       "wantedfiletext-nocat": "De volgende bestanden worden gebruikt maar bestaan niet. Bestanden van externe repositories kunnen zijn opgenomen in de lijst, ondanks dat ze bestaan. Dergelijke valse positieven worden <del>doorgehaald weergegeven</del>.",
        "wantedfiletext-nocat-noforeign": "De volgende bestanden zijn in gebruik maar bestaan niet.",
        "wantedtemplates": "Niet-bestaande sjablonen met koppelingen",
        "mostlinked": "Pagina's waar het meest naar verwezen wordt",
        "tooltip-ca-nstab-category": "Categoriepagina bekijken",
        "tooltip-minoredit": "Deze wijziging als een kleine wijziging markeren",
        "tooltip-save": "Wijzigingen opslaan",
+       "tooltip-publish": "Uw wijzigingen publiceren",
        "tooltip-preview": "Een voorvertoning maken. Gebruik dit voordat u opslaat!",
        "tooltip-diff": "Weergeven welke wijzigingen u aan de tekst hebt gemaakt",
        "tooltip-compareselectedversions": "De verschillen tussen de geselecteerde versies van deze pagina bekijken.",
        "logentry-protect-protect-cascade": "$1 heeft $3 {{GENDER:$2|beveiligd}} $4 [cascade]",
        "logentry-protect-modify": "$1 heeft het beveiligingsniveau van $3 {{GENDER:$2|aangepast}} $4",
        "logentry-protect-modify-cascade": "$1 heeft het beveiligingsniveau van $3 {{GENDER:$2|aangepast}} $4 [cascade]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|heeft}} groepslidmaatschap voor $3 gewijzigd van $4 naar $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|heeft}} groepslidmaatschap voor {{GENDER:$6|$3}} gewijzigd van $4 naar $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|heeft}} het groepslidmaatschap gewijzigd voor $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|is}} automatisch gepromoveerd van $4 naar $5",
        "logentry-upload-upload": "$1 heeft $3 {{GENDER:$2|geüpload}}",
index c01b64a..2d415db 100644 (file)
                        "Gaute",
                        "Macofe",
                        "Chameleon222",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Mortensson"
                ]
        },
        "tog-underline": "Strek under lenkjer:",
        "tog-hideminor": "Gøym småplukk i lista over siste endringar",
        "tog-hidepatrolled": "Gøym patruljerte endringar i lista over siste endringar",
        "tog-newpageshidepatrolled": "Gøym patruljerte sider frå lista over nye sider",
+       "tog-hidecategorization": "Løyn sidekategoriseringa",
        "tog-extendwatchlist": "Utvid overvakingslista til å vise alle endringane, ikkje berre dei siste",
        "tog-usenewrc": "Grupper endringar etter side i siste endringane og på overvakingslista",
        "tog-numberheadings": "Vis nummererte overskrifter",
@@ -41,6 +43,8 @@
        "tog-watchdefault": "Legg til sidene og filene eg endrar på overvakingslista mi",
        "tog-watchmoves": "Legg til sidene og filene eg flytter på overvakingslista mi",
        "tog-watchdeletion": "Legg til sidene og filene eg slettar på overvakingslista mi",
+       "tog-watchuploads": "Overvak nye filer som eg lastar opp",
+       "tog-watchrollback": "Overvak sider som eg har attra",
        "tog-minordefault": "Merk endringar som «småplukk» som standard",
        "tog-previewontop": "Vis førehandsvisinga før endringsboksen",
        "tog-previewonfirst": "Førehandsvis første endring",
        "tog-watchlisthidebots": "Gøym endringar gjorde av robotar i overvakingslista",
        "tog-watchlisthideminor": "Gøym småplukk i overvakingslista",
        "tog-watchlisthideliu": "Gøym endringar av innlogga brukarar i overvakingslista.",
+       "tog-watchlistreloadautomatically": "Oppdater overvakingslista automatisk når eit filter vert endra (krev JavaScript)",
        "tog-watchlisthideanons": "Gøym endringar av anonyme brukarar i overvakingslista.",
        "tog-watchlisthidepatrolled": "Gøym patruljerte endringar i overvakingslista",
+       "tog-watchlisthidecategorization": "Løyn sidekategoriseringa",
        "tog-ccmeonemails": "Send meg kopi av e-postane eg sender til andre brukarar",
        "tog-diffonly": "Ikkje vis sideinnhaldet under skilnadene mellom versjonane",
        "tog-showhiddencats": "Vis gøymde kategoriar",
        "october-date": "$1. oktober",
        "november-date": "$1. november",
        "december-date": "$1. desember",
+       "period-am": "f.m.",
+       "period-pm": "e.m.",
        "pagecategories": "{{PLURAL:$1|Kategori|Kategoriar}}",
        "category_header": "Artiklar i kategorien «$1»",
        "subcategories": "Underkategoriar",
        "morenotlisted": "Lista er ikkje heil.",
        "mypage": "Sida mi",
        "mytalk": "Diskusjon",
-       "anontalk": "Diskusjonside for denne IP-adressa",
+       "anontalk": "Diskusjon",
        "navigation": "Navigering",
        "and": "&#32;og",
        "qbfind": "Finn",
index 486d5e9..97c6921 100644 (file)
@@ -4,7 +4,8 @@
                        "Denö",
                        "Hiloin Natoi",
                        "Ilja.mos",
-                       "Mashoi7"
+                       "Mashoi7",
+                       "Misosoof"
                ]
        },
        "tog-underline": "Linkien alleviivuamine:",
        "resetpass_submit": "Azeta peittosana da kirjuttai sistiemah:",
        "changepassword-success": "Sinun peittosana on vaihtettu!",
        "changepassword-throttled": "Olet oppinuh kirjuttuakseh liijan moni kerdua. Ole hyvä, vuota $1 enne ku opit uvvessah.",
+       "botpasswords-label-create": "Luaji",
+       "botpasswords-label-update": "Päivitä",
+       "botpasswords-label-cancel": "Hylgiä",
+       "botpasswords-label-delete": "Poista",
        "resetpass_forbidden": "Ei voi vaihtua peittosanua",
        "resetpass-no-info": "Et voi nähtä tädä sivuu kuni et ole kirjutannuhes.",
        "resetpass-submit-loggedin": "Vaihta peittosana",
        "upload-form-label-infoform-description": "Kuvavus",
        "upload-form-label-usage-title": "Käyttö",
        "upload-form-label-usage-filename": "Failunimi",
-       "foreign-structured-upload-form-label-own-work": "Tämä on minun oma ruado",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategouriet",
+       "upload-form-label-own-work": "Tämä on minun oma ruado",
+       "upload-form-label-infoform-categories": "Kategouriet",
        "license-header": "Licenzii",
        "imgfile": "tiijosto",
        "listfiles_name": "Nimi",
index d711ecd..1449441 100644 (file)
        "preferences": "ପସନ୍ଦ",
        "mypreferences": "ପସନ୍ଦ",
        "prefs-edits": "ସମ୍ପାଦନା ସଂଖ୍ୟା:",
-       "prefsnologintext2": "ନିà¬\9cର à¬ªà¬¸à¬¨à­\8dଦ à¬¬à¬¦à¬²ାଇବା ପାଇଁ ଲଗ ଇନ କରନ୍ତୁ ।",
+       "prefsnologintext2": "ନିà¬\9cର à¬ªà¬¸à¬¨à­\8dଦ à¬¬à¬¦à¬³ାଇବା ପାଇଁ ଲଗ ଇନ କରନ୍ତୁ ।",
        "prefs-skin": "ବହିରାବରଣ",
        "skin-preview": "ସାଇତା ଆଗରୁ ଦେଖଣା",
        "datedefault": "କୌଣସି ପସନ୍ଦ ନାହିଁ",
index 9bb2e21..65bcad1 100644 (file)
        "upload-file-error": "ਅੰਦਰੂਨੀ ਗਲਤੀ",
        "upload-misc-error": "ਅਣਪਛਾਤੀ ਅੱਪਲੋਡ ਗਲਤੀ",
        "upload-http-error": "ਇੱਕ HTTP ਗ਼ਲਤੀ ਹੋਈ: $1",
-       "foreign-structured-upload-form-label-infoform-date": "ਤਾਰੀਖ਼",
+       "upload-form-label-infoform-date": "ਤਾਰੀਖ਼",
        "backend-fail-notexists": "ਫ਼ਾਈਲ $1 ਮੌਜੂਦ ਨਹੀਂ ਹੈ।",
        "backend-fail-delete": "ਫ਼ਾਈਲ \"$1\" ਮਿਟਾਈ ਨਹੀਂ ਜਾ ਸਕੀ।",
        "backend-fail-alreadyexists": "ਫ਼ਾਈਲ \"$1\" ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ।",
index 77a6e8b..43656ec 100644 (file)
        "tog-ccmeonemails": "Przesyłaj mi kopie wiadomości, które wysyłam do innych użytkowników",
        "tog-diffonly": "Nie pokazuj treści stron pod porównaniami zmian",
        "tog-showhiddencats": "Pokazuj ukryte kategorie",
-       "tog-norollbackdiff": "Pomiń pokazywanie zmian po użyciu funkcji „cofnij”",
+       "tog-norollbackdiff": "Nie pokazuj zmian po użyciu funkcji „cofnij”",
        "tog-useeditwarning": "Ostrzegaj mnie, gdy opuszczam stronę edycji bez zapisania zmian",
        "tog-prefershttps": "Zawsze używaj bezpiecznego połączenia po zalogowaniu",
        "underline-always": "Zawsze",
        "minoredit": "To jest drobna zmiana",
        "watchthis": "Obserwuj",
        "savearticle": "Zapisz",
+       "publishpage": "Opublikuj stronę",
        "preview": "Podgląd",
        "showpreview": "Pokaż podgląd",
        "showdiff": "Podgląd zmian",
        "upload-form-label-infoform-description-tooltip": "Krótko opisz wszystko istotne, co dotyczy tej pracy.\nW przypadku zdjęcia wymień najważniejsze ujęte obiekty, sytuację lub miejsce.",
        "upload-form-label-usage-title": "Korzystanie",
        "upload-form-label-usage-filename": "Nazwa pliku",
-       "foreign-structured-upload-form-label-own-work": "To moja własna praca",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorie",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Potwierdzam, że wysyłam ten plik zgodnie z warunkami i zasadami licencjonowania obowiązującymi na {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Jeśli nie możesz wysłać tego pliku zgodnie z zasadami obowiązującymi na {{SITENAME}}, zamknij ten komunikat i spróbuj innej metody.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Możesz skorzystać też z [[Special:Upload|domyślnej strony przesyłania plików]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Rozumiem, że przesyłam ten plik do współdzielonego repozytorium. Potwierdzam, że robię to zgodnie z warunkami i zasadami licencjonowania tam obowiązującymi.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Jeśli nie jesteś w stanie przesłać tego pliku zgodnie z zasadami współdzielonego repozytorium, zamknij to okno i spróbuj innej metody.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Możesz spróbować użyć [[Special:Upload|strony przesyłania plików {{GRAMMAR:D.lp|{{SITENAME}}}}]], jeżeli zasady tej strony dopuszczają publikację tego pliku.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Oświadczam, że mam prawa autorskie do tego pliku, nieodwołalnie publikuję go na Wikimedia Commons na licencji [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0] i zgadzam się na [https://wikimediafoundation.org/wiki/Terms_of_Use/pl warunki użytkowania].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Jeżeli nie masz praw autorskich do tego pliku albo chcesz go opublikować na innej licencji, rozważ użycie [https://commons.wikimedia.org/wiki/Special:UploadWizard kreatora przesyłania plików].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Możesz spróbować użyć [[Special:Upload|strony przesyłania plików {{GRAMMAR:D.lp|{{SITENAME}}}}]], jeżeli zasady tej strony dopuszczają publikację tego pliku.",
+       "upload-form-label-own-work": "To moja własna praca",
+       "upload-form-label-infoform-categories": "Kategorie",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Potwierdzam, że wysyłam ten plik zgodnie z warunkami i zasadami licencjonowania obowiązującymi na {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Jeśli nie możesz wysłać tego pliku zgodnie z zasadami obowiązującymi na {{SITENAME}}, zamknij ten komunikat i spróbuj innej metody.",
+       "upload-form-label-not-own-work-local-local": "Możesz skorzystać też z [[Special:Upload|domyślnej strony przesyłania plików]].",
+       "upload-form-label-own-work-message-default": "Rozumiem, że przesyłam ten plik do współdzielonego repozytorium. Potwierdzam, że robię to zgodnie z warunkami i zasadami licencjonowania tam obowiązującymi.",
+       "upload-form-label-not-own-work-message-default": "Jeśli nie jesteś w stanie przesłać tego pliku zgodnie z zasadami współdzielonego repozytorium, zamknij to okno i spróbuj innej metody.",
+       "upload-form-label-not-own-work-local-default": "Możesz spróbować użyć [[Special:Upload|strony przesyłania plików {{GRAMMAR:D.lp|{{SITENAME}}}}]], jeżeli zasady tej strony dopuszczają publikację tego pliku.",
+       "upload-form-label-own-work-message-shared": "Oświadczam, że mam prawa autorskie do tego pliku, nieodwołalnie publikuję go na Wikimedia Commons na licencji [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0] i zgadzam się na [https://wikimediafoundation.org/wiki/Terms_of_Use/pl warunki użytkowania].",
+       "upload-form-label-not-own-work-message-shared": "Jeżeli nie masz praw autorskich do tego pliku albo chcesz go opublikować na innej licencji, rozważ użycie [https://commons.wikimedia.org/wiki/Special:UploadWizard kreatora przesyłania plików].",
+       "upload-form-label-not-own-work-local-shared": "Możesz spróbować użyć [[Special:Upload|strony przesyłania plików {{GRAMMAR:D.lp|{{SITENAME}}}}]], jeżeli zasady tej strony dopuszczają publikację tego pliku.",
        "backend-fail-stream": "Nie można odczytać pliku $1.",
        "backend-fail-backup": "Nie można utworzyć kopii zapasowej pliku  $1 .",
        "backend-fail-notexists": "Plik  $1  nie istnieje.",
        "whatlinkshere-prev": "{{PLURAL:$1|poprzednie|poprzednie $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|następne|następne $1}}",
        "whatlinkshere-links": "← linkujące",
-       "whatlinkshere-hideredirs": "$1 przekierowania",
-       "whatlinkshere-hidetrans": "$1 dołączenia",
-       "whatlinkshere-hidelinks": "$1 linki",
-       "whatlinkshere-hideimages": "$1 linki z plików",
+       "whatlinkshere-hideredirs": "Ukryj przekierowania",
+       "whatlinkshere-hidetrans": "Ukryj dołączenia",
+       "whatlinkshere-hidelinks": "Ukryj linki",
+       "whatlinkshere-hideimages": "Ukryj linki z plików",
        "whatlinkshere-filters": "Filtry",
        "whatlinkshere-submit": "Dalej",
        "autoblockid": "automatyczna blokada nr $1",
        "lockdbsuccesstext": "Baza danych została zablokowana.<br />\nPamiętaj by [[Special:UnlockDB|zdjąć blokadę]] po zakończeniu działań administracyjnych.",
        "unlockdbsuccesstext": "Baza danych została odblokowana.",
        "lockfilenotwritable": "Nie można zapisać pliku blokady bazy danych.\nBlokowanie i odblokowywanie bazy danych, wymaga by plik mógł być zapisywany przez web serwer.",
+       "databaselocked": "Baza danych jest już zablokowana.",
        "databasenotlocked": "Baza danych nie jest zablokowana.",
        "lockedbyandtime": "(przez $1 dnia $2 o $3)",
        "move-page": "Przenieś $1",
        "feedback-useragent": "Aplikacja klienta:",
        "searchsuggest-search": "Szukaj",
        "searchsuggest-containing": "zawierające...",
+       "api-error-autoblocked": "Twój adres IP został automatycznie zablokowany, ponieważ był używany przez zablokowanego użytkownika.",
        "api-error-badaccess-groups": "Nie masz uprawnień aby przesyłać pliki do tej wiki.",
        "api-error-badtoken": "Błąd wewnętrzny – nieprawidłowy kod weryfikacyjny (token).",
+       "api-error-blocked": "Została ci zablokowana możliwość edycji.",
        "api-error-copyuploaddisabled": "Przesyłanie poprzez podanie adresu URL zostało na tym serwerze wyłączone.",
        "api-error-duplicate": "{{PLURAL:$1|Jest już inny plik|Są już inne pliki}} o tej samej zawartości",
        "api-error-duplicate-archive": "{{PLURAL:$1|Był już inny plik|Były już inne pliki}} o takiej samej zawartości, ale {{PLURAL:$1|został usunięty|zostały usunięte}}.",
        "randomrootpage": "Losowa strona (bez podstron)",
        "log-action-filter-block": "Rodzaj blokady:",
        "log-action-filter-delete": "Rodzaj usunięcia:",
+       "log-action-filter-patrol": "Rodzaj patrolu:",
        "log-action-filter-protect": "Rodzaj zabezpieczenia:",
+       "log-action-filter-rights": "Typ zmiany uprawień",
        "log-action-filter-upload": "Rodzaj przesłanych:",
        "log-action-filter-all": "Wszystkie",
        "log-action-filter-block-block": "Zablokowanie",
        "log-action-filter-managetags-delete": "Usunięcie znacznika",
        "log-action-filter-managetags-activate": "Aktywacja znacznika",
        "log-action-filter-managetags-deactivate": "Deaktywacja znacznika",
+       "log-action-filter-patrol-patrol": "Ręczny",
+       "log-action-filter-patrol-autopatrol": "Automatyczny",
        "log-action-filter-protect-protect": "Zabezpieczenie",
        "log-action-filter-protect-modify": "Zmiana zabezpieczenia",
        "log-action-filter-protect-unprotect": "Odbezpieczenie",
+       "log-action-filter-rights-rights": "Ręczna zmiana",
+       "log-action-filter-rights-autopromote": "Automatyczna zmiana",
        "log-action-filter-upload-upload": "Nowe przesłane",
        "log-action-filter-upload-overwrite": "Przesłane ponownie"
 }
index 8e677db..76b66bf 100644 (file)
@@ -6,7 +6,8 @@
                        "Umherirrender",
                        "아라",
                        "عثمان خان شاہ",
-                       "Macofe"
+                       "Macofe",
+                       "Amire80"
                ]
        },
        "tog-underline": "کرښنې تړنې:",
        "minoredit": "دا يو وړوکی سمون دی",
        "watchthis": "همدا مخ کتل",
        "savearticle": "مخ خوندي کول",
+       "publishpage": "مخ خپرول",
        "preview": "مخليدنه",
        "showpreview": "مخليدنه",
        "showdiff": "بدلونونه ښکاره کول",
        "newarticle": "(نوی)",
        "newarticletext": "تاسې د يوې داسې تړنې څارنه کړې چې لا تر اوسه پورې نه شته.\nکه همدا مخ ليکل غواړۍ، نو په لانديني چوکاټ کې خپل متن وټاپئ (د لا نورو مالوماتو لپاره د [$1 لارښود مخ] وگورئ).\nکه چېرته تاسې دلته په تېروتنه راغلي ياست، نو يواځې د خپل د کتنمل '''مخ پر شا''' تڼۍ مو وټوکئ.",
        "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": "دم مهال په دې مخ کې څه نشته.\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-view": "د \"$1\" گڼون نه دی ثبت شوی.",
        "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": "نېټه",
+       "upload-form-label-own-work": "دا زما خپل کار دی",
+       "upload-form-label-infoform-categories": "وېشنيزې",
+       "upload-form-label-infoform-date": "نېټه",
        "backend-fail-notexists": "د $1 په نوم دوتنه نشته.",
        "backend-fail-delete": "د \"$1\" دوتنه ړنګه نه شوه.",
        "backend-fail-alreadyexists": "د $1 دوتنه له پخوا نه شته.",
        "listgrouprights-rights": "رښتې",
        "listgrouprights-helppage": "Help:د ډلې رښتې",
        "listgrouprights-members": "(د غړو لړليک)",
-       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($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",
        "ipb-unblock": "له يوه کارن-نوم يا IP پتې بنديز ليري کول",
        "ipb-blocklist": "شته بنديزونه کتل",
        "ipb-blocklist-contribs": "د {{GENDER:$1|$1}} ونډې",
+       "ipb-blocklist-duration-left": "$1 پاتې دی",
        "unblockip": "کارن له بنديزه وېستل",
        "unblockiptext": "د لاندې فورمې په کارولو سره يو بنديز شوي کارن يا آی پي پتې ته د ليکلو لاسرسی ورکولی شی.",
        "ipusubmit": "دا بنديز ليرې کول",
        "watchlistedit-raw-done": "ستاسې کتنلړ اوسمهاله شو.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 سرليک ورگډ شو|$1 سرليکونه ورگډ شوه}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 سرليک ليرې شو|$1 سرليکونه ليري شوه}}:",
-       "watchlistedit-clear-title": "کتنلړ سپين شو",
+       "watchlistedit-clear-title": "کتنلړ سپينول",
        "watchlistedit-clear-legend": "کتنلړ سپينول",
        "watchlistedit-clear-titles": "سرليکونه:",
        "watchlistedit-clear-submit": "کتنلړ سپينول (دا دايمي ده!)",
index 6000918..b55ded6 100644 (file)
        "tog-watchdefault": "Adicionar as páginas e arquivos que eu editar à minha lista de páginas vigiadas",
        "tog-watchmoves": "Adicionar as páginas e arquivos que eu mover à minha lista de páginas vigiadas",
        "tog-watchdeletion": "Adicionar as páginas e arquivos que eu eliminar à minha lista de páginas vigiadas",
+       "tog-watchuploads": "Adicionar arquivos que envio para minha lista de vigiados",
        "tog-watchrollback": "Adicionar páginas onde fiz uma reversão às minhas páginas vigiadas",
        "tog-minordefault": "Marcar todas as edições como menores por padrão",
        "tog-previewontop": "Mostrar previsão antes da caixa de edição",
        "noemail": "Não há um endereço de e-mail associado ao usuário \"$1\".",
        "noemailcreate": "Você precisa fornecer um endereço de e-mail válido",
        "passwordsent": "Uma nova senha está sendo enviada para o endereço de e-mail registrado para \"$1\".\nPor favor, reconecte-se ao recebê-lo.",
-       "blocked-mailpassword": "O seu endereço de IP foi bloqueado de editar e, portanto, não será possível utilizar o lembrete de senha (para serem evitados envios abusivos a outras pessoas).",
+       "blocked-mailpassword": "O seu endereço de IP foi bloqueado para editar. Para evitar abusos, não é permitido o uso de recuperação de senha a partir deste endereço IP.",
        "eauthentsent": "Uma mensagem de confirmação foi enviada para o endereço de e-mail fornecido.\nAntes de qualquer outro e-mail ser enviado para a sua conta, você precisará seguir as instruções da mensagem, de modo a confirmar que a conta é mesmo sua.",
        "throttled-mailpassword": "Um lembrete de senha já foi enviado {{PLURAL:$1|na última hora|nas últimas $1 horas}}.\nPara prevenir abusos, apenas um lembrete poderá ser enviado a cada {{PLURAL:$1|hora|$1 horas}}.",
        "mailerror": "Erro a enviar o email: $1",
        "recentchangeslinked-page": "Nome da página:",
        "recentchangeslinked-to": "Inversamente, mostrar mudanças nas páginas que contêm ligações para esta",
        "recentchanges-page-added-to-category": "[[:$1]]adicionada à categoria",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] e [[Special:WhatLinksHere/$1|{{PLURAL:$2|uma página|$2 páginas}}]] adicionadas à categoria",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] adicionado à categoria, [[Special:WhatLinksHere/$1|esta página é incluída em outras páginas]]",
        "recentchanges-page-removed-from-category": "[[:$1]] removida da categoria",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] e [[Special:WhatLinksHere/$1|{{PLURAL:$2|uma página|$2 páginas}}]] removidas da categoria",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] removido da categoria, [[Special:WhatLinksHere/$1|esta página é incluída em outras páginas]]",
        "autochange-username": "Alteração automática do MediaWiki",
        "upload": "Enviar arquivo",
        "uploadbtn": "Enviar arquivo",
        "upload-form-label-infoform-description": "Descrição",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nome do arquivo",
-       "foreign-structured-upload-form-label-own-work": "Isto é o meu próprio trabalho",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorias",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Você pode também querer tentar [[Special:Upload|the default upload page]]",
+       "upload-form-label-own-work": "Isto é o meu próprio trabalho",
+       "upload-form-label-infoform-categories": "Categorias",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-not-own-work-local-local": "Você pode também querer tentar [[Special:Upload|the default upload page]]",
        "backend-fail-stream": "Não foi possível transmitir o arquivo  $1.",
        "backend-fail-backup": "Não foi possível fazer backup do arquivo  $1 .",
        "backend-fail-notexists": "O arquivo $1 não existe.",
        "backend-fail-read": "Não foi possível ler o arquivo $1.",
        "backend-fail-create": "Não foi possível criar ou alterar o arquivo $1.",
        "backend-fail-maxsize": "Não foi possível criar ou alterar o arquivo $1 por ele ser maior que {{PLURAL:$2|1 byte|$2 bytes}}.",
-       "backend-fail-readonly": "O servidor de armazenamento \"$1\" está atualmente no modo \"somente leitura\". A razão dada foi: \"$2\"",
+       "backend-fail-readonly": "A armazenagem de \"$1\" está atualmente somente leitura. O motivo é: <em>$2</em>",
        "backend-fail-synced": "O arquivo \"$1\" está em um estado inconsistente dentro do sistema de armazenamento interno",
        "backend-fail-connect": "Não foi possível se conectar com o servidor de armazenamento \"$1\".",
        "backend-fail-internal": "Ocorreu um erro desconhecido no servidor de armazenamento \"$1\".",
        "uploadstash-summary": "Esta página dá acesso aos arquivos enviados (ou que estão no processo de envio) mas que ainda não foram publicados no wiki. Estes arquivos não são visíveis para ninguém, exceto para o usuário que os enviou.",
        "uploadstash-clear": "Apagar os arquivos escondidos",
        "uploadstash-nofiles": "Você não tem nenhum arquivo escondido.",
-       "uploadstash-badtoken": "Não foi possível executar essa operação, talvez porque as suas credenciais de edição expiraram. Tente novamente.",
-       "uploadstash-errclear": "Não foi possível apagar os arquivos.",
+       "uploadstash-badtoken": "A realização daquela ação falhou, talvez porque suas credenciais de edição expiraram. Por favor, tente novamente.",
+       "uploadstash-errclear": "A limpeza dos arquivos falhou.",
        "uploadstash-refresh": "Atualizar a lista de arquivos",
        "uploadstash-thumbnail": "ver miniatura",
        "invalid-chunk-offset": "Deslocamento de fragmento inválido",
        "apihelp-no-such-module": "Modulo \"$1\" não foram achados.",
        "apisandbox": "Caixa de areia da API",
        "apisandbox-api-disabled": "A API está desabilitada neste site.",
-       "apisandbox-intro": "Use esta página para realizar testes com o '''serviço web de API do MediaWiki'''.\nConsulte a [//www.mediawiki.org/wiki/API:Main_page a documentação API] para obter mais detalhes de uso da API.  Exemplo: [//www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo de uma Página principal].  Selecione uma ação para mais exemplos.\n\nNote que, embora esta seja uma área de testes, as operações que executar nesta página podem modificar a wiki.",
+       "apisandbox-intro": "Use esta página para realizar testes com o '''serviço web de API do MediaWiki'''.\nConsulte a [//www.mediawiki.org/wiki/API:Main_page a documentação API] para obter mais detalhes de uso da API.  Exemplo: [//www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo de uma Página principal].  Selecione uma ação para mais exemplos.\n\nNote que, embora esta seja uma área de testes, as ações que executar nesta página podem modificar a wiki.",
        "apisandbox-submit": "Fazer requisição",
        "apisandbox-reset": "Limpar",
-       "apisandbox-examples": "Exemplo",
-       "apisandbox-results": "Resultado",
+       "apisandbox-retry": "Tentar novamente",
+       "apisandbox-loading": "Carregando informação para o módulo API \"$1\"...",
+       "apisandbox-helpurls": "Links de ajuda",
+       "apisandbox-examples": "Exemplos",
+       "apisandbox-dynamic-parameters": "Parâmetros adicionais",
+       "apisandbox-dynamic-parameters-add-label": "Parâmetro adicional",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nome do parâmetro",
+       "apisandbox-deprecated-parameters": "Parâmetros obsoletos",
+       "apisandbox-submit-invalid-fields-title": "Alguns campos são inválidos",
+       "apisandbox-results": "Resultados",
        "apisandbox-request-url-label": "URL solicitante:",
-       "apisandbox-request-time": "Tempo do pedido: $1",
+       "apisandbox-request-time": "Tempo do pedido: {{PLURAL:$1|$1 ms}}",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Pesquisar referências bibliográficas",
        "booksources-search": "Pesquisar",
        "delete-toobig": "Esta página possui um longo histórico de edições, com mais de $1 {{PLURAL:$1|edição|edições}}.\nA eliminação de tais páginas foi restrita, a fim de se evitarem problemas acidentais em {{SITENAME}}.",
        "delete-warning-toobig": "Esta página possui um longo histórico de edições, com mais de $1 {{PLURAL:$1|edição|edições}}.\nEliminá-la poderá causar problemas na base de dados de {{SITENAME}};\nprossiga com cuidado.",
        "deleteprotected": "Não é possível eliminar esta página porque foi protegida.",
-       "deleting-backlinks-warning": "'''Cuidado:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Outras páginas]] se ligam ou redirecionam para a página que você está prestes a deletar.",
+       "deleting-backlinks-warning": "'''Cuidado:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Other pages]] ligam ou redirecionam para a página que você está prestes a excluir.",
        "rollback": "Reverter edições",
        "rollbacklink": "reverter",
        "rollbacklinkcount": "reverter $1 {{PLURAL:$1|edição|edições}}",
        "protect-locked-blocked": "Você não poderá alterar os níveis de proteção enquanto estiver bloqueado. Esta é a configuração atual para a página '''$1''':",
        "protect-locked-dblock": "Não é possível alterar os níveis de proteção, uma vez que a base de dados se encontra trancada.\nEsta é a configuração atual para a página '''$1''':",
        "protect-locked-access": "Sua conta não possui permissões para alterar os níveis de proteção de uma página.\nEsta é a configuração atual para a página '''$1''':",
-       "protect-cascadeon": "Esta página encontra-se protegida, uma vez que se encontra incluída {{PLURAL:$1|na página listada a seguir, protegida|nas páginas listadas a seguir, protegidas}} com a \"proteção progressiva\" ativada. Você poderá alterar o nível de proteção desta página, mas isso não afetará a \"proteção progressiva\".",
+       "protect-cascadeon": "Esta página está protegida porque é transclusa da seguinte {{PLURAL:$1|página, que possui|páginas, que possuem}} a proteção em cascata ativas.\nAs mudanças no nível de proteção desta página não afetam a proteção em cascata.",
        "protect-default": "Permitir todos os usuários",
        "protect-fallback": "Permitir apenas os usuários com privilégio de \"$1\"",
        "protect-level-autoconfirmed": "Permitir apenas usuários auto-confirmados",
        "tags-edit-revision-legend": "Adicionar ou remover etiquetas {{PLURAL:$1|desta revisão|de todas as $1 revisões}}",
        "tags-edit-logentry-legend": "Adicionar ou remover etiquetas {{PLURAL:$1|desta entrada de registro|de todas as $1 entradas de registro}}",
        "tags-edit-existing-tags": "Etiquetas existentes:",
-       "tags-edit-existing-tags-none": "''Nenhuma''",
+       "tags-edit-existing-tags-none": "<em>Nenhuma</em>",
        "tags-edit-new-tags": "Novas etiquetas:",
        "tags-edit-add": "Adicionar estas etiquetas:",
        "tags-edit-remove": "Remover estas etiquetas:",
        "tags-edit-reason": "Motivo:",
        "tags-edit-revision-submit": "Aplicar alterações para {{PLURAL:$1|esta revisão|$1 revisões}}",
        "tags-edit-logentry-submit": "Aplicar alterações para {{PLURAL:$1|esta entrada de registro|$1 entradas de registro}}",
-       "tags-edit-success": "As alterações foram aplicadas com sucesso.",
+       "tags-edit-success": "As alterações foram aplicadas.",
        "tags-edit-failure": "As alterações não puderam ser aplicadas:\n$1",
        "tags-edit-nooldid-title": "Revisão inválida",
        "tags-edit-nooldid-text": "Você não especificou nenhuma revisão para executar esta função, ou a revisão especificada não existe.",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegeu}} $3 $4 [em cascata]",
        "logentry-protect-modify": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4 [em cascata]",
-       "logentry-rights-rights": "$1 alterou os grupos de usuário de $3 de $4 para $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|mudou}} membros do grupo para {{GENDER:$6|$3}} de $4 para $5",
        "logentry-rights-rights-legacy": "$1 alterou os grupos de $3",
        "logentry-rights-autopromote": "$1 foi promovido automaticamente de $4 para $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
        "api-error-badaccess-groups": "Você não tem permissão para enviar arquivos para este wiki.",
        "api-error-badtoken": "Erro interno: token inválido.",
        "api-error-copyuploaddisabled": "O upload por URL está desativado neste servidor.",
-       "api-error-duplicate": "Já {{PLURAL:$1|há outro arquivo|existem outros arquivos}} com o mesmo conteúdo",
+       "api-error-duplicate": "Já {{PLURAL:$1|há outro arquivo|existem outros arquivos}} no site com o mesmo conteúdo",
        "api-error-duplicate-archive": "Já {{PLURAL:$1|existiu outro arquivo|existiram outros arquivos}} neste site com o mesmo conteúdo que, no entanto, {{PLURAL:$1|foi removido|foram removidos}}.",
        "api-error-empty-file": "O arquivo que você enviou está vazio.",
        "api-error-emptypage": "Não é permitido criar páginas novas vazias.",
index 51f26c1..4168a65 100644 (file)
@@ -70,7 +70,8 @@
                        "Diniscoelho",
                        "Josep Maria Roca Peña",
                        "Luan",
-                       "Gato Preto"
+                       "Gato Preto",
+                       "Jdforrester"
                ]
        },
        "tog-underline": "Sublinhar ligações:",
        "minoredit": "Marcar como edição menor",
        "watchthis": "Vigiar esta página",
        "savearticle": "Gravar página",
+       "publishpage": "Publicar página",
        "preview": "Antevisão",
        "showpreview": "Antever resultado",
        "showdiff": "Mostrar alterações",
        "upload-form-label-infoform-description": "Descrição",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nome do ficheiro",
-       "foreign-structured-upload-form-label-own-work": "Este é minha obra própria",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorias",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que estou a carregar este ficheiro segundo as condições de serviço e política de licenças de {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Se não é capaz de carregar este ficheiro sob as políticas de {{SITENAME}}, por favor feche esta janela e tente outro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Poderá querer experimentar [[Special:Upload|a página padrão de carregamento]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Entendo que estou a carregar este ficheiro em um repositório partilhado. Confirmo que estou a fazê-lo cumprindo com os termos de serviço e com as políticas de licenciamento.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Se não é capaz de carregar este ficheiro sob as políticas do repositório partilhado, por favor feche esta janela e tente outro método.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se este ficheiro puder ser carregado de acordo com suas as políticas.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Confirmo que sou o proprietário dos direitos de autor deste ficheiro, e aceito partilhar irrevogavelmente este ficheiro para o Wikimedia Commons nos termos da licença [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuição-CompartilhaIgual 4.0], e concordo com os [https://wikimediafoundation.org/wiki/Terms_of_Use Termos de Utilização].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Se não é o proprietário dos direitos de autor deste ficheiro, ou caso deseje partilhá-lo sob uma licença diferente, considere utilizar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Assistente de Envio de Ficheiros do Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se o sítio aceitar o carregamento deste ficheiro de acordo com as suas políticas.",
+       "upload-form-label-own-work": "Este é minha obra própria",
+       "upload-form-label-infoform-categories": "Categorias",
+       "upload-form-label-infoform-date": "Data",
+       "upload-form-label-own-work-message-local": "Confirmo que estou a carregar este ficheiro segundo as condições de serviço e política de licenças de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Se não é capaz de carregar este ficheiro sob as políticas de {{SITENAME}}, por favor feche esta janela e tente outro método.",
+       "upload-form-label-not-own-work-local-local": "Poderá querer experimentar [[Special:Upload|a página padrão de carregamento]].",
+       "upload-form-label-own-work-message-default": "Entendo que estou a carregar este ficheiro em um repositório partilhado. Confirmo que estou a fazê-lo cumprindo com os termos de serviço e com as políticas de licenciamento.",
+       "upload-form-label-not-own-work-message-default": "Se não é capaz de carregar este ficheiro sob as políticas do repositório partilhado, por favor feche esta janela e tente outro método.",
+       "upload-form-label-not-own-work-local-default": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se este ficheiro puder ser carregado de acordo com suas as políticas.",
+       "upload-form-label-own-work-message-shared": "Confirmo que sou o proprietário dos direitos de autor deste ficheiro, e aceito partilhar irrevogavelmente este ficheiro para o Wikimedia Commons nos termos da licença [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuição-CompartilhaIgual 4.0], e concordo com os [https://wikimediafoundation.org/wiki/Terms_of_Use Termos de Utilização].",
+       "upload-form-label-not-own-work-message-shared": "Se não é o proprietário dos direitos de autor deste ficheiro, ou caso deseje partilhá-lo sob uma licença diferente, considere utilizar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Assistente de Envio de Ficheiros do Commons].",
+       "upload-form-label-not-own-work-local-shared": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se o sítio aceitar o carregamento deste ficheiro de acordo com as suas políticas.",
        "backend-fail-stream": "Não foi possível transmitir o ficheiro \"$1\".",
        "backend-fail-backup": "Não foi possível fazer cópia de segurança do ficheiro \"$1\".",
        "backend-fail-notexists": "O ficheiro $1 não existe.",
index 9764245..751bb82 100644 (file)
        "minoredit": "Text above Save page button in editor\n\nSee also:\n* {{msg-mw|Minoredit}}\n* {{msg-mw|Accesskey-minoredit}}\n* {{msg-mw|Tooltip-minoredit}}",
        "watchthis": "Text of checkbox above {{msg-mw|Showpreview}} button in editor.\n\nSee also:\n* {{msg-mw|Watchthis}}\n* {{msg-mw|Accesskey-watch}}\n* {{msg-mw|Tooltip-watch}}\n{{Identical|Watch this page}}",
        "savearticle": "Text on the Save page button. See also {{msg-mw|showpreview}} and {{msg-mw|showdiff}} for the other buttons.\n\nSee also:\n* {{msg-mw|Savearticle}}\n* {{msg-mw|Accesskey-save}}\n* {{msg-mw|Tooltip-save}}\n{{Identical|Save page}}",
+       "publishpage": "Text on the button to save the changes to the page. It should be an action which is short and makes clear that the effect is immediate and public.\n\nSee also {{msg-mw|showpreview}} and {{msg-mw|showdiff}} for the other buttons.\n\nNote: This i18n is being introduced in advance of usage to provide extra time for translators.\n\nSee also:\n* {{msg-mw|Accesskey-publish}}\n* {{msg-mw|Tooltip-publish}}\n{{Identical|Publish page}}",
        "preview": "The title of the Preview page shown after clicking the \"Show preview\" button in the edit page. Since this is a heading, it should probably be translated as a noun and not as a verb.\n\n{{Identical|Preview}}",
        "showpreview": "The text of the button to preview the page you are editing. See also {{msg-mw|showdiff}} and {{msg-mw|savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}\n{{Identical|Show preview}}",
        "showdiff": "Button below the edit page. See also {{msg-mw|Showpreview}} and {{msg-mw|Savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}\n{{Identical|Show change}}",
        "upload-form-label-infoform-description-tooltip": "The tooltip documenting the description fields on the details page.\n\nIdentical to {{msg-mw|mwe-upwiz-tooltip-description}}.",
        "upload-form-label-usage-title": "Title for the insert form showing how to use the uploaded item.\n{{Identical|Usage}}",
        "upload-form-label-usage-filename": "Label for the file name input\n{{Identical|Filename}}",
-       "foreign-structured-upload-form-label-own-work": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Label for own work confirmation checkbox",
-       "foreign-structured-upload-form-label-infoform-categories": "Label for category selector input\n{{Identical|Category}}",
-       "foreign-structured-upload-form-label-infoform-date": "Label for date input\n{{Identical|Date}}",
-       "foreign-structured-upload-form-label-own-work-message-local": "Message shown by local when a user affirms that their file upload to the local wiki follows the terms of service and licensing policies of the local wiki.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Message shown by local when a user cannot upload a file to the local wiki.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Suggests uploading a file via Special:Upload instead of using whatever method they're currently using.",
-       "foreign-structured-upload-form-label-own-work-message-default": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Message shown by default when a user cannot upload a file to a remote wiki.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Legal message, confirming that the user is allowed to upload the file.",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Explains alternatives when the copyright isn't owned by the uploader.",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Message suggesting the user might want to upload a file locally instead of to Wikimedia Commons.",
+       "upload-form-label-own-work": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Label for own work confirmation checkbox",
+       "upload-form-label-infoform-categories": "Label for category selector input\n{{Identical|Category}}",
+       "upload-form-label-infoform-date": "Label for date input\n{{Identical|Date}}",
+       "upload-form-label-own-work-message-local": "Message shown by local when a user affirms that their file upload to the local wiki follows the terms of service and licensing policies of the local wiki.",
+       "upload-form-label-not-own-work-message-local": "Message shown by local when a user cannot upload a file to the local wiki.",
+       "upload-form-label-not-own-work-local-local": "Suggests uploading a file via Special:Upload instead of using whatever method they're currently using.",
+       "upload-form-label-own-work-message-default": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
+       "upload-form-label-not-own-work-message-default": "Message shown by default when a user cannot upload a file to a remote wiki.",
+       "upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki.",
+       "upload-form-label-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Legal message, confirming that the user is allowed to upload the file.",
+       "upload-form-label-not-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Explains alternatives when the copyright isn't owned by the uploader.",
+       "upload-form-label-not-own-work-local-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Message suggesting the user might want to upload a file locally instead of to Wikimedia Commons.",
        "backend-fail-stream": "Parameters:\n* $1 - a filename",
        "backend-fail-backup": "Parameters:\n* $1 - a filename",
        "backend-fail-notexists": "Parameters:\n* $1 - a filename",
        "changecontentmodel-success-text": "Message telling user that their change has been successfully done.\n* $1 - Target page title",
        "changecontentmodel-cannot-convert": "Error message shown if the content model cannot be changed to the specified type. $1 is the page title, $2 is the localized content model name.",
        "changecontentmodel-nodirectediting": "Error message shown if the content model does not allow for direct editing. $1 is the localized name of the content model.",
+       "changecontentmodel-emptymodels-title": "Title of the error page shown if the content model cannot be changed to any of the available types.",
+       "changecontentmodel-emptymodels-text": "Text of the error page shown if the content model cannot be changed to any of the available types. $1 is the page title.",
        "log-name-contentmodel": "{{doc-logpage}}\n\nTitle of [[Special:Log/contentmodel]].",
        "log-description-contentmodel": "Text in [[Special:Log/contentmodel]].",
        "logentry-contentmodel-new": "{{Logentry}}\n$4 is not used.\n$5 is the new content model.",
        "whatlinkshere-prev": "This is part of the navigation message on the top and bottom of Whatlinkshere pages, where it is used as the first argument of {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - the number of items shown per page. It is not used when $1 is zero; not sure what happens when $1 is one.\nSpecial pages use {{msg-mw|Prevn}} instead (still as an argument to {{msg-mw|Viewprevnext}}).\n\nSee also:\n* {{msg-mw|Whatlinkshere-next}}\n{{Identical|Previous}}",
        "whatlinkshere-next": "This is part of the navigation message on the top and bottom of Whatlinkshere pages, where it is used as the second argument of {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - the number of items shown per page. It is not used when $1 is zero; not sure what happens when $1 is one.\nSpecial pages use {{msg-mw|Nextn}} instead (still as an argument to {{msg-mw|Viewprevnext}}).\n\nSee also:\n* {{msg-mw|Whatlinkshere-prev}}\n{{Identical|Next}}",
        "whatlinkshere-links": "Used on [[Special:WhatLinksHere]]. It is a link to the WhatLinksHere page of that page.\n\nExample line:\n* [[Main Page]] ([[Special:WhatLinksHere/Main Page|{{int:whatlinkshere-links}}]])\n{{Identical|Link}}",
-       "whatlinkshere-hideredirs": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Redirect}}",
-       "whatlinkshere-hidetrans": "First filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Transclusion}}",
-       "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Link}}",
+       "whatlinkshere-hideredirs": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
+       "whatlinkshere-hidetrans": "First filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
+       "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
        "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}}",
        "unlockdbsuccesssub": "Used as subtitle in [[Special:UnlockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
        "lockdbsuccesstext": "Used as message text in [[Special:LockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
        "unlockdbsuccesstext": "Used as message text in [[Special:UnlockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
-       "lockfilenotwritable": "'No longer needed' on wikipedia.",
+       "lockfilenotwritable": "Used as error message in [[Special:LockDB]].",
+       "databaselocked": "Used as error message in [[Special:LockDB]].\nThe title of this error message is {{msg-mw|Lockdb}}.\n\nSee also:\n* {{msg-mw|Lockdb|title}}\n* {{msg-mw|Databaselocked|message}}",
        "databasenotlocked": "Used as error message in [[Special:UnlockDB]].\nThe title of this error message is {{msg-mw|Lockdb}}.\n\nSee also:\n* {{msg-mw|Lockdb|title}}\n* {{msg-mw|Databasenotlocked|message}}",
        "lockedbyandtime": "Used as part of the message when a database is locked through [[Special:LockDB]]. Parameters:\n* $1 is the user that locked the database.\n* $2 is the date on which the lock was made\n* $3 is the time at which the lock was made",
        "move-page": "Used as page title of [[Special:MovePage]] to move pages.\n\nSee example: [[Special:MovePage/Portal:En]].\n\nParameters:\n* $1 - the name of the page to be moved (without link)\n{{Identical|Move}}",
        "accesskey-ca-nstab-category": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Nstab-category}}\n* {{msg-mw|Accesskey-ca-nstab-category}}\n* {{msg-mw|Tooltip-ca-nstab-category}}",
        "accesskey-minoredit": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Minoredit}}\n* {{msg-mw|Accesskey-minoredit}}\n* {{msg-mw|Tooltip-minoredit}}",
        "accesskey-save": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Savearticle}}\n* {{msg-mw|Accesskey-save}}\n* {{msg-mw|Tooltip-save}}",
+       "accesskey-publish": "{{doc-accesskey}}\n\nNote: This i18n is being introduced in advance of usage to provide extra time for translators.\nSee also:\n* {{msg-mw|publishpage}}\n* {{msg-mw|Tooltip-publish}}",
        "accesskey-preview": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}",
        "accesskey-diff": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}",
        "accesskey-compareselectedversions": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Compareselectedversions}}\n* {{msg-mw|Accesskey-compareselectedversions}}\n* {{msg-mw|Tooltip-compareselectedversions}}",
        "tooltip-ca-nstab-category": "Tooltip shown when hovering over the {{msg-mw|Nstab-category}} tab.\n\nSee also:\n* {{msg-mw|Nstab-category}}\n* {{msg-mw|Accesskey-ca-nstab-category}}\n* {{msg-mw|Tooltip-ca-nstab-category}}",
        "tooltip-minoredit": "Tooltip shown when hovering over the \"{{msg-mw|Minoredit}}\" link below the edit form.\n\nSee also:\n* {{msg-mw|Minoredit}}\n* {{msg-mw|Accesskey-minoredit}}\n* {{msg-mw|Tooltip-minoredit}}",
        "tooltip-save": "This is the text that appears when you hover the mouse over {{msg-mw|Savearticle}} button on the edit page.\n\nSee also:\n* {{msg-mw|Savearticle}}\n* {{msg-mw|Accesskey-save}}\n* {{msg-mw|Tooltip-save}}",
+       "tooltip-publish": "This is the text that appears when you hover the mouse over {{msg-mw|publishpage}} button on the edit page.\n\nNote: This i18n is being introduced in advance of usage to provide extra time for translators.\n\nSee also:\n* {{msg-mw|publishpage}}\n* {{msg-mw|Accesskey-publish}}\n{{Identical|Publish page}}",
        "tooltip-preview": "Tooltip shown when hovering over {{msg-mw|Showpreview}} button.\n\nIf the length of the translated message is over 60 characters (including spaces) then the end of the message will be cut off when using Firefox 2.0.0.7 browser, Linux operating system and the Monobook skin.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}",
        "tooltip-diff": "This is the text (tooltip) that appears when you hover the mouse over {{msg-mw|Showdiff}} button on the edit page.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}",
        "tooltip-compareselectedversions": "Tooltip of {{msg-mw|Compareselectedversions}} (which is used as button in history pages).\n\nSee also:\n* {{msg-mw|Compareselectedversions}}\n* {{msg-mw|Accesskey-compareselectedversions}}\n* {{msg-mw|Tooltip-compareselectedversions}}",
        "variantname-gan": "{{Optional}}\n\nVariant option for wikis with variants conversion enabled.",
        "variantname-sr-ec": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-ec</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-cyrl</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
        "variantname-sr-el": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-el</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-latn</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
-       "variantname-sr": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
+       "variantname-sr": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
        "variantname-kk-kz": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "variantname-kk-tr": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "variantname-kk-cn": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.\n{{Identical|User agent}}",
        "searchsuggest-search": "Greyed out default text in the simple search box in the Vector skin. (It disappears and lets the user enter the requested search terms when the search box receives focus.)\n\n{{Identical|Search}}",
        "searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.",
+       "api-error-autoblocked": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Autoblockedtext}}.",
        "api-error-badaccess-groups": "API error message that can be used for client side localisation of API errors.",
        "api-error-badtoken": "API error message that can be used for client side localisation of API errors.",
+       "api-error-blocked": "API error message that can be used for client side localisation of API errors.",
        "api-error-copyuploaddisabled": "API error message that can be used for client side localisation of API errors.",
        "api-error-duplicate": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files",
        "api-error-duplicate-archive": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files",
        "api-error-nomodule": "API error message that can be used for client side localisation of API errors.",
        "api-error-ok-but-empty": "API error message that can be used for client side localisation of API errors.",
        "api-error-overwrite": "API error message that can be used for client side localisation of API errors.",
+       "api-error-ratelimited": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Actionthrottledtext}}",
        "api-error-stashfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-publishfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-stasherror": "API error message that can be used for client side localisation of API errors.",
index af03e7f..fb7e4fc 100644 (file)
        "userrights-changeable-col": "Grupuri pe care le puteți schimba",
        "userrights-unchangeable-col": "Grupuri pe care nu le puteți schimba",
        "userrights-conflict": "Conflict al schimbării drepturilor de utilizator! Reverificați și confirmați-vă modificările.",
-       "userrights-removed-self": "V-ați eliminat cu succes propriile drepturi. Ca urmare, nu mai puteți accesa această pagină.",
+       "userrights-removed-self": "V-ați eliminat propriile drepturi. Ca urmare, nu mai puteți accesa această pagină.",
        "group": "Grup:",
        "group-user": "Utilizatori",
        "group-autoconfirmed": "Utilizatori autoconfirmați",
        "upload-form-label-infoform-description-tooltip": "Descrieți pe scurt orice este notabil despre lucrare.\nPentru o fotografie, menționați principalele lucruri care sunt reprezentate, evenimentul sau locul.",
        "upload-form-label-usage-title": "Utilizare",
        "upload-form-label-usage-filename": "Numele fișierului",
-       "foreign-structured-upload-form-label-own-work": "Aceasta este propria mea operă",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorii",
-       "foreign-structured-upload-form-label-infoform-date": "Dată",
-       "foreign-structured-upload-form-label-own-work-message-local": "Confirm că încarc acest fișier în concordanță cu termenii serviciului și politicile de licențiere de la {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Dacă nu puteți încărca acest fișier în conformitate cu politicile de la {{SITENAME}}, închideți această casetă de dialog și încercați altă metodă.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Poate doriți să încercați [[Special:Upload|pagina de încărcare implicită]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Înțeleg că încarc acest fișier într-un depozit partajat. Confirm că fac acest lucru conform termenilor serviciului și politicilor de licențiere de acolo.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Dacă nu puteți încărca acest fișier în conformitate cu politicile depozitului partajat, închideți această casetă de dialog și încercați altă metodă.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Poate doriți să încercați [[Special:Upload|pagina de încărcare de la {{SITENAME}}]], în cazul în care acest fișier poate fi încărcat acolo în conformitate cu politicele lor.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Declar că dețin drepturile de autor asupra acestui fișier, accept să public irevocabil acest fișier la Wikimedia Commons sub licența [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuire și distribuire în condiții identice 4.0] și sunt de acord cu [https://wikimediafoundation.org/wiki/Terms_of_Use Termenii de utilizare].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Dacă nu dețineți drepturile de autor asupra acestui fișier sau doriți să-l publicați sub o altă licență, puteți utiliza [https://commons.wikimedia.org/wiki/Special:UploadWizard Expertul de încărcare de la Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Poate doriți să încercați [[Special:Upload|pagina de încărcare de la {{SITENAME}}]], în cazul în care acest site permite încărcarea acestui fișier în conformitate cu politicele lor.",
+       "upload-form-label-own-work": "Aceasta este propria mea operă",
+       "upload-form-label-infoform-categories": "Categorii",
+       "upload-form-label-infoform-date": "Dată",
+       "upload-form-label-own-work-message-local": "Confirm că încarc acest fișier în concordanță cu termenii serviciului și politicile de licențiere de la {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Dacă nu puteți încărca acest fișier în conformitate cu politicile de la {{SITENAME}}, închideți această casetă de dialog și încercați altă metodă.",
+       "upload-form-label-not-own-work-local-local": "Poate doriți să încercați [[Special:Upload|pagina de încărcare implicită]].",
+       "upload-form-label-own-work-message-default": "Înțeleg că încarc acest fișier într-un depozit partajat. Confirm că fac acest lucru conform termenilor serviciului și politicilor de licențiere de acolo.",
+       "upload-form-label-not-own-work-message-default": "Dacă nu puteți încărca acest fișier în conformitate cu politicile depozitului partajat, închideți această casetă de dialog și încercați altă metodă.",
+       "upload-form-label-not-own-work-local-default": "Poate doriți să încercați [[Special:Upload|pagina de încărcare de la {{SITENAME}}]], în cazul în care acest fișier poate fi încărcat acolo în conformitate cu politicele lor.",
+       "upload-form-label-own-work-message-shared": "Declar că dețin drepturile de autor asupra acestui fișier, accept să public irevocabil acest fișier la Wikimedia Commons sub licența [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuire și distribuire în condiții identice 4.0] și sunt de acord cu [https://wikimediafoundation.org/wiki/Terms_of_Use Termenii de utilizare].",
+       "upload-form-label-not-own-work-message-shared": "Dacă nu dețineți drepturile de autor asupra acestui fișier sau doriți să-l publicați sub o altă licență, puteți utiliza [https://commons.wikimedia.org/wiki/Special:UploadWizard Expertul de încărcare de la Commons].",
+       "upload-form-label-not-own-work-local-shared": "Poate doriți să încercați [[Special:Upload|pagina de încărcare de la {{SITENAME}}]], în cazul în care acest site permite încărcarea acestui fișier în conformitate cu politicele lor.",
        "backend-fail-stream": "Imposibil de citit fișierul $1.",
        "backend-fail-backup": "Imposibil de efectuat o copie de rezervă a fișierului $1.",
        "backend-fail-notexists": "Fișierul $1 nu există.",
        "special-characters-group-ipa": "AFI",
        "special-characters-group-symbols": "Simboluri",
        "special-characters-group-greek": "Greacă",
+       "special-characters-group-greekextended": "Greacă extinsă",
        "special-characters-group-cyrillic": "Chirilică",
        "special-characters-group-arabic": "Arabă",
        "special-characters-group-arabicextended": "Arabă extinsă",
index f9515d4..eb0bed1 100644 (file)
        "upload-form-label-infoform-description": "Descrizione",
        "upload-form-label-usage-title": "Ause",
        "upload-form-label-usage-filename": "Nome d'u file",
-       "foreign-structured-upload-form-label-infoform-categories": "Categorije",
-       "foreign-structured-upload-form-label-infoform-date": "Date",
+       "upload-form-label-infoform-categories": "Categorije",
+       "upload-form-label-infoform-date": "Date",
        "backend-fail-stream": "Non ge pozze trasmettere 'u file $1.",
        "backend-fail-backup": "Non ge pozze cupià 'u file $1.",
        "backend-fail-notexists": "'U file $1 non g'esiste.",
index bda02c8..bfd77ff 100644 (file)
@@ -90,7 +90,8 @@
                        "Ядерный Трамвай",
                        "Исмаил Садуев",
                        "Lemondoge",
-                       "SamGold"
+                       "SamGold",
+                       "Jdforrester"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "minoredit": "Малое изменение",
        "watchthis": "Включить эту страницу в список наблюдения",
        "savearticle": "Записать страницу",
+       "publishpage": "издавать страницу",
        "preview": "Предпросмотр",
        "showpreview": "Предварительный просмотр",
        "showdiff": "Внесённые изменения",
        "userpage-userdoesnotexist": "Учётной записи «<nowiki>$1</nowiki>» не существует. Убедитесь, что вы действительно желаете создать или изменить эту страницу.",
        "userpage-userdoesnotexist-view": "Не зарегистрировано учётной записи «$1».",
        "blocked-notice-logextract": "Этот участник в данный момент заблокирован.\nНиже приведена последняя запись из журнала блокировок:",
-       "clearyourcache": "'''Замечание.''' Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.\n* '''Firefox / Safari:''' Удерживая клавишу ''Shift'', нажмите на панели инструментов ''Обновить'' либо нажмите ''Ctrl-F5'' или ''Ctrl-R'' (''⌘-R'' на Mac)\n* '''Google Chrome:''' Нажмите ''Ctrl-Shift-R'' (''⌘-Shift-R'' на Mac)\n* '''Internet Explorer:''' Удерживая ''Ctrl'', нажмите ''Обновить'' либо нажмите ''Ctrl-F5''\n* '''Opera:''' Выберите очистку кэша в меню ''Инструменты → Настройки''",
+       "clearyourcache": "<strong>Замечание.</strong> Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.\n* <strong>Firefox / Safari:</strong> Удерживая клавишу <em>Shift</em>, нажмите на панели инструментов <em>Обновить</em> либо нажмите <em>Ctrl-F5</em> или <em>Ctrl-R</em> (<em>⌘-R</em> на Mac)\n* <strong>Google Chrome:</strong> Нажмите <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Mac)\n* <strong>Internet Explorer:</strong> Удерживая <em>Ctrl</em>, нажмите <em>Обновить</em> либо нажмите <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Перейдите в <em>Menu → Настройки</em> (<em>Opera → Настройки</em> на Mac), а затем <em>Безопасность → Очистить историю посещений → Кэшированные изображения и файлы</em>",
        "usercssyoucanpreview": "'''Подсказка.''' Нажмите кнопку «{{int:showpreview}}», чтобы проверить свой новый CSS-файл перед сохранением.",
        "userjsyoucanpreview": "'''Подсказка.''' Нажмите кнопку «{{int:showpreview}}», чтобы проверить свой новый JS-файл перед сохранением.",
        "usercsspreview": "'''Помните, что это только предварительный просмотр вашего CSS-файла, он ещё не сохранён!'''",
        "upload-form-label-infoform-description-tooltip": "Коротко опишите всё самое важное об этом произведении. Для фото — укажите, что главное изображено, обстоятельства съёмки или место.",
        "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": "В том случае, если этот файл может быть загружен в соответствии с правилами сайта {{SITENAME}}, вы также можете попробовать использовать его [[Special:Upload|страницу загрузки]].",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Я подтверждаю, что являюсь владельцем авторских прав на этот файл, и соглашаюсь на безотзывной основе разместить этот файл на Викискладе под лицензией [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0], а также соглашаюсь с [https://wikimediafoundation.org/wiki/Условия_использования Условиями использования].",
-       "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": "В том случае, если этот файл может быть загружен в соответствии с правилами сайта {{SITENAME}}, вы также можете попробовать использовать его [[Special:Upload|страницу загрузки]].",
+       "upload-form-label-own-work": "Это моя собственная работа",
+       "upload-form-label-infoform-categories": "Категории",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Я подтверждаю, что загружаю этот файл в соответствиями с правилами и лицензионной политикой сайта {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Если Вы не можете загрузить этот файл в соответствиями с правилами сайта {{SITENAME}}, пожалуйста, закройте это диалоговое окно и попробуйте другой метод.",
+       "upload-form-label-not-own-work-local-local": "Возможно, вы также захотите попробовать [[Special:Upload|страницу загрузки по умолчанию]].",
+       "upload-form-label-own-work-message-default": "Я понимаю, что загружаю этот файл в общий репозиторий. Я подтверждаю, что я делаю это в соответствии с пользовательским соглашением и лицензионной политикой.",
+       "upload-form-label-not-own-work-message-default": "Если Вы не можете загрузить этот файл в соответствиями с правилами общего хранилища, пожалуйста, закройте это диалоговое окно и попробуйте другой метод.",
+       "upload-form-label-not-own-work-local-default": "В том случае, если этот файл может быть загружен в соответствии с правилами сайта {{SITENAME}}, вы также можете попробовать использовать его [[Special:Upload|страницу загрузки]].",
+       "upload-form-label-own-work-message-shared": "Я подтверждаю, что являюсь владельцем авторских прав на этот файл, и соглашаюсь на безотзывной основе разместить этот файл на Викискладе под лицензией [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0], а также соглашаюсь с [https://wikimediafoundation.org/wiki/Условия_использования Условиями использования].",
+       "upload-form-label-not-own-work-message-shared": "Если вы не являетесь владельцем авторских прав на этот файл, или вы хотите выпустить его под другой лицензией, рассмотрите возможность использования [https://commons.wikimedia.org/wiki/Special:UploadWizard Мастера загрузки на Викисладе].",
+       "upload-form-label-not-own-work-local-shared": "В том случае, если этот файл может быть загружен в соответствии с правилами сайта {{SITENAME}}, вы также можете попробовать использовать его [[Special:Upload|страницу загрузки]].",
        "backend-fail-stream": "Не удалось транслировать файл $1.",
        "backend-fail-backup": "Невозможно сделать резервную копию файла $1.",
        "backend-fail-notexists": "Файл $1 не существует.",
        "changecontentmodel-success-text": "Модель содержимого [[:$1]] была изменена.",
        "changecontentmodel-cannot-convert": "Содержимое [[:$1]] не может быть преобразовано к типу $2.",
        "changecontentmodel-nodirectediting": "Модель содержимого $1 не поддерживает прямое редактирование",
+       "changecontentmodel-emptymodels-title": "Нет доступных моделей содержимого",
+       "changecontentmodel-emptymodels-text": "Содержимое на [[:$1]] не может быть преобразовано ни к одному типу.",
        "log-name-contentmodel": "Журнал изменения моделей содержимого",
        "log-description-contentmodel": "События, связанные с моделями содержимого страниц",
        "logentry-contentmodel-new": "$1 создал{{GENDER:$2||а}} страницу $3 с использованием нестандартной модели содержимого «$5»",
        "lockdbsuccesstext": "База данных проекта была заблокирована.<br />\nНе забудьте [[Special:UnlockDB|убрать блокировку]] после завершения процедуры обслуживания.",
        "unlockdbsuccesstext": "База данных проекта была разблокирована.",
        "lockfilenotwritable": "Нет права на запись в файл блокировки базы данных. Чтобы заблокировать или разблокировать базу данных, веб-сервер должен иметь разрешение на запись в этот файл.",
+       "databaselocked": "База данных уже заблокирована.",
        "databasenotlocked": "База данных не была заблокирована.",
        "lockedbyandtime": "($1 $2 $3)",
        "move-page": "$1 — переименование",
        "tooltip-ca-nstab-category": "Страница категории",
        "tooltip-minoredit": "Отметить это изменение как незначительное",
        "tooltip-save": "Сохранить ваши изменения",
+       "tooltip-publish": "Опубликовать ваши изменения",
        "tooltip-preview": "Предварительный просмотр страницы; пожалуйста, используйте его перед сохранением!",
        "tooltip-diff": "Показать изменения, сделанные по отношению к исходному тексту.",
        "tooltip-compareselectedversions": "Посмотреть разницу между двумя выбранными версиями этой страницы.",
        "feedback-useragent": "Браузер:",
        "searchsuggest-search": "Поиск",
        "searchsuggest-containing": "содержащие…",
+       "api-error-autoblocked": "Ваш IP-адрес был автоматически заблокирован, потому что он был использован заблокированным участником.",
        "api-error-badaccess-groups": "Вам не разрешено загружать файлы в эту вики.",
        "api-error-badtoken": "Внутренняя ошибка:  некорректный токен.",
+       "api-error-blocked": "Редактирование было для вас заблокировано.",
        "api-error-copyuploaddisabled": "Загрузка по URL-адресу отключена на этом сервере.",
        "api-error-duplicate": "Уже {{PLURAL:$1|существует другой файл|существуют другие файлы}} с таким же содержимым.",
        "api-error-duplicate-archive": "Раньше на сайте {{PLURAL:$1|1=уже был файл|были файлы}} с точно таким же содержанием, но {{PLURAL:$1|1=он был удалён|они были удалены}}.",
        "api-error-nomodule": "Внутренняя ошибка: не настроен модуль загрузки.",
        "api-error-ok-but-empty": "Внутренняя ошибка: нет ответа от сервера.",
        "api-error-overwrite": "Не допускается замена существующего файла.",
+       "api-error-ratelimited": "Вы пытаетесь загрузить несколько файлов за более короткий промежуток времени, чем это позволено.\nПожалуйста, попробуйте ещё раз через несколько минут.",
        "api-error-stashfailed": "Внутренняя ошибка: сервер не смог сохранить временный файл.",
        "api-error-publishfailed": "Внутренняя ошибка: сервер не смог сохранить временный файл.",
        "api-error-stasherror": "При загрузке файла в хранилище произошла ошибка.",
index 6bd7f31..c9c9069 100644 (file)
        "restriction-level-autoconfirmed": "अर्धसंरक्षितम्",
        "restriction-level-all": "कोऽपि स्तरः ।",
        "undelete": "अपमर्जितपुटानि अवलोकयतु ।",
-       "undeletepage": "à¤\85पमरà¥\8dà¤\9cितपà¥\81à¤\9fानि à¤¦à¥\83षà¥\8dà¤\9fà¥\8dवा à¤ªà¥\81नसà¥\8dथापयतà¥\81 à¥¤",
+       "undeletepage": "à¤\85पमरà¥\8dà¤\9cितपà¥\81षà¥\8dठानि à¤¦à¥\83षà¥\8dà¤\9fà¥\8dवा à¤ªà¥\81नसà¥\8dथापयतà¥\81",
        "undeletepagetitle": "'''अधः [[:$1|$1]] इत्येतेषाम् अपनीतावृत्तीनां दर्शनं भवति ।",
        "viewdeletedpage": "अपमर्जितपुटानि अवलोकयतु ।",
        "undeletepagetext": "{{PLURAL:$1|$1 पृष्ठं|$1 पृष्ठानि}} इत्येतानि अपनीतानि किन्तु एतानि लेखागारे सन्ति अपि च पुनस्थापितानि कर्तुं शक्यते ।",
index 6a155bb..5d6618f 100644 (file)
        "upload-form-label-infoform-description-tooltip": "Кылгастык бу айымньы туһунан сүрүннээн этиҥ. Хаартыскаҕа сүнньүнэн туох ойууламмытый, ханна түһэриллибитий.",
        "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": "Өскө, {{SITENAME}} быраабылатынан угар сатанар буоллаҕына, кини [[Special:Upload|киллэрии тэрилин]] туһаныаххын сөп.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Бу билэни бас билэрбин уонна Биики Ыскылаакка төнүннэрбэттии [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0] лиссиэнсийэннэн угары бигэргэтэбин. Ону тэҥэ [https://wikimediafoundation.org/wiki/Условия_использования Туһаныы усулуобуйатын кытта] сөбүлэһэбин.",
-       "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": "Өскө, {{SITENAME}} быраабылатынан угар сатанар буоллаҕына, кини [[Special:Upload|киллэрии тэрилин]] туһаныаххын эмиэ сөп.",
+       "upload-form-label-own-work": "Бу бэйэм оҥоруум",
+       "upload-form-label-infoform-categories": "Категорията",
+       "upload-form-label-infoform-date": "Күнэ-дьыла",
+       "upload-form-label-own-work-message-local": "{{SITENAME}} быраабылатын уонна лиссиэнсийэлиир бэлиитикэтин тутуһан бу билэни киллэрэрбин бигэргэтэбин.",
+       "upload-form-label-not-own-work-message-local": "Бу билэҕин {{SITENAME}} быраабылатынан угар кыаҕыҥ суох буоллаҕына, маны сап уонна атын ньыманан туһанан көр.",
+       "upload-form-label-not-own-work-local-local": "Баҕар [[Special:Upload|киллэрии сүрүн ньыматын]] туһаныаххын баҕарыаҥ.",
+       "upload-form-label-own-work-message-default": "Уопсай репозиторийга угарбын өйдөөн туран угабын. Туһаныы сиэрин уонна лиссиэнсийэлиир бэлиитикэни кытта сөп түбэһэрин мэктиэлиибин.",
+       "upload-form-label-not-own-work-message-default": "Бу билэҕин уопсай репозиторий быраабылатынан угар кыаҕыҥ суох буоллаҕына, маны сап уонна атын ньыманы туһанан көр.",
+       "upload-form-label-not-own-work-local-default": "Өскө, {{SITENAME}} быраабылатынан угар сатанар буоллаҕына, кини [[Special:Upload|киллэрии тэрилин]] туһаныаххын сөп.",
+       "upload-form-label-own-work-message-shared": "Бу билэни бас билэрбин уонна Биики Ыскылаакка төнүннэрбэттии [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0] лиссиэнсийэннэн угары бигэргэтэбин. Ону тэҥэ [https://wikimediafoundation.org/wiki/Условия_использования Туһаныы усулуобуйатын кытта] сөбүлэһэбин.",
+       "upload-form-label-not-own-work-message-shared": "Өскөтө билэни бас билбэт буоллаххына, биитэр атын лиссиэнсийэннэн угуоххун баҕарар буоллаххына, манна баар ньыманы туһаныаххын сөп: [https://commons.wikimedia.org/wiki/Special:UploadWizard Биики Ыскылаакка угуу маастара].",
+       "upload-form-label-not-own-work-local-shared": "Өскө, {{SITENAME}} быраабылатынан угар сатанар буоллаҕына, кини [[Special:Upload|киллэрии тэрилин]] туһаныаххын эмиэ сөп.",
        "backend-fail-stream": "$1 билэни ыытар табыллыбата.",
        "backend-fail-backup": "Бу билэ $1 резервнэй куопуйатын оҥорор табыллыбата.",
        "backend-fail-notexists": "Маннык $1 билэ суох эбит.",
index 23ddbe9..11f8af2 100644 (file)
        "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": "تاريخ",
+       "upload-form-label-own-work": "هيءُ منهنجو پنهنجو ڪم آهي.",
+       "upload-form-label-infoform-categories": "زمرا",
+       "upload-form-label-infoform-date": "تاريخ",
        "backend-fail-notexists": "فائيل ''$1'' وجود نٿو رکي.",
        "backend-fail-delete": "\"$1\" فائيل ڊهي نہ سگھيو.",
        "backend-fail-alreadyexists": "\"$1\" فائيل اڳ ئي وجود رکي ٿو.",
index 26fea82..062454c 100644 (file)
        "upload-form-label-infoform-description": "Opis",
        "upload-form-label-usage-title": "Korištenje",
        "upload-form-label-usage-filename": "Ime datoteke",
-       "foreign-structured-upload-form-label-own-work": "Ovo je moje djelo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Potvrđujem kako postavljam ovu datoteku u skladu sa uvjetima korištenja i politikom licenciranja na {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Ukoliko niste u stanju postaviti ovu datoteku pod politikom {{SITENAME}}, molimo zatvorite ovaj dijalog i pokušajte drugom metodom.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Također možete pokušati [[Special:Upload|na standarnoj stranici za postavljanje]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Razumijem kako postavljam ovu datoteku na dijeljeno skladište. Potvrđujem kako to činim u skladu sa uvjetima korištenja i ovdašnjom politikom licenciranja.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Ukoliko niste u stanju postaviti ovu datoteku pod politikom dijeljene ostave, molimo zatvorite ovaj dijalog i pokušajte drugu metodu.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Možete također pokušati koristeći  [[Special:Upload|stranicu za postavljanje na  {{SITENAME}}]], ukoliko se ova datoteka može postaviti pod tamošnjom politikom.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava za ovu datoteku i slažem se da ću je neopozivo postaviti na Wikimedia Commons pod licencom [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], te se slažem s [https://wikimediafoundation.org/wiki/Terms_of_Use Uvjetima korištenja].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku ili je želite postaviti pod drugom licencom, imajte na umu da možete koristiti [https://commons.wikimedia.org/wiki/Special:UploadWizard čarobnjak za postavljanje datoteka na Commonsu].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Također možete koristiti [[Special:Upload|stranicu za postavljanje datoteka na projektu {{SITENAME}}]] ako politika stranice dozvoljava postavljanje ove datoteke.",
+       "upload-form-label-own-work": "Ovo je moje djelo",
+       "upload-form-label-infoform-categories": "Kategorije",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Potvrđujem kako postavljam ovu datoteku u skladu sa uvjetima korištenja i politikom licenciranja na {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Ukoliko niste u stanju postaviti ovu datoteku pod politikom {{SITENAME}}, molimo zatvorite ovaj dijalog i pokušajte drugom metodom.",
+       "upload-form-label-not-own-work-local-local": "Također možete pokušati [[Special:Upload|na standarnoj stranici za postavljanje]].",
+       "upload-form-label-own-work-message-default": "Razumijem kako postavljam ovu datoteku na dijeljeno skladište. Potvrđujem kako to činim u skladu sa uvjetima korištenja i ovdašnjom politikom licenciranja.",
+       "upload-form-label-not-own-work-message-default": "Ukoliko niste u stanju postaviti ovu datoteku pod politikom dijeljene ostave, molimo zatvorite ovaj dijalog i pokušajte drugu metodu.",
+       "upload-form-label-not-own-work-local-default": "Možete također pokušati koristeći  [[Special:Upload|stranicu za postavljanje na  {{SITENAME}}]], ukoliko se ova datoteka može postaviti pod tamošnjom politikom.",
+       "upload-form-label-own-work-message-shared": "Potvrđujem da posjedujem autorska prava za ovu datoteku i slažem se da ću je neopozivo postaviti na Wikimedia Commons pod licencom [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], te se slažem s [https://wikimediafoundation.org/wiki/Terms_of_Use Uvjetima korištenja].",
+       "upload-form-label-not-own-work-message-shared": "Ako ne posjedujete autorska prava za ovu datoteku ili je želite postaviti pod drugom licencom, imajte na umu da možete koristiti [https://commons.wikimedia.org/wiki/Special:UploadWizard čarobnjak za postavljanje datoteka na Commonsu].",
+       "upload-form-label-not-own-work-local-shared": "Također možete koristiti [[Special:Upload|stranicu za postavljanje datoteka na projektu {{SITENAME}}]] ako politika stranice dozvoljava postavljanje ove datoteke.",
        "backend-fail-stream": "Ne mogu da emitujem datoteku $1.",
        "backend-fail-backup": "Ne mogu da napravim rezervu datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
index e4c3484..0edaa16 100644 (file)
        "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": "දිනය",
+       "upload-form-label-own-work": "මෙය මගේ ස්වකීය නිර්මාණයකි",
+       "upload-form-label-infoform-categories": "ප්‍රවර්ග",
+       "upload-form-label-infoform-date": "දිනය",
        "backend-fail-stream": "$1 ගොනුව ප්‍රවාහ කල නොහැක.",
        "backend-fail-backup": "$1 ගොනුව උපස්ථ කල නොහැක.",
        "backend-fail-notexists": "$1 ගොනුව නොපවතියි.",
index 1a85f04..728952f 100644 (file)
@@ -54,7 +54,7 @@
        "tog-ccmeonemails": "Pošlji mi kopijo e-pošt, ki jih pošljem drugim uporabnikom",
        "tog-diffonly": "Pod primerjavo ne prikaži vsebine strani",
        "tog-showhiddencats": "Prikaži skrite kategorije",
-       "tog-norollbackdiff": "Ne prikaži primerjave po izvedeni vrnitvi",
+       "tog-norollbackdiff": "Po izvedeni vrnitvi ne prikaži primerjave",
        "tog-useeditwarning": "Opozori me, ko skušam zapreti urejevalno polje z neshranjenimi spremembami",
        "tog-prefershttps": "Med prijavo vedno uporabljaj varno povezavo",
        "underline-always": "Vedno",
        "minoredit": "manjše urejanje",
        "watchthis": "Opazuj članek",
        "savearticle": "Shrani stran",
+       "publishpage": "Objavi stran",
        "preview": "Predogled",
        "showpreview": "Prikaži predogled",
        "showdiff": "Prikaži spremembe",
        "userpage-userdoesnotexist": "Uporabniški račun »<nowiki>$1</nowiki>« ni registriran.\nProsimo preverite, ali res želite ustvariti/urediti to stran.",
        "userpage-userdoesnotexist-view": "Uporabniški račun »$1« ni registriran.",
        "blocked-notice-logextract": "Ta uporabnik je trenutno blokiran.\nNajnovejši vnos v dnevniku blokad je prikazan spodaj:",
-       "clearyourcache": "'''Opomba:''' Da bodo spremembe prišle do veljave, po shranitvi izpraznite predpomnilnik svojega brskalnika.\n* '''Firefox/Safari:''' Držite ''Shift'' in kliknite ''Ponovno naloži'' (''Reload'') ali pritisnite ''Ctrl-Shift-R'' ali ''Ctrl-R'' (''⌘-R'' na sistemu Mac)\n* '''Internet Explorer:''' Držite ''Ctrl-F5'' in kliknite ''Osveži'' (''Refresh'') ali pritisnite ''Ctrl-F5''\n* '''Google Chrome:''' Pritisnite ''Ctrl-Shift-R'' (''⌘-Shift-R'' na sistemu Mac)\n* '''Opera:''' Počistite predpomnilnik v ''Tools → Preferences''",
+       "clearyourcache": "<strong>Opomba:</strong> Da bodo spremembe prišle do veljave, po shranitvi izpraznite predpomnilnik svojega brskalnika.\n* <strong>Firefox/Safari:</strong> Držite <em>Shift</em> in kliknite <em>Ponovno naloži</em> (<em>Reload</em>) ali pritisnite <em>Ctrl-Shift-R</em> ali <em>Ctrl-R</em> (<em>⌘-R</em> na sistemu Mac)\n* <strong>Internet Explorer:</strong> Držite <em>Ctrl-F5</em> in kliknite <em>Osveži</em> (<em>Refresh</em>) ali pritisnite <em>Ctrl-F5</em>\n* <strong>Google Chrome:</strong> Pritisnite <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na sistemu Mac)\n* <strong>Opera:</strong> Pojdite v <em>Meni → Nastavitve</em> (<em>Opera → Nastavitve</em> na sistemu Mac) in nato na <em>Zasebnost in varnost → Počisti podatke o brskanju → Predpomnjene slike in datoteke</em>.",
        "usercssyoucanpreview": "'''Nasvet:''' Za preizkušanje svojega novega CSS pred shranjevanjem uporabite gumb »{{int:showpreview}}«.",
        "userjsyoucanpreview": "'''Nasvet:''' Za preizkušanje svojega novega JavaScripta pred shranjevanjem uporabite gumb »{{int:showpreview}}«.",
        "usercsspreview": "'''Svoj uporabniški CSS le predogledujete.'''\n'''Ni še bil shranjen!'''",
        "upload-form-label-infoform-description-tooltip": "Na kratko opišite vse opazno o delu.\nPri fotografijah omenite glavne stvari, ki so upodobljene, priložnost ali kraj.",
        "upload-form-label-usage-title": "Uporaba",
        "upload-form-label-usage-filename": "Ime datoteke",
-       "foreign-structured-upload-form-label-own-work": "To je moje lastno delo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Potrjujem, da datoteko nalagam v skladu s pogoji uporabe in pravili o licenciranju na {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Če datoteke ne morete naložiti pod pogoji {{SITENAME}}, zaprite to okno in poskusite drugo metodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Morda želite poskusiti [[Special:Upload|privzeto stran za nalaganje]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Razumem, da datoteko nalagam v deljeno hrambo. Potrjujem, da to počnem v skladu s tukajšnjimi pogoji uporabe in pravili za licenciranje.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Če datoteke ne morete naložiti pod pogoji deljene hrambe, zaprite to okno in poskusite drugo metodo.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Morda želite datoteko poskusiti naložiti na [[Special:Upload|strani za nalaganje na {{SITENAME}}]], če jo lahko naložite pod njihovimi pravili.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Izjavljam, da sem lastnik avtorskih pravic te datoteke, strinjam se z nepreklicno objavo datoteke v Wikimedijini Zbirki pod dovoljenjem [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Priznanje avtorstva-Deljenje pod enakimi pogoji 4.0] in strinjam se s [https://wikimediafoundation.org/wiki/Terms_of_Use Pogoji uporabe].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Če niste lastnik avtorskih pravic datoteke ali jo želite objaviti pod drugačnim dovoljenje, uporabite [https://commons.wikimedia.org/wiki/Special:UploadWizard Čarovnik za nalaganje v Zbirko].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Morda želite datoteko poskusiti naložiti na [[Special:Upload|strani za nalaganje na {{SITENAME}}]], če stran dovoljuje nalaganje datoteke pod njihovimi pravili.",
+       "upload-form-label-own-work": "To je moje lastno delo",
+       "upload-form-label-infoform-categories": "Kategorije",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Potrjujem, da datoteko nalagam v skladu s pogoji uporabe in pravili o licenciranju na {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Če datoteke ne morete naložiti pod pogoji {{SITENAME}}, zaprite to okno in poskusite drugo metodo.",
+       "upload-form-label-not-own-work-local-local": "Morda želite poskusiti [[Special:Upload|privzeto stran za nalaganje]].",
+       "upload-form-label-own-work-message-default": "Razumem, da datoteko nalagam v deljeno hrambo. Potrjujem, da to počnem v skladu s tukajšnjimi pogoji uporabe in pravili za licenciranje.",
+       "upload-form-label-not-own-work-message-default": "Če datoteke ne morete naložiti pod pogoji deljene hrambe, zaprite to okno in poskusite drugo metodo.",
+       "upload-form-label-not-own-work-local-default": "Morda želite datoteko poskusiti naložiti na [[Special:Upload|strani za nalaganje na {{SITENAME}}]], če jo lahko naložite pod njihovimi pravili.",
+       "upload-form-label-own-work-message-shared": "Izjavljam, da sem lastnik avtorskih pravic te datoteke, strinjam se z nepreklicno objavo datoteke v Wikimedijini Zbirki pod dovoljenjem [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Priznanje avtorstva-Deljenje pod enakimi pogoji 4.0] in strinjam se s [https://wikimediafoundation.org/wiki/Terms_of_Use Pogoji uporabe].",
+       "upload-form-label-not-own-work-message-shared": "Če niste lastnik avtorskih pravic datoteke ali jo želite objaviti pod drugačnim dovoljenje, uporabite [https://commons.wikimedia.org/wiki/Special:UploadWizard Čarovnik za nalaganje v Zbirko].",
+       "upload-form-label-not-own-work-local-shared": "Morda želite datoteko poskusiti naložiti na [[Special:Upload|strani za nalaganje na {{SITENAME}}]], če stran dovoljuje nalaganje datoteke pod njihovimi pravili.",
        "backend-fail-stream": "Ne morem pretakati datoteke $1.",
        "backend-fail-backup": "Ne morem varnostno kopirati datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne obstaja.",
        "changecontentmodel-success-text": "Spremenili smo vrsto vsebine [[:$1]].",
        "changecontentmodel-cannot-convert": "Vsebine na [[:$1]] ni mogoče pretvoriti v vrsto $2.",
        "changecontentmodel-nodirectediting": "Model vsebine $1 ne podpira neposrednega urejanja",
+       "changecontentmodel-emptymodels-title": "Na voljo ni noben model vsebine",
+       "changecontentmodel-emptymodels-text": "Vsebine na [[:$1]] ni mogoče pretvoriti v katero koli vrsto.",
        "log-name-contentmodel": "Dnevnik sprememb modela vsebine",
        "log-description-contentmodel": "Dogodki, povezani z modeli vsebin strani",
        "logentry-contentmodel-new": "$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} stran $3 z neprivzetim modelom vsebine »$5«",
        "lockdbsuccesstext": "Podatkovna baza je bila zaklenjena.<br />\nNe pozabite je [[Special:UnlockDB|odkleniti]], ko boste končali z vzdrževanjem.",
        "unlockdbsuccesstext": "Zbirka podatkov {{GRAMMAR:rodilnik|{{SITENAME}}}} je spet odklenjena.",
        "lockfilenotwritable": "Datoteka zaklepanja zbirke podatkov ni zapisljiva.\nZa zaklepanje in odklepanje zbirke podatkov mora biti ta datoteka zapisljiva s strani spletnega strežnika.",
+       "databaselocked": "Zbirka podatkov je že zaklenjena.",
        "databasenotlocked": "Zbirka podatkov ni zaklenjena.",
        "lockedbyandtime": "($1 dne $2 ob $3)",
        "move-page": "Preimenuj $1",
        "tooltip-ca-nstab-category": "Prikaže stran kategorije",
        "tooltip-minoredit": "Označite kot manjše urejanje",
        "tooltip-save": "Shranite vnesene spremembe (ste si jih predogledali?)",
+       "tooltip-publish": "Objavite svoje spremembe",
        "tooltip-preview": "Pred shranjevanjem si, prosimo, predoglejte stran!",
        "tooltip-diff": "Preglejte spremembe, ki ste jih vnesli.",
        "tooltip-compareselectedversions": "Preglejte razlike med izbranima redakcijama.",
        "feedback-useragent": "Uporabniški agent:",
        "searchsuggest-search": "Iskanje",
        "searchsuggest-containing": "vsebujoč ...",
+       "api-error-autoblocked": "Vaš IP-naslov smo samodejno blokirali, saj ga je uporabljal blokiran uporabnik.",
        "api-error-badaccess-groups": "Nalaganje datotek na ta wiki vam ni dovoljeno.",
        "api-error-badtoken": "Notranja napaka: slab žeton.",
+       "api-error-blocked": "Urejanje vam je preprečeno.",
        "api-error-copyuploaddisabled": "Nalaganje preko URL je na tem strežniku onemogočeno.",
        "api-error-duplicate": "Na strani že {{PLURAL:$1|obstaja druga datoteka|obstajata drugi datoteki|obstajajo druge datoteke}} z enako vsebino.",
        "api-error-duplicate-archive": "Na strani {{PLURAL:$1|je že bila druga datoteka|sta že bili drugi datoteki|so že bile nekatere druge datoteke}} z enako vsebino, vendar {{PLURAL:$1|je bila izbrisana|sta bili izbrisani|so bile izbrisane}}.",
        "api-error-nomodule": "Notranja napaka: modul nalaganja ni izbran.",
        "api-error-ok-but-empty": "Notranja napaka: strežnik se ne odziva.",
        "api-error-overwrite": "Prepisovanje obstoječe datoteke ni dovoljeno.",
+       "api-error-ratelimited": "Poskušate naložiti več datotek v kratkem časovnem obdobju kot to dovoljuje ta wiki. Prosimo, poskusite znova čez nekaj minut.",
        "api-error-stashfailed": "Notranja napaka: strežnik ni uspel shraniti začasne datoteke.",
        "api-error-publishfailed": "Notranja napaka: strežnik ni uspel objaviti začasne datoteke.",
        "api-error-stasherror": "Pri nalaganju datoteke v hrambo je prišlo do napake.",
index 3d08fa1..faba454 100644 (file)
        "upload-form-label-infoform-name": "Назив",
        "upload-form-label-infoform-description": "Опис",
        "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": "Датум",
+       "upload-form-label-own-work": "Ово је моје сопствено дело",
+       "upload-form-label-infoform-categories": "Категорије",
+       "upload-form-label-infoform-date": "Датум",
        "backend-fail-stream": "Не могу да емитујем датотеку $1.",
        "backend-fail-backup": "Не могу да направим резерву датотеке $1.",
        "backend-fail-notexists": "Датотека $1 не постоји.",
index 696e8f4..3879905 100644 (file)
        "upload-form-label-infoform-name": "Ime",
        "upload-form-label-infoform-description": "Opis",
        "upload-form-label-usage-filename": "Naziv datoteke",
-       "foreign-structured-upload-form-label-own-work": "Ovo je moje sopstveno delo",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work": "Ovo je moje sopstveno delo",
+       "upload-form-label-infoform-categories": "Kategorije",
+       "upload-form-label-infoform-date": "Datum",
        "backend-fail-stream": "Ne mogu da emitujem datoteku $1.",
        "backend-fail-backup": "Ne mogu da napravim rezervu datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
index 3d3aa9d..df323fe 100644 (file)
        "minoredit": "Mindre ändring (m)",
        "watchthis": "Bevaka denna sida",
        "savearticle": "Spara sidan",
+       "publishpage": "Publicera sida",
        "preview": "Förhandsgranska",
        "showpreview": "Visa förhandsgranskning",
        "showdiff": "Visa ändringar",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" är inte ett registrerat användarkonto. Tänk efter om du vill skapa/redigera den här sidan.",
        "userpage-userdoesnotexist-view": "Kontot \"$1\" är inte registrerat.",
        "blocked-notice-logextract": "Användaren är blockerad.\nOrsaken till senaste blockeringen kan ses nedan:",
-       "clearyourcache": "'''OBS:''' Efter du sparat sidan kan du behöva tömma din webbläsares cache för att se ändringarna.\n*'''Firefox / Safari:''' Håll ned ''Skift'' och klicka på ''Uppdatera sidan'' eller tryck antingen ''Ctrl-F5'' eller ''Ctrl-R'' (''⌘-R'' på Mac)\n*'''Google Chrome:''' Tryck ''Ctrl-Skift-R''  (''⌘-Shift-R'' på Mac)\n*'''Internet Explorer:'''  Håll ned ''Ctrl'' och klicka på ''Uppdatera'' eller tryck ''Ctrl-F5''\n*'''Opera:''' Rensa cachen i ''Verktyg → Inställningar''",
+       "clearyourcache": "<strong>OBS:</strong> Efter du sparat sidan kan du behöva tömma din webbläsares cache för att se ändringarna.\n*<strong>Firefox / Safari:</strong> Håll ned <em>Skift</em> och klicka på <em>Uppdatera sidan</em> eller tryck antingen <em>Ctrl-F5</em> eller <em>Ctrl-R</em> (<em>⌘-R</em> på Mac)\n*<strong>Google Chrome:</strong> Tryck <em>Ctrl-Skift-R</em>  (<em>⌘-Shift-R</em> på Mac)\n*<strong>Internet Explorer:</strong>  Håll ned <em>Ctrl</em> och klicka på <em>Uppdatera</em> eller tryck <em>Ctrl-F5</em>\n*<strong>Opera:</strong> Gå till <em>Meny → Inställningar</em> (<em>Opera → Inställningar</em> på en Mac) och sedan på <em>Sekretess & säkerhet → Rensa webbläsardata → Hämtade bilder och filer</em>.",
        "usercssyoucanpreview": "'''Tips:''' Använd knappen \"{{int:showpreview}}\" för att testa din nya CSS innan du sparar.",
        "userjsyoucanpreview": "'''Tips:''' Använd knappen \"{{int:showpreview}}\" för att testa ditt nya JavaScript innan du sparar.",
        "usercsspreview": "'''Kom ihåg att du bara förhandsgranskar din användar-CSS.'''\n'''Den har inte sparats än!'''",
        "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 taggar för valda sidversioner",
+       "history-edit-tags": "Redigera märken för valda sidversioner",
        "rev-deleted-comment": "(redigeringssammanfattning togs bort)",
        "rev-deleted-user": "(användarnamn borttaget)",
        "rev-deleted-event": "(loggdetaljer borttagna)",
        "right-override-export-depth": "Exportera sidor inklusive länkade sidor till ett djup på 5",
        "right-sendemail": "Skicka e-post till andra användare",
        "right-passwordreset": "Visa e-postmeddelanden med lösenordsåterställning",
-       "right-managechangetags": "Skapa och radera [[Special:Tags|taggar]] från databasen",
-       "right-applychangetags": "Tillämpa [[Special:Tags|taggar]] tillsammans med ens ändringar",
+       "right-managechangetags": "Skapa och radera [[Special:Tags|märken]] från databasen",
+       "right-applychangetags": "Tillämpa [[Special:Tags|märken]] tillsammans med ens ändringar",
        "right-changetags": "Lägg till och ta bort godtyckliga [[Special:Tags|märken]] på individuella sidversioner och loggposter.",
        "grant-generic": "Rättighetsgrupp \"$1\"",
        "grant-group-page-interaction": "Interagera med sidor",
        "action-viewmyprivateinfo": "visa din privata information",
        "action-editmyprivateinfo": "redigera din privata information",
        "action-editcontentmodel": "ändra innehållsmodellen för en sida",
-       "action-managechangetags": "skapa och radera taggar från databasen",
-       "action-applychangetags": "tillämpa taggar tillsammans med dina ändringar",
+       "action-managechangetags": "skapa och radera märken från databasen",
+       "action-applychangetags": "tillämpa märken tillsammans med dina ändringar",
        "action-changetags": "lägg till och ta bort godtyckliga märken på individuella sidversioner och loggposter",
        "nchanges": "$1 {{PLURAL:$1|ändring|ändringar}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sedan senaste besöket}}",
        "upload-form-label-infoform-description-tooltip": "Beskriv kortfattat allt anmärkningsvärt om verket.\nFör ett foto, nämn huvudmotiv, tillfälle eller plats.",
        "upload-form-label-usage-title": "Användning",
        "upload-form-label-usage-filename": "Filnamn",
-       "foreign-structured-upload-form-label-own-work": "Detta är mitt eget verk",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategorier",
-       "foreign-structured-upload-form-label-infoform-date": "Datum",
-       "foreign-structured-upload-form-label-own-work-message-local": "Jag bekräftar att jag laddar upp denna fil enligt {{SITENAME}}s användarvillkor och licenspolicys.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Stäng denna dialogruta och prova ett annat sätt om du inte kan ladda upp denna fil under {{SITENAME}}s policys.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Du kanske också skulle vilja prova [[Special:Upload|standarduppladdningssidan]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Jag förstår att jag laddar upp denna fil till ett delat centralförvar. Jag bekräftar att jag gör det enligt de användarvillkor och licenspolicys som finns där.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Stäng denna dialogruta och prova en annan metod om du inte kan ladda upp denna fil under de policys som gäller för det delade centralförvaret.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Du kanske också skulle vilja prova att använda [[Special:Upload|uppladdningssidan på {{SITENAME}}]] om denna fil kan laddas upp där under deras policys.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Jag intygar att jag äger upphovsrätten för denna fil och samtycker till att oåterkalleligen släppa filen på Wikimedia Commons under licensen \n[https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] och jag accepterar [https://wikimediafoundation.org/wiki/Terms_of_Use villkoren för användning].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Om du inte äger upphovsrätten för denna fil eller om du önskar att släppa den under en annan licens bör du överväga att använda [https://commons.wikimedia.org/wiki/Special:UploadWizard uppladdningsguiden på Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Du kanske skulle vilja prova att använda [[Special:Upload|uppladdningssidan på {{SITENAME}}]] om webbplatsens policys tillåter att denna fil laddas upp.",
+       "upload-form-label-own-work": "Detta är mitt eget verk",
+       "upload-form-label-infoform-categories": "Kategorier",
+       "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-local": "Jag bekräftar att jag laddar upp denna fil enligt {{SITENAME}}s användarvillkor och licenspolicys.",
+       "upload-form-label-not-own-work-message-local": "Stäng denna dialogruta och prova ett annat sätt om du inte kan ladda upp denna fil under {{SITENAME}}s policys.",
+       "upload-form-label-not-own-work-local-local": "Du kanske också skulle vilja prova [[Special:Upload|standarduppladdningssidan]].",
+       "upload-form-label-own-work-message-default": "Jag förstår att jag laddar upp denna fil till ett delat centralförvar. Jag bekräftar att jag gör det enligt de användarvillkor och licenspolicys som finns där.",
+       "upload-form-label-not-own-work-message-default": "Stäng denna dialogruta och prova en annan metod om du inte kan ladda upp denna fil under de policys som gäller för det delade centralförvaret.",
+       "upload-form-label-not-own-work-local-default": "Du kanske också skulle vilja prova att använda [[Special:Upload|uppladdningssidan på {{SITENAME}}]] om denna fil kan laddas upp där under deras policys.",
+       "upload-form-label-own-work-message-shared": "Jag intygar att jag äger upphovsrätten för denna fil och samtycker till att oåterkalleligen släppa filen på Wikimedia Commons under licensen \n[https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] och jag accepterar [https://wikimediafoundation.org/wiki/Terms_of_Use villkoren för användning].",
+       "upload-form-label-not-own-work-message-shared": "Om du inte äger upphovsrätten för denna fil eller om du önskar att släppa den under en annan licens bör du överväga att använda [https://commons.wikimedia.org/wiki/Special:UploadWizard uppladdningsguiden på Commons].",
+       "upload-form-label-not-own-work-local-shared": "Du kanske skulle vilja prova att använda [[Special:Upload|uppladdningssidan på {{SITENAME}}]] om webbplatsens policys tillåter att denna fil laddas upp.",
        "backend-fail-stream": "Kunde inte strömma filen $1.",
        "backend-fail-backup": "Kunde inte säkerhetskopiera filen ''$1''.",
        "backend-fail-notexists": "Filen $1 finns inte.",
        "logempty": "Inga matchande träffar i loggen.",
        "log-title-wildcard": "Sök efter sidtitlar som börjar med texten",
        "showhideselectedlogentries": "Visa/Dölj markerade loggposter",
-       "log-edit-tags": "Redigera taggar i valda loggposter",
+       "log-edit-tags": "Redigera märken i valda loggposter",
        "checkbox-select": "Välj: $1",
        "checkbox-all": "Alla",
        "checkbox-none": "Ingen",
        "changecontentmodel-success-text": "Innehållstypen för [[:$1]] har ändrats.",
        "changecontentmodel-cannot-convert": "Innehållet på [[:$1]] kan inte konverteras till typen $2.",
        "changecontentmodel-nodirectediting": "Innehållsmodellen $1 stöder inte direkt redigering",
+       "changecontentmodel-emptymodels-title": "Inget innehållsmodeller finns tillgängliga",
+       "changecontentmodel-emptymodels-text": "Innehållet på [[:$1]] kan inte konverteras till någon typ.",
        "log-name-contentmodel": "Ändringslogg för innehållsmodellen",
        "log-description-contentmodel": "Händelser som är relaterade till en sidas innehållsmodeller",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|skapade}} sidan $3 med den icke-standardiserade innehållsmodellen \"$5\"",
        "lockdbsuccesstext": "Databasen är nu låst.\n<br />Kom ihåg att [[Special:UnlockDB|ta bort låsningen]] när du är färdig med ditt underhåll.",
        "unlockdbsuccesstext": "Databasen är upplåst.",
        "lockfilenotwritable": "Det går inte att skriva till databasens låsfil. För att låsa eller låsa upp databasen, så måste webbservern kunna skriva till den filen.",
+       "databaselocked": "Databasen är redan låst.",
        "databasenotlocked": "Databasen är inte låst.",
        "lockedbyandtime": "(av $1 den $2 kl. $3)",
        "move-page": "Flytta $1",
        "tooltip-ca-nstab-category": "Visa kategorisidan",
        "tooltip-minoredit": "Markera som mindre ändring",
        "tooltip-save": "Spara dina ändringar",
+       "tooltip-publish": "Publicera dina ändringar",
        "tooltip-preview": "Förhandsgranska dina ändringar, vänligen använd detta innan du sparar!",
        "tooltip-diff": "Visa vilka ändringar du har gjort i texten.",
        "tooltip-compareselectedversions": "Visa skillnaden mellan de två markerade versionerna av den här sidan.",
        "tags-hitcount": "$1 {{PLURAL:$1|ändring|ändringar}}",
        "tags-manage-no-permission": "Du har inte behörighet att hantera förändringstaggar.",
        "tags-manage-blocked": "Du kan inte hantera ändringsmärken när du är blockerad.",
-       "tags-create-heading": "Skapa en ny tag",
+       "tags-create-heading": "Skapa ett nytt märke",
        "tags-create-explanation": "Som standard, kommer nyskapade taggar att bli tillgängliga för användning av användare och botar.",
-       "tags-create-tag-name": "Taggnamn:",
+       "tags-create-tag-name": "Märkesnamn:",
        "tags-create-reason": "Anledning:",
        "tags-create-submit": "Skapa",
-       "tags-create-no-name": "Du måste ange ett taggnamn.",
-       "tags-create-invalid-chars": "Taggnamn får inte innehålla kommatecken (<code>,</code>) eller snedstreck (<code>/</code>).",
-       "tags-create-invalid-title-chars": "Taggnamn får inte innehålla tecken som inte kan användas i sidtitlar.",
-       "tags-create-already-exists": "Taggen \"$1\" finns redan.",
-       "tags-create-warnings-above": "Följande {{PLURAL:$2|varning |varningar}} stöttes på när du försöker skapa etiketten \" $1 \":",
-       "tags-create-warnings-below": "Vill du fortsätta att skapa taggen?",
-       "tags-delete-title": "Radera tagg",
-       "tags-delete-explanation-initial": "Du är på väg att ta bort taggen \"$1\" från databasen.",
+       "tags-create-no-name": "Du måste ange ett märkesnamn.",
+       "tags-create-invalid-chars": "Märkesnamn får inte innehålla kommatecken (<code>,</code>) eller snedstreck (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Märkesnamn får inte innehålla tecken som inte kan användas i sidtitlar.",
+       "tags-create-already-exists": "Märket \"$1\" finns redan.",
+       "tags-create-warnings-above": "Följande {{PLURAL:$2|varning|varningar}} uppstod när du försökte skapa märket \"$1\":",
+       "tags-create-warnings-below": "Vill du fortsätta att skapa märket?",
+       "tags-delete-title": "Radera märke",
+       "tags-delete-explanation-initial": "Du är på väg att ta bort märket \"$1\" från databasen.",
        "tags-delete-explanation-in-use": "Den kommer att tas bort från {{PLURAL:$2|$2 sidversioner eller loggposter|alla $2 sidversioner och/eller loggposter}} som den för närvarande används på.",
-       "tags-delete-explanation-warning": "Denna åtgärd är <strong>oåterkallelig</strong> och <strong>kan inte ångras</strong>, inte ens av databasadministratörer. Var säker på att detta är den tagg du vill radera.",
-       "tags-delete-explanation-active": "<strong>Taggen\" $1 \" är fortfarande aktiv, och kommer att fortsätta att appliceras i framtiden.</strong> För att hindra detta, gå till den eller de platser där taggen är inställd att användas, och inaktivera den där.",
+       "tags-delete-explanation-warning": "Denna åtgärd är <strong>oåterkallelig</strong> och <strong>kan inte ångras</strong>, inte ens av databasadministratörer. Var säker på att detta är det märke du vill radera.",
+       "tags-delete-explanation-active": "<strong>Märket \"$1\" är fortfarande aktivt, och kommer att fortsätta att appliceras i framtiden.</strong> För att hindra detta, gå till den eller de platser där märket är inställd att användas, och inaktivera den där.",
        "tags-delete-reason": "Anledning:",
-       "tags-delete-submit": "Radera denna tagg oåterkalleligen",
-       "tags-delete-not-allowed": "Tagg definierade med ett tillägg kan inte raderas utan att tillägget specifikt tillåter det.",
-       "tags-delete-not-found": "Taggen \"$1\" finns inte.",
-       "tags-delete-too-many-uses": "Taggen \"$1\" appliceras på mer än $2 {{PLURAL:$2|version|versioner}}, vilket innebär att den inte kan raderas.",
-       "tags-delete-warnings-after-delete": "Taggen \"$1\" raderades, men följande {{PLURAL:$2|varning|varningar}} inträffade:",
-       "tags-activate-title": "Aktivera tagg",
-       "tags-activate-question": "Du är på väg att aktivera taggen \"$1\".",
+       "tags-delete-submit": "Radera denna märke oåterkalleligen",
+       "tags-delete-not-allowed": "Märken definierade med ett tillägg kan inte raderas utan att tillägget specifikt tillåter det.",
+       "tags-delete-not-found": "Märket \"$1\" finns inte.",
+       "tags-delete-too-many-uses": "Märket \"$1\" appliceras på fler än $2 {{PLURAL:$2|version|versioner}}, vilket innebär att det inte kan raderas.",
+       "tags-delete-warnings-after-delete": "Märket \"$1\" raderades, men följande {{PLURAL:$2|varning|varningar}} uppstod:",
+       "tags-activate-title": "Aktivera märke",
+       "tags-activate-question": "Du är på väg att aktivera märket \"$1\".",
        "tags-activate-reason": "Anledning:",
-       "tags-activate-not-allowed": "Det är inte möjligt att aktivera taggen \"$1\".",
-       "tags-activate-not-found": "Taggen \"$1\" finns inte.",
+       "tags-activate-not-allowed": "Det är inte möjligt att aktivera märket \"$1\".",
+       "tags-activate-not-found": "Märket \"$1\" finns inte.",
        "tags-activate-submit": "Aktivera",
-       "tags-deactivate-title": "Inaktivera tagg",
-       "tags-deactivate-question": "Du är på väg att inaktivera taggen \"$1\".",
+       "tags-deactivate-title": "Inaktivera märke",
+       "tags-deactivate-question": "Du är på väg att inaktivera märket \"$1\".",
        "tags-deactivate-reason": "Anledning:",
-       "tags-deactivate-not-allowed": "Det är inte möjligt att inaktivera taggen \"$1\".",
+       "tags-deactivate-not-allowed": "Det är inte möjligt att inaktivera märket \"$1\".",
        "tags-deactivate-submit": "Inaktivera",
-       "tags-apply-no-permission": "Du har inte behörighet att tillämpa taggar på dina ändringar",
+       "tags-apply-no-permission": "Du har inte behörighet att tillämpa märken på dina ändringar",
        "tags-apply-blocked": "Du kan inte ange ändringsmärken med dina ändringar medans du är blockerad.",
        "tags-apply-not-allowed-one": "Märket \"$1\" kan inte läggas till manuellt.",
        "tags-apply-not-allowed-multi": "Följande {{PLURAL:$2|märke|märken}} kan inte läggas till manuellt: $1",
-       "tags-update-no-permission": "Du har inte behörighet att lägga till eller ta bort taggar från individuella sidversioner eller loggposter.",
+       "tags-update-no-permission": "Du har inte behörighet att lägga till eller ta bort märken från individuella sidversioner eller loggposter.",
        "tags-update-blocked": "Du kan inte lägga till eller ta bort ändringsmärken när du är blockerad.",
        "tags-update-add-not-allowed-one": "Märket \"$1\" kan inte läggas till manuellt.",
        "tags-update-add-not-allowed-multi": "Följande {{PLURAL:$2|märke|märken}} kan inte läggas till manuellt: $1",
        "logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
        "log-name-managetags": "Märkeshanteringslogg",
        "log-description-managetags": "Denna sida innehåller administrativa [[Special:Tags|märke]]srelaterade uppgifter. Loggen innehåller bara åtgärder som utförts manuellt av en administratör; märken kan skapas eller raderas av wikins mjukvara utan att en post registreras i loggen.",
-       "logentry-managetags-create": "$1 {{GENDER:$2|skapade}} taggen \"$4\"",
-       "logentry-managetags-delete": "$1 {{GENDER:$2|raderade}} taggen \"$4\" (borttagen från $5 {{PLURAL:$5|version eller loggpost|versioner och/eller loggposter}})",
-       "logentry-managetags-activate": "$1 {{GENDER:$2|aktiverade}} taggen \"$4\" för användning av användare och botar.",
-       "logentry-managetags-deactivate": "$1 {{GENDER:$2|inaktiverade}} taggen \"$4\" för användning av användare och botar.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|skapade}} märket \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|raderade}} märket \"$4\" (borttagen från $5 {{PLURAL:$5|version eller loggpost|versioner och/eller loggposter}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktiverade}} märket \"$4\" för användning av användare och botar.",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|inaktiverade}} märket \"$4\" för användning av användare och botar.",
        "log-name-tag": "Märkeslogg",
-       "log-description-tag": "Denna sida visar när användare har lagt till eller tagit bort [[Special:Tags|taggar]] från individuella sidversioner eller loggposter. Loggen registrerar inte handlingar där märken hanteras i redigeringar, raderingar eller liknande handlingar.",
+       "log-description-tag": "Denna sida visar när användare har lagt till eller tagit bort [[Special:Tags|märken]] från individuella sidversioner eller loggposter. Loggen registrerar inte handlingar där märken hanteras i redigeringar, raderingar eller liknande handlingar.",
        "logentry-tag-update-add-revision": "$1 {{GENDER:$2|lade till}} {{PLURAL:$7|märket|märkena}} $6 för sidversionen $4 av sidan $3",
        "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|lade till}} {{PLURAL:$7|märket|märkena}} $6 till loggposten $5 för siden $3",
        "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|tog bort}} {{PLURAL:$9|märket|märkena}} $8 från sidversionen $4 av sidan $3",
        "feedback-bugnew": "Jag kontrollerade. Rapportera ett nytt fel",
        "feedback-bugornote": "Om du har möjlighet att ge en detaljerad teknisk beskrivning av felet kan du lämna en [$1 buggrapport]. \nAnvänd annars formuläret nedan. Din kommentar kommer att läggas till på sidan \"[$3 $2]\", tillsammans med ditt användarnamn.",
        "feedback-cancel": "Avbryt",
-       "feedback-close": "Färdig",
+       "feedback-close": "Fixat",
        "feedback-external-bug-report-button": "Registrera en teknisk uppgift",
        "feedback-dialog-title": "Skicka återkoppling",
        "feedback-dialog-intro": "Du kan använda det enkla formuläret nedan för att skicka in din återkoppling. Din kommentar kommer att läggas till på sidan \"$1\" tillsammans med ditt användarnamn.",
        "feedback-useragent": "Användaragent:",
        "searchsuggest-search": "Sök",
        "searchsuggest-containing": "innehåller...",
+       "api-error-autoblocked": "Din IP-adress har blockerats automatiskt eftersom den har använts av en blockerad användare.",
        "api-error-badaccess-groups": "Du får inte ladda upp filer till denna wiki.",
        "api-error-badtoken": "Internt fel: felaktig nyckel.",
+       "api-error-blocked": "Du har blockerats från att redigera.",
        "api-error-copyuploaddisabled": "Uppladdning via URL är inaktiverad på den här servern.",
        "api-error-duplicate": "Det finns redan {{PLURAL:$1|en annan fil|andra filer}} på webbplatsen med samma innehåll.",
        "api-error-duplicate-archive": "Det fanns redan {{PLURAL:$1|en annan fil|några andra filer}} på webbplatsen med samma innehåll, men {{PLURAL:$1|den har|de har}} raderats.",
        "api-error-nomodule": "Internt fel: ingen uppladdningsmodul uppsatt.",
        "api-error-ok-but-empty": "Internt fel: Inget svar från servern.",
        "api-error-overwrite": "Det är inte tillåtet att skriva över en befintlig fil.",
+       "api-error-ratelimited": "Du försöker ladda upp fler filer inom en kort tidsrymd än denna wiki tillåter.\nFörsök igen om några minuter.",
        "api-error-stashfailed": "Internt fel: servern kunde inte lagra temporär fil.",
        "api-error-publishfailed": "Internt fel: Servern kunde inte publicera temporär fil.",
        "api-error-stasherror": "Ett fel uppstod under uppladdningen av filen till mellanlagringsfilen.",
        "sessionprovider-nocookies": "Cookies kan vara inaktiverade. Se till att du har cookies aktiverat och försök igen.",
        "randomrootpage": "Slumprotsida",
        "log-action-filter-block": "Typ av blockering:",
+       "log-action-filter-contentmodel": "Typ av innehållsmodellsändring:",
        "log-action-filter-delete": "Typ av radering:",
        "log-action-filter-import": "Importeringstyp:",
+       "log-action-filter-managetags": "Typ av märkeshanteringsåtgärd:",
        "log-action-filter-move": "Flyttningstyp:",
        "log-action-filter-newusers": "Typ av kontoskapande:",
        "log-action-filter-patrol": "Typ av patrullering:",
        "log-action-filter-protect": "Typ av skydd:",
+       "log-action-filter-rights": "Typ av rättighetsändring",
        "log-action-filter-suppress": "Censurtyp",
        "log-action-filter-upload": "Typ av uppladdning:",
        "log-action-filter-all": "Alla",
        "log-action-filter-block-reblock": "Blockeringsändring",
        "log-action-filter-block-unblock": "Tog bort blockering",
        "log-action-filter-contentmodel-change": "Ändring av innehållsmodell",
+       "log-action-filter-contentmodel-new": "Skapande av sida med icke-standardiserad innehållsmodell",
        "log-action-filter-delete-delete": "Radering av sida",
        "log-action-filter-delete-restore": "Återställde sida",
        "log-action-filter-delete-event": "Radering av logg",
        "log-action-filter-delete-revision": "Radering av sidversion",
+       "log-action-filter-import-interwiki": "Interwikiimport",
        "log-action-filter-import-upload": "Importera med XML-uppladdning",
        "log-action-filter-managetags-create": "Märke skapad",
        "log-action-filter-managetags-delete": "Märke raderad",
        "log-action-filter-managetags-activate": "Märke aktiverad",
        "log-action-filter-managetags-deactivate": "Märke inaktiverad",
-       "log-action-filter-move-move": "Flyttning utan att skriva över omdirigeringar",
-       "log-action-filter-move-move_redir": "Flyttning med att skriva över omdirigeringar",
+       "log-action-filter-move-move": "Flyttning utan överskrivning av omdirigeringar",
+       "log-action-filter-move-move_redir": "Flyttning med överskrivning av omdirigeringar",
        "log-action-filter-newusers-create": "Skapade av anonyma användare",
        "log-action-filter-newusers-create2": "Skapade av registrerade användare",
        "log-action-filter-newusers-autocreate": "Skapades automatiskt",
+       "log-action-filter-newusers-byemail": "Skapades med lösenord via e-post",
        "log-action-filter-patrol-patrol": "Manuell patrullering",
        "log-action-filter-patrol-autopatrol": "Automatisk patrullering",
        "log-action-filter-protect-protect": "Skydd",
        "log-action-filter-protect-move_prot": "Flyttade skydd",
        "log-action-filter-rights-rights": "Manuell ändring",
        "log-action-filter-rights-autopromote": "Automatisk ändring",
+       "log-action-filter-suppress-event": "Loggcensur",
+       "log-action-filter-suppress-revision": "Sidversionscensur",
+       "log-action-filter-suppress-delete": "Sidcensur",
        "log-action-filter-upload-upload": "Ny uppladdning",
        "log-action-filter-upload-overwrite": "Återuppladdning"
 }
index 01370ca..14de43c 100644 (file)
        "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": "தேதி",
+       "upload-form-label-own-work": "இது என் சொந்த வேலை",
+       "upload-form-label-infoform-categories": "பகுப்புகள்",
+       "upload-form-label-infoform-date": "தேதி",
        "backend-fail-stream": " $1 கோப்பை stream செய்ய இயலவில்லை  .",
        "backend-fail-backup": " $1 கோப்பை பின்சேமிப்பு (backup) செய்ய இயலவில்லை  .",
        "backend-fail-notexists": " \"$1\"  என்னும் கோப்பு எதுவும் இல்லை",
index 60e4246..fc8fc69 100644 (file)
        "minoredit": "ಉಂದು ಎಲ್ಯ ಬದಲಾವಣೆ",
        "watchthis": "ಈ ಪುಟೊನು ತೂಲೆ",
        "savearticle": "ಪುಟೊನು ಒರಿಪಾಲೆ",
+       "publishpage": "ಪುಟೋನು ಪ್ರಕಟಿಸಲೇ",
        "preview": "ಮುನ್ನೋಟ",
        "showpreview": "ಮುನ್ನೋಟೊ ತೋಜಾವು",
        "showdiff": "ಬದಲಾವಣೆಲೆನ್ ತೋಜಾವ್",
        "tooltip-ca-nstab-category": "ವರ್ಗೊದ ಪುಟೊನು ತೂಲೆ",
        "tooltip-minoredit": "ಇಂದೆನ್ ಎಲ್ಯ ಬದಲಾವಣೆ ಪಂಡ್ದ್ ಗುರ್ತ ಮಲ್ಪುಲೆ",
        "tooltip-save": "ಈರ್ ಮಲ್ತ್‌ನ ಬದಲಾವಣೆಲೆನ್ ಒರಿಪ್ಪಾಲೆ",
+       "tooltip-publish": "ಇರೇನಾ ಬದಲಾವನೇನ್ ತೊಜಲೇ",
        "tooltip-preview": "ಈರ್ ಮಲ್ತ‍್‌ನ ಬದಲಾವಣೆತ ಮುನ್ನೋಟ - ಈ ಪುಟನ್ ಒರಿಪಾವುನ ದು೦ಬು ಉಂದೆನ್ ತೂಲೆ",
        "tooltip-diff": "ಈ ಲೇಕನೊಗ್ ಮಲ್ತಿನ ಬದಲಾವಣೆಲೆನ್ ತೋಜಾವ್",
        "tooltip-compareselectedversions": "ಈ ಪುಟತ ಆಯ್ಕೆ ಮಲ್ತಿನ ರಡ್ಡ್ ಆವೃತ್ತಿದ ವ್ಯತ್ಯಾಸನ್ ತೂಲೆ",
index 4f5de01..de45686 100644 (file)
        "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": "తేదీ",
+       "upload-form-label-own-work": "ఇది నా స్వంత కృతి",
+       "upload-form-label-infoform-categories": "వర్గాలు",
+       "upload-form-label-infoform-date": "తేదీ",
        "backend-fail-stream": "\"$1\" ఫైలును స్ట్రీమింగు చెయ్యలేకపోయాం.",
        "backend-fail-backup": "\"$1\" ఫైలును బ్యాకప్పు చెయ్యలేకపోయాం.",
        "backend-fail-notexists": "$1 ఫైలు అసలు లేనేలేదు.",
index 9bc092e..141e30d 100644 (file)
        "prefs-help-signature": "Tartışma sayfalarındaki yorumlar \"<nowiki>~~~~</nowiki>\" ile imzalanmalıdır, bu imzanıza ve zaman damgasına dönüştürülür.",
        "badsig": "Geçersiz ham imza; HTML etiketlerini kontrol edin.",
        "badsiglength": "İmzanız çok uzun.\n$1 {{PLURAL:$1|karakterin|karakterin}} altında olmalı.",
-       "yourgender": "Cinsel kimlik?",
+       "yourgender": "Cinsiyet?",
        "gender-unknown": "Açıklamak istemiyorum",
        "gender-male": "Erkek",
        "gender-female": "Kadın",
        "rcshowhidemine": "Benim değişikliklerimi $1",
        "rcshowhidemine-show": "göster",
        "rcshowhidemine-hide": "gizle",
-       "rcshowhidecategorization": "$1 sayfa kategorizasyonu",
-       "rcshowhidecategorization-show": "Göster",
-       "rcshowhidecategorization-hide": "Gizle",
+       "rcshowhidecategorization": "sayfa kategorizasyonunu $1",
+       "rcshowhidecategorization-show": "göster",
+       "rcshowhidecategorization-hide": "gizle",
        "rclinks": "Son $2 günde yapılan son $1 değişikliği göster;<br /> $3",
        "diff": "fark",
        "hist": "geçmiş",
        "upload-form-label-infoform-description": "Açıklama",
        "upload-form-label-usage-title": "Kullanımı",
        "upload-form-label-usage-filename": "Dosya adı",
-       "foreign-structured-upload-form-label-own-work": "Bu benim kendi çalışmam",
-       "foreign-structured-upload-form-label-infoform-categories": "Kategoriler",
-       "foreign-structured-upload-form-label-infoform-date": "Tarih",
+       "upload-form-label-own-work": "Bu benim kendi çalışmam",
+       "upload-form-label-infoform-categories": "Kategoriler",
+       "upload-form-label-infoform-date": "Tarih",
        "backend-fail-stream": "$1 dosyası okunamadı.",
        "backend-fail-backup": "\"$1\" dosyası yedeklenemedi.",
        "backend-fail-notexists": "$1 dosyası mevcut değil.",
index 96f7c0b..9080afa 100644 (file)
        "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": "Дата",
+       "upload-form-label-own-work": "Бу минем үз эшем",
+       "upload-form-label-infoform-categories": "Төркемнәр",
+       "upload-form-label-infoform-date": "Дата",
        "uploadstash": "Яшерен йөкләү",
        "uploadstash-summary": "Әлеге бит йөкләнгән (яисә йукләү барышында булган), әмма викида әлегә күрсәтелмәгән файлларны карау мөмкинлеген бирә. Бу файлларны йөкләгән кулланучыдан башка беркемдә күрә алмый.",
        "uploadstash-clear": "Яшерен файлларны бетерү",
index 2461405..4e7ea76 100644 (file)
        "filename-bad-prefix": "Faylnıñ iseme '''«$1»''' dip başlana. Zinhar, faylnı taswirlawçı isem biregez.",
        "filename-prefix-blacklist": " #<!-- niçek bar şulay qaldırığız --> <pre>\n# Sintaksis töbändägeçä:\n#   *  «#» dip başlanğan barlıq närsä dä qömmentariy dip atalaçaq\n#   * Härber buş rät — faylnıñ isemeneñ prefiksı, sifrlı kamera birüçe isem\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # qaysıber käräzle telefonnar\nIMG # barlıq\nJD # Jenoptik\nMGP # Pentax\nPICT # törle\n #</pre> <!-- niçek bar şulay qaldırığız -->",
        "upload-form-label-usage-title": "Qullanılış",
-       "foreign-structured-upload-form-label-infoform-categories": "Törkemnär",
-       "foreign-structured-upload-form-label-infoform-date": "Data",
+       "upload-form-label-infoform-categories": "Törkemnär",
+       "upload-form-label-infoform-date": "Data",
        "license": "Litsenziäse:",
        "license-header": "Litsenziäse",
        "nolicense": "Yuq",
index ae20f1d..4ea5a42 100644 (file)
@@ -11,7 +11,8 @@
                        "بىلگە",
                        "아라",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Amire80"
                ]
        },
        "tog-underline": "ئۇلانما ئاستى سىزىقى:",
        "listgrouprights-rights": "ھوقۇق",
        "listgrouprights-helppage": "Help: گۇرۇپپا ھوقۇقى",
        "listgrouprights-members": "(ئەزالار تىزىملىكى)",
-       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($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",
index 84d2d2e..24f55bf 100644 (file)
        "minoredit": "Незначна зміна",
        "watchthis": "Спостерігати за цією сторінкою",
        "savearticle": "Зберегти сторінку",
+       "publishpage": "Опублікувати сторінку",
        "preview": "Попередній перегляд",
        "showpreview": "Попередній перегляд",
        "showdiff": "Показати зміни",
        "userpage-userdoesnotexist": "Користувач під назвою \"<nowiki>$1</nowiki>\" не зареєстрований. Переконайтеся, що ви хочете створити/редагувати цю сторінку.",
        "userpage-userdoesnotexist-view": "Обліковий запис користувача „$1“ не зареєстровано.",
        "blocked-notice-logextract": "Цей користувач наразі заблокований.\nОстанній запис у журналі блокувань такий:",
-       "clearyourcache": "'''Увага:''' Після збереження слід очистити кеш оглядача, щоб побачити зміни.\n* '''Firefox / Safari:''' тримайте ''Shift'', коли натискаєте ''Оновити'', або натисніть ''Ctrl-F5'' чи ''Ctrl-Shift-R'' (''⌘-R'' на Apple Mac)\n* '''Google Chrome:''' натисніть ''Ctrl-Shift-R'' (''⌘-Shift-R'' на Apple Mac)\n* '''Internet Explorer:''' тримайте ''Ctrl'', коли натискаєте ''Оновити'', або натисніть ''Ctrl-F5''\n* '''Opera:''' очистіть кеш за допомогою ''Інструменти → Налаштування''",
+       "clearyourcache": "<strong>Увага:</strong> Після збереження слід очистити кеш оглядача, щоб побачити зміни.\n* <strong>Firefox / Safari:</strong> тримайте <em>Shift</em>, коли натискаєте <em>Оновити</em>, або натисніть <em>Ctrl-F5</em> чи <em>Ctrl-Shift-R</em> (<em>⌘-R</em> на Apple Mac)\n* <strong>Google Chrome:</strong> натисніть <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Apple Mac)\n* <strong>Internet Explorer:</strong> тримайте <em>Ctrl</em>, коли натискаєте <em>Оновити</em>, або натисніть <em>Ctrl-F5</em>\n* <strong>Opera:</strong> очистіть кеш за допомогою <em>Інструменти → Налаштування</em> (<em>Opera → Побажання</em> на Apple Mac) та перейдіть на <em>Привітність & безпека → очистити дані браузера → кеш</em>",
        "usercssyoucanpreview": "'''Підказка:''' використовуйте кнопку «{{int:showpreview}}», щоб протестувати ваш новий css-файл перед збереженням.",
        "userjsyoucanpreview": "'''Підказка:''' використовуйте кнопку «{{int:showpreview}}», щоб протестувати ваш новий код JavaScript перед збереженням.",
        "usercsspreview": "'''Пам'ятайте, що це лише попередній перегляд вашого css-файлу.'''\n'''Його ще не збережено!'''",
        "upload-form-label-infoform-description-tooltip": "Коротко напишіть усе основне та цікаве про цю роботу.\nНаприклад, для фото опишіть, що сфотографовано, місце та нагоду знімка.",
        "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": "Я підтверджую, що вивантажую цей файл згідно з умовами користування та політики ліцензування {{GRAMMAR:locative|{{SITENAME}}}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Якщо Ви не можете завантажити цей файл згідно з правилами {{GRAMMAR:genitive|{{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|сторінку завантаження на {{GRAMMAR:locative|{{SITENAME}}}}]], якщо цей файл може бути завантажений згідно з їх правилами.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Я підтверджую, що я є власником авторських прав на цей файл та погоджуюся беззастережно поширити його у Вікісховищі на умовах ліцензії [https://creativecommons.org/licenses/by-sa/4.0/deed.uk Creative CommonsAttribution-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|сторінку завантаження на {{GRAMMAR:locative|{{SITENAME}}}}]], якщо цей файл може бути завантажений на цей сайт згідно з його правилами.",
+       "upload-form-label-own-work": "Це моя власна робота",
+       "upload-form-label-infoform-categories": "Категорії",
+       "upload-form-label-infoform-date": "Дата",
+       "upload-form-label-own-work-message-local": "Я підтверджую, що вивантажую цей файл згідно з умовами користування та політики ліцензування {{GRAMMAR:locative|{{SITENAME}}}}.",
+       "upload-form-label-not-own-work-message-local": "Якщо Ви не можете завантажити цей файл згідно з правилами {{GRAMMAR:genitive|{{SITENAME}}}}, будь ласка, закрийте цей вікно та оберіть інший спосіб.",
+       "upload-form-label-not-own-work-local-local": "Ви також можете спробувати [[Special:Upload|сторінку завантаження за замовчуванням]].",
+       "upload-form-label-own-work-message-default": "Я розумію, що я завантажую цей файл до спільного сховища. Я підтверджую, що я роблю це у відповідності до Умов надання послуг та правил ліцензування.",
+       "upload-form-label-not-own-work-message-default": "Якщо ви не можете завантажити цей файл згідно з правилами спільного сховища, будь ласка, закрийте цей вікно та оберіть інший спосіб.",
+       "upload-form-label-not-own-work-local-default": "Ви також можете спробувати використати [[Special:Upload|сторінку завантаження на {{GRAMMAR:locative|{{SITENAME}}}}]], якщо цей файл може бути завантажений згідно з їх правилами.",
+       "upload-form-label-own-work-message-shared": "Я підтверджую, що я є власником авторських прав на цей файл та погоджуюся беззастережно поширити його у Вікісховищі на умовах ліцензії [https://creativecommons.org/licenses/by-sa/4.0/deed.uk Creative CommonsAttribution-ShareAlike 4.0], і я згоден з [https://wikimediafoundation.org/wiki/Terms_of_Use умовами використання].",
+       "upload-form-label-not-own-work-message-shared": "Якщо ви не є власником авторських прав на цей файл або ви хочете розповсюджувати його на умовах іншої ліцензії, рекомендуємо використати [https://commons.wikimedia.org/wiki/Special:UploadWizard Майстер завантажень на Вікісховищі].",
+       "upload-form-label-not-own-work-local-shared": "Ви також можете спробувати використати [[Special:Upload|сторінку завантаження на {{GRAMMAR:locative|{{SITENAME}}}}]], якщо цей файл може бути завантажений на цей сайт згідно з його правилами.",
        "backend-fail-stream": "Не вдалося транслювати файл $1.",
        "backend-fail-backup": "Не вдалося створити резервну копію файлу $1.",
        "backend-fail-notexists": "Файл $1 не існує.",
        "changecontentmodel-success-text": "Тип вмісту сторінки [[:$1]] було змінено.",
        "changecontentmodel-cannot-convert": "Вміст сторінки [[:$1]] не можна перетворити на вміст типу $2.",
        "changecontentmodel-nodirectediting": "Модель вмісту $1 не підтримує пряме редагування",
+       "changecontentmodel-emptymodels-title": "Немає доступних моделей коментарів",
+       "changecontentmodel-emptymodels-text": "Вміст сторінки [[:$1]] не може бути перетворений до будь якого типу.",
        "log-name-contentmodel": "Журнал змін моделі вмісту",
        "log-description-contentmodel": "Події, пов'язані з моделями вмісту сторінки",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|створив|створила}} сторінку $3, використовуючи нестандартну модель вмісту «$5»",
        "unblockip": "Розблокувати IP-адресу",
        "unblockiptext": "Використовуйте подану нижче форму, щоб відновити можливість збереження з раніше заблокованої IP-адреси.",
        "ipusubmit": "Зняти це блокування",
-       "unblocked": "[[User:$1|$1]] {{GENDER:$1|Ñ\80азблокований|Ñ\80азблокована}}",
+       "unblocked": "[[User:$1|$1]] {{GENDER:$1|Ñ\80озблокований|Ñ\80озблокована}}",
        "unblocked-range": "$1 розблоковано",
        "unblocked-id": "Блокування $1 було зняте",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] вже розлоковано.",
        "lockdbsuccesstext": "Базу даних проекту заблоковано.<br />\nНе забудьте її [[Special:UnlockDB|розблокувати]] після завершення обслуговування.",
        "unlockdbsuccesstext": "Базу даних проекту розблоковано.",
        "lockfilenotwritable": "Немає права на запис в файл блокування бази даних. Щоб заблокувати чи розблокувати БД, веб-сервер повинен мати дозвіл на запис в цей файл.",
+       "databaselocked": "База даних вже заблокована.",
        "databasenotlocked": "База даних не заблокована.",
        "lockedbyandtime": "($1 $2 $3)",
        "move-page": "Перейменування сторінки «$1»",
        "tooltip-ca-nstab-category": "Сторінка категорії",
        "tooltip-minoredit": "Позначити це редагування як незначне",
        "tooltip-save": "Зберегти ваші зміни",
+       "tooltip-publish": "Опублікувати ваші зміни",
        "tooltip-preview": "Попередній перегляд сторінки, будь ласка, використовуйте перед збереженням!",
        "tooltip-diff": "Показати зміни, що зроблені відносно початкового тексту.",
        "tooltip-compareselectedversions": "Переглянути різницю між двома вказаними версіями цієї сторінки.",
        "confirmemail_body_set": "Хтось (можливо ви) з IP-адреси $1\nназначив цю електронну скриньку для облікового запису „$2“ в проекті {{SITENAME}}.\n\nАби підтвердити, що цей обліковий запис справді належить вам, і дозволити надсилання листів\nз сайту {{SITENAME}}, відкрийте наступне посилання у веб-оглядачі:\n\n$3\n\nЯкщо даний обліковий запис *не* належить вам, перейдіть за наступним посиланням\nі відмініть цим підтвердження електронної адреси:\n\n$5\n\nКод підтвердження дійсний до $4.",
        "confirmemail_invalidated": "Підтвердження адреси електронної пошти скасоване",
        "invalidateemail": "Скасувати підтвердження адреси електронної пошти",
+       "notificationemail_subject_changed": "Електронну адресу, зареєстровану для сайту {{SITENAME}}, було змінено",
+       "notificationemail_subject_removed": "Електронну адресу, зареєстровану для сайту {{SITENAME}}, було вилучено",
+       "notificationemail_body_changed": "Хтось, ймовірно Ви, з IP-адреси $1,\nзмінив електронну адресу облікового запису «$2» на «$3» на сайті {{SITENAME}}.\n\nЯкщо це були не Ви, негайно зв'яжіться з адміністратором сайту.",
+       "notificationemail_body_removed": "Хтось, ймовірно Ви, з IP-адреси $1,\nвилучив електронну адресу облікового запису «$2» на сайті {{SITENAME}}.\n\nЯкщо це були не Ви, негайно зв'яжіться з адміністратором сайту.",
        "scarytranscludedisabled": "[«Interwiki transcluding» вимкнено]",
        "scarytranscludefailed": "[Помилка звертання до шаблону $1]",
        "scarytranscludefailed-httpstatus": "[Не вдалось завантажити шаблон для $1: HTTP $2]",
        "watchlistedit-raw-done": "Ваш список спостереження збережений.",
        "watchlistedit-raw-added": "{{PLURAL:$1|$1 заголовок був доданий|$1 заголовки були додані|$1 заголовків були додані}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|$1 заголовок був вилучений|$1 заголовки були вилучені|$1 заголовків були вилучені}}:",
-       "watchlistedit-clear-title": "Ð\9eÑ\87иÑ\89еннÑ\8f Ñ\81пиÑ\81кÑ\83 спостереження",
+       "watchlistedit-clear-title": "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82и Ñ\81пиÑ\81ок спостереження",
        "watchlistedit-clear-legend": "Очистити список спостереження",
        "watchlistedit-clear-explain": "Усі сторінки буде вилучено з Вашого списку спостереження",
        "watchlistedit-clear-titles": "Сторінки:",
        "feedback-useragent": "User Agent:",
        "searchsuggest-search": "Пошук",
        "searchsuggest-containing": "що містять...",
+       "api-error-autoblocked": "Вашу IP-адресу було заблоковано автоматично, тому що її використовував заблокований користувач.",
        "api-error-badaccess-groups": "Вам не дозволено завантажувати файли до цього вікіпроекту.",
        "api-error-badtoken": "Внутрішня помилка: некоректний токен.",
+       "api-error-blocked": "Можливість редагування для вас заблоковано.",
        "api-error-copyuploaddisabled": "На цьому сервері вимкнене завантаження за URL-адресою.",
        "api-error-duplicate": "Уже {{PLURAL:$1|1=існує інший файл|існують інші файли}} з таким самим вмістом.",
        "api-error-duplicate-archive": "Раніше на сайті вже {{PLURAL:$1|1=був файл|були файли}} з ідентичним вмістом, але {{PLURAL:$1|1=його|їх}} вилучили.",
        "api-error-nomodule": "Внутрішня помилка: Відсутній модуль завантажень.",
        "api-error-ok-but-empty": "Внутрішня помилка: сервер не відповідає.",
        "api-error-overwrite": "Заміну існуючого файлу не дозволено.",
+       "api-error-ratelimited": "Ви намагаєтесь завантажити більше файлів за короткий проміжок часу, ніж дозволено у цій вікі. Будь ласка, спробуйте за декілька хвилин.",
        "api-error-stashfailed": "Внутрішня помилка: сервер не зміг зберегти тимчасовий файл.",
        "api-error-publishfailed": "Внутрішня помилка: сервер не зміг опублікувати тимчасовий файл.",
        "api-error-stasherror": "Сталася помилка при завантаженні файлу у сховище.",
index aae60f7..f29edf3 100644 (file)
        "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": "تاریخ",
+       "upload-form-label-own-work": "یہ میرا ذاتی کام ہے",
+       "upload-form-label-infoform-categories": "زمرہ جات",
+       "upload-form-label-infoform-date": "تاریخ",
        "license": "اجازہ:",
        "license-header": "اجازہ کاری",
        "listfiles-delete": "حذف",
index d788a2f..66a40c6 100644 (file)
@@ -52,6 +52,7 @@
        "tog-watchdefault": "Tự động theo dõi các trang và tập tin tôi sửa",
        "tog-watchmoves": "Tự động theo dõi các trang và tập tin tôi di chuyển",
        "tog-watchdeletion": "Tự động theo dõi các trang và tập tin tôi xóa",
+       "tog-watchuploads": "Thêm các tập tin tải lên của tôi vào danh sách theo dõi của tôi",
        "tog-watchrollback": "Tự động theo dõi các trang tôi lùi sửa",
        "tog-minordefault": "Mặc định đánh dấu tất cả sửa đổi của tôi là sửa đổi nhỏ",
        "tog-previewontop": "Hiển thị phần xem trước nằm trên hộp sửa đổi",
        "minoredit": "Sửa đổi nhỏ",
        "watchthis": "Theo dõi trang này",
        "savearticle": "Lưu trang",
+       "publishpage": "Xuất bản trang",
        "preview": "Xem trước",
        "showpreview": "Xem trước",
        "showdiff": "Xem thay đổi",
        "userpage-userdoesnotexist": "Đây chưa có tài khoản với tên “<nowiki>$1</nowiki>”. Xin hãy kiểm tra lại nếu bạn muốn tạo hay sửa trang này.",
        "userpage-userdoesnotexist-view": "Chưa có tài khoản với tên “$1”.",
        "blocked-notice-logextract": "Người dùng này hiện đang bị cấm sửa đổi. Nhật trình cấm gần nhất được ghi ở dưới để tiện theo dõi:",
-       "clearyourcache": "'''Chú ý:''' Sau khi lưu trang, có thể bạn sẽ phải xóa bộ nhớ đệm của trình duyệt để xem các thay đổi.\n* '''Firefox / Safari:''' Nhấn giữ phím ''Shift'' trong khi nhấn ''Tải lại'' (''Reload''), hoặc nhấn tổ hợp ''Ctrl-F5'' hay ''Ctrl-R'' (⌘R trên Mac)\n* '''Google Chrome:''' Nhấn tổ hợp ''Ctrl-Shift-R'' (⇧⌘R trên Mac)\n* '''Internet Explorer:''' Nhấn giữ phím ''Ctrl'' trong khi nhấn ''Làm tươi'' (''Refresh''), hoặc nhấn tổ hợp ''Ctrl-F5''\n* '''Opera:''' Xóa bộ nhớ đệm trong ''Công cụ → Sở thích'' (''Tools → Preferences'')",
+       "clearyourcache": "<strong>Chú ý:</strong> Sau khi lưu trang, có thể bạn sẽ phải xóa bộ nhớ đệm của trình duyệt để xem các thay đổi.\n* <strong>Firefox / Safari:</strong> Nhấn giữ phím <em>Shift</em> trong khi nhấn <em>Tải lại</em> (<em>Reload</em>), hoặc nhấn tổ hợp <em>Ctrl-F5</em> hay <em>Ctrl-R</em> (⌘R trên Mac)\n* <strong>Google Chrome:</strong> Nhấn tổ hợp <em>Ctrl-Shift-R</em> (⇧⌘R trên Mac)\n* <strong>Internet Explorer:</strong> Nhấn giữ phím <em>Ctrl</em> trong khi nhấn <em>Làm tươi</em>, hoặc nhấn tổ hợp <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Mở <em>Menu → Cài đặt</em> (<em>Opera → Tùy chỉnh</em> trên Mac), mở tab <em>Quyền riêng tư & bảo mật</em>, bấm <em>Xóa dữ liệu duyệt web</em> và đánh hộp kiểm <em>Hình ảnh và tệp trong cache</em>.",
        "usercssyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản CSS của bạn trước khi lưu trang.",
        "userjsyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JS của bạn trước khi lưu trang.",
        "usercsspreview": "'''Hãy nhớ rằng bạn chỉ đang xem trước trang CSS cá nhân của bạn.\nNó chưa được lưu!'''",
        "recentchangeslinked-page": "Tên trang:",
        "recentchangeslinked-to": "Hiện thay đổi tại những trang có liên kết đến trang này thay thế",
        "recentchanges-page-added-to-category": "[[:$1]] được xếp vào thể loại",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] và [[Special:WhatLinksHere/$1|{{PLURAL:$2|một trang|$2 trang}} nữa]] được xếp vào thể loại",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] được xếp vào thể loại; [[Special:WhatLinksHere/$1|trang này được nhúng vào các trang khác]]",
        "recentchanges-page-removed-from-category": "[[:$1]] được gỡ khỏi thể loại",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] và [[Special:WhatLinksHere/$1|{{PLURAL:$2|một trang|$2 trang}} nữa]] được gỡ khỏi thể loại",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] được xóa gỡ thể loại; [[Special:WhatLinksHere/$1|trang này được nhúng vào các trang khác]]",
        "autochange-username": "MediaWiki thay đổi tự động",
        "upload": "Tải tập tin lên",
        "uploadbtn": "Tải tập tin lên",
        "upload-form-label-infoform-description-tooltip": "Miêu tả một cách ngắn gọn mỗi điều đáng kể về tác phẩm này.\nNếu là hình chụp, hãy nói đến những vật thể chính, cũng như tình hình, sự kiện, hay địa điểm của hình chụp.",
        "upload-form-label-usage-title": "Sử dụng",
        "upload-form-label-usage-filename": "Tên tập tin",
-       "foreign-structured-upload-form-label-own-work": "Đây là tác phẩm của chính tôi",
-       "foreign-structured-upload-form-label-infoform-categories": "Thể loại",
-       "foreign-structured-upload-form-label-infoform-date": "Ngày tháng",
-       "foreign-structured-upload-form-label-own-work-message-local": "Tôi xác nhận rằng tôi tải lên tập tin này tuân theo các điều khoản sử dụng và quy định giấy phép của {{SITENAME}}.",
-       "foreign-structured-upload-form-label-not-own-work-message-local": "Nếu bạn không được phép tải lên tập tin này tuân theo quy định của {{SITENAME}}, xin vui lòng đóng hộp thoại này và thử tải lên bằng một phương pháp khác.",
-       "foreign-structured-upload-form-label-not-own-work-local-local": "Bạn cũng có thể muốn sử dụng [[Special:Upload|trang tải lên mặc định]].",
-       "foreign-structured-upload-form-label-own-work-message-default": "Tôi hiểu rằng tôi đang tải tập tin này lên một kho dùng chung. Tôi xác nhận rằng tôi làm việc này tuân theo các điều khoản sử dụng và quy định về giấy phép tại đấy.",
-       "foreign-structured-upload-form-label-not-own-work-message-default": "Nếu bạn không có thể tải tập tin này lên mà tuân theo quy định của kho dùng chung, xin vui lòng đóng hộp thoại này và thử một cách khác.",
-       "foreign-structured-upload-form-label-not-own-work-local-default": "Bạn có thể muốn thử [[Special:Upload|trang tải lên tại {{SITENAME}}]] nếu tập tin này có thể được tải lên đấy theo các quy định của họ.",
-       "foreign-structured-upload-form-label-own-work-message-shared": "Tôi khẳng định rằng tôi giữ quyền tác giả của tập tin này và đồng ý phát hành, một cách không thể hủy bỏ, tập tin này cho Wikimedia Commons theo giấy phép [https://creativecommons.org/licenses/by-sa/4.0/deed.vi Creative Commons Ghi công–Chia sẻ tương tự 4.0], và tôi chấp nhận các [https://wikimediafoundation.org/wiki/Terms_of_Use/vi?uselang=vi Điều khoản Sử dụng].",
-       "foreign-structured-upload-form-label-not-own-work-message-shared": "Nếu bạn không giữ quyền tác giả của tập tin hoặc muốn phát hành nó theo một giấy phép khác, xin nghĩ đến việc sử dụng [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=vi Trình thuật sĩ tải lên Commons].",
-       "foreign-structured-upload-form-label-not-own-work-local-shared": "Bạn cũng có thể muốn thử [[Special:Upload|trang tải lên tại {{SITENAME}}]] nếu trang đó cho phép tải lên tập tin này theo các quy định của họ.",
+       "upload-form-label-own-work": "Đây là tác phẩm của chính tôi",
+       "upload-form-label-infoform-categories": "Thể loại",
+       "upload-form-label-infoform-date": "Ngày tháng",
+       "upload-form-label-own-work-message-local": "Tôi xác nhận rằng tôi tải lên tập tin này tuân theo các điều khoản sử dụng và quy định giấy phép của {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-local": "Nếu bạn không được phép tải lên tập tin này tuân theo quy định của {{SITENAME}}, xin vui lòng đóng hộp thoại này và thử tải lên bằng một phương pháp khác.",
+       "upload-form-label-not-own-work-local-local": "Bạn cũng có thể muốn sử dụng [[Special:Upload|trang tải lên mặc định]].",
+       "upload-form-label-own-work-message-default": "Tôi hiểu rằng tôi đang tải tập tin này lên một kho dùng chung. Tôi xác nhận rằng tôi làm việc này tuân theo các điều khoản sử dụng và quy định về giấy phép tại đấy.",
+       "upload-form-label-not-own-work-message-default": "Nếu bạn không có thể tải tập tin này lên mà tuân theo quy định của kho dùng chung, xin vui lòng đóng hộp thoại này và thử một cách khác.",
+       "upload-form-label-not-own-work-local-default": "Bạn có thể muốn thử [[Special:Upload|trang tải lên tại {{SITENAME}}]] nếu tập tin này có thể được tải lên đấy theo các quy định của họ.",
+       "upload-form-label-own-work-message-shared": "Tôi khẳng định rằng tôi giữ quyền tác giả của tập tin này và đồng ý phát hành, một cách không thể hủy bỏ, tập tin này cho Wikimedia Commons theo giấy phép [https://creativecommons.org/licenses/by-sa/4.0/deed.vi Creative Commons Ghi công–Chia sẻ tương tự 4.0], và tôi chấp nhận các [https://wikimediafoundation.org/wiki/Terms_of_Use/vi?uselang=vi Điều khoản Sử dụng].",
+       "upload-form-label-not-own-work-message-shared": "Nếu bạn không giữ quyền tác giả của tập tin hoặc muốn phát hành nó theo một giấy phép khác, xin nghĩ đến việc sử dụng [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=vi Trình thuật sĩ tải lên Commons].",
+       "upload-form-label-not-own-work-local-shared": "Bạn cũng có thể muốn thử [[Special:Upload|trang tải lên tại {{SITENAME}}]] nếu trang đó cho phép tải lên tập tin này theo các quy định của họ.",
        "backend-fail-stream": "Không thể gửi luồng tập tin $1.",
        "backend-fail-backup": "Không thể sao lưu tập tin $1.",
        "backend-fail-notexists": "Tập tin $1 không tồn tại.",
        "changecontentmodel-nodirectediting": "Kiểu nội dung $1 không hỗ trợ sửa đổi trực tiếp",
        "log-name-contentmodel": "Nhật trình thay đổi kiểu nội dung",
        "log-description-contentmodel": "Sự kiện có liên quan đến kiểu nội dung của trang.",
-       "logentry-contentmodel-new": "$1 {{GENDER:$2}}đã tạo trang $3 với mô hình nội dung không mặc định “$5”",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2}}đã tạo trang $3 với kiểu nội dung không mặc định “$5”",
        "logentry-contentmodel-change": "$1 {{GENDER:$2}}đã thay đổi kiểu nội dung của trang $3 từ “$4” thành “$5”",
        "logentry-contentmodel-change-revertlink": "lùi lại",
        "logentry-contentmodel-change-revert": "lùi lại",
        "whatlinkshere-prev": "{{PLURAL:$1|kết quả trước|$1 kết quả trước}}",
        "whatlinkshere-next": "{{PLURAL:$1|kết quả sau|$1 kết quả sau}}",
        "whatlinkshere-links": "← liên kết",
-       "whatlinkshere-hideredirs": "$1 trang đổi hướng",
+       "whatlinkshere-hideredirs": "Ẩn trang đổi hướng",
        "whatlinkshere-hidetrans": "$1 trang nhúng",
-       "whatlinkshere-hidelinks": "$1 liên kết",
-       "whatlinkshere-hideimages": "$1 liên kết tập tin",
+       "whatlinkshere-hidelinks": "Ẩn liên kết",
+       "whatlinkshere-hideimages": "Ẩn liên kết tập tin",
        "whatlinkshere-filters": "Bộ lọc",
        "whatlinkshere-submit": "Xem",
        "autoblockid": "Cấm tự động #$1",
        "ipb-unblock": "Bỏ cấm thành viên hay địa chỉ IP",
        "ipb-blocklist": "Xem danh sách đang bị cấm",
        "ipb-blocklist-contribs": "Đóng góp của $1",
+       "ipb-blocklist-duration-left": "còn $1 nữa",
        "unblockip": "Bỏ cấm thành viên",
        "unblockiptext": "Sử dụng mẫu sau để phục hồi lại quyền sửa đổi đối với một địa chỉ IP hoặc tên thành viên đã bị cấm trước đó.",
        "ipusubmit": "Bỏ cấm",
        "tooltip-ca-nstab-category": "Xem trang thể loại",
        "tooltip-minoredit": "Đánh dấu đây là sửa đổi nhỏ",
        "tooltip-save": "Lưu lại những thay đổi của bạn",
+       "tooltip-publish": "Xuất bản các thay đổi của bạn",
        "tooltip-preview": "Xem trước những thay đổi, hãy dùng nó trước khi lưu!",
        "tooltip-diff": "Xem thay đổi bạn đã thực hiện.",
        "tooltip-compareselectedversions": "Xem khác biệt giữa hai phiên bản đã chọn của trang này.",
        "confirmemail_body_set": "Ai đó, có thể là bạn, từ địa chỉ IP $1, đã đặt địa chỉ này là địa\nchỉ thư điện tử của tài khoản “$2” tại {{SITENAME}}.\n\nĐể xác nhận rằng tài khoản này thực sự là của bạn và để kích hoạt các tính năng\nthư điện tử tại {{SITENAME}}, xin mở liên kết này trong trình duyệt:\n\n$3\n\nNếu tài khoản *không* phải là của bạn, hãy nhấn vào liên kết này để hủy thủ tục\nxác nhận địa chỉ thư điện tử:\n\n$5\n\nMã xác nhận này sẽ hết hạn vào $4.",
        "confirmemail_invalidated": "Đã hủy xác nhận địa chỉ thư điện tử",
        "invalidateemail": "Hủy xác nhận thư điện tử",
+       "notificationemail_subject_changed": "Địa chỉ thư điện tử đăng ký tại {{SITENAME}} đã được thay đổi",
+       "notificationemail_subject_removed": "Địa chỉ thư điện tử đăng ký tại {{SITENAME}} đã được loại bỏ",
+       "notificationemail_body_changed": "Ai đó, có thể là bạn, từ địa chỉ IP $1,\nđã thay đổi địa chỉ thư điện tử của tài khoản “$2” thành “$3” tại {{SITENAME}}.\n\nNếu bạn không phải là người thay đổi địa chỉ này, xin hãy liên lạc với một bảo quản viên của trang Web ngay lập tức.",
+       "notificationemail_body_removed": "Ai đó, có thể là bạn, từ địa chỉ IP $1,\nđã loại bỏ địa chỉ thư điện tử của tài khoản “$2” tại {{SITENAME}}.\n\nNếu bạn không phải là người loại bỏ địa chỉ này, xin hãy liên lạc với một bảo quản viên của trang Web ngay lập tức.",
        "scarytranscludedisabled": "[Nhúng giữa các wiki bị tắt]",
        "scarytranscludefailed": "[Truy xuất bản mẫu $1 bị thất bại]",
        "scarytranscludefailed-httpstatus": "[Truy xuất bản mẫu $1 bị thất bại: HTTP $2]",
        "watchlistedit-raw-done": "Danh sách các trang bạn theo dõi đã được cập nhật.",
        "watchlistedit-raw-added": "$1 tựa đề đã được thêm vào:",
        "watchlistedit-raw-removed": "$1 tựa đề đã được xóa khỏi danh sách:",
-       "watchlistedit-clear-title": "Đã xóa sạch danh sách theo dõi",
+       "watchlistedit-clear-title": "Xóa sạch danh sách theo dõi",
        "watchlistedit-clear-legend": "Xóa sạch danh sách theo dõi",
        "watchlistedit-clear-explain": "Tất cả các tiêu đề sẽ được xóa khỏi danh sách theo dõi của bạn.",
        "watchlistedit-clear-titles": "Các tiêu đề:",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2}}đã khóa $3 $4 [theo tầng]",
        "logentry-protect-modify": "$1 {{GENDER:$2}}đã đổi mức khóa $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2}}đã đổi mức khóa $3 $4 [theo tầng]",
-       "logentry-rights-rights": "$1 {{GENDER:$2}}đã đổi các nhóm bao gồm $3 từ $4 đến $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2}}đã đổi các nhóm bao gồm {{GENDER:$6}}$3 từ $4 đến $5",
        "logentry-rights-rights-legacy": "{{GENDER:$2}}$1 đã đổi các nhóm bao gồm $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2}}đã được tự động phong cấp từ $4 đến $5",
        "logentry-upload-upload": "$1 {{GENDER:$2}}đã tải lên $3",
        "feedback-useragent": "Tác nhân người dùng:",
        "searchsuggest-search": "Tìm kiếm",
        "searchsuggest-containing": "có chứa…",
+       "api-error-autoblocked": "Địa chỉ IP của bạn bị cấm tự động vì nó đã được sử dụng bởi một người dùng bị cấm.",
        "api-error-badaccess-groups": "Bạn không được phép tải tập tin lên wiki này.",
        "api-error-badtoken": "Lỗi nội bộ: Dấu hiệu bị hỏng.",
+       "api-error-blocked": "Bạn đã bị cấm không được sửa đổi.",
        "api-error-copyuploaddisabled": "Chức năng tải lên từ URL đã bị tắt trên máy chủ này.",
        "api-error-duplicate": "Wiki này đã có {{PLURAL:$1|tập tin|$1 tập tin}} cùng nội dung có tên khác.",
        "api-error-duplicate-archive": "{{PLURAL:$1|Một|Các}} tập tin khác cùng nội dung đã tồn tại trên website, nhưng {{PLURAL:$1|nó|chúng}} đã bị xóa.",
        "api-error-nomodule": "Lỗi nội bộ: Mô đun tải lên không được định rõ.",
        "api-error-ok-but-empty": "Lỗi nội bộ: Máy chủ không phản hồi.",
        "api-error-overwrite": "Không được ghi đè một tập tin đã tồn tại.",
+       "api-error-ratelimited": "Bạn cố tải lên nhiều tập tin trong một thời gian ngắn vượt quá hạn chế của wiki này.",
        "api-error-stashfailed": "Lỗi nội bộ: Máy chủ bị thất bại trong việc lưu giữ tập tin tạm.",
        "api-error-publishfailed": "Lỗi nội bộ: Máy chủ bị thất bại trong việc xuất bản tập tin tạm.",
        "api-error-stasherror": "Đã xuất hiện lỗi khi tải tập tin lên hàng đợi.",
        "api-error-unknownerror": "Lỗi không rõ: “$1”.",
        "api-error-uploaddisabled": "Chức năng tải lên đã bị tắt trên wiki này.",
        "api-error-verification-error": "Tập tin này có thể bị hỏng hoặc có phần mở rộng sai.",
+       "api-error-was-deleted": "Một tập tin cùng tên này đã được tải lên và bị xóa về sau.",
        "duration-seconds": "$1 giây",
        "duration-minutes": "$1 phút",
        "duration-hours": "$1 giờ",
        "special-characters-group-ipa": "Phiên âm quốc tế",
        "special-characters-group-symbols": "Ký hiệu",
        "special-characters-group-greek": "Hy Lạp",
+       "special-characters-group-greekextended": "Hy Lạp mở rộng",
        "special-characters-group-cyrillic": "Kirin",
        "special-characters-group-arabic": "Ả Rập",
        "special-characters-group-arabicextended": "Ả Rập mở rộng",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "phiên dựa trên cookie",
        "sessionprovider-nocookies": "Cookie có thể bị vô hiệu hóa. Đảm bảo bạn đã bật cookie và bắt đầu một lần nữa.",
        "randomrootpage": "Trang gốc ngẫu nhiên",
+       "log-action-filter-block": "Kiểu cấm:",
+       "log-action-filter-contentmodel": "Kiểu thay đổi kiểu nội dung:",
+       "log-action-filter-delete": "Kiểu xóa:",
+       "log-action-filter-import": "Kiểu nhập:",
+       "log-action-filter-managetags": "Kiểu tác vụ quản lý thẻ:",
+       "log-action-filter-move": "Kiểu di chuyển:",
+       "log-action-filter-newusers": "Kiểu tạo tài khoản:",
+       "log-action-filter-patrol": "Kiểu tuần tra:",
        "log-action-filter-protect": "Loại bảo vệ:",
+       "log-action-filter-rights": "Kiểu thay đổi quyền:",
+       "log-action-filter-suppress": "Kiểu ẩn giấu",
        "log-action-filter-upload": "Loại tải lên:",
        "log-action-filter-all": "Tất cả",
        "log-action-filter-block-block": "Khối",
+       "log-action-filter-block-reblock": "Thay đổi tác vụ cấm",
+       "log-action-filter-block-unblock": "Bỏ cấm",
+       "log-action-filter-contentmodel-change": "Thay đổi kiểu nội dung",
+       "log-action-filter-contentmodel-new": "Tạo trang có kiểu nội dung không chuẩn",
+       "log-action-filter-delete-delete": "Xóa trang",
+       "log-action-filter-delete-restore": "Phục hồi trang",
+       "log-action-filter-delete-event": "Xóa nhật trình",
+       "log-action-filter-delete-revision": "Xóa phiên bản",
+       "log-action-filter-import-interwiki": "Nhập liên wiki",
        "log-action-filter-import-upload": "Nhập bằng cách tải lên XML",
+       "log-action-filter-managetags-create": "Tạo thẻ",
+       "log-action-filter-managetags-delete": "Xóa thẻ",
+       "log-action-filter-managetags-activate": "Kích hoạt thẻ",
+       "log-action-filter-managetags-deactivate": "Vô hiệu thẻ",
+       "log-action-filter-move-move": "Di chuyển mà không ghi đè trang đổi hướng",
+       "log-action-filter-move-move_redir": "Di chuyển mà ghi đè trang đổi hướng",
        "log-action-filter-newusers-create": "Tạo bởi người dùng vô danh",
        "log-action-filter-newusers-create2": "Tạo bởi người dùng đã đăng ký",
+       "log-action-filter-newusers-autocreate": "Tạo tự động",
        "log-action-filter-newusers-byemail": "Tạo với mật khẩu được gửi qua thư điện tử",
+       "log-action-filter-patrol-patrol": "Tuần tra thủ công",
+       "log-action-filter-patrol-autopatrol": "Tuần tra tự động",
        "log-action-filter-protect-protect": "Bảo vệ",
+       "log-action-filter-protect-modify": "Thay đổi mức khóa",
+       "log-action-filter-protect-unprotect": "Mở khóa",
+       "log-action-filter-protect-move_prot": "Di chuyển khóa",
+       "log-action-filter-rights-rights": "Thay đổi thủ công",
        "log-action-filter-rights-autopromote": "Tự động thay đổi",
+       "log-action-filter-suppress-event": "Ẩn giấu nhật trình",
+       "log-action-filter-suppress-revision": "Ẩn giấy phiên bản",
+       "log-action-filter-suppress-delete": "Ẩn giấu trang",
+       "log-action-filter-suppress-block": "Ẩn giấu người dùng bằng cách cấm",
+       "log-action-filter-suppress-reblock": "Ẩn giấu người dùng bằng cách cấm lại",
        "log-action-filter-upload-upload": "Tải lên mới",
        "log-action-filter-upload-overwrite": "Tải lên lại"
 }
index b4e8ba2..d63feb5 100644 (file)
@@ -53,7 +53,7 @@
        "tog-ccmeonemails": "Padad-i ak hin mga kopya hin mga email nga akon ginpapadara ha iba nga mga gumaramit",
        "tog-diffonly": "Ayaw igpakita an sulod han pakli ha ilarom han pagkakaiba",
        "tog-showhiddencats": "Igpakita an mga tinago nga mga kaarangay",
-       "tog-norollbackdiff": "Iglat-ang an kaiban kahuman himoa an libot-pabalik",
+       "tog-norollbackdiff": "Ayaw igpakita an kaiban kahuman himoa an rollback",
        "tog-useeditwarning": "Pasabti ako kun nabaya ako hin ginliwat ng pakli nga waray katipig an mga pagbag-o",
        "tog-prefershttps": "Pirmihi paggamit hin segurado nga koneksyon kun nakalog-in",
        "underline-always": "Pirme",
        "createaccount-title": "Paghimo hin akawnt para han {{SITENAME}}",
        "createaccount-text": "Mayda tawo nga naghimo hin akawnt nga gingamit an imo email address ha {{SITENAME}} ($4) nga ginngaranan nga \"$2\", nga may-ada tigaman-panakob nga \"$3\".\n\nKinahanglan ka maglog-in ngan igbal-iw an imo tigaman-panakob yana dayon.\n\nPuydi nimo pabay-on ini nga mensahe, kun ini nga paghimo hin akwant in nagsayop la.",
        "login-throttled": "Damo na an imo login attempts ha pagkayana.\nAlayon paghulat hin $1 san-o ka umutro.",
-       "login-abort-generic": "An imo paglog-in in diri malinamposon - Naundang",
+       "login-abort-generic": "An imo paglog-in in pakyas - Gin-undang",
        "login-migrated-generic": "An imo account in nabalhin, ngan an imo agnay-gumaramit in waray na hinin nga wiki.",
        "loginlanguagelabel": "Pinulongan: $1",
        "suspicious-userlogout": "Waray ka tugoti pag-logout tungod nga baga ini ginpadangat hin usa nga broken browser o caching proxy.",
        "newpassword": "Bag-o nga tigaman-pagsulod:",
        "retypenew": "Utroha pagbutang an bag-o nga tigaman-pagsulod:",
        "resetpass_submit": "Igbutang an password ngan log in",
-       "changepassword-success": "Malinamposon an pagbal-iw hit imo tigaman-panakob!",
+       "changepassword-success": "Malinamposon an pagliwat hit imo password!",
        "changepassword-throttled": "Damo na nga mga paningkamot hin pagsakob an imo ginhimò.\nAlayon paghulat hin $1 san-o ka umutro.",
        "botpasswords": "Mga bot password",
        "botpasswords-disabled": "Ginparong an mga bot password.",
        "rev-delundel": "igpakita/igtago",
        "rev-showdeleted": "igpakita",
        "revisiondelete": "Pagpara/pagtanggal han pagpara nga mga rebisyon",
+       "revdelete-nooldid-title": "Diri ginkakarawat an target revision",
        "revdelete-show-file-confirm": "Sigurado ka nga gusto mo makita an ginpara nga pagliwat han file \"<nowiki>$1</nowiki>\" tikang $2 ha $3?",
        "revdelete-show-file-submit": "Oo",
        "revdelete-hide-text": "Rebisyon nga sinurat",
        "right-reupload": "Sapawa an mga aada nga mga paypay",
        "right-reupload-own": "Igsapaw an aada yana nga mga paypay nga ginkarga-pasaka nimo mismo",
        "right-upload_by_url": "Igkarga paigbaw an mga paypay tikang ha uska URL",
+       "right-purge": "Igpurge an site cache han pakli bisan waray kompirmasyon",
        "right-autoconfirmed": "Diri malalalbtan hin IP-nga-nahibasi nga mga rate hin paglimit",
        "right-bot": "Igtrato komo uska naglulugaring nga proseso",
        "right-writeapi": "Paggamit han write API",
        "upload-form-label-infoform-name": "Ngaran",
        "upload-form-label-usage-title": "Paggamit",
        "upload-form-label-usage-filename": "Ngaran han file",
-       "foreign-structured-upload-form-label-own-work": "Buhat ko ini",
-       "foreign-structured-upload-form-label-infoform-categories": "Mga kategorya",
-       "foreign-structured-upload-form-label-infoform-date": "Petsa",
+       "upload-form-label-own-work": "Buhat ko ini",
+       "upload-form-label-infoform-categories": "Mga kategorya",
+       "upload-form-label-infoform-date": "Petsa",
        "backend-fail-notexists": "Waray ngada an paypay nga $1.",
        "backend-fail-delete": "Diri nakakapara han paypay nga \"$1\".",
        "backend-fail-alreadyexists": "May-ada na paypay nga \"$1\".",
        "listgrouprights-removegroup-self": "Igtanggal an {{PLURAL:$2|grupo|mga grupo}} tikang ha kalugaringon nga akawnt: $1",
        "listgrouprights-addgroup-self-all": "Igdugang an ngatanan nga mga grupo ha kalugaringon nga akawnt",
        "listgrouprights-removegroup-self-all": "Igtanggal an ngatanan nga mga grupo tikang ha kalugaringon nga akawnt",
+       "listgrants-rights": "Mga katungod",
+       "trackingcategories": "Ginsusubay an mga kategorya",
+       "trackingcategories-name": "Ngaran han mensahe",
        "mailnologin": "Waray kakadtoan nga address",
        "mailnologintext": "Kinahanglan nimo nga [[Special:UserLogin|nakalog-in]] ngan may-ada balido nga email address ha imo[[Special:Preferences|mga preperensya]] para makapadangat hin email ngadto ha iba nga mga gumaramit.",
        "emailuser": "Ig-e-mail ini nga gumaramit",
        "protectcomment": "Katadongan:",
        "protect-default": "Togota an ngatanan nga mga gumaramit",
        "protect-level-sysop": "Tuguti la an mga magdudumara",
+       "protect-expiring": "mawawaray gamit pag-$1 (UTC)",
+       "protect-expiring-local": "mawawaray gamit $1",
+       "protect-expiry-indefinite": "waray kataposan",
        "protect-othertime": "Lain nga oras:",
        "protect-othertime-op": "lain nga oras",
        "protect-otherreason": "Lain/dugang nga katadongan:",
index f8a8300..cbfcdeb 100644 (file)
        "destfilename": "目标文件名:",
        "watchthisupload": "關注箇文件",
        "upload-misc-error": "弗識個傳錯誤",
-       "foreign-structured-upload-form-label-infoform-date": "日脚",
+       "upload-form-label-infoform-date": "日脚",
        "backend-fail-delete": "文件“$1”刪弗爻。",
        "backend-fail-move": "嘸處畀“$1”移到“$2”。",
        "backend-fail-opentemp": "臨時文件開弗爻。",
index 97278ac..fe5623f 100644 (file)
@@ -17,7 +17,8 @@
                        "පසිඳු කාවින්ද",
                        "Matma Rex",
                        "Macofe",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Alefbeis"
                ]
        },
        "tog-underline": "שטרייכט אונטער לינקען",
@@ -35,6 +36,7 @@
        "tog-watchdefault": "צולייגן בלעטער וואס איך רעדאקטיר צו מיין אכטונג ליסטע",
        "tog-watchmoves": "צולייגן בלעטער וואס איך באוועג און טעקעס וואס איך לאד ארויף צו מיין אכטונג ליסטע",
        "tog-watchdeletion": "צולייגן בלעטער וואס איך מעק אויס צו מיין אויפפאסונג ליסטע",
+       "tog-watchuploads": "לייגט צו נייע פיילס וואס איך טוה ארויפלאדירן צו מיין וואטש ליסטע",
        "tog-watchrollback": "צולייגן צו מיין אויפפאסן ליסטע בלעטער אויף וואס איך האב אדורכגעפירט א צוריקשטעלן.",
        "tog-minordefault": "באגרענעצן אלע רעדאַקטירונגען גרונטלעך אלס מינערדיק",
        "tog-previewontop": "צײַג די \"פֿאָרויסיגע װײַזונג\" גלײַך בײַ דער ערשטער באַאַרבעטונג",
@@ -58,7 +60,7 @@
        "tog-ccmeonemails": "שיק מיר קאפיעס פון בליצבריוו וואס איך שיק צו אנדערע באַניצער",
        "tog-diffonly": "ווייז נישט אינהאלט אונטער די דיפערענץ",
        "tog-showhiddencats": "ווײַזן באהאלטענע קאטעגאריעס",
-       "tog-norollbackdiff": "×\94×\99פ×\98 ×\90×\99×\91ער ווײַזן אונטערשייד נאכן אויספֿירן א צוריקדריי",
+       "tog-norollbackdiff": "× ×\99ש×\98 ווײַזן אונטערשייד נאכן אויספֿירן א צוריקדריי",
        "tog-useeditwarning": "שטעלן א ווארענונג ווען איך לאז איבער א רעדאקטירונג בלאט מיט נישט אויפגעהיטענע ענדערונגען",
        "tog-prefershttps": "ניצט שטענדיק א זיכערע פארבינדונג ווען ארײַנגלאגירט",
        "underline-always": "אייביג",
        "february-gen": "פעברואר",
        "march-gen": "מערץ",
        "april-gen": "אַפּריל",
-       "may-gen": "×\9e×\99י",
+       "may-gen": "×\9e×\90Ö·י",
        "june-gen": "יוני",
        "july-gen": "יולי",
        "august-gen": "אויגוסט",
        "returnto": "צוריקקערן צו $1.",
        "tagline": "פֿון {{SITENAME}}",
        "help": "הילף",
-       "search": "×\96×\95×\9b×\9f",
-       "searchbutton": "×\96×\95×\9b×\9f",
+       "search": "×\96×\95×\9a",
+       "searchbutton": "×\96×\95×\9a",
        "go": "גיין",
        "searcharticle": "גיין",
        "history": "בלאט היסטאריע",
        "protectedpage": "באשיצטער בלאט",
        "jumpto": "שפּרינג צו:",
        "jumptonavigation": "נאַוויגאַציע",
-       "jumptosearch": "×\96×\95×\9b×\9f",
+       "jumptosearch": "×\96×\95×\9a",
        "view-pool-error": "אנטשולדיגט, די סערווערס זענען איבערגעפילט איצט.\nצופיל באניצער פרובירן צו ליינען דעם בלאט.\nביטע ווארטן א ביסל צייט בעפאר איר פרובירט ווידער אריינגיין אינעם בלאט.\n\n$1",
        "generic-pool-error": "אנטשולדיגט, די סערווערס זענען איבערגעפילט איצט.\nצופיל באניצער פרובירן צו באקוקן דעם רעסורס.\nביטע ווארטן א ביסל צייט בעפאר איר פרובירט ווידער אריינטרעטן אין דעם רעסורס.",
        "pool-timeout": "אַריבער דער צײַט וואַרטן פֿאר דער שליסונג",
        "newmessageslinkplural": "{{PLURAL:$1|א נייע מעלדונג|999=נייע מעלדונגען}}",
        "newmessagesdifflinkplural": "לעצטע {{PLURAL:$1|ענדערונג|999=ענדערונגען}}",
        "youhavenewmessagesmulti": "איר האט נייע מעלדונגען אין $1",
-       "editsection": "×\91×\90Ö·×\90ַר×\91×¢×\98ן",
+       "editsection": "רע×\93×\90ַק×\98×\99רן",
        "editold": "רעדאַקטירן",
        "viewsourceold": "ווײַזן מקור",
        "editlink": "רעדאַקטירן",
        "red-link-title": "$1 (בלאט טוט נאָך נישט עקזיסטירן)",
        "sort-descending": "סארטירן אַראָפ",
        "sort-ascending": "סארטירן אַרויף",
-       "nstab-main": "×\90ַר×\98×\99ק×\9c",
+       "nstab-main": "×\91×\9c×\90Ö·×\98",
        "nstab-user": "באַניצער בלאט",
        "nstab-media": "מעדיע בלאט",
        "nstab-special": "ספעציעלער בלאט",
        "virus-unknownscanner": "אומבאוואוסטער אנטי־ווירוס:",
        "logouttext": "'''איר האָט זיך ארויסלאָגירט.'''\n\nבאמערקט אז געוויסע בלעטער קענען זיך ווייטער ארויסשטעלן אזוי ווי ווען איר זענט אריינלאגירט, ביז איר וועט אויסליידיגן דעם בלעטערער זאפאס.",
        "cannotlogoutnow-title": "קען נישט ארויסלאגירן אצינד",
+       "cannotlogoutnow-text": "ארויסלאגירן נישט מעגלעך ווען מען ניצט $1.",
        "welcomeuser": "ברוך הבא, $1!",
        "welcomecreation-msg": "מ'האט געשאפן אייער קאנטע.\nפארגעסט נישט צו ענדערן אייערע [[Special:Preferences|{{SITENAME}} פרעפערענצן]].",
        "yourname": "באַניצער נאָמען:",
        "userlogin-remembermypassword": "לאז מיך בלײַבן ארײַנלאגירט",
        "userlogin-signwithsecure": "ניצן זיכערן סארווער",
        "cannotloginnow-title": "קען נישט אריינלאגירן אצינד",
+       "cannotloginnow-text": "אריינלאגירן נישט מעגלעך ווען מען ניצט $1.",
        "yourdomainname": "אײַער געביט:",
        "password-change-forbidden": "איר קען נישט ענדערן פאסווערטער אויף דער וויקי.",
        "externaldberror": "עס איז אדער פארגעקומען אן אויטענטיקאציע דאטנבאזע פֿעלער אדער איר זענט נישט ערמעגליכט צו דערהיינטיגן אייער דרויסנדיגע קאנטע.",
        "nocookieslogin": "{{SITENAME}} נוצט קיכלעך כדי אַרײַנלאגירן באַניצער.\nבײַ אײַך זענען קיכלעך אומדערמעגלעכט.\nביטע אַקטיווירט זיי און פרובירט נאכאַמאָל.",
        "nocookiesfornew": "מען האט נישט געשאַפֿן די באַניצער קאנטע, ווײַל מען האט נישט געקענט באַשטעטיקן איר מקור.\nטוט פֿעסטשטעלן אָז קיכלעך זענען אַקטיווירט, לאָדט אָן נאכאַמאל דעם בלאַט און פרואווט ווידער.",
        "noname": "איר האט נישט אַרײַנגעשטעלט קײַן גילטיקן באַניצער נאָמען.",
-       "loginsuccesstitle": "אריינלאגירט מיט הצלחה",
+       "loginsuccesstitle": "אריינלאגירט",
        "loginsuccess": "'''איר זענט אַצינד אַרײַנלאָגירט אין {{SITENAME}} ווי \"$1\".'''",
        "nosuchuser": "נישטא קיין באניצער מיטן נאמען  \"$1\".\n\nקוקט איבער אײַער אויסלייג, אדער [[Special:UserLogin/signup|שאַפֿט א נײַע קאנטע]].",
        "nosuchusershort": "נישטאָ קיין באַניצער מיטן נאָמען \"$1\".\nביטע באַשטעטיקט דעם אויסלייג.",
        "createaccount-title": "קאנטע באשאפֿן אין {{SITENAME}}",
        "createaccount-text": "עמעצער האט באשאפֿן א קאנטע פֿאר אייער ע-פאסט אדרעס אין {{SITENAME}} ($4) מיטן נאמען \"$2\" און  פאסווארט \"$3\". איר דארפט אצינד איינלאגירן און ענדערן דאס פאסווארט.\n\nאיר קענט איגנארירן די מעלדונג, ווען די קאנטע איז באשאפֿן בטעות.",
        "login-throttled": "איר האט געפרוווט צופֿיל מאל אריינלאגירן.\nזייט אזוי גוט און וואַרט $1 איידער איר פרוווט נאכאמאל.",
-       "login-abort-generic": "×\90ײַער ×\90רײַנ×\9c×\90×\92×\99ר×\95× ×\92 ×\90×\99×\96 × ×\99ש×\98 ×\92×¢×\95×\95×¢×\9f ×\93ערפֿ×\90×\9c×\92ר×\99×\99×\9a—אָפגעשטעלט",
+       "login-abort-generic": "×\90ײַער ×\90רײַנ×\9c×\90×\92×\99ר×\95× ×\92 ×\90×\99×\96 ×\93×\95ר×\9b×\92עפ×\90×\9c×\9f—אָפגעשטעלט",
        "login-migrated-generic": "אײַער קאנטע איז געווארן מיגרירט, און אײַער באניצער־נאמען איז מער נישט פאראן אויף דער וויקי.",
        "loginlanguagelabel": "שפראך: $1",
        "suspicious-userlogout": " אײַער בקשה אַרויסלאָגירן זיך איז אפגעלייגט געווארן ווייַל אייגנטלעך איז זי געשיקט דורך אַ צעבראכענעם בלעטערער אָדער א פראקסי מיט א זאפאס.",
        "createacct-another-realname-tip": "עכטער נאמען איז אפציאנאל.\nאויב איר וויילט אויס צוצושטעלן אים, וועט דאס גענוצט ווערן צו געבן אטריבוציע פאר זייער ארבעט.",
-       "pt-login": "אַרײַנלאגירן",
+       "pt-login": "אריינלאגירן",
        "pt-login-button": "אַרײַנלאָגירן",
        "pt-createaccount": "שאַפֿן אַ קאנטע",
        "pt-userlogout": "אַרויסלאָגירן",
        "newpassword": "ניי פּאסוואָרט:",
        "retypenew": "ווידער שרײַבן פאַסווארט:",
        "resetpass_submit": "שטעלן פאסווארט און אריינלאגירן",
-       "changepassword-success": "אייער פאַסווארט איז געטוישט געווארן מיט דערפֿאלג!",
+       "changepassword-success": "אייער פאַסווארט איז געטוישט געווארן!",
        "changepassword-throttled": "איר האט געפרוווט צופֿיל מאל אריינלאגירן.\nזייט אזוי גוט און וואַרט $1 איידער איר פרוווט נאכאמאל.",
+       "botpasswords": "באט פאסווערטער",
+       "botpasswords-label-appid": "באט נאמען:",
        "botpasswords-label-create": "שאַפֿן",
        "botpasswords-label-update": "דערהײַנטיקן",
        "botpasswords-label-cancel": "אַנולירן",
        "botpasswords-label-delete": "אויסמעקן",
        "botpasswords-label-resetpassword": "ווידערשטעלן פאַסווארט",
+       "botpasswords-label-grants-column": "נאכגעגעבן",
+       "botpasswords-created-title": "באט פאסווארט געשאפן",
+       "botpasswords-created-body": "דאס באט פאסווארט פאר באט־נאמען \"$1\" פון באניצער \"$2\" איז געשאפן געווארן.",
+       "botpasswords-updated-title": "באט פאסווארט דערהיינטיקט",
+       "botpasswords-updated-body": "דאס באט פאסווארט פאר באט־נאמען \"$1\" פון באניצער \"$2\" איז דערהיינטיקט געווארן.",
+       "botpasswords-deleted-title": "באט פאסווארט אויסגעמעקט",
        "resetpass_forbidden": "פאסווערטער קענען נישט ווערן געטוישט",
        "resetpass-no-info": "איר דארפֿט זיין אריינלאגירט צוצוקומען גלייך צו דעם דאזיגן בלאט.",
        "resetpass-submit-loggedin": "טוישן פאסווארט",
        "resetpass-submit-cancel": "אַנולירן",
-       "resetpass-wrong-oldpass": "×\90×\95×\9e×\92×\99×\9c×\98×\99×\92 ×¦×²Ö·×\98×\95×\95ײַ×\9c×\99ק ×\90×\93ער ×\9c×\95×\99פֿ×\99ק ×¤×\90ַס×\95×\95×\90ר×\98.\n×\90×\99ר ×\94×\90×\98 ×\9e×¢×\92×\9c×¢×\9a ×©×\95×\99×\9f ×\92×¢×\98×\95×\99ש×\98 ×\90×\99×\99ער ×¤×\90ַס×\95×\95×\90ר×\98 ×\9e×\99×\98 ×\94צ×\9c×\97×\94 ×\90×\93ער ×\92×¢×\91×¢×\98×\9f ×\90 × ×²Ö·  ×¦×²Ö·×\98×\95×\95ײַ×\9c×\99ק ×¤×\90ַס×\95×\95×\90ר×\98.",
+       "resetpass-wrong-oldpass": "אומגילטיג צײַטווײַליק אדער לויפֿיק פאַסווארט.\nאיר האט מעגלעך שוין געטוישט אייער פאַסווארט אדער געבעטן א נײַ  צײַטווײַליק פאַסווארט.",
        "resetpass-recycled": "זײַט אזוי גוט שטעטל אירע פאסווארט צו עפעס אנדערש פונעם לויפיקן פאסווארט.",
        "resetpass-temp-emailed": "איר האט זיך ארי לאגירת מיט א פראוויזארישן קאד געשיקט דורכן ע־פאסט. כדי שליסן דאס ארײַנלאגירן, דארט איר שטעלן א נײַ פאסווארט דא.",
        "resetpass-temp-password": "צײַטווייליק פאַסווארט:",
        "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-emailsentemail": "טאמער איז דער ע־פאסט אדרעס פארקניפט מיט אייער קאנטע, וועט מען שיקן א פאסווארט צוריקשטעלן ע-פּאָסט.",
+       "passwordreset-emailsentusername": "טאמער איז פאראן אן ע־פאסט אדרעס פארקניפט מיט דעם באניצער־נאמען, וועט מען שיקן א פאסווארט צוריקשטעלן ע-פּאָסט.",
        "passwordreset-emailsent-capture": "מען האט געשיקט א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן.",
        "passwordreset-emailerror-capture": "מען האט געשאפן א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן, אבער שיקן צום {{GENDER:$2|באניצער}}איז דורכגעפאלן: $1",
        "changeemail": "ענדערן אדער אראפנעמען ע-פּאָסט אַדרעס",
        "minoredit": "דאס איז א מינערדיגע ענדערונג",
        "watchthis": "טוט אױפֿפּאַסן דעם בלאט",
        "savearticle": "אויפהיטן בלאַט",
+       "publishpage": "פובליצירן בלאט",
        "preview": "פֿאראויסקוק",
        "showpreview": "ווייזן פאָרױסקוק",
        "showdiff": "ווײַז די ענדערונגען",
        "userpage-userdoesnotexist": "באניצער קאנטע \"$1\" איז נישט אײַנגעשריבן.\nקוקט איבער צי איר ווילט שאפֿן/רעדאקטירן דעם בלאט.",
        "userpage-userdoesnotexist-view": "באניצער קאנטע \"$1\" איז נישט איינגעשריבן.",
        "blocked-notice-logextract": "דער באַניצער איז דערווייַל פֿאַרשפאַרט.\nדי לעצטע בלאָקירן לאג אַקציע איז צוגעשטעלט אונטן:",
-       "clearyourcache": "'''אַכטונג:''' נאכן אויפֿהיטן, ברויכט איר אפשר נאך אַריבערגיין דעם בלעטערערס זאַפאַס צו זען די ענדערונגען.\n\n* '''פֿייערפוקס/סאפֿארי:''' האלט אראפ ''שיפֿט'' בשעתן דרוקן ''Reload'', אדער דרוקט ''Ctrl-F5'' אדער ''Ctrl-R'' (אויף א מאקינטאש ''⌘-R'')\n\n* '''גוגל כראם:''' דרוקט ''Ctrl-Shift-R'' (אויף א מאקינטאש ''⌘-Shift-R'')\n\n* '''אינטערנעט עקספלארער:''' האלט אראפ ''Ctrl'' בשעתן קליקן ''Refresh'', אדער  דרוקט ''Ctrl-F5''\n\n* '''אפערע:''' ליידיגט אויס דעם זאַפאַס אין ''Tools → Preferences'' (''העדפות'' > ''כלים'')",
+       "clearyourcache": "'''אַכטונג:''' נאכן אויפֿהיטן, ברויכט איר אפשר נאך אַריבערגיין דעם בלעטערערס זאַפאַס צו זען די ענדערונגען.\n\n* '''פֿייערפוקס/סאפֿארי:''' האלט אראפ ''שיפֿט'' בשעתן דרוקן ''Reload'', אדער דרוקט ''Ctrl-F5'' אדער ''Ctrl-R'' (אויף א מאקינטאש ''⌘-R'')\n\n* '''גוגל כראם:''' דרוקט ''Ctrl-Shift-R'' (אויף א מאקינטאש ''⌘-Shift-R'')\n\n* '''אינטערנעט עקספלארער:''' האלט אראפ ''Ctrl'' בשעתן קליקן ''Refresh'', אדער  דרוקט ''Ctrl-F5''\n\n* <strong>אפערע:</strong> גייט צו <em>מעניו → שטעלונגען</em> (<em> אפערע → פרעפערנצן</em> אויף א מעק) און דערנאך צו <em>פריוואטקייט & און זיכערהייט → אראפראמען בלעטערן דאטן → בילדער און טעקעס אין זאפאס</em>",
        "usercssyoucanpreview": "'''טיפ:''' נוצט דאס {{int:showpreview}} קנעפל אויספרובירן אייער CSS בעפארן אויפהיטן.",
        "userjsyoucanpreview": "'''טיפ:''' נוצט דאס {{int:showpreview}} קנעפל אויספרובירן אייער  JavaScript בעפארן אויפהיטן.",
        "usercsspreview": "'''געדענקט אז איר טוט בלויז פאראויס זען אייער באניצער CSS.'''\n'''ער איז דערווייל נאכנישט אויפֿגעהיטן!'''",
        "revdelete-unsuppress": "טוה אפ באגרענעצונגן אין גענדערטע רעוויזיעס",
        "revdelete-log": "אורזאַך:",
        "revdelete-submit": "צושטעלן צו {{PLURAL:$1|סעלעקטירטער רעוויזיע| סעלעקטירטע רעוויזיעס}}",
-       "revdelete-success": "'''רע×\95×\95×\99×\96×\99×¢ ×\96×¢×\91×\90ַרק×\99×\99×\98 ×\93ערפֿ×\90×\9c×\92ר×\99×\99×\9a ×\93ער×\94ײַנ×\98×\99ק×\98.'''",
+       "revdelete-success": "'''רעוויזיע זעבאַרקייט דערהײַנטיקט.'''",
        "revdelete-failure": "'''נישט מעגלעך צו דערהײַנטיקן רעוויזיע זעבאַרקייט:'''\n$1",
-       "logdelete-success": "'''לאג באהאלטן איז סוקסעספול איינגעשטעלט.'''",
+       "logdelete-success": "'''לאגבוך זעבארקייט איינגעשטעלט.'''",
        "logdelete-failure": "'''נישט מעגלעך צו שטעלן לאג זעבאַרקייט:'''\n$1",
        "revdel-restore": "טויש די זעבארקייט",
        "pagehist": "בלאט היסטאריע",
        "userrights-changeable-col": "גרופעס איר קענט ענדערן",
        "userrights-unchangeable-col": "גרופעס איר קענט נישט ענדערן",
        "userrights-conflict": "קאנפֿליקט פון באניצער־רעכטן ענדערונגען! זייט אזוי גוט רעצענזירן און באשטעטיקן אײַערע ענדערונגען.",
-       "userrights-removed-self": "×\90×\99ר ×\94×\90×\98 ×\93ערפ×\90×\9c×\92ר×\99×\99×\9a ×\90ר×\90פ×\92×¢× ×\95×\9e×¢×\9f ×\90×\99×\99ערע ×\90×\99×\99×\92×¢× ×¢ ×¨×¢×\9b×\98×¢. אזוי קענט איר מער נישט דערגרייכן דעם בלאט.",
+       "userrights-removed-self": "×\90×\99ר ×\94×\90×\98 ×\90ר×\90פ×\92×¢× ×\95×\9e×¢×\9f ×\90×\99×\99ערע ×\90×\99×\99×\92×¢× ×¢ ×¨×¢×\9b×\98×\9f. אזוי קענט איר מער נישט דערגרייכן דעם בלאט.",
        "group": "גרופע:",
        "group-user": "באניצערס",
        "group-autoconfirmed": "באַשטעטיקטע באַניצער",
        "grant-group-file-interaction": "אינטעראגירן מיט מעדיע",
        "grant-group-email": "שיקן ע־פאסט",
        "grant-createaccount": "שאַפֿן קאנטעס",
+       "grant-uploadfile": "אַרויפֿלאָדן נייע טעקעס",
+       "grant-basic": "בעיסיק רעכטן",
+       "grant-viewmywatchlist": "קוקט אייער אויפפאסונג ליסטע",
        "newuserlogpage": "נייע באַניצערס לאָג-בוך",
        "newuserlogpagetext": "דאס איז א לאג פון באַניצערס אײַנשרײַבונגען.",
        "rightslog": "באַניצער רעכטן לאג",
        "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-not-own-work-local-local": "אפשר ווילט איר פרובירן [[Special:Upload|דעם גרונטלעכן ארויפלאד־בלאט]].",
+       "upload-form-label-own-work": "דאס איז מיין אייגענע ארבעט.",
+       "upload-form-label-infoform-categories": "קאַטעגאריעס",
+       "upload-form-label-infoform-date": "דאַטע",
+       "upload-form-label-not-own-work-local-local": "אפשר ווילט איר פרובירן [[Special:Upload|דעם גרונטלעכן ארויפלאד־בלאט]].",
        "backend-fail-stream": "קען נישט מאכן שטראמען טעקע $1.",
        "backend-fail-notexists": "נישט פֿאראן די טעקע $1.",
        "backend-fail-notsame": "א נישט־אידענטישע טעקע עקזיסטירט שוין ביי \"$1\".",
        "imagelinks": "טעקע באַניץ",
        "linkstoimage": "{{PLURAL:$1|דער פאלגנדער בלאט ניצט|די פאלגנדע בלעטער ניצן}} דאס דאזיגע בילד:",
        "linkstoimage-more": "מער ווי $1 {{PLURAL:$1|בלאַט פֿאַרבינדט|בלעטער פֿאַרבינדן}} צו דער דאזיגער טעקע.\nדי פֿאלגנדע ליסטע ווײַזט  {{PLURAL:$1|דעם ערשטן בלאַט לינק|די ערשטע $1 בלאַט לינקען}} צו דער טעקע.\nס'איז פֿאַראַן[[Special:WhatLinksHere/$2|פֿולע רשימה]].",
-       "nolinkstoimage": "× ×\99ש×\98×\90 ×§×\99×\99×\9f ×\91×\9c×¢×\98ער ×\95×\95×\90ס × ×\99צ×\9f ×\93×\90ס ×\93×\90×\96×\99×\92×¢ ×\91×\99×\9c×\93.",
+       "nolinkstoimage": "× ×\99ש×\98×\90 ×§×\99×\99×\9f ×\91×\9c×¢×\98ער ×\95×\95×\90ס ×¤×\90ר×\91×\99× ×\93×\9f ×¦×\95 ×\93×\99 ×\98עקע.",
        "morelinkstoimage": "באַקוקן  [[Special:WhatLinksHere/$1|מער לינקען]] צו דער טעקע.",
        "linkstoimage-redirect": "$1 (טעקע ווײַטערפֿירונג) $2",
        "duplicatesoffile": "די פֿאלגנדע {{PLURAL:$1|טעקע דופליקירט|$1 טעקעס דופליקירן}} די דאזיגע טעקע ([[Special:FileDuplicateSearch/$2|נאך פרטים]]):",
        "unusedtemplates": "נישט באניצטע מוסטערן",
        "unusedtemplatestext": "דער בלאט ווײַזט אלע בלעטער אינעם {{ns:template}} נאמענטייל וואס זענען נישט אײַנגעשלאסן אין אן אנדער בלאט. געדענקט צו באקוקן אנדערע בלעטער פאר לינקען צו די מוסטערן איידער איר מעקט זיי אויס.",
        "unusedtemplateswlh": "אנדערע פֿאַרבינדונגען",
-       "randompage": "צ×\95פֿע×\9c×\99×\92ער ×\90ַר×\98×\99ק×\9c",
+       "randompage": "צ×\95פֿע×\9c×\99×\92ער ×\91×\9c×\90×\98",
        "randompage-nopages": "נישטא קיין בלעטער אין {{PLURAL:$2|דעם פאלגנדן נאמענטייל |די פאלגנדע נאמענטיילן}} \"$1\".",
        "randomincategory": "צופעליקער בלאט אין קאטעגאריע",
        "randomincategory-invalidcategory": "\"$1\" איז נישט קיין גילטיקער קאטעגאריע נאמען.",
        "querypage-disabled": "דער באַזונדער־בלאַט איז אומאַקטיווירט צוליב אויספֿירונג סיבות.",
        "apihelp": "API־הילף",
        "apihelp-no-such-module": "מאָדול \"$1\" נישט געפונען.",
+       "apisandbox-unfullscreen": "ווייזן בלאט",
        "apisandbox-reset": "רייניקן",
+       "apisandbox-retry": "פרובירן נאכאמאל",
+       "apisandbox-helpurls": "הילף לינקען",
+       "apisandbox-examples": "ביישפילן",
        "apisandbox-results": "רעזולטאטן",
        "booksources": "דרויסנדיגע ליטעראַטור ISBN",
        "booksources-search-legend": "זוכן פאר דרויסנדע ביכער מקורות",
        "logempty": "נישטא קיין פאַסנדיקע זאכן אין לאג.",
        "log-title-wildcard": "זוכן טיטלען וואס הייבן אָן מיט דעם טעקסט",
        "showhideselectedlogentries": "ווײַזן/באַהאַלטן געקליבענע לאגבוך אקציעס",
+       "checkbox-all": "אַלע",
+       "checkbox-none": "קיינע",
+       "checkbox-invert": "אומקערן",
        "allpages": "אַלע בלעטער",
        "nextpage": "קומענדיקער בלאַט ($1)",
        "prevpage": "פֿריִערדיקער בלאַט ($1)",
        "listgrouprights-namespaceprotection-header": "נאמענטייל באשרענקונגען",
        "listgrouprights-namespaceprotection-namespace": "נאָמענטייל",
        "listgrouprights-namespaceprotection-restrictedto": "רעכט(ן) וואס דערלויבט באניצער צו רעדאקטירן",
+       "listgrants-grant": "צולאזן",
+       "listgrants-rights": "רעכטן",
        "trackingcategories": "אויפפאסן־קאטעגאריעס",
        "trackingcategories-msg": "אויפפאסן־קאטעגאריע",
        "trackingcategories-name": "מעלדונג נאמען",
        "wlnote": "אונטן {{PLURAL:$1|איז די לעצטע ענדערונג|זענען די לעצטע <strong>$1</strong> ענדערונגען}} אין {{PLURAL:$2|דער לעצטער שעה|די לעצטע <strong>$2</strong> שעה'ן}} ביז $3, $4.",
        "wlshowlast": "ווײַזן די לעצטע $1 שעה'ן  $2 טעג",
        "watchlist-hide": "באַהאַלטן",
+       "watchlist-submit": "ווײַזן",
        "wlshowtime": "צייט־פעריאד צו ווייזן:",
        "wlshowhideminor": "מינערדיקער רעדאקטירונגען",
        "wlshowhidebots": "באטן",
        "wlshowhideanons": "אַנאָנימע באַניצער",
        "wlshowhidepatr": "פאטראלירטע רעדאקטירונגען",
        "wlshowhidemine": "מיינע רעקאקטירונגען",
+       "wlshowhidecategorization": "בלאט קאטעגאריזירונג",
        "watchlist-options": "אויפֿפאַסן ליסטע ברירות",
        "watching": "אויפפאסענדונג…",
        "unwatching": "נעמט אראפ פון אויפפאסונג ליסטע…",
        "delete-toobig": "דער בלאַט האט א גרויסע רעדאקטירונג היסטאריע, מער ווי $1 {{PLURAL:$1|רעוויזיע|רעוויזיעס}}. אויסמעקן אזעלכע בלעטער איז באַגרענעצט געווארן בכדי צו פֿאַרמײַדן א צופֿעליגע פֿאַרשטערונג פֿון  {{SITENAME}}.",
        "delete-warning-toobig": "דער בלאַט האט א גרויסע רעדאקטירונג היסטאריע, מער ווי $1 {{PLURAL:$1|רעוויזיע|רעוויזיעס}}. אויסמעקן אים קען פֿאַרשטערן דאַטנבאַזע אפעראַציעס פֿון {{SITENAME}}; זײַט פֿארזיכטיג איידער איר מעקט אויס.",
        "deleteprotected": "איר קענט נישט אויסמעקן דעם בלאט ווײַל ער איז געשיצט.",
-       "deleting-backlinks-warning": "'''ווארענוג:'''\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|אנדערע בלעטער]]  פארבינדן צום בלאט אדער אריבערשליסן דעם בלאט איר האלט ביי אויסמעקן.",
+       "deleting-backlinks-warning": "</strong>ווארענוג:<strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|אנדערע בלעטער]]  פארבינדן צום בלאט אדער אריבערשליסן דעם בלאט איר האלט ביי אויסמעקן.",
        "rollback": "צוריקדרייען רעדאַקטירונגען",
        "rollbacklink": "צוריקדרייען",
        "rollbacklinkcount": "צוריקדרייען $1 {{PLURAL:$1|רעדאקטירונג|רעדאקטירונגען}}",
        "rollbackfailed": "צוריקדרייען דורכגעפֿאַלן",
        "cantrollback": "מען קען נישט צוריקדרייען די ענדערונג – דער לעצטער בײַשטייערער איז דער איינציגסטער שרײַבער אין דעם בלאַט.",
        "alreadyrolled": "מען קען נישט צוריקדרייען די לעצטע ענדערונג פון בלאט [[:$1]] פֿון\n[[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'''\".",
+       "editcomment": "קורץ ווארט איז געווען: <em>$1</em>.",
        "revertpage": "רעדאַקטירונגען פֿון  [[Special:Contributions/$2|$2]] צוריקגענומען ([[User talk:$2|רעדן]])  צו דער לעצטער ווערסיע פֿון [[User:$1|$1]]",
        "revertpage-nouser": "צוריקגעשטעלט רעדאַקטירונגען פֿון א באהאלטענעם באַניצער צו לעצטער רעוויזיע פֿון {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "צוריקגעדרייט רעדאַקטירונגען פֿון $1 צו דער לעצטע ווערסיע פֿון $2",
        "changecontentmodel-title-label": "בלאט־טיטל",
        "changecontentmodel-model-label": "נייער אינהאלט מאדעל",
        "changecontentmodel-reason-label": "אורזאַך:",
+       "changecontentmodel-submit": "טוישן",
        "logentry-contentmodel-change-revertlink": "צוריקשטעלן",
        "logentry-contentmodel-change-revert": "צוריקשטעלן",
        "protectlogpage": "באשיצונג לאָג-בוך",
        "ipb-unblock": "אויפֿבלאקירן א באַניצער נאמען אדער IP אדרעס",
        "ipb-blocklist": "זעט עקזיסטירנדע בלאקירונגען",
        "ipb-blocklist-contribs": "בײַשטײַערונגען פֿון {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "נאך $1",
        "unblockip": "אויפֿבלאקירן באניצער",
        "unblockiptext": "מיט דעם פארמולאר קענט איר צוריקשטעלן שרייבן ערלויבניש צו אן IP אדרעס אדער באניצער נאמען וואס איז געווען בלאקירט.",
        "ipusubmit": "אוועקנעמען דעם בלאק",
        "blocklink": "ארויסטרייבן",
        "unblocklink": "באַפֿרײַען",
        "change-blocklink": "ענדערן בלאק",
-       "contribslink": "×\91×\90Ö·× ×\99צערס ×\91ײַש×\98ײַער×\95× ×\92×¢×\9f",
+       "contribslink": "בײַשטײַערונגען",
        "emaillink": "שיקן ע־פאסט",
        "autoblocker": "אויטאמאטיש בלאקירט ווייל אײַער IP אדרעס איז לעצטנס געניצט געווארן דורך [[User:$1|$1]]. \nדער סיבה וואס איז אנגעבען געווארן איז: \"$2\".",
        "blocklogpage": "בלאקירן לאג",
        "import-nonewrevisions": "קיין רעוויזיעס נישט אימפארטירט (אדער אלע שוין דא, אדער איבערגעהיפט צוליב גרײַזן).",
        "xml-error-string": "$1 בײַ שורה $2, זייל $3 (בייט $4): $5",
        "import-upload": "אַרויפֿלאָדן XML דאַטן",
-       "import-token-mismatch": "×\90ָנ×\95×\95ער ×¤×\95×\9f ×¡×¢×¡×\99×¢ ×\93×\90Ö·×\98×\9f.\n ×\91×\99×\98×¢ ×¤×¨×\95×\91×\99ר×\98 × ×\90×\9b×\90×\9e×\90×\9c.",
+       "import-token-mismatch": "פ×\90ר×\9c×\95ס×\98 ×¤×\95×\9f ×¡×¢×¡×\99×¢ ×\93×\90×\98×\9f. \n\nקע×\9f ×\96×\99×\99×\9f ×\90×\96 ×\90×\99ר ×\96×¢× ×¢×\9f ×\92×¢×\95×\95×\90ר×\9f ×\90ר×\95×\99ס×\9c×\90×\92×\99ר×\98\n<strong>×\91×\99×\98×¢ ×¤×¨×\95×\91×\99ר×\98 × ×\90×\9b×\90×\9e×\90×\9c</strong>. \n\n×\90×\95×\99×\91 ×¡'×\90ר×\91×¢×\98 × ×\90×\9a ×\90×\9cס × ×\99×\98, ×¤×¨×\95×\91×\99ר×\98 [[Special:UserLogout|×\90ר×\95×\99ס×\9c×\90×\92×\99ר×\9f]] ×\90×\95×\9f ×\96×\99×\9a ×¦×\95ר×\99ק ×\90ר×\99×\99× ×\9c×\90×\92×\99ר×\9f.",
        "import-invalid-interwiki": "נישט מעגלעך צו אימפארטירן פון ספעציפֿירטער וויקי.",
        "import-error-edit": "דעם בלאט \"$1\" קען מען נישט אימפארטירן ווייל איר האט נישט די רעכט אים צו רעדאקטירן.",
        "import-error-create": "דעם  בלאט \"$1\" האט מען נישט אימפארטירט ווייל איר האט נישט די רעכט צו שאפן אים.",
        "tooltip-pt-mycontris": "ליסטע פון {{GENDER:|אייערע}} ביישטייערונגען",
        "tooltip-pt-login": "עס איז רעקאָמענדירט זיך אײַנשרײַבן; ס'איז אבער נישט קיין פֿליכט",
        "tooltip-pt-logout": "ארויסלאגירן",
-       "tooltip-pt-createaccount": "איר ווערט דערמוטיגט צו שאפן א קאנטע און אריינלאגירן; ס'איז אביר נישט אבליגאטאריש",
+       "tooltip-pt-createaccount": "איר ווערט דערמוטיגט צו שאַפֿן א קאנטע און אריינלאגירן; ס׳איז אבער נישט פארפליכטעט",
        "tooltip-ca-talk": "שמועס וועגן דעם אינהאַלט בלאַט",
-       "tooltip-ca-edit": "רעדאקטירן דעם בלאַט",
+       "tooltip-ca-edit": "רעדאַקטירן דעם בלאַט",
        "tooltip-ca-addsection": "אָנהייבן א נײַע אָפטיילונג",
        "tooltip-ca-viewsource": "דאס איז א פֿארשלאסענער בלאט, איר קענט נאר באַקוקן זיין מקור",
        "tooltip-ca-history": "פריערדיגע ווערסיעס פון דעם בלאט.",
        "tooltip-ca-move": "באַוועגן דעם בלאַט",
        "tooltip-ca-watch": "לייגט צו דעם בלאט אויפצופאסן",
        "tooltip-ca-unwatch": "נעמט אַראָפּ דעם בלאַט פון נאָכפאָלג־ליסטע",
-       "tooltip-search": "×\96×\95×\9b×\98 ×\90×\99× ×¢×\9d ×¡×\99×\99×\98",
+       "tooltip-search": "×\96×\95×\9a {{SITENAME}}",
        "tooltip-search-go": "גייט צו א בלאט מיט אט דעם נאמען, אויב ער עקסיסטירט",
        "tooltip-search-fulltext": "זוכט דעם טעקסט אין די בלעטער",
-       "tooltip-p-logo": "×\94×\95×\99פ×\98 ×\96×\99×\99ט",
+       "tooltip-p-logo": "×\91×\90Ö·×\96×\95×\9b×\9f ×\93×¢×\9d ×\94×\95×\99פ×\98 ×\91×\9c×\90Ö·ט",
        "tooltip-n-mainpage": "באַזוכט דעם הויפּט־זײַט",
        "tooltip-n-mainpage-description": "באַזוכן דעם הויפט בלאַט",
        "tooltip-n-portal": "גייט אריין אין די געמיינדע צו שמועסן",
        "tooltip-n-currentevents": "מער אינפארמאציע איבער אקטועלע געשענישען",
-       "tooltip-n-recentchanges": "ליסטע פון לעצטע ענדערונגען",
+       "tooltip-n-recentchanges": "ליסטע פון לעצטע ענדערונגען אין דעם וויקי",
        "tooltip-n-randompage": "וועלט אויס א צופעליגער בלאט",
-       "tooltip-n-help": "×\94×\99×\9c×£",
-       "tooltip-t-whatlinkshere": "×\90×\9c×¢ ×\91×\9c×¢×\98ער ×\95×\95×\90ס ×¤×\90ר×\91×\99× ×\93×¢×\9f ×¦×\95 ×\93×¢×\9d ×\91×\9c×\90×\98",
+       "tooltip-n-help": "×\93ער ×¤×\9c×\90×¥ ×\90×\95×\99סצ×\95×\92עפ×\99× ×¢×\9f",
+       "tooltip-t-whatlinkshere": "×\90×\9c×¢ ×\9c×\99ס×\98×¢ ×¤×\95×\9f ×\90×\9c×¢ ×\91×\9c×¢×\98ער ×\95×\95×\90ס ×¤×\90ר×\91×\99× ×\93×\98 ×\90×\94ער",
        "tooltip-t-recentchangeslinked": "אלע ענדערונגען פון בלעטער וואס זענען אהער פארבינדען",
        "tooltip-feed-rss": "דערהײַנטיגט אויטאמאטיש פון אר.עס.עס. RSS",
        "tooltip-feed-atom": "לייג צו אן אטאמאטישער אפדעיט דורך אטאם Atom",
        "lastmodifiedatby": "די לעצטע ענדערונג פֿון דעם בלאַט איז געווען $2, $1 דורך $3.",
        "othercontribs": "באזירט אויף ארבעט פון $1.",
        "others": "אנדערע",
-       "siteusers": "{{PLURAL:$2|באַניצער| באַניצערס}} {{SITENAME}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1| באַניצער}}| באַניצערס}} $1",
        "anonusers": "{{SITENAME}} {{PLURAL:$2| אַנאנימער באַניצער|אַנאנימע באַניצער}} $1",
        "creditspage": "בלאט קרעדיטס",
        "nocredits": "נישט פאראן קיין אינפארמאציע פאר דעם בלאט.",
        "scarytranscludedisabled": "[אינטערוויקי אריבערשליסן איז אַנולירט]",
        "scarytranscludetoolong": "[URL צו לאנג]",
        "deletedwhileediting": "ווארענונג: דער בלאט איז געווארן אויסגעמעקט נאכדעם וואס איר האט אנגעהויבן רעדאקטירן!",
-       "confirmrecreate": "באַניצער [[User:$1|$1]] ([[User talk:$1|רעדן]]) האט אויסגעמעקט דעם בלאט נאכדעם וואס איר האט אנגעהויבן דאס צו ענדערן, אלס אָנגעבליכער סיבה:\n:'''$2'''\nביטע באשטעטיגט אז איר ווילט טאקע צוריקשטעלן דעם בלאט.",
+       "confirmrecreate": "באַניצער [[User:$1|$1]] ([[User talk:$1|רעדן]]) {{GENDER:$1|האט אויסגעמעקט}} דעם בלאט נאכדעם וואס איר האט אנגעהויבן דאס צו ענדערן, אלס אָנגעבליכער סיבה:\n: <em>$2</em>\nביטע באשטעטיגט אז איר ווילט טאקע צוריקשטעלן דעם בלאט.",
        "recreate": "שאַפֿן פֿונדאסניי",
        "confirm_purge_button": "אויספֿירן",
        "confirm-purge-top": "אויסקלארן די קאשעי פון דעם בלאט?",
        "fileduplicatesearch-submit": "זוכן",
        "fileduplicatesearch-info": "$1 × $2 פיקסעל<br />טעקע גרייס: $3<br /> טיפ MIME: $4",
        "fileduplicatesearch-noresults": "קיין טעקע מיטן נאמען \"$1\" נישט געטראפֿן.",
-       "specialpages": "ספּעציעלע זײַטן",
+       "specialpages": "ספעציעלע בלעטער",
        "specialpages-note-top": "לעגענדע",
        "specialpages-note": "* נארמאַלע באַזונדערע בלעטער.\n* <span class=\"mw-specialpagerestricted\">באַגרענעצטע באַזונדערע בלעטער.</span>",
        "specialpages-group-maintenance": "אויפֿהאַלטונג באַריכטן",
        "logentry-newusers-create2": "באניצער קאנטע $1 איז {{GENDER:$2|געשאפן געווארן}} דורך $3",
        "logentry-newusers-byemail": "באניצער קאנטע $3 איז {{GENDER:$2|געשאפן געווארן}} דורך $1 און דאס פאסווארט איז געשיקט געווארט דורך ע־פאסט",
        "logentry-newusers-autocreate": "באַניצער קאנטע $1 {{GENDER:$2|געשאפן}} אויטאמאטיש",
-       "logentry-rights-rights": "$1 האָט {{GENDER:$2|געביטן}} גרופּע מיטגלידערשאַפט פאַר $3 פון $4 אויף $5",
+       "logentry-rights-rights": "$1 האָט {{GENDER:$2|געביטן}} גרופּע מיטגלידערשאַפט פאַר {{GENDER:$6|$3}} פון $4 אויף $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|האט געביטן}} גרופע מיטגלידערשאפט פאר $3",
        "logentry-rights-autopromote": "$1 אויטאמאטיש  {{GENDER:$2|פראמאווירט}} פון $4 צו $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|האט ארויפגעלאדן}} $3",
        "feedback-subject": "טעמע:",
        "feedback-submit": "אײַנגעבן",
        "feedback-thanks": "ייש\"כ! אײַער פֿידבעק איז געווארן ארויפגעלעגט צום בלאט \"[$2 $1]\".",
-       "searchsuggest-search": "×\96×\95×\9b×\9f",
+       "searchsuggest-search": "×\96×\95×\9a",
        "searchsuggest-containing": "כולל…",
        "api-error-badaccess-groups": "איר האט נישט קיין רעכטן אַרויפֿלאָדן טעקעס אויף דער וויקי.",
        "api-error-badtoken": "אינערלעכער גרײַז: סימן טויג נישט.",
index 1e1cd61..fa2b86e 100644 (file)
        "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": "日子",
+       "upload-form-label-own-work": "呢個係我自己嘅作品",
+       "upload-form-label-infoform-categories": "分類",
+       "upload-form-label-infoform-date": "日子",
        "backend-fail-stream": "傳送唔到檔案「$1」。",
        "backend-fail-backup": "檔案 \"$1\" 唔備份得。",
        "backend-fail-notexists": "檔案$1唔存在。",
index 299d974..f261a47 100644 (file)
        "changepassword-success": "您已经修改了您的密码!",
        "changepassword-throttled": "您最近尝试了多次登录。请等待$1后再试。",
        "botpasswords": "机器人密码",
-       "botpasswords-summary": "<em>机器人密码</em>允许通过API访问用户账户而不使用账户的主要登录凭据。通过机器人密码登录时,用户权限可能会受限制。\n\n如果您不知道为什么您想这样做,您就不应该这样做。没有人会要求您生成这些密码之一,并向其提供。",
+       "botpasswords-summary": "<em>机器人密码</em>允许在不使用账户的主要登录凭据的情况下,通过API访问用户账户。通过机器人密码登录时可用的用户权限可以被限制。\n\n在不知道为什么要这样做的情况下,您不应该使用此功能。任何人都不应该让您生成这些密码并向其提供。",
        "botpasswords-disabled": "机器人密码已禁用。",
        "botpasswords-no-central-id": "要使用机器人密码,您必须登录至已集中的账户。",
        "botpasswords-existing": "现有机器人密码",
        "botpasswords-label-delete": "删除",
        "botpasswords-label-resetpassword": "重置密码",
        "botpasswords-label-grants": "应用授权:",
-       "botpasswords-help-grants": "每个授权提供列举的,对用户账户已拥有的用户权限的访问权。参见[[Special:ListGrants|授权表]]以获取更多信息。",
+       "botpasswords-help-grants": "每个授权将会赋予被列出、且用户账户已拥有权限的访问权。参见[[Special:ListGrants|授权表]]以获取更多信息。",
        "botpasswords-label-restrictions": "使用限制:",
        "botpasswords-label-grants-column": "已授权",
        "botpasswords-bad-appid": "机器人名“$1”无效。",
        "minoredit": "标记为小编辑",
        "watchthis": "监视本页",
        "savearticle": "保存页面",
+       "publishpage": "发布页面",
        "preview": "预览",
        "showpreview": "显示预览",
        "showdiff": "显示更改",
        "userpage-userdoesnotexist": "用户账户“$1”没有注册。请在创建/编辑本页前检查。",
        "userpage-userdoesnotexist-view": "用户账户“$1”没有被注册。",
        "blocked-notice-logextract": "这位用户目前已被封禁。以下提供最近的封禁日志以供参考:",
-       "clearyourcache": "<strong>注意:</strong>在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。\n* <strong>Firefox或Safari:</strong>按住“Shift”的同时单击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)\n* <strong>Google Chrome:</strong>按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)\n* <strong>Internet Explorer:</strong>按住“Ctrl”的同时单击“刷新”,或按“Ctrl-F5”\n* <strong>Opera:</strong>在“工具→首选项”中清除缓存",
+       "clearyourcache": "<strong>注意:</strong>在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。\n* <strong>Firefox或Safari:</strong>按住<em>Shift</em>的同时单击<em>刷新</em>,或按<em>Ctrl-F5</em>或<em>Ctrl-R</em>(Mac为<em>⌘-R</em>)\n* <strong>Google Chrome:</strong>按<em>Ctrl-Shift-R</em>(Mac为<em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong>按住<em>Ctrl</em>的同时单击<em>刷新</em>,或按<em>Ctrl-F5</em>\n* <strong>Opera:</strong>前往<em>菜单 → 设置</em>(Mac为<em>Opera → Preferences</em>),然后em>隐私和安全 → 清除浏览数据 → 缓存的图片和文件</em>。",
        "usercssyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
        "userjsyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 JavaScript 。",
        "usercsspreview": "<strong>请记住您现在只是在预览你的用户CSS。它尚未保存!</strong>",
        "grant-group-email": "发送电子邮件",
        "grant-group-high-volume": "执行大量活动",
        "grant-group-customization": "自定义与设置",
-       "grant-group-administration": "执行行政操作",
+       "grant-group-administration": "执行管理操作",
        "grant-group-other": "杂项活动",
        "grant-blockusers": "封禁与解封用户",
        "grant-createaccount": "创建账户",
        "upload-form-label-infoform-description-tooltip": "简单描述有关作品的任何显著信息。\n对于照片,可提及描述的主要事物、场景或地点。",
        "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/ 知识共享 署名-相同方式共享 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}}上的上传页面]]。",
+       "upload-form-label-own-work": "这是我的作品",
+       "upload-form-label-infoform-categories": "分类",
+       "upload-form-label-infoform-date": "日期",
+       "upload-form-label-own-work-message-local": "我确认我正在依据{{SITENAME}}上的服务条款和许可协议方针上传文件。",
+       "upload-form-label-not-own-work-message-local": "如果您无法依据{{SITENAME}}的方针上传此文件,请关闭此对话框并尝试其他方法。",
+       "upload-form-label-not-own-work-local-local": "您也可以尝试[[Special:Upload|默认上传页面]]。",
+       "upload-form-label-own-work-message-default": "我知道我正在上传此文件至一个共享的存储库。我确认我依据这里的服务条款和许可方针做此事。",
+       "upload-form-label-not-own-work-message-default": "如果您无法依据分享存储库的方针上传此文件,请关闭此对话框并尝试其他方法。",
+       "upload-form-label-not-own-work-local-default": "如果此文件可以依据他们的方针上传的话,您也可以尝试使用[[Special:Upload|{{SITENAME}}上的上传页面]]。",
+       "upload-form-label-own-work-message-shared": "我证明我拥有此文件的版权,并不可撤销地同意采用[https://creativecommons.org/licenses/by-sa/4.0/ 知识共享 署名-相同方式共享 4.0]许可协议将此文件发布至维基共享资源,并且我同意[https://wikimediafoundation.org/wiki/Terms_of_Use 使用条款]。",
+       "upload-form-label-not-own-work-message-shared": "如果您并不拥有此文件的版权,或者您希望将其以其他许可协议发布,请考虑使用[https://commons.wikimedia.org/wiki/Special:UploadWizard 共享资源的上传向导]。",
+       "upload-form-label-not-own-work-local-shared": "如果网站允许依据他们的方针上传此文件的话,您也可以尝试使用[[Special:Upload|{{SITENAME}}上的上传页面]]。",
        "backend-fail-stream": "无法流传送文件$1。",
        "backend-fail-backup": "无法备份文件$1。",
        "backend-fail-notexists": "条目$1不存在。",
        "listgrouprights-namespaceprotection-header": "名字空间限制",
        "listgrouprights-namespaceprotection-namespace": "名字空间",
        "listgrouprights-namespaceprotection-restrictedto": "允许用户编辑的权限",
-       "listgrants": "æ\9d\83é\99\90",
+       "listgrants": "æ\8e\88æ\9d\83",
        "listgrants-summary": "以下是与用户权限访问相关的授权列表。用户可以授予应用程序访问它们的账户,但限定于用户授予应用程序的功能权限。代表一位用户的应用程序不能使用用户没有的权限。\n这里可能有关于个别权限的[[{{MediaWiki:Listgrouprights-helppage}}|额外信息]]。",
        "listgrants-grant": "授权",
        "listgrants-rights": "权限",
        "changecontentmodel-success-text": "[[:$1]]的内容类型被更改。",
        "changecontentmodel-cannot-convert": "[[:$1]]上的内容不能转换为$2的一个类型。",
        "changecontentmodel-nodirectediting": "$1内容模型不支持直接编辑",
+       "changecontentmodel-emptymodels-title": "没有内容模型可用",
+       "changecontentmodel-emptymodels-text": "[[:$1]]上的内容不能转换为任何类型。",
        "log-name-contentmodel": "内容模型更改日志",
        "log-description-contentmodel": "与一个页面的内容模型相关的活动",
        "logentry-contentmodel-new": "$1已使用非默认的内容模型“$5”{{GENDER:$2|创建}}页面$3",
        "whatlinkshere-prev": "{{PLURAL:$1|前|前$1个}}",
        "whatlinkshere-next": "{{PLURAL:$1|后|后$1个}}",
        "whatlinkshere-links": "←链接",
-       "whatlinkshere-hideredirs": "$1重定向",
-       "whatlinkshere-hidetrans": "$1嵌入",
-       "whatlinkshere-hidelinks": "$1链接",
-       "whatlinkshere-hideimages": "$1文件链接",
+       "whatlinkshere-hideredirs": "隐藏重定向",
+       "whatlinkshere-hidetrans": "隐藏嵌入",
+       "whatlinkshere-hidelinks": "隐藏链接",
+       "whatlinkshere-hideimages": "隐藏文件链接",
        "whatlinkshere-filters": "过滤器",
        "whatlinkshere-submit": "提交",
        "autoblockid": "自动封禁#$1",
        "lockdbsuccesstext": "数据库已锁定。<br />请记住在维护工作完成后[[Special:UnlockDB|解锁数据库]]。",
        "unlockdbsuccesstext": "数据库已解锁。",
        "lockfilenotwritable": "数据库锁定文件不可写。要锁定和解锁数据库,该文件必须对网络服务器可写。",
+       "databaselocked": "数据库已被锁定。",
        "databasenotlocked": "数据库未被锁定。",
        "lockedbyandtime": "(由 {{GENDER:$1|$1}} 于$2 $3执行)",
        "move-page": "移动$1",
        "tooltip-ca-nstab-category": "查看分类页面",
        "tooltip-minoredit": "标记本编辑为小编辑",
        "tooltip-save": "保存你的更改",
+       "tooltip-publish": "发布您的更改",
        "tooltip-preview": "预览您的更改。请在保存前使用此功能。",
        "tooltip-diff": "显示您对该文字所做的更改",
        "tooltip-compareselectedversions": "查看该页面两个选定的版本之间的差异。",
        "feedback-useragent": "用户代理:",
        "searchsuggest-search": "搜索",
        "searchsuggest-containing": "含有...",
+       "api-error-autoblocked": "您的IP地址已被自动封禁,因为它曾被一位已封禁用户使用。",
        "api-error-badaccess-groups": "您没有将文件上传到此 wiki 的权限。",
        "api-error-badtoken": "内部错误:会话无效。",
+       "api-error-blocked": "您已被封禁,不能编辑。",
        "api-error-copyuploaddisabled": "通过URL上传的功能已被此服务器禁用。",
        "api-error-duplicate": "在网站上已经具有相同内容的{{PLURAL:$1|另一个文件|另一些文件}}。",
        "api-error-duplicate-archive": "在网站上曾经具有相同内容的{{PLURAL:$1|另一个文件|另一些文件}},但已被删除。",
        "api-error-nomodule": "内部错误:缺少上传模块集。",
        "api-error-ok-but-empty": "内部错误:服务器没有响应。",
        "api-error-overwrite": "不允许覆盖现有文件。",
+       "api-error-ratelimited": "您正在尝试在比该wiki允许时间更短的时间内上传更多文件。请等待几分钟后再试。",
        "api-error-stashfailed": "内部错误:服务器保存临时文件失败。",
        "api-error-publishfailed": "内部错误:服务器发布临时文件失败。",
        "api-error-stasherror": "上传文件存档时出现错误。",
index c3e5aaa..2ec731c 100644 (file)
@@ -70,7 +70,8 @@
                        "Bowleerin",
                        "飞舞回堂前",
                        "Bbslam",
-                       "Zerng07"
+                       "Zerng07",
+                       "Reke"
                ]
        },
        "tog-underline": "底線標示連結:",
        "minoredit": "這是一個小修訂",
        "watchthis": "監視此頁面",
        "savearticle": "儲存頁面",
+       "publishpage": "發布頁面",
        "preview": "預覽",
        "showpreview": "顯示預覽",
        "showdiff": "顯示變更",
        "upload-form-label-infoform-description-tooltip": "簡短描述該作品任何值得說明的事項。\n以照片為例,可提及照片中的事物、情境及地點。",
        "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}} 的上傳頁面]]。",
+       "upload-form-label-own-work": "這是我的作品",
+       "upload-form-label-infoform-categories": "分類",
+       "upload-form-label-infoform-date": "日期",
+       "upload-form-label-own-work-message-local": "我確定我上傳的檔案已遵守下列 {{SITENAME}} 的服務條款與授權條款。",
+       "upload-form-label-not-own-work-message-local": "若您無法同意遵守 {{SITENAME}} 的政策上傳檔案,請關閉此對話框並嘗試其他方法。",
+       "upload-form-label-not-own-work-local-local": "您也可嘗試[[Special:Upload|預設的上傳頁面]]。",
+       "upload-form-label-own-work-message-default": "我明白我將上傳此檔案到一個共享的儲存庫,我確認已遵守本站的服務條款與授權政策。",
+       "upload-form-label-not-own-work-message-default": "若您無法同意遵守共享儲存庫的政策上傳檔案,請關閉此對話框並嘗試其他方法。",
+       "upload-form-label-not-own-work-local-default": "若此檔案可遵守該站的授權政策上傳檔案,您可能會希望直接嘗試使用 [[Special:Upload|{{SITENAME}} 的上傳頁面]]。",
+       "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 使用條款]。",
+       "upload-form-label-not-own-work-message-shared": "若您並未擁有此檔案的版權,或者您希望使用其他的授權條款發佈此檔案,請考慮使用[https://commons.wikimedia.org/wiki/Special:UploadWizard 通用上傳精靈]。",
+       "upload-form-label-not-own-work-local-shared": "若該站的授權政策允許上傳此檔案,您可能會希望直接嘗試使用 [[Special:Upload|{{SITENAME}} 的上傳頁面]]。",
        "backend-fail-stream": "無法傳輸檔案 \"$1\"。",
        "backend-fail-backup": "無法備份檔案 \"$1\"。",
        "backend-fail-notexists": "檔案 $1 不存在。",
        "changecontentmodel-success-text": "已變更 [[:$1]] 的內容類型。",
        "changecontentmodel-cannot-convert": "[[:$1]] 的內容無法轉換為 $2 類型。",
        "changecontentmodel-nodirectediting": "$1 的內容模型不支援直接編輯",
+       "changecontentmodel-emptymodels-title": "沒有內容模型可用",
+       "changecontentmodel-emptymodels-text": "[[:$1]]上的內容不能轉換為任何類型。",
        "log-name-contentmodel": "內容模型變更日誌",
        "log-description-contentmodel": "與頁面內容模型相關的事件",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|已使用}}非預設的內容模型 \"$5\" 建立頁面 $3",
        "lockdbsuccesstext": "已鎖定資料庫。<br />\n請記得在維護完成後 [[Special:UnlockDB|解除鎖定]] 資料庫。",
        "unlockdbsuccesstext": "已解除鎖定資料庫。",
        "lockfilenotwritable": "沒有權限寫入資料庫鎖定檔案。\n網頁伺服器需要該檔案的寫入權限以鎖定和解除鎖定資料庫。",
+       "databaselocked": "資料庫已被鎖定。",
        "databasenotlocked": "資料庫尚未鎖定。",
        "lockedbyandtime": "(由 {{GENDER:$1|$1}} 於 $2 的 $3)",
        "move-page": "移動 $1",
        "tooltip-ca-nstab-category": "檢視分類頁面",
        "tooltip-minoredit": "標記為小修訂",
        "tooltip-save": "儲存您的變更",
+       "tooltip-publish": "發佈您的更改",
        "tooltip-preview": "請在儲存前預覽您的變更!",
        "tooltip-diff": "顯示您對內容所做的變更",
        "tooltip-compareselectedversions": "查閱此頁面兩個已選擇的修訂間的差異",
        "invalidateemail": "取消電子郵件確認",
        "notificationemail_subject_changed": "{{SITENAME}} 註冊的電子郵件位址已變更",
        "notificationemail_subject_removed": "{{SITENAME}} 註冊的電子郵件位址已移除",
+       "notificationemail_body_changed": "來自IP位址$1的某個人(可能是您),在{{SITENAME}}上將帳號\"$2\"的電子郵件位址改成\"$3\"。\n\n如果非您本人所為,請立即跟網站管理員聯繫。",
+       "notificationemail_body_removed": "來自IP位址$1的某人(可能是您),在{{SITENAME}}上移除了帳號$2的電子郵件位址。\n\n如果非您本人所為,請立即跟網站管理員聯繫。",
        "scarytranscludedisabled": "[Interwiki 轉換代碼不可用]",
        "scarytranscludefailed": "[模板 $1 讀取失敗]",
        "scarytranscludefailed-httpstatus": "[模板 $1 讀取失敗:HTTP $2]",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|已保護}} $3 $4 [連鎖]",
        "logentry-protect-modify": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|已更改}} $3 的保護層級 $4 [連鎖]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|已更改}} $3 的群組成員資格由 $4 成為 $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|已更改}} {{GENDER:$6|$3}} 的群組成員資格由 $4 成為 $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|已更改}} $3 的群組成員資格",
        "logentry-rights-autopromote": "$1 已自動{{GENDER:$2|提升}}從 $4 成為 $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|已上傳}} $3",
        "feedback-useragent": "使用者代理:",
        "searchsuggest-search": "搜尋",
        "searchsuggest-containing": "包含...",
+       "api-error-autoblocked": "您的IP位址已經被自動封禁,因為它曾經被一名已封禁的使用者使用過。",
        "api-error-badaccess-groups": "您沒有權限在此 Wiki 上傳檔案。",
        "api-error-badtoken": "內部錯誤:密鑰錯誤。",
+       "api-error-blocked": "您已被封禁,無法編輯。",
        "api-error-copyuploaddisabled": "此伺服器已停用使用 URL 上傳檔案的功能。",
        "api-error-duplicate": "在網站上已有相同內容的{{PLURAL:$1|其他檔案|其他檔案}}。",
        "api-error-duplicate-archive": "在網站上曾有相同內容的{{PLURAL:$1|其他檔案|其他檔案}},但已被刪除。",
        "api-error-nomodule": "內部錯誤:缺少上傳模組集。",
        "api-error-ok-but-empty": "內部錯誤:伺服器沒有回應。",
        "api-error-overwrite": "不允許覆蓋已存在的檔案。",
+       "api-error-ratelimited": "您正在嘗試在比本wiki所允許時間更短的時間內,上傳更多的檔案。請稍待幾分鐘之後再試一次。",
        "api-error-stashfailed": "內部錯誤:伺服器儲存暫存檔案失敗。",
        "api-error-publishfailed": "內部錯誤:伺服器發佈暫存檔案失敗。",
        "api-error-stasherror": "上傳檔案至儲藏庫時發生錯誤。",
        "api-error-unknownerror": "不明錯誤:\"$1\"。",
        "api-error-uploaddisabled": "此 Wiki 的上傳功能已停用。",
        "api-error-verification-error": "此檔案可能已損壞,或副檔名錯誤。",
+       "api-error-was-deleted": "與此名稱相同的檔案曾被上傳過,隨後遭到刪除。",
        "duration-seconds": "$1 秒",
        "duration-minutes": "$1 分鐘",
        "duration-hours": "$1 小時",
        "special-characters-group-ipa": "國際音標",
        "special-characters-group-symbols": "符號",
        "special-characters-group-greek": "希臘文",
+       "special-characters-group-greekextended": "希臘字母擴展",
        "special-characters-group-cyrillic": "斯拉夫文",
        "special-characters-group-arabic": "阿拉伯文",
        "special-characters-group-arabicextended": "阿拉伯文擴充",
index ee04481..2c577ed 100644 (file)
@@ -48,22 +48,31 @@ $namespaceGenderAliases = [
 $specialPageAliases = [
        'Activeusers'               => [ 'Aktivní_uživatelé', 'Aktivni_uzivatele' ],
        'Allmessages'               => [ 'Všechna_hlášení', 'Všechny_zprávy', 'Vsechna_hlaseni', 'Vsechny_zpravy' ],
+       'AllMyUploads'              => [ 'Všechny_moje_soubory', 'Všechny_mé_soubory' ],
        'Allpages'                  => [ 'Všechny_stránky', 'Vsechny_stranky' ],
        'Ancientpages'              => [ 'Nejstarší_stránky', 'Staré_stránky', 'Stare_stranky' ],
+       'ApiHelp'                   => [ 'Nápověda_k_API' ],
+       'ApiSandbox'                => [ 'API_pískoviště' ],
+       'Badtitle'                  => [ 'Neplatný_název' ],
        'Blankpage'                 => [ 'Prázdná_stránka' ],
        'Block'                     => [ 'Blokování', 'Blokovani', 'Blokovat_uživatele', 'Blokovat_IP', 'Blokovat_uzivatele' ],
        'Booksources'               => [ 'Zdroje_knih' ],
+       'BotPasswords'              => [ 'Hesla_pro_boty' ],
        'BrokenRedirects'           => [ 'Přerušená_přesměrování', 'Prerusena_presmerovani' ],
        'Categories'                => [ 'Kategorie' ],
+       'ChangeContentModel'        => [ 'Změnit_model_obsahu_stránky' ],
        'ChangeEmail'               => [ 'Změna_emailu', 'Zmena_emailu' ],
-       'ChangePassword'            => [ 'Změna_hesla', 'Zmena_hesla', 'Resetovat_heslo' ],
+       'ChangePassword'            => [ 'Změna_hesla', 'Zmena_hesla' ],
        'ComparePages'              => [ 'Porovnání_stránek', 'PorovnáníStránek', 'Porovnani_stranek', 'PorovnaniStranek' ],
        'Confirmemail'              => [ 'Potvrdit_e-mail' ],
        'Contributions'             => [ 'Příspěvky', 'Prispevky' ],
        'CreateAccount'             => [ 'Vytvořit_účet', 'Vytvorit_ucet' ],
        'Deadendpages'              => [ 'Slepé_stránky', 'Slepe_stranky' ],
        'DeletedContributions'      => [ 'Smazané_příspěvky', 'Smazane_prispevky' ],
+       'Diff'                      => [ 'Rozdíl' ],
        'DoubleRedirects'           => [ 'Dvojitá_přesměrování', 'Dvojita_presmerovani' ],
+       'EditTags'                  => [ 'Upravit_značky' ],
+       'EditWatchlist'             => [ 'Upravit_seznam_sledovaných_stránek' ],
        'Emailuser'                 => [ 'E-mail' ],
        'ExpandTemplates'           => [ 'Testy_šablon' ],
        'Export'                    => [ 'Exportovat_stránky' ],
@@ -76,7 +85,9 @@ $specialPageAliases = [
        'LinkSearch'                => [ 'Hledání_odkazů', 'Hledani_odkazu' ],
        'Listadmins'                => [ 'Seznam_správců', 'Seznam_spravcu' ],
        'Listbots'                  => [ 'Seznam_botů', 'Seznam_botu' ],
+       'ListDuplicatedFiles'       => [ 'Seznam_duplicitních_souborů' ],
        'Listfiles'                 => [ 'Seznam_souborů', 'Seznam_souboru' ],
+       'Listgrants'                => [ 'Seznam_grantů' ],
        'Listgrouprights'           => [ 'Práva_uživatelských_skupin', 'Seznam_uživatelských_práv', 'Seznam_uzivatelskych_prav' ],
        'Listredirects'             => [ 'Seznam_přesměrování', 'Seznam_presmerovani' ],
        'Listusers'                 => [ 'Uživatelé', 'Uzivatele', 'Seznam_uživatelů', 'Seznam_uzivatelu' ],
@@ -84,6 +95,7 @@ $specialPageAliases = [
        'Log'                       => [ 'Protokolovací_záznamy', 'Protokoly', 'Protokol', 'Protokolovaci_zaznamy' ],
        'Lonelypages'               => [ 'Sirotčí_stránky', 'Sirotci_stranky' ],
        'Longpages'                 => [ 'Nejdelší_stránky', 'Nejdelsi_stranky' ],
+       'MediaStatistics'           => [ 'Statistika_souborů', 'Statistiky_souborů' ],
        'MergeHistory'              => [ 'Sloučení_historie', 'Slouceni_historie', 'Sloučit_historii' ],
        'MIMEsearch'                => [ 'Hledání_podle_MIME', 'Hledani_podle_MIME', 'Hledat_podle_MIME_typu' ],
        'Mostcategories'            => [ 'Stránky_s_nejvíce_kategoriemi', 'Stranky_s_nejvice_kategoriemi', 'Stránky_s_nejvyšším_počtem_kategorií' ],
@@ -94,17 +106,27 @@ $specialPageAliases = [
        'Mostrevisions'             => [ 'Stránky_s_nejvíce_editacemi', 'Stranky_s_nejvice_editacemi', 'Stránky_s_nejvyšším_počtem_editací' ],
        'Movepage'                  => [ 'Přesunout_stránku', 'Přejmenovat_stránku' ],
        'Mycontributions'           => [ 'Mé_příspěvky', 'Me_prispevky' ],
+       'MyLanguage'                => [ 'V_mém_jazyce', 'Můj_jazyk' ],
        'Mypage'                    => [ 'Moje_stránka', 'Moje_stranka' ],
        'Mytalk'                    => [ 'Moje_diskuse' ],
+       'Myuploads'                 => [ 'Moje_soubory', 'Mé_soubory' ],
        'Newimages'                 => [ 'Nové_obrázky', 'Galerie_nových_obrázků', 'Nove_obrazky' ],
        'Newpages'                  => [ 'Nové_stránky', 'Nove_stranky', 'Nejnovější_stránky', 'Nejnovejsi_stranky' ],
+       'PasswordReset'             => [ 'Reset_hesla', 'Resetovat_heslo' ],
+       'PagesWithProp'             => [ 'Stránky_s_vlastností', 'Stránky_s_vlastnostmi' ],
+       'PasswordReset'             => [ 'Reset_hesla', 'Resetovat_heslo', 'Obnova_hesla', 'Obnovit_heslo' ],
+       'PermanentLink'             => [ 'Trvalý_odkaz' ],
        'Preferences'               => [ 'Nastavení', 'Nastaveni' ],
+       'Prefixindex'               => [ 'Stránky_podle_začátku' ],
        'Protectedpages'            => [ 'Zamčené_stránky', 'Zamcene_stranky' ],
        'Protectedtitles'           => [ 'Zamčené_názvy', 'Zamcene_nazvy', 'Stránky_které_nelze_vytvořit' ],
        'Randompage'                => [ 'Náhodná_stránka', 'Nahodna_stranka' ],
        'Randomredirect'            => [ 'Náhodné_přesměrování', 'Nahodne_presmerovani' ],
+       'RandomInCategory'          => [ 'Náhodná_stránka_v_kategorii' ],
+       'Randomrootpage'            => [ 'Náhodná_kořenová_stránka' ],
        'Recentchanges'             => [ 'Poslední_změny', 'Posledni_zmeny' ],
        'Recentchangeslinked'       => [ 'Související_změny', 'Souvisejici_zmeny' ],
+       'Redirect'                  => [ 'Přesměrování', 'Přesměrovat' ],
        'Revisiondelete'            => [ 'Smazat_revizi' ],
        'Search'                    => [ 'Hledání', 'Hledani' ],
        'Shortpages'                => [ 'Nejkratší_stránky', 'Nejkratsi_stranky' ],
index 2b97f7a..c832237 100644 (file)
--- a/load.php
+++ b/load.php
@@ -25,9 +25,8 @@
 use MediaWiki\Logger\LoggerFactory;
 
 // This endpoint is supposed to be independent of request cookies and other
-// details of the session. Log warnings for violations of the no-session
-// constraint.
-define( 'MW_NO_SESSION', 'warn' );
+// details of the session. Enforce this constraint with respect to session use.
+define( 'MW_NO_SESSION', 1 );
 
 require __DIR__ . '/includes/WebStart.php';
 
index 8993146..f9dd58c 100644 (file)
@@ -216,7 +216,7 @@ class ConvertExtensionToRegistration extends Maintenance {
        }
 
        public function handleHooks( $realName, $value ) {
-               foreach ( $value as $hookName => $handlers ) {
+               foreach ( $value as $hookName => &$handlers ) {
                        foreach ( $handlers as $func ) {
                                if ( $func instanceof Closure ) {
                                        $this->error( "Error: Closures cannot be converted to JSON. " .
@@ -230,6 +230,9 @@ class ConvertExtensionToRegistration extends Maintenance {
                                        );
                                }
                        }
+                       if ( count( $handlers ) === 1 ) {
+                               $handlers = $handlers[0];
+                       }
                }
                $this->json[$realName] = $value;
        }
index 915c699..fe99d8e 100644 (file)
@@ -54,6 +54,7 @@
 姊弟 姐弟
 姊夫 姐夫
 大姊 大姐
+大姊姊      大姐姐
 御姊 御姐
 表姊 表姐
 堂姊 堂姐
 著處 着处
 著她 着她
 著妳 着妳
-著姓 着姓
 著它 着它
 著定 着定
 著實 着实
index f76d875..997acfc 100644 (file)
 电影里      電影裏
 广播里      廣播裏
 电视里      電視裏
+公寓里      公寓裏
 窝里斗      窩裏鬥
 苑裡 苑裡
 霄裡 霄裡
index 12431b3..271a055 100644 (file)
@@ -747,6 +747,8 @@ IP地址    IP位址
 流動網絡   行動網路
 网络游戏   網路遊戲
 網絡遊戲   網路遊戲
+电脑网络   電腦網路
+電腦網絡   電腦網路
 咪高峰      麥克風
 電單車      機車
 搜索引擎   搜尋引擎
index 5c6a70b..a9e8f3b 100644 (file)
 騰格里      騰格里
 村里長      村里長
 進制 進制
+總裁制      總裁制
+獨裁制      獨裁制
 模范三軍   模范三軍
 陳冲 陳冲
 劉佳怜      劉佳怜
index 492a99d..94756f0 100644 (file)
 併骨
 併網
 併線
-併流
+江併流
+水併流
 逼併
 併名
 併火
 意大利麵
 湯下麵
 茶麵
-麵
+麵
 北山索麵
 土索麵
 米麵
 、麵點
 麵製品
 乾脆麵
+磨麵
 冷面相
 糞穢衊面
 僕僕
 犖确
 磽确
 确瘠
-言辯而确
-數與虜确
-關弓與我确
 拚捨
 廣捨
 齊王捨牛
 翻鬆
 浮鬆
 弄鬆
+旋鬆
 精鬆
 懈鬆
 鬆蛋
 跌扑
 轉向往
 酒帘
-裡面包
 金表態
 金表情
 金表揚
 長几
 隆准許
 雄斗斗
+裡面包
+表面包
+外面包
 面包住
 面包辦
 面包廂
 面粉碎
 面粉紅
 面食飯
+水表面
+費米面
 顛顛仆仆
 高干擾
 高干預
 折子戲
 搤肮拊背
 文采郁郁
-腊之以為餌
 腊毒
 蜡月
 蜡祭
 范文照
 機械系
 體系
+維系統
 心理
 鹰鵰
 天地志狼
 電影裡
 廣播裡
 電視裡
+公寓裡
+公寓里弄
 裏白 #植物常用名
 烏蘇里 #分詞用
 首發
 有只允
 有只採
 有只用
+所有只
 葉叶琹
 胡子昂
 胡子嬰
 製得
 製取
 譯製
+燉製
+煮製
 遏制 #以下分詞用
 管制
 抑制
 啊喂
 呵喂
 呦喂
-水表面
-表面包
-費米面
 松口鎮
 沙瑯
 琺瑯
diff --git a/maintenance/mssql/archives/named_constraints.sql b/maintenance/mssql/archives/named_constraints.sql
deleted file mode 100644 (file)
index 94b77ea..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-DECLARE @fullyQualifiedTableName nvarchar(max),
-@tableName sysname,
-@fieldName sysname,
-@constr sysname,
-@constrNew sysname,
-@sqlcmd nvarchar(max),
-@sqlcreate nvarchar(max)
-
-SET @fullyQualifiedTableName = '/*_*//*$tableName*/'
-SET @tableName = '/*$tableName*/'
-SET @fieldName = '/*$fieldName*/'
-
-SELECT @constr = CONSTRAINT_NAME
-FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
-WHERE TABLE_NAME = @tableName
-AND CONSTRAINT_CATALOG = '/*$wgDBname*/'
-AND CONSTRAINT_SCHEMA = '/*$wgDBmwschema*/'
-AND CONSTRAINT_TYPE = 'CHECK'
-AND CONSTRAINT_NAME LIKE ('CK__' + left(@tableName,9) + '__' + left(@fieldName,5) + '%')
-
-SELECT @constrNew = CONSTRAINT_NAME
-FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
-WHERE TABLE_NAME = @tableName
-AND CONSTRAINT_CATALOG = '/*$wgDBname*/'
-AND CONSTRAINT_SCHEMA = '/*$wgDBmwschema*/'
-AND CONSTRAINT_TYPE = 'CHECK'
-AND CONSTRAINT_NAME = (@fieldName + '_ckc')
-
-IF @constr IS NOT NULL
-BEGIN
-  SET @sqlcmd =  'ALTER TABLE ' + @fullyQualifiedTableName + ' DROP CONSTRAINT [' + @constr + ']'
-  EXECUTE sp_executesql @sqlcmd
-END
-IF @constrNew IS NULL
-BEGIN
-  SET @sqlcreate =  'ALTER TABLE ' + @fullyQualifiedTableName + ' WITH NOCHECK ADD CONSTRAINT ' + @fieldName + '_ckc CHECK /*$checkConstraint*/;'
-  EXECUTE sp_executesql @sqlcreate
-END
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-add-cl_collation_ext_index.sql b/maintenance/mssql/archives/patch-add-cl_collation_ext_index.sql
new file mode 100644 (file)
index 0000000..8137dc6
--- /dev/null
@@ -0,0 +1,2 @@
+-- @since 1.27
+CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);
diff --git a/maintenance/mssql/archives/patch-archive-drop-fks.sql b/maintenance/mssql/archives/patch-archive-drop-fks.sql
new file mode 100644 (file)
index 0000000..3055ac9
--- /dev/null
@@ -0,0 +1,59 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/archive DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'ar_parent_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+-- while we're at it, let's fix up the other foreign key constraints on archive
+-- as future patches touch constraints on other tables, they'll take the time to update constraint names there as well
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'ar_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/archive ADD CONSTRAINT ar_user__user_id__fk FOREIGN KEY (ar_user) REFERENCES /*_*/mwuser(user_id);--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/text')
+       AND c.name = 'ar_text_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/archive ADD CONSTRAINT ar_text_id__old_id__fk FOREIGN KEY (ar_text_id) REFERENCES /*_*/text(old_id) ON DELETE CASCADE;
diff --git a/maintenance/mssql/archives/patch-bot_passwords.sql b/maintenance/mssql/archives/patch-bot_passwords.sql
new file mode 100644 (file)
index 0000000..7718ffa
--- /dev/null
@@ -0,0 +1,13 @@
+--
+-- This table contains a user's bot passwords: passwords that allow access to
+-- the account via the API with limited rights.
+--
+CREATE TABLE /*_*/bot_passwords (
+       bp_user int NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+       bp_app_id nvarchar(32) NOT NULL,
+       bp_password nvarchar(255) NOT NULL,
+       bp_token nvarchar(255) NOT NULL,
+       bp_restrictions nvarchar(max) NOT NULL,
+       bp_grants nvarchar(max) NOT NULL,
+       PRIMARY KEY (bp_user, bp_app_id)
+);
diff --git a/maintenance/mssql/archives/patch-categorylinks-constraints.sql b/maintenance/mssql/archives/patch-categorylinks-constraints.sql
new file mode 100644 (file)
index 0000000..cf9b565
--- /dev/null
@@ -0,0 +1,20 @@
+DECLARE @baseSQL nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @baseSQL = 'ALTER TABLE /*_*/categorylinks DROP CONSTRAINT ';--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/categorylinks')
+       AND c.name = 'cl_type';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/categorylinks ADD CONSTRAINT cl_type_ckc CHECK (cl_type IN('page', 'subcat', 'file'));
diff --git a/maintenance/mssql/archives/patch-drop-page_counter.sql b/maintenance/mssql/archives/patch-drop-page_counter.sql
new file mode 100644 (file)
index 0000000..54ab9f7
--- /dev/null
@@ -0,0 +1,19 @@
+DECLARE @sql nvarchar(max),
+       @id sysname;--
+
+SET @sql = 'ALTER TABLE /*_*/page DROP CONSTRAINT ';--
+
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id = OBJECT_ID('/*_*/page')
+       AND c.name = 'page_counter';--
+
+SET @sql = @sql + @id;--
+
+EXEC sp_executesql @sql;--
+
+ALTER TABLE /*_*/page DROP COLUMN page_counter;
diff --git a/maintenance/mssql/archives/patch-drop-rc_cur_time.sql b/maintenance/mssql/archives/patch-drop-rc_cur_time.sql
new file mode 100644 (file)
index 0000000..01c46d3
--- /dev/null
@@ -0,0 +1,19 @@
+DECLARE @sql nvarchar(max),
+       @id sysname;--
+
+SET @sql = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';--
+
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND c.name = 'rc_cur_time';--
+
+SET @sql = @sql + @id;--
+
+EXEC sp_executesql @sql;--
+
+ALTER TABLE /*_*/recentchanges DROP COLUMN rc_cur_time;
diff --git a/maintenance/mssql/archives/patch-drop-ss_total_views.sql b/maintenance/mssql/archives/patch-drop-ss_total_views.sql
new file mode 100644 (file)
index 0000000..7525ed5
--- /dev/null
@@ -0,0 +1,19 @@
+DECLARE @sql nvarchar(max),
+       @id sysname;--
+
+SET @sql = 'ALTER TABLE /*_*/site_stats DROP CONSTRAINT ';--
+
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id = OBJECT_ID('/*_*/site_stats')
+       AND c.name = 'ss_total_views';--
+
+SET @sql = @sql + @id;--
+
+EXEC sp_executesql @sql;--
+
+ALTER TABLE /*_*/site_stats DROP COLUMN ss_total_views;
diff --git a/maintenance/mssql/archives/patch-drop-user_options.sql b/maintenance/mssql/archives/patch-drop-user_options.sql
new file mode 100644 (file)
index 0000000..ab37956
--- /dev/null
@@ -0,0 +1,19 @@
+DECLARE @sql nvarchar(max),
+       @id sysname;--
+
+SET @sql = 'ALTER TABLE /*_*/mwuser DROP CONSTRAINT ';--
+
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'user_options';--
+
+SET @sql = @sql + @id;--
+
+EXEC sp_executesql @sql;--
+
+ALTER TABLE /*_*/mwuser DROP COLUMN user_options;
diff --git a/maintenance/mssql/archives/patch-filearchive-constraints.sql b/maintenance/mssql/archives/patch-filearchive-constraints.sql
new file mode 100644 (file)
index 0000000..cefead5
--- /dev/null
@@ -0,0 +1,34 @@
+DECLARE @baseSQL nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @baseSQL = 'ALTER TABLE /*_*/filearchive DROP CONSTRAINT ';--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/filearchive')
+       AND c.name = 'fa_major_mime';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/filearchive')
+       AND c.name = 'fa_media_type';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/filearchive ADD CONSTRAINT fa_major_mime_ckc check (fa_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
+ALTER TABLE /*_*/filearchive ADD CONSTRAINT fa_media_type_ckc check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));
diff --git a/maintenance/mssql/archives/patch-filearchive-schema.sql b/maintenance/mssql/archives/patch-filearchive-schema.sql
new file mode 100644 (file)
index 0000000..cf1c01f
--- /dev/null
@@ -0,0 +1,120 @@
+-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
+-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
+-- remove the -- from the end of each statement.
+
+DECLARE @temp table (
+       fa_id int,
+       fa_name nvarchar(255),
+       fa_archive_name nvarchar(255),
+       fa_storage_group nvarchar(16),
+       fa_storage_key nvarchar(64),
+       fa_deleted_user int,
+       fa_deleted_timestamp varchar(14),
+       fa_deleted_reason nvarchar(max),
+       fa_size int,
+       fa_width int,
+       fa_height int,
+       fa_metadata nvarchar(max),
+       fa_bits int,
+       fa_media_type varchar(16),
+       fa_major_mime varchar(16),
+       fa_minor_mime nvarchar(100),
+       fa_description nvarchar(255),
+       fa_user int,
+       fa_user_text nvarchar(255),
+       fa_timestamp varchar(14),
+       fa_deleted tinyint,
+       fa_sha1 nvarchar(32)
+);--
+
+INSERT INTO @temp
+SELECT * FROM /*_*/filearchive;--
+
+DROP TABLE /*_*/filearchive;--
+
+CREATE TABLE /*_*/filearchive (
+  fa_id int NOT NULL PRIMARY KEY IDENTITY,
+  fa_name nvarchar(255) NOT NULL default '',
+  fa_archive_name nvarchar(255) default '',
+  fa_storage_group nvarchar(16),
+  fa_storage_key nvarchar(64) default '',
+  fa_deleted_user int,
+  fa_deleted_timestamp varchar(14) default '',
+  fa_deleted_reason nvarchar(max),
+  fa_size int default 0,
+  fa_width int default 0,
+  fa_height int default 0,
+  fa_metadata varbinary(max),
+  fa_bits int default 0,
+  fa_media_type varchar(16) default null,
+  fa_major_mime varchar(16) not null default 'unknown',
+  fa_minor_mime nvarchar(100) default 'unknown',
+  fa_description nvarchar(255),
+  fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  fa_user_text nvarchar(255),
+  fa_timestamp varchar(14) default '',
+  fa_deleted tinyint NOT NULL default 0,
+  fa_sha1 nvarchar(32) NOT NULL default '',
+  CONSTRAINT fa_major_mime_ckc check (fa_major_mime in('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
+  CONSTRAINT fa_media_type_ckc check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
+);--
+
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);--
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);--
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);--
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);--
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1);--
+
+SET IDENTITY_INSERT /*_*/filearchive ON;--
+
+INSERT INTO /*_*/filearchive
+(
+       fa_id,
+       fa_name,
+       fa_archive_name,
+       fa_storage_group,
+       fa_storage_key,
+       fa_deleted_user,
+       fa_deleted_timestamp,
+       fa_deleted_reason,
+       fa_size,
+       fa_width,
+       fa_height,
+       fa_metadata,
+       fa_bits,
+       fa_media_type,
+       fa_major_mime,
+       fa_minor_mime,
+       fa_description,
+       fa_user,
+       fa_user_text,
+       fa_timestamp,
+       fa_deleted,
+       fa_sha1
+)
+SELECT
+       fa_id,
+       fa_name,
+       fa_archive_name,
+       fa_storage_group,
+       fa_storage_key,
+       fa_deleted_user,
+       fa_deleted_timestamp,
+       fa_deleted_reason,
+       fa_size,
+       fa_width,
+       fa_height,
+       CONVERT(varbinary(max), fa_metadata, 0),
+       fa_bits,
+       fa_media_type,
+       fa_major_mime,
+       fa_minor_mime,
+       fa_description,
+       fa_user,
+       fa_user_text,
+       fa_timestamp,
+       fa_deleted,
+       fa_sha1
+FROM @temp t;--
+
+SET IDENTITY_INSERT /*_*/filearchive OFF;
diff --git a/maintenance/mssql/archives/patch-il_from_namespace.sql b/maintenance/mssql/archives/patch-il_from_namespace.sql
new file mode 100644 (file)
index 0000000..e4ac98f
--- /dev/null
@@ -0,0 +1,4 @@
+ALTER TABLE /*_*/imagelinks
+  ADD il_from_namespace int NOT NULL default 0;
+
+CREATE INDEX /*i*/il_backlinks_namespace ON /*_*/imagelinks (il_from_namespace,il_to,il_from);
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-image-constraints.sql b/maintenance/mssql/archives/patch-image-constraints.sql
new file mode 100644 (file)
index 0000000..0aeb627
--- /dev/null
@@ -0,0 +1,34 @@
+DECLARE @baseSQL nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @baseSQL = 'ALTER TABLE /*_*/image DROP CONSTRAINT ';--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/image')
+       AND c.name = 'img_major_mime';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/image')
+       AND c.name = 'img_media_type';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/image ADD CONSTRAINT img_major_mime_ckc check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
+ALTER TABLE /*_*/image ADD CONSTRAINT img_media_type_ckc check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));
diff --git a/maintenance/mssql/archives/patch-image-schema.sql b/maintenance/mssql/archives/patch-image-schema.sql
new file mode 100644 (file)
index 0000000..213b438
--- /dev/null
@@ -0,0 +1,84 @@
+-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
+-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
+-- remove the -- from the end of each statement.
+
+DECLARE @temp table (
+       img_name varbinary(255),
+       img_size int,
+       img_width int,
+       img_height int,
+       img_metadata varbinary(max),
+       img_bits int,
+       img_media_type varchar(16),
+       img_major_mime varchar(16),
+       img_minor_mime nvarchar(100),
+       img_description nvarchar(255),
+       img_user int,
+       img_user_text nvarchar(255),
+       img_timestamp nvarchar(14),
+       img_sha1 nvarchar(32)
+);--
+
+INSERT INTO @temp
+SELECT * FROM /*_*/image;--
+
+DROP TABLE /*_*/image;--
+
+CREATE TABLE /*_*/image (
+  img_name nvarchar(255) NOT NULL default '' PRIMARY KEY,
+  img_size int NOT NULL default 0,
+  img_width int NOT NULL default 0,
+  img_height int NOT NULL default 0,
+  img_metadata varbinary(max) NOT NULL,
+  img_bits int NOT NULL default 0,
+  img_media_type varchar(16) default null,
+  img_major_mime varchar(16) not null default 'unknown',
+  img_minor_mime nvarchar(100) NOT NULL default 'unknown',
+  img_description nvarchar(255) NOT NULL,
+  img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  img_user_text nvarchar(255) NOT NULL,
+  img_timestamp nvarchar(14) NOT NULL default '',
+  img_sha1 nvarchar(32) NOT NULL default '',
+  CONSTRAINT img_major_mime_ckc check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
+  CONSTRAINT img_media_type_ckc check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
+);--
+
+CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);--
+CREATE INDEX /*i*/img_size ON /*_*/image (img_size);--
+CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);--
+CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1);--
+CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);--
+
+INSERT INTO /*_*/image
+(
+       img_name,
+       img_size,
+       img_width,
+       img_height,
+       img_metadata,
+       img_bits,
+       img_media_type,
+       img_major_mime,
+       img_minor_mime,
+       img_description,
+       img_user,
+       img_user_text,
+       img_timestamp,
+       img_sha1
+)
+SELECT
+       img_name,
+       img_size,
+       img_width,
+       img_height,
+       img_metadata,
+       img_bits,
+       img_media_type,
+       img_major_mime,
+       img_minor_mime,
+       img_description,
+       img_user,
+       img_user_text,
+       img_timestamp,
+       img_sha1
+FROM @temp t;
diff --git a/maintenance/mssql/archives/patch-kill-cl_collation_index.sql b/maintenance/mssql/archives/patch-kill-cl_collation_index.sql
new file mode 100644 (file)
index 0000000..7f75a62
--- /dev/null
@@ -0,0 +1,7 @@
+--
+-- Kill cl_collation index.
+-- @since 1.27
+--
+
+DROP INDEX /*i*/cl_collation ON /*_*/categorylinks;
+
diff --git a/maintenance/mssql/archives/patch-logging-drop-fks.sql b/maintenance/mssql/archives/patch-logging-drop-fks.sql
new file mode 100644 (file)
index 0000000..c9cbca3
--- /dev/null
@@ -0,0 +1,37 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/logging DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/logging')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'log_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/logging')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
+       AND c.name = 'log_page';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;
diff --git a/maintenance/mssql/archives/patch-oldimage-constraints.sql b/maintenance/mssql/archives/patch-oldimage-constraints.sql
new file mode 100644 (file)
index 0000000..69ede2c
--- /dev/null
@@ -0,0 +1,34 @@
+DECLARE @baseSQL nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @baseSQL = 'ALTER TABLE /*_*/oldimage DROP CONSTRAINT ';--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/oldimage')
+       AND c.name = 'oi_major_mime';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/oldimage')
+       AND c.name = 'oi_media_type';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/oldimage ADD CONSTRAINT oi_major_mime_ckc check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
+ALTER TABLE /*_*/oldimage ADD CONSTRAINT oi_media_type_ckc check (oi_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));
diff --git a/maintenance/mssql/archives/patch-oldimage-schema.sql b/maintenance/mssql/archives/patch-oldimage-schema.sql
new file mode 100644 (file)
index 0000000..3391c1b
--- /dev/null
@@ -0,0 +1,91 @@
+-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
+-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
+-- remove the -- from the end of each statement.
+
+DECLARE @temp table (
+       oi_name varbinary(255),
+       oi_archive_name varbinary(255),
+       oi_size int,
+       oi_width int,
+       oi_height int,
+       oi_bits int,
+       oi_description nvarchar(255),
+       oi_user int,
+       oi_user_text nvarchar(255),
+       oi_timestamp varchar(14),
+       oi_metadata nvarchar(max),
+       oi_media_type varchar(16),
+       oi_major_mime varchar(16),
+       oi_minor_mime nvarchar(100),
+       oi_deleted tinyint,
+       oi_sha1 nvarchar(32)
+);--
+
+INSERT INTO @temp
+SELECT * FROM /*_*/oldimage;--
+
+DROP TABLE /*_*/oldimage;--
+
+CREATE TABLE /*_*/oldimage (
+  oi_name nvarchar(255) NOT NULL default '',
+  oi_archive_name nvarchar(255) NOT NULL default '',
+  oi_size int NOT NULL default 0,
+  oi_width int NOT NULL default 0,
+  oi_height int NOT NULL default 0,
+  oi_bits int NOT NULL default 0,
+  oi_description nvarchar(255) NOT NULL,
+  oi_user int REFERENCES /*_*/mwuser(user_id),
+  oi_user_text nvarchar(255) NOT NULL,
+  oi_timestamp varchar(14) NOT NULL default '',
+  oi_metadata varbinary(max) NOT NULL,
+  oi_media_type varchar(16) default null,
+  oi_major_mime varchar(16) not null default 'unknown',
+  oi_minor_mime nvarchar(100) NOT NULL default 'unknown',
+  oi_deleted tinyint NOT NULL default 0,
+  oi_sha1 nvarchar(32) NOT NULL default '',
+  CONSTRAINT oi_major_mime_ckc check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
+  CONSTRAINT oi_media_type_ckc check (oi_media_type IN('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
+);--
+
+CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text, oi_timestamp);--
+CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name, oi_timestamp);--
+CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name, oi_archive_name);--
+CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1);--
+
+INSERT INTO /*_*/oldimage
+(
+       oi_name,
+       oi_archive_name,
+       oi_size,
+       oi_width,
+       oi_height,
+       oi_bits,
+       oi_description,
+       oi_user,
+       oi_user_text,
+       oi_timestamp,
+       oi_metadata,
+       oi_media_type,
+       oi_major_mime,
+       oi_minor_mime,
+       oi_deleted,
+       oi_sha1
+)
+SELECT
+       oi_name,
+       oi_archive_name,
+       oi_size,
+       oi_width,
+       oi_height,
+       oi_bits,
+       oi_description,
+       oi_user,
+       oi_user_text,
+       oi_timestamp,
+       CONVERT(varbinary(max), oi_metadata, 0),
+       oi_media_type,
+       oi_major_mime,
+       oi_minor_mime,
+       oi_deleted,
+       oi_sha1
+FROM @temp t;
diff --git a/maintenance/mssql/archives/patch-pl_from_namespace.sql b/maintenance/mssql/archives/patch-pl_from_namespace.sql
new file mode 100644 (file)
index 0000000..b3bbd78
--- /dev/null
@@ -0,0 +1,4 @@
+ALTER TABLE /*_*/pagelinks
+       ADD pl_from_namespace int NOT NULL default 0;
+
+CREATE INDEX /*i*/pl_backlinks_namespace ON /*_*/pagelinks (pl_from_namespace,pl_namespace,pl_title,pl_from);
diff --git a/maintenance/mssql/archives/patch-pp_sortkey.sql b/maintenance/mssql/archives/patch-pp_sortkey.sql
new file mode 100644 (file)
index 0000000..b13b605
--- /dev/null
@@ -0,0 +1,8 @@
+-- Add a 'sortkey' field to page_props so pages can be efficiently
+-- queried by the numeric value of a property.
+
+ALTER TABLE /*_*/page_props
+        ADD pp_sortkey float DEFAULT NULL;
+
+CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page
+        ON /*_*/page_props ( pp_propname, pp_sortkey, pp_page );
diff --git a/maintenance/mssql/archives/patch-recentchanges-drop-fks.sql b/maintenance/mssql/archives/patch-recentchanges-drop-fks.sql
new file mode 100644 (file)
index 0000000..24f78f6
--- /dev/null
@@ -0,0 +1,76 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
+       AND c.name = 'rc_cur_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'rc_this_oldid';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'rc_last_oldid';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+-- while we're at it, let's fix up the other foreign key constraints on recentchanges
+-- as future patches touch constraints on other tables, they'll take the time to update constraint names there as well
+ALTER TABLE /*_*/recentchanges DROP CONSTRAINT FK_rc_logid_log_id;--
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_logid__log_id__fk FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'rc_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_user__user_id__fk FOREIGN KEY (rc_user) REFERENCES /*_*/mwuser(user_id);
diff --git a/maintenance/mssql/archives/patch-tl_from_namespace.sql b/maintenance/mssql/archives/patch-tl_from_namespace.sql
new file mode 100644 (file)
index 0000000..9655165
--- /dev/null
@@ -0,0 +1,4 @@
+ALTER TABLE /*_*/templatelinks
+       ADD tl_from_namespace int NOT NULL default 0;
+
+CREATE INDEX /*i*/tl_backlinks_namespace ON /*_*/templatelinks (tl_from_namespace,tl_namespace,tl_title,tl_from);
diff --git a/maintenance/mssql/archives/patch-uploadstash-constraints.sql b/maintenance/mssql/archives/patch-uploadstash-constraints.sql
new file mode 100644 (file)
index 0000000..1cd668c
--- /dev/null
@@ -0,0 +1,20 @@
+DECLARE @baseSQL nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @baseSQL = 'ALTER TABLE /*_*/uploadstash DROP CONSTRAINT ';--
+
+SELECT @id = cc.name
+FROM sys.check_constraints cc
+JOIN sys.columns c
+       ON c.object_id = cc.parent_object_id
+       AND c.column_id = cc.parent_column_id
+WHERE
+       cc.parent_object_id = OBJECT_ID('/*_*/uploadstash')
+       AND c.name = 'us_media_type';--
+
+SET @SQL = @baseSQL + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/uploadstash ADD CONSTRAINT us_media_type_ckc check (us_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));
index 86bd735..12cfed8 100644 (file)
@@ -38,7 +38,6 @@ CREATE TABLE /*_*/mwuser (
    user_newpassword  NVARCHAR(255)  NOT NULL DEFAULT '',
    user_newpass_time varchar(14) NULL DEFAULT NULL,
    user_email        NVARCHAR(255)  NOT NULL DEFAULT '',
-   user_options      NVARCHAR(MAX) NOT NULL DEFAULT '',
    user_touched      varchar(14)      NOT NULL DEFAULT '',
    user_token        NCHAR(32)      NOT NULL DEFAULT '',
    user_email_authenticated varchar(14) DEFAULT NULL,
@@ -101,6 +100,20 @@ CREATE TABLE /*_*/user_properties (
 CREATE UNIQUE CLUSTERED INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property);
 CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property);
 
+--
+-- This table contains a user's bot passwords: passwords that allow access to
+-- the account via the API with limited rights.
+--
+CREATE TABLE /*_*/bot_passwords (
+       bp_user int NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+       bp_app_id nvarchar(32) NOT NULL,
+       bp_password nvarchar(255) NOT NULL,
+       bp_token nvarchar(255) NOT NULL,
+       bp_restrictions nvarchar(max) NOT NULL,
+       bp_grants nvarchar(max) NOT NULL,
+       PRIMARY KEY (bp_user, bp_app_id)
+);
+
 
 --
 -- Core of the wiki: each page has an entry here which identifies
@@ -193,17 +206,17 @@ CREATE TABLE /*_*/archive (
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_text NVARCHAR(MAX) NOT NULL,
    ar_comment NVARCHAR(255) NOT NULL,
-   ar_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+   ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
    ar_user_text NVARCHAR(255) NOT NULL,
    ar_timestamp varchar(14) NOT NULL default '',
    ar_minor_edit BIT NOT NULL DEFAULT 0,
    ar_flags NVARCHAR(255) NOT NULL,
    ar_rev_id INT NULL, -- NOT a FK, the row gets deleted from revision and moved here
-   ar_text_id INT REFERENCES /*_*/text(old_id) ON DELETE CASCADE,
+   ar_text_id INT CONSTRAINT ar_text_id__old_id__fk FOREIGN KEY REFERENCES /*_*/text(old_id) ON DELETE CASCADE,
    ar_deleted TINYINT NOT NULL DEFAULT 0,
    ar_len INT,
    ar_page_id INT NULL, -- NOT a FK, the row gets deleted from page and moved here
-   ar_parent_id INT NULL REFERENCES /*_*/revision(rev_id),
+   ar_parent_id INT NULL, -- NOT FK
    ar_sha1 nvarchar(32) default null,
    ar_content_model nvarchar(32) DEFAULT NULL,
   ar_content_format nvarchar(64) DEFAULT NULL
@@ -218,11 +231,13 @@ CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
 --
 CREATE TABLE /*_*/pagelinks (
    pl_from INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+   pl_from_namespace int NOT NULL DEFAULT 0,
    pl_namespace INT NOT NULL DEFAULT 0,
    pl_title NVARCHAR(255) NOT NULL DEFAULT '',
 );
 CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title);
 CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from);
+CREATE INDEX /*i*/pl_backlinks_namespace ON /*_*/pagelinks (pl_from_namespace,pl_namespace,pl_title,pl_from);
 
 
 --
@@ -230,12 +245,14 @@ CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,p
 --
 CREATE TABLE /*_*/templatelinks (
   tl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+  tl_from_namespace int NOT NULL default 0,
   tl_namespace int NOT NULL default 0,
   tl_title nvarchar(255) NOT NULL default ''
 );
 
 CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title);
 CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from);
+CREATE INDEX /*i*/tl_backlinks_namespace ON /*_*/templatelinks (tl_from_namespace,tl_namespace,tl_title,tl_from);
 
 
 --
@@ -246,6 +263,7 @@ CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_tit
 CREATE TABLE /*_*/imagelinks (
   -- Key to page_id of the page containing the image / media link.
   il_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+  il_from_namespace int NOT NULL default 0,
 
   -- Filename of target image.
   -- This is also the page_title of the file's description page;
@@ -255,6 +273,7 @@ CREATE TABLE /*_*/imagelinks (
 
 CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to);
 CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from);
+CREATE INDEX /*i*/il_backlinks_namespace ON /*_*/imagelinks (il_from_namespace,il_to,il_from);
 
 --
 -- Track category inclusions *used inline*
@@ -313,8 +332,8 @@ CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_
 -- Used by the API (and some extensions)
 CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp);
 
--- FIXME: Not used, delete this
-CREATE INDEX /*i*/cl_collation ON /*_*/categorylinks (cl_collation);
+-- Used when updating collation (e.g. updateCollation.php)
+CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);
 
 --
 -- Track all existing categories.  Something is a category if 1) it has an en-
@@ -375,6 +394,9 @@ CREATE TABLE /*_*/externallinks (
 
 CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from);
 CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index);
+-- el_to index intentionally not added; we cannot index nvarchar(max) columns,
+-- but we also cannot restrict el_to to a smaller column size as the external
+-- link may be larger.
 
 --
 -- Track interlanguage links
@@ -536,7 +558,7 @@ CREATE TABLE /*_*/image (
   -- Filename.
   -- This is also the title of the associated description page,
   -- which will be in namespace 6 (NS_FILE).
-  img_name varbinary(255) NOT NULL default 0x PRIMARY KEY,
+  img_name nvarchar(255) NOT NULL default '' PRIMARY KEY,
 
   -- File size in bytes.
   img_size int NOT NULL default 0,
@@ -600,11 +622,12 @@ CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,im
 --
 CREATE TABLE /*_*/oldimage (
   -- Base filename: key to image.img_name
-  oi_name varbinary(255) NOT NULL default 0x REFERENCES /*_*/image(img_name) ON DELETE CASCADE ON UPDATE CASCADE,
+  -- Not a FK because deleting images removes them from image
+  oi_name nvarchar(255) NOT NULL default '',
 
   -- Filename of the archived file.
   -- This is generally a timestamp and '!' prepended to the base name.
-  oi_archive_name varbinary(255) NOT NULL default 0x,
+  oi_archive_name nvarchar(255) NOT NULL default '',
 
   -- Other fields as in image...
   oi_size int NOT NULL default 0,
@@ -616,7 +639,7 @@ CREATE TABLE /*_*/oldimage (
   oi_user_text nvarchar(255) NOT NULL,
   oi_timestamp varchar(14) NOT NULL default '',
 
-  oi_metadata nvarchar(max) NOT NULL,
+  oi_metadata varbinary(max) NOT NULL,
   oi_media_type varchar(16) default null,
   oi_major_mime varchar(16) not null default 'unknown',
   oi_minor_mime nvarchar(100) NOT NULL default 'unknown',
@@ -629,7 +652,6 @@ CREATE TABLE /*_*/oldimage (
 
 CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
 CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
--- oi_archive_name truncated to 14 to avoid key length overflow
 CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name);
 CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1);
 
@@ -668,7 +690,7 @@ CREATE TABLE /*_*/filearchive (
   fa_size int default 0,
   fa_width int default 0,
   fa_height int default 0,
-  fa_metadata nvarchar(max),
+  fa_metadata varbinary(max),
   fa_bits int default 0,
   fa_media_type varchar(16) default null,
   fa_major_mime varchar(16) not null default 'unknown',
@@ -763,16 +785,11 @@ CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
 -- the last few days, see Article::editUpdates()
 --
 CREATE TABLE /*_*/recentchanges (
-  rc_id int NOT NULL PRIMARY KEY IDENTITY,
+  rc_id int NOT NULL CONSTRAINT recentchanges__pk PRIMARY KEY IDENTITY,
   rc_timestamp varchar(14) not null default '',
 
-  -- This is no longer used
-  -- Field kept in database for downgrades
-  -- @todo: add drop patch with 1.24
-  rc_cur_time varchar(14) NOT NULL default '',
-
   -- As in revision
-  rc_user int NOT NULL default 0 REFERENCES /*_*/mwuser(user_id),
+  rc_user int NOT NULL default 0 CONSTRAINT rc_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
   rc_user_text nvarchar(255) NOT NULL,
 
   -- When pages are renamed, their RC entries do _not_ change.
@@ -794,13 +811,13 @@ CREATE TABLE /*_*/recentchanges (
   -- Key to page_id (was cur_id prior to 1.5).
   -- This will keep links working after moves while
   -- retaining the at-the-time name in the changes list.
-  rc_cur_id int REFERENCES /*_*/page(page_id),
+  rc_cur_id int, -- NOT FK
 
   -- rev_id of the given revision
-  rc_this_oldid int REFERENCES /*_*/revision(rev_id),
+  rc_this_oldid int, -- NOT FK
 
   -- rev_id of the prior revision, for generating diff links.
-  rc_last_oldid int REFERENCES /*_*/revision(rev_id),
+  rc_last_oldid int, -- NOT FK
 
   -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG,RC_EXTERNAL)
   rc_type tinyint NOT NULL default 0,
@@ -969,7 +986,7 @@ CREATE TABLE /*_*/logging (
   log_timestamp varchar(14) NOT NULL default '',
 
   -- The user who performed this action; key to user_id
-  log_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  log_user int, -- NOT an FK, if a user is deleted we still want to maintain a record of who did a thing
 
   -- Name of the user who performed this action
   log_user_text nvarchar(255) NOT NULL default '',
@@ -978,7 +995,7 @@ CREATE TABLE /*_*/logging (
   -- this will point to the user page.
   log_namespace int NOT NULL default 0,
   log_title nvarchar(255) NOT NULL default '',
-  log_page int NULL REFERENCES /*_*/page(page_id) ON DELETE SET NULL,
+  log_page int NULL, -- NOT an FK, logging entries are inserted for deleted pages which still reference the deleted page ids
 
   -- Freeform text. Interpreted as edit history comments.
   log_comment nvarchar(255) NOT NULL default '',
@@ -1003,7 +1020,7 @@ CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timesta
 
 INSERT INTO /*_*/logging (log_user,log_page,log_params) VALUES(0,0,'');
 
-ALTER TABLE /*_*/recentchanges ADD CONSTRAINT FK_rc_logid_log_id FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_logid__log_id__fk FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;
 
 CREATE TABLE /*_*/log_search (
   -- The type of ID (rev ID, log ID, rev timestamp, username)
@@ -1157,11 +1174,13 @@ CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
 CREATE TABLE /*_*/page_props (
   pp_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
   pp_propname nvarchar(60) NOT NULL,
-  pp_value nvarchar(max) NOT NULL
+  pp_value nvarchar(max) NOT NULL,
+  pp_sortkey float DEFAULT NULL
 );
 
 CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname);
 CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page);
+CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page ON /*_*/page_props (pp_propname,pp_sortkey,pp_page);
 
 
 -- A table to log updates, one text key row per update.
index 48d9705..dbce7a7 100755 (executable)
@@ -70,7 +70,7 @@ COMMITMSG=$(cat <<END
 Update OOjs UI to v$OOJSUI_VERSION
 
 Release notes:
- https://git.wikimedia.org/blob/oojs%2Fui.git/v$OOJSUI_VERSION/History.md
+ https://phabricator.wikimedia.org/diffusion/GOJU/browse/master/History.md;v$OOJSUI_VERSION
 END
 )
 
index b91cb28..d3e778c 100755 (executable)
@@ -49,7 +49,7 @@ COMMITMSG=$(cat <<END
 Update OOjs to v$OOJS_VERSION
 
 Release notes:
- https://git.wikimedia.org/blob/oojs%2Fcore.git/v$OOJS_VERSION/History.md
+ https://phabricator.wikimedia.org/diffusion/GOJS/browse/master/History.md;v$OOJS_VERSION
 END
 )
 
index 186feb2..922cc87 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
  */
 class UpdateCollation extends Maintenance {
        const BATCH_SIZE = 100; // Number of rows to process in one batch
-       const SYNC_INTERVAL = 20; // Wait for slaves after this many batches
+       const SYNC_INTERVAL = 5; // Wait for slaves after this many batches
 
        public $sizeHistogram = [];
 
@@ -51,7 +51,7 @@ TEXT
                );
 
                $this->addOption( 'force', 'Run on all rows, even if the collation is ' .
-                       'supposed to be up-to-date.' );
+                       'supposed to be up-to-date.', false, false, 'f' );
                $this->addOption( 'previous-collation', 'Set the previous value of ' .
                        '$wgCategoryCollation here to speed up this script, especially if your ' .
                        'categorylinks table is large. This will only update rows with that ' .
@@ -70,6 +70,7 @@ TEXT
                global $wgCategoryCollation;
 
                $dbw = $this->getDB( DB_MASTER );
+               $dbr = $this->getDB( DB_SLAVE );
                $force = $this->getOption( 'force' );
                $dryRun = $this->getOption( 'dry-run' );
                $verboseStats = $this->getOption( 'verbose-stats' );
@@ -97,6 +98,7 @@ TEXT
                $options = [
                        'LIMIT' => self::BATCH_SIZE,
                        'ORDER BY' => $orderBy,
+                       'STRAIGHT_JOIN' // per T58041
                ];
 
                if ( $force || $dryRun ) {
@@ -110,7 +112,7 @@ TEXT
                                ];
                        }
 
-                       $count = $dbw->estimateRowCount(
+                       $count = $dbr->estimateRowCount(
                                'categorylinks',
                                '*',
                                $collationConds,
@@ -118,7 +120,7 @@ TEXT
                        );
                        // Improve estimate if feasible
                        if ( $count < 1000000 ) {
-                               $count = $dbw->selectField(
+                               $count = $dbr->selectField(
                                        'categorylinks',
                                        'COUNT(*)',
                                        $collationConds,
@@ -131,6 +133,7 @@ TEXT
                                return;
                        }
                        $this->output( "Fixing collation for $count rows.\n" );
+                       wfWaitForSlaves();
                }
                $count = 0;
                $batchCount = 0;
index bef1688..92c182d 100644 (file)
  * @file
  */
 
+// This endpoint is supposed to be independent of request cookies and other
+// details of the session. Log warnings for violations of the no-session
+// constraint.
+define( 'MW_NO_SESSION', 'warn' );
+
 require_once __DIR__ . '/includes/WebStart.php';
 
 if ( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
index 9563609..466f26a 100644 (file)
  * @file
  */
 
+// This endpoint is supposed to be independent of request cookies and other
+// details of the session. Log warnings for violations of the no-session
+// constraint.
+define( 'MW_NO_SESSION', 'warn' );
+
 ini_set( 'zlib.output_compression', 'off' );
 
 $wgEnableProfileInfo = false;
index cb7adbe..cf2abdb 100644 (file)
@@ -735,7 +735,6 @@ return [
                'scripts' => [
                        'resources/lib/moment/moment.js',
                        'resources/src/moment-global.js',
-                       'resources/src/moment-local-dmy.js',
                ],
                'languageScripts' => [
                        'af' => 'resources/lib/moment/locale/af.js',
@@ -817,6 +816,13 @@ return [
                        'zh-hans' => 'resources/lib/moment/locale/zh-cn.js',
                        'zh-hant' => 'resources/lib/moment/locale/zh-tw.js',
                ],
+               // HACK: skinScripts come after languageScripts, and we need locale overrides to come
+               // after locale definitions
+               'skinScripts' => [
+                       'default' => [
+                               'resources/src/moment-locale-overrides.js',
+                       ],
+               ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
@@ -1213,6 +1219,8 @@ return [
                        'upload-form-label-usage-filename',
                        'api-error-unknownerror',
                        'api-error-unknown-warning',
+                       'api-error-autoblocked',
+                       'api-error-blocked',
                        'api-error-badaccess-groups',
                        'api-error-badtoken',
                        'api-error-copyuploaddisabled',
@@ -1280,18 +1288,18 @@ return [
                        'mediawiki.libs.jpegmeta',
                ],
                'messages' => [
-                       '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-default',
-                       'foreign-structured-upload-form-label-not-own-work-message-default',
-                       'foreign-structured-upload-form-label-not-own-work-local-default',
-                       'foreign-structured-upload-form-label-own-work-message-shared',
-                       'foreign-structured-upload-form-label-not-own-work-message-shared',
-                       'foreign-structured-upload-form-label-not-own-work-local-shared',
-                       'foreign-structured-upload-form-label-own-work-message-local',
-                       'foreign-structured-upload-form-label-not-own-work-message-local',
-                       'foreign-structured-upload-form-label-not-own-work-local-local',
+                       'upload-form-label-own-work',
+                       'upload-form-label-infoform-categories',
+                       'upload-form-label-infoform-date',
+                       'upload-form-label-own-work-message-default',
+                       'upload-form-label-not-own-work-message-default',
+                       'upload-form-label-not-own-work-local-default',
+                       'upload-form-label-own-work-message-shared',
+                       'upload-form-label-not-own-work-message-shared',
+                       'upload-form-label-not-own-work-local-shared',
+                       'upload-form-label-own-work-message-local',
+                       'upload-form-label-not-own-work-message-local',
+                       'upload-form-label-not-own-work-local-local',
                ],
        ],
        'mediawiki.toc' => [
@@ -1869,6 +1877,7 @@ return [
                        'thumbnail.html' => 'resources/src/mediawiki.special/templates/thumbnail.html',
                ],
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.upload.js',
+               'styles' => 'resources/src/mediawiki.special/mediawiki.special.upload.css',
                'messages' => [
                        'widthheight',
                        'size-bytes',
@@ -2288,6 +2297,26 @@ return [
                ],
        ],
 
+       'mediawiki.router' => [
+               'scripts' => [
+                       'resources/src/mediawiki.router/index.js',
+               ],
+               'targets' => [ 'desktop', 'mobile' ],
+               'dependencies' => [
+                       'oojs-router',
+               ],
+       ],
+
+       'oojs-router' => [
+               'scripts' => [
+                       'resources/lib/oojs-router/oojs-router.js',
+               ],
+               'targets' => [ 'desktop', 'mobile' ],
+               'dependencies' => [
+                       'oojs',
+               ],
+       ],
+
        /* OOjs UI */
        // WARNING: OOjs-UI is NOT TESTED with older browsers and is likely to break
        // if loaded in browsers that don't support ES5
diff --git a/resources/lib/oojs-router/AUTHORS.txt b/resources/lib/oojs-router/AUTHORS.txt
new file mode 100644 (file)
index 0000000..5390c84
--- /dev/null
@@ -0,0 +1 @@
+Jon Robson <jdlrobson@gmail.com>
diff --git a/resources/lib/oojs-router/LICENSE-MIT b/resources/lib/oojs-router/LICENSE-MIT
new file mode 100644 (file)
index 0000000..acbe708
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright 2011-2016 OOjs Team and other contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/resources/lib/oojs-router/oojs-router.js b/resources/lib/oojs-router/oojs-router.js
new file mode 100644 (file)
index 0000000..b136923
--- /dev/null
@@ -0,0 +1,205 @@
+/*!
+ * OOjs Router v0.1.0
+ * https://www.mediawiki.org/wiki/OOjs
+ *
+ * Copyright 2011-2016 OOjs Team and other contributors.
+ * Released under the MIT license
+ * http://oojs-router.mit-license.org
+ *
+ * Date: 2016-05-05T19:27:58Z
+ */
+( function ( $ ) {
+
+'use strict';
+
+/**
+ * Does hash match entry.path? If it does apply the
+ * callback for the Entry object.
+ *
+ * @method
+ * @private
+ * @ignore
+ * @param {string} hash string to match
+ * @param {Object} entry Entry object
+ * @return {boolean} Whether hash matches entry.path
+ */
+function matchRoute( hash, entry ) {
+       var match = hash.match( entry.path );
+       if ( match ) {
+               entry.callback.apply( this, match.slice( 1 ) );
+               return true;
+       }
+       return false;
+}
+
+/**
+ * Provides navigation routing and location information
+ *
+ * @class Router
+ * @mixins OO.EventEmitter
+ */
+function Router() {
+       var self = this;
+       OO.EventEmitter.call( this );
+       // use an object instead of an array for routes so that we don't
+       // duplicate entries that already exist
+       this.routes = {};
+       this.enabled = true;
+       this.oldHash = this.getPath();
+
+       $( window ).on( 'popstate', function () {
+               self.emit( 'popstate' );
+       } );
+
+       $( window ).on( 'hashchange', function () {
+               self.emit( 'hashchange' );
+       } );
+
+       this.on( 'hashchange', function () {
+               // ev.originalEvent.newURL is undefined on Android 2.x
+               var routeEv;
+
+               if ( self.enabled ) {
+                       routeEv = $.Event( 'route', {
+                               path: self.getPath()
+                       } );
+                       self.emit( 'route', routeEv );
+
+                       if ( !routeEv.isDefaultPrevented() ) {
+                               self.checkRoute();
+                       } else {
+                               // if route was prevented, ignore the next hash change and revert the
+                               // hash to its old value
+                               self.enabled = false;
+                               self.navigate( self.oldHash );
+                       }
+               } else {
+                       self.enabled = true;
+               }
+
+               self.oldHash = self.getPath();
+       } );
+}
+OO.mixinClass( Router, OO.EventEmitter );
+
+/**
+ * Check the current route and run appropriate callback if it matches.
+ *
+ * @method
+ */
+Router.prototype.checkRoute = function () {
+       var hash = this.getPath();
+
+       $.each( this.routes, function ( id, entry ) {
+               return !matchRoute( hash, entry );
+       } );
+};
+
+/**
+ * Bind a specific callback to a hash-based route, e.g.
+ *
+ *     @example
+ *     route( 'alert', function () { alert( 'something' ); } );
+ *     route( /hi-(.*)/, function ( name ) { alert( 'Hi ' + name ) } );
+ * Note that after defining all available routes it is up to the caller
+ * to check the existing route via the checkRoute method.
+ *
+ * @method
+ * @param {Object} path string or RegExp to match.
+ * @param {Function} callback Callback to be run when hash changes to one
+ * that matches.
+ */
+Router.prototype.route = function ( path, callback ) {
+       var entry = {
+               path: typeof path === 'string' ?
+                       new RegExp( '^' + path.replace( /[\\^$*+?.()|[\]{}]/g, '\\$&' ) + '$' )
+                       : path,
+               callback: callback
+       };
+       this.routes[ entry.path ] = entry;
+};
+
+/**
+ * Navigate to a specific route.
+ *
+ * @method
+ * @param {string} path string with a route (hash without #).
+ */
+Router.prototype.navigate = function ( path ) {
+       var history = window.history;
+       // Take advantage of `pushState` when available, to clear the hash and
+       // not leave `#` in the history. An entry with `#` in the history has
+       // the side-effect of resetting the scroll position when navigating the
+       // history.
+       if ( path === '' && history && history.pushState ) {
+               // To clear the hash we need to cut the hash from the URL.
+               path = window.location.href.replace( /#.*$/, '' );
+               history.pushState( null, document.title, path );
+               this.checkRoute();
+       } else {
+               window.location.hash = path;
+       }
+};
+
+/**
+ * Triggers back on the window
+ */
+Router.prototype.goBack = function () {
+       window.history.back();
+};
+
+/**
+ * Navigate to the previous route. This is a wrapper for window.history.back
+ *
+ * @method
+ * @return {jQuery.Deferred}
+ */
+Router.prototype.back = function () {
+       var deferredRequest = $.Deferred(),
+               self = this,
+               timeoutID;
+
+       this.once( 'popstate', function () {
+               clearTimeout( timeoutID );
+               deferredRequest.resolve();
+       } );
+
+       this.goBack();
+
+       // If for some reason (old browser, bug in IE/windows 8.1, etc) popstate doesn't fire,
+       // resolve manually. Since we don't know for sure which browsers besides IE10/11 have
+       // this problem, it's better to fall back this way rather than singling out browsers
+       // and resolving the deferred request for them individually.
+       // See https://connect.microsoft.com/IE/feedback/details/793618/history-back-popstate-not-working-as-expected-in-webview-control
+       // Give browser a few ms to update its history.
+       timeoutID = setTimeout( function () {
+               self.off( 'popstate' );
+               deferredRequest.resolve();
+       }, 50 );
+
+       return deferredRequest;
+};
+
+/**
+ * Get current path (hash).
+ *
+ * @method
+ * @return {string} Current path.
+ */
+Router.prototype.getPath = function () {
+       return window.location.hash.slice( 1 );
+};
+
+/**
+ * Determine if current browser supports onhashchange event
+ *
+ * @method
+ * @return {boolean}
+ */
+Router.prototype.isSupported = function () {
+       return 'onhashchange' in window;
+};
+
+module.exports = Router;
+
+}( jQuery ) );
index 14508b6..9a8b058 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
index 1a241cb..9ec7278 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-element-hidden {
        display: none !important;
 .oo-ui-optionWidget.oo-ui-widget-enabled {
        cursor: pointer;
 }
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+       cursor: default;
+}
 .oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
        display: block;
        white-space: nowrap;
        display: none;
 }
 .oo-ui-textInputWidget [type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-results-button,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-results-decoration {
+.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button {
        display: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
index c47ce7f..ba293e4 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-element-hidden {
        display: none !important;
        font-weight: bold;
        text-decoration: none;
 }
+.oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
+       outline: 0;
+}
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
        margin-left: 0;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
        margin-left: 0.46875em;
 }
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.2);
-       outline: 0;
-}
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
        margin-right: 0;
 }
@@ -75,6 +74,9 @@
        padding-right: 0.25em;
        color: #333333;
 }
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #347bff, 0 0 0 1px #347bff;
+}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #555555;
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #444444;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #2962cc;
-}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #347bff;
 }
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+       color: #2962cc;
+}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #1f4999;
        box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #2962cc;
-}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #347bff;
 }
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+       color: #2962cc;
+}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #1f4999;
        box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #8c130d;
-}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #d11d13;
 }
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+       color: #8c130d;
+}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #73100a;
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
        color: #cccccc;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus {
-       box-shadow: none;
-}
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
        opacity: 0.2;
           -moz-transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
                transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
 }
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
-       outline: 0;
-}
 .oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        line-height: 1.2em;
        background-color: #ebebeb;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #347bff;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
        background-color: #ebf2ff;
        border-color: #859dcc;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #1f4999;
-       border-color: #1f4999;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #1f4999;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #347bff;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
        background-color: #ebf2ff;
        border-color: #859dcc;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #1f4999;
-       border-color: #1f4999;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #1f4999;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #d11d13;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
        background-color: #fbe8e7;
        border-color: #b77c79;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #73100a;
-       border-color: #73100a;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #73100a;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #d11d13;
+       box-shadow: inset 0 0 0 1px #d11d13;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #347bff;
        border-color: #347bff;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
-       background: #2962cc;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+       background-color: #2962cc;
        border-color: #2962cc;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #347bff;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #347bff;
        border-color: #347bff;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
-       background: #2962cc;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+       background-color: #2962cc;
        border-color: #2962cc;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #347bff;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #d11d13;
        border-color: #d11d13;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
-       background: #8c130d;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+       background-color: #8c130d;
        border-color: #8c130d;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #d11d13;
-}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #999999;
        color: #ffffff;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       border-color: #d11d13;
+       box-shadow: inset 0 0 0 1px #ffffff;
+}
 .oo-ui-clippableElement-clippable {
        -webkit-box-sizing: border-box;
           -moz-box-sizing: border-box;
 .oo-ui-optionWidget.oo-ui-widget-enabled {
        cursor: pointer;
 }
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+       cursor: default;
+}
 .oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
        display: block;
        white-space: nowrap;
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
        opacity: 0.2;
 }
+.oo-ui-radioSelectWidget:focus {
+       outline: 0;
+}
+.oo-ui-radioSelectWidget:focus .oo-ui-radioOptionWidget.oo-ui-optionWidget-selected .oo-ui-radioInputWidget [type="radio"] + span {
+       border-width: 2px;
+}
 .oo-ui-radioOptionWidget {
        cursor: default;
        padding: 0.25em 0;
        border-radius: 0;
        margin-left: -1px;
 }
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button:focus {
+       z-index: 2;
+}
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
        border-bottom-left-radius: 2px;
        border-top-left-radius: 2px;
        display: none;
 }
 .oo-ui-textInputWidget [type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-results-button,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-results-decoration {
+.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button {
        display: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
        outline: 0;
        border-color: #347bff;
-       box-shadow: inset 0 0 0 0.1em #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
index 64c6be6..cbc02eb 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
@@ -2001,10 +2001,13 @@ OO.ui.mixin.ButtonElement.prototype.toggleFramed = function ( framed ) {
 /**
  * Set the button's active state.
  *
- * The active state occurs when a {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} or
- * a {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} is pressed. This method does nothing
- * for other button types.
+ * The active state can be set on:
  *
+ *  - {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} when it is selected
+ *  - {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} when it is toggle on
+ *  - {@link OO.ui.ButtonWidget ButtonWidget} when clicking the button would only refresh the page
+ *
+ * @protected
  * @param {boolean} value Make button active
  * @chainable
  */
@@ -2017,6 +2020,7 @@ OO.ui.mixin.ButtonElement.prototype.setActive = function ( value ) {
 /**
  * Check if the button is active
  *
+ * @protected
  * @return {boolean} The button is active
  */
 OO.ui.mixin.ButtonElement.prototype.isActive = function () {
@@ -3332,6 +3336,7 @@ OO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @cfg {boolean} [active=false] Whether button should be shown as active
  * @cfg {string} [href] Hyperlink to visit when the button is clicked.
  * @cfg {string} [target] The frame or window in which to open the hyperlink.
  * @cfg {boolean} [noFollow] Search engine traversal hint (default: true)
@@ -3366,6 +3371,7 @@ OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
        this.$element
                .addClass( 'oo-ui-buttonWidget' )
                .append( this.$button );
+       this.setActive( config.active );
        this.setHref( config.href );
        this.setTarget( config.target );
        this.setNoFollow( config.noFollow );
@@ -3522,6 +3528,14 @@ OO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {
        return this;
 };
 
+// Override method visibility hints from ButtonElement
+/**
+ * @method setActive
+ */
+/**
+ * @method isActive
+ */
+
 /**
  * A ButtonGroupWidget groups related buttons and is used together with OO.ui.ButtonWidget and
  * its subclasses. Each button in a group is addressed by a unique reference. Buttons can be added,
@@ -5021,6 +5035,7 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
                toggle: 'onToggle'
        } );
        this.$element.on( {
+               focus: this.onFocus.bind( this ),
                mousedown: this.onMouseDown.bind( this ),
                mouseover: this.onMouseOver.bind( this ),
                mouseleave: this.onMouseLeave.bind( this )
@@ -5101,6 +5116,19 @@ OO.ui.SelectWidget.static.passAllFilter = function () {
 
 /* Methods */
 
+/**
+ * Handle focus events
+ *
+ * @private
+ * @param {jQuery.Event} event
+ */
+OO.ui.SelectWidget.prototype.onFocus = function () {
+       // The styles for focus state depend on one of the items being selected.
+       if ( !this.getSelectedItem() ) {
+               this.selectItem( this.getFirstSelectableItem() );
+       }
+};
+
 /**
  * Handle mouse down events.
  *
index 19e8b17..3a99fba 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
index a207c8f..d757813 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-21T17:34:15Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
index 6b789f4..82335a4 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-21T17:34:15Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
index f0cb8af..d976448 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
index 7c575e0..7a45a25 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
        right: 0;
        text-overflow: ellipsis;
 }
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
-       float: left;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileType {
        float: right;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
        position: absolute;
 }
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-clearButton {
        z-index: 2;
 }
 .oo-ui-selectFileWidget-dropTarget {
        cursor: default;
        height: 5.5em;
-       text-align: left;
        padding: 0;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
        position: relative;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName,
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileName {
+       display: block;
+       padding-right: 2.375em;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileType {
        display: block;
        float: none;
 }
        position: absolute;
        right: 0.5em;
 }
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-dropTarget {
-       text-align: center;
-}
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel {
        display: block;
 }
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
        display: none;
 }
+.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
+       cursor: no-drop;
+}
 .oo-ui-selectFileWidget:last-child {
        margin-right: 0;
 }
        font-size: 1.1em;
        padding: 0.75em;
 }
+.oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
+       font-size: 90.90909%;
+}
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
        padding-right: 1.5em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
        font-weight: bold;
 }
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
-       font-style: italic;
-}
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
        opacity: 0.5;
 }
index 7dfbf1b..a530235 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
 .oo-ui-buttonSelectWidget:last-child {
        margin-right: 0;
 }
+.oo-ui-buttonSelectWidget:focus {
+       outline: 0;
+}
+.oo-ui-buttonSelectWidget:focus .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected .oo-ui-buttonElement-button {
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
+       z-index: 2;
+}
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
        border-radius: 0;
        margin-left: -1px;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus {
        border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
        outline: 0;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on {
        right: 0;
        text-overflow: ellipsis;
 }
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
-       float: left;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+.oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileType {
        float: right;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
        position: absolute;
 }
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-clearButton {
        z-index: 2;
 }
 .oo-ui-selectFileWidget-dropTarget {
        cursor: default;
        height: 5.5em;
-       text-align: left;
        padding: 0;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
        position: relative;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName,
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileName {
+       display: block;
+       padding-right: 2.375em;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-fileType {
        display: block;
        float: none;
 }
        position: absolute;
        right: 0.5em;
 }
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-dropTarget {
-       text-align: center;
-}
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel {
        display: block;
 }
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
        display: none;
 }
+.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
+       cursor: no-drop;
+}
 .oo-ui-selectFileWidget:last-child {
        margin-right: 0;
 }
        margin-left: 0.5em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       display: block;
        line-height: 2.3em;
        margin: 0;
        overflow: hidden;
        white-space: nowrap;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
        text-overflow: ellipsis;
-       left: 0.5em;
-       right: 0.5em;
+       left: 0;
+       right: 0;
+       padding-left: 0.5em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
        color: #888888;
        height: 2.3em;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
+       background-color: #f3f3f3;
        color: #cccccc;
        text-shadow: 0 1px 1px #ffffff;
        border-color: #dddddd;
-       background-color: #f3f3f3;
+       cursor: default;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
        right: 4.4625em;
+       padding-left: 0;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
        right: 2.0875em;
 .oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
        right: 2em;
+       padding-left: 0;
 }
 .oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop .oo-ui-selectFileWidget-dropTarget {
        background-color: #ebf2ff;
        font-size: 1.1em;
        padding: 0.75em;
 }
+.oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
+       font-size: 90.90909%;
+}
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
        padding-right: 1.5em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
        font-weight: bold;
 }
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
-       font-style: italic;
-}
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
        opacity: 0.5;
 }
           -moz-box-sizing: border-box;
                box-sizing: border-box;
        vertical-align: middle;
-       padding: 0 0.4em;
-       margin: 0.1em;
        height: 1.7em;
        line-height: 1.7em;
        background-color: #eeeeee;
-       border: 1px solid #cccccc;
        color: #555555;
+       margin: 0.1em;
+       border: 1px solid #cccccc;
        border-radius: 2px;
+       padding: 0 0.4em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
        display: inline-block;
 .oo-ui-capsuleItemWidget:focus {
        outline: 0;
        border-color: #347bff;
+       box-shadow: inset 0 0 0 1px #347bff;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
+       background-color: #f3f3f3;
        color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
        border-color: #dddddd;
-       background-color: #f3f3f3;
+       text-shadow: 0 1px 1px #ffffff;
 }
 .oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
-       margin-top: -1.4em;
-       padding-left: 0.3em;
+       display: none;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
+       padding-right: 1.5375em;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
+       display: block;
+       position: absolute;
+       top: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button {
+       display: block;
+       width: 1.5375em;
+       height: 100%;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-indicator-clear {
+       position: absolute;
+       top: 0;
+       right: 0.3em;
+       bottom: 0;
+       height: auto;
 }
 .oo-ui-searchWidget-query {
        position: absolute;
 .oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
        width: 2.5em;
 }
-.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
        border-right-width: 0;
 }
-.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
        border-left-width: 0;
index a084d1a..e3c2bd5 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
@@ -332,74 +332,23 @@ OO.ui.mixin.DraggableGroupElement.prototype.onItemDropOrDragEnd = function () {
  * @fires reorder
  */
 OO.ui.mixin.DraggableGroupElement.prototype.onDragOver = function ( e ) {
-       var dragOverObj, $optionWidget, itemOffset, itemMidpoint, itemBoundingRect,
-               itemSize, cssOutput, dragPosition, overIndex, itemPosition, after,
-               targetIndex = null,
+       var overIndex, targetIndex,
                item = this.getDragItem(),
-               dragItemIndex = item.getIndex(),
-               clientX = e.originalEvent.clientX,
-               clientY = e.originalEvent.clientY;
+               dragItemIndex = item.getIndex();
 
        // Get the OptionWidget item we are dragging over
-       dragOverObj = this.getElementDocument().elementFromPoint( clientX, clientY );
-       $optionWidget = $( dragOverObj ).closest( '.oo-ui-draggableElement' );
-       if ( $optionWidget[ 0 ] ) {
-               itemOffset = $optionWidget.offset();
-               itemBoundingRect = $optionWidget[ 0 ].getBoundingClientRect();
-               itemPosition = $optionWidget.position();
-               overIndex = $optionWidget.data( 'index' );
-       }
+       overIndex = $( e.target ).closest( '.oo-ui-draggableElement' ).data( 'index' );
+
+       if ( overIndex !== undefined && overIndex !== dragItemIndex ) {
+               targetIndex = overIndex + ( overIndex > dragItemIndex ? 1 : 0 );
 
-       if (
-               itemOffset &&
-               overIndex !== dragItemIndex
-       ) {
-               if ( this.orientation === 'horizontal' ) {
-                       // Calculate where the mouse is relative to the item width
-                       itemSize = itemBoundingRect.width;
-                       itemMidpoint = itemBoundingRect.left + itemSize / 2;
-                       dragPosition = clientX;
-                       // Which side of the item we hover over will dictate
-                       // where to drop the selected item, on the left or
-                       // on the right
-                       cssOutput = {
-                               left: dragPosition < itemMidpoint ? itemPosition.left : itemPosition.left + itemSize,
-                               top: itemPosition.top
-                       };
-               } else {
-                       // Calculate where the mouse is relative to the item height
-                       itemSize = itemBoundingRect.height;
-                       itemMidpoint = itemBoundingRect.top + itemSize / 2;
-                       dragPosition = clientY;
-                       // Which side of the item we hover over will dictate
-                       // where to drop the selected item, on the top or
-                       // on the bottom
-                       cssOutput = {
-                               top: dragPosition < itemMidpoint ? itemPosition.top : itemPosition.top + itemSize,
-                               left: itemPosition.left
-                       };
-               }
-               // Store whether we are before or after an item to rearrange
-               // For horizontal layout, we need to account for RTL, as this is flipped
-               if ( this.orientation === 'horizontal' && this.dir === 'rtl' ) {
-                       after = dragPosition < itemMidpoint;
-               } else {
-                       after = dragPosition > itemMidpoint;
-               }
-               targetIndex = overIndex + ( after ? 1 : 0 );
-               // Check the targetIndex isn't immediately to the left or right of the current item (a no-op)
-               if ( targetIndex === dragItemIndex || targetIndex === dragItemIndex + 1 ) {
-                       targetIndex = null;
-               }
-       }
-       if ( targetIndex !== null ) {
                if ( targetIndex > 0 ) {
                        this.$group.children().eq( targetIndex - 1 ).after( item.$element );
                } else {
                        this.$group.prepend( item.$element );
                }
-               // Move item in itemsOrder array. Needs to account for left shift if the item is moved forward.
-               this.itemsOrder.splice( targetIndex - ( targetIndex > dragItemIndex ? 1 : 0 ), 0,
+               // Move item in itemsOrder array
+               this.itemsOrder.splice( overIndex, 0,
                        this.itemsOrder.splice( dragItemIndex, 1 )[ 0 ]
                );
                this.updateIndexes();
index 1629301..6dfe142 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
        background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
index 1e46581..9a544d6 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:53Z
+ * Date: 2016-05-10T22:58:31Z
  */
 .oo-ui-window {
        background: transparent;
index aa8f8d9..37b7d90 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.16.6
+ * OOjs UI v0.17.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-04-19T21:57:49Z
+ * Date: 2016-05-10T22:58:27Z
  */
 ( function ( OO ) {
 
index e1ad562..703911b 100644 (file)
@@ -2,6 +2,7 @@
        "prefix": "oo-ui-icon",
        "intro": "@import '../../../../src/styles/common';",
        "images": {
+               "fullScreen": { "file": "images/icons/fullScreen.svg" },
                "image": { "file": "images/icons/image.svg" },
                "imageGallery": { "file": {
                        "ltr": "images/icons/imageGallery-ltr.svg",
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.png b/resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.png
new file mode 100644 (file)
index 0000000..ced1035
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.svg b/resources/lib/oojs-ui/themes/apex/images/icons/fullScreen.svg
new file mode 100644 (file)
index 0000000..06b709b
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
+    <path id="arrow" d="M6 6v4l1.28-1.28 2 2 1.423-1.44-2-2L10 6z"/>
+    <use transform="rotate(90 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(180 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(-90 12 12)" xlink:href="#arrow"/>
+</svg>
index 809bc6a..56da53c 100644 (file)
@@ -9,6 +9,7 @@
                }
        },
        "images": {
+               "fullScreen": { "file": "images/icons/fullScreen.svg" },
                "image": { "file": {
                        "ltr": "images/icons/image-ltr.svg",
                        "rtl": "images/icons/image-rtl.svg"
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.png
new file mode 100644 (file)
index 0000000..b7a3cb5
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen-invert.svg
new file mode 100644 (file)
index 0000000..e7aec3d
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+    <path id="arrow" d="M6 6v4l1.28-1.28 2 2 1.423-1.44-2-2L10 6z"/>
+    <use transform="rotate(90 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(180 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(-90 12 12)" xlink:href="#arrow"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.png
new file mode 100644 (file)
index 0000000..ced1035
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/fullScreen.svg
new file mode 100644 (file)
index 0000000..06b709b
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
+    <path id="arrow" d="M6 6v4l1.28-1.28 2 2 1.423-1.44-2-2L10 6z"/>
+    <use transform="rotate(90 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(180 12 12)" xlink:href="#arrow"/>
+    <use transform="rotate(-90 12 12)" xlink:href="#arrow"/>
+</svg>
index 79e8731..bdb5ce8 100644 (file)
         */
        function togglingHandler( $toggle, $collapsible, e, options ) {
                var wasCollapsed, $textContainer, collapseText, expandText;
-
-               if ( options === undefined ) {
-                       options = {};
-               }
+               options = options || {};
 
                if ( e ) {
                        if (
         * @chainable
         */
        $.fn.makeCollapsible = function ( options ) {
-               if ( options === undefined ) {
-                       options = {};
-               }
+               options = options || {};
 
                this.each( function () {
                        var $collapsible, collapseText, expandText, $caption, $toggle, actionHandler, buildDefaultToggleLink,
index b1a63b0..4c75e33 100644 (file)
@@ -14,7 +14,7 @@
                        $table = $( '#mw_metadata' ),
                        $tbody = $table.find( 'tbody' );
 
-               if ( !$tbody.length || !$tbody.find( '.collapsable' ).length ) {
+               if ( !$tbody.find( '.collapsable' ).length ) {
                        return;
                }
 
index 975ec2a..d04e3a6 100644 (file)
@@ -84,6 +84,7 @@ pre,
 }
 
 img,
+figure,
 .wikitable,
 .thumb {
        /* Pagination */
@@ -172,6 +173,7 @@ a {
 .mw-body a.external.text:after,
 .mw-body a.external.autonumber:after {
        content: " (" attr( href ) ")";
+       word-break: break-all;
        word-wrap: break-word;
 }
 
index daebac1..cfdf797 100644 (file)
@@ -112,13 +112,14 @@ abbr[title],
 .mw-plusminus-neg,
 .mw-plusminus-null {
        unicode-bidi: -moz-isolate;
-       unicode-bidi: -webkit-isolate;
        unicode-bidi: isolate;
 }
 
 /* Comment portions of RC entries */
 span.comment {
        font-style: italic;
+       unicode-bidi: -moz-isolate;
+       unicode-bidi: isolate;
 }
 
 /**
diff --git a/resources/src/mediawiki.router/index.js b/resources/src/mediawiki.router/index.js
new file mode 100644 (file)
index 0000000..a49cfeb
--- /dev/null
@@ -0,0 +1,2 @@
+var Router = require( 'oojs-router' );
+module.exports = new Router();
index 66b3fb2..99d465b 100644 (file)
@@ -35,7 +35,6 @@ span.reference {
        line-height: 1;
        vertical-align: super;
        unicode-bidi: -moz-isolate;
-       unicode-bidi: -webkit-isolate;
        unicode-bidi: isolate;
 }
 
diff --git a/resources/src/mediawiki.special/mediawiki.special.upload.css b/resources/src/mediawiki.special/mediawiki.special.upload.css
new file mode 100644 (file)
index 0000000..b916248
--- /dev/null
@@ -0,0 +1,10 @@
+/*!
+ * Styling for Special:Upload
+ */
+.mw-destfile-warning {
+       border: 1px solid #fde29b;
+       padding: .5em 1em;
+       margin-bottom: 1em;
+       color: #705000;
+       background-color: #fdf1d1;
+}
index 49af809..dd48367 100644 (file)
@@ -80,8 +80,9 @@
                                } else if ( page.invalidreason ) {
                                        resultOut = mw.html.escape( page.invalidreason );
                                }
-                               $spinnerDestCheck.remove();
                                uploadWarning.processResult( resultOut, uploadWarning.nameToCheck );
+                       } ).always( function () {
+                               $spinnerDestCheck.remove();
                        } );
                },
 
                },
 
                setWarning: function ( warning ) {
-                       var $warning = $( $.parseHTML( warning ) );
+                       var $warningBox = $( '#wpDestFile-warning' ),
+                               $warning = $( $.parseHTML( warning ) );
                        mw.hook( 'wikipage.content' ).fire( $warning );
-                       $( '#wpDestFile-warning' ).empty().append( $warning );
+                       $warningBox.empty().append( $warning );
 
                        // Set a value in the form indicating that the warning is acknowledged and
                        // doesn't need to be redisplayed post-upload
                        if ( !warning ) {
                                $( '#wpDestFileWarningAck' ).val( '' );
+                               $warningBox.removeAttr( 'class' );
                        } else {
                                $( '#wpDestFileWarningAck' ).val( '1' );
+                               $warningBox.attr( 'class', 'mw-destfile-warning' );
                        }
 
                }
                                prop: 'text',
                                pst: true
                        } ).done( function ( result ) {
-                               $spinnerLicense.remove();
                                uploadLicense.processResult( result, license );
+                       } ).always( function () {
+                               $spinnerLicense.remove();
                        } );
                },
 
index 58115c3..2eb84e6 100644 (file)
         * @constructor
         * @inheritdoc
         */
-       function ForeignTitle() {
-               ForeignTitle.parent.apply( this, arguments );
+       function ForeignTitle( title, namespace ) {
+               // We only need to handle categories here... but we don't know the target language.
+               // So assume that any namespace-like prefix is the 'Category' namespace...
+               title = title.replace( /^(.+?)_*:_*(.*)$/, 'Category:$2' ); // HACK
+               ForeignTitle.parent.call( this, title, namespace );
        }
        OO.inheritClass( ForeignTitle, mw.Title );
        ForeignTitle.prototype.getNamespacePrefix = function () {
old mode 100644 (file)
new mode 100755 (executable)
index 8c2b53a..df03679
         * @cfg {boolean} [performSearchOnClick=true] If true, the script will start a search when-
         *  ever a user hits a suggestion. If false, the text of the suggestion is inserted into the
         *  text field only.
+        *  @cfg {string} [dataLocation='header'] Where the search input field will be
+        *  used (header or content).
         */
        mw.widgets.SearchInputWidget = function MwWidgetsSearchInputWidget( config ) {
                config = $.extend( {
                        type: 'search',
                        icon: 'search',
                        maxLength: undefined,
-                       performSearchOnClick: true
+                       performSearchOnClick: true,
+                       dataLocation: 'header'
                }, config );
 
                // Parent constructor
index 3d97711..fdd4a8a 100644 (file)
                                disambiguation: OO.getProp( suggestionPage, 'pageprops', 'disambiguation' ) !== undefined,
                                imageUrl: OO.getProp( suggestionPage, 'thumbnail', 'source' ),
                                description: OO.getProp( suggestionPage, 'terms', 'description' ),
-                               // sort index
+                               // Sort index
                                index: suggestionPage.index
                        };
 
                                        missing: false,
                                        redirect: true,
                                        disambiguation: false,
-                                       description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title )
+                                       description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title ),
+                                       // Sort index, just below its target
+                                       index: suggestionPage.index + 0.5
                                };
                                titles.push( redirects[ i ] );
                        }
index b8cc059..899daa5 100644 (file)
@@ -94,7 +94,9 @@
                        url = ( ajaxOptions && ajaxOptions.url ) || this.defaults.ajax.url;
                        origin = ( parameters && parameters.origin ) || this.defaults.parameters.origin;
                        url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) +
-                               'origin=' + encodeURIComponent( origin );
+                               // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6
+                               // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235.
+                               'origin=' + encodeURIComponent( origin ).replace( /\./g, '%2E' );
                        newAjaxOptions = $.extend( {}, ajaxOptions, { url: url } );
                } else {
                        newAjaxOptions = ajaxOptions;
index b4ff40a..3e010d0 100644 (file)
                                // Prevent jQuery from overriding the Content-Type header
                                ajaxOptions.contentType = false;
                        } else {
-                               // Some deployed MediaWiki >= 1.17 forbid periods in URLs, due to an IE XSS bug
-                               // So let's escape them here. See bug #28235
                                // This works because jQuery accepts data as a query string or as an Object
-                               ajaxOptions.data = $.param( parameters ).replace( /\./g, '%2E' );
-
+                               ajaxOptions.data = $.param( parameters );
                                // If we extracted a token parameter, add it back in.
                                if ( token ) {
                                        ajaxOptions.data += '&token=' + encodeURIComponent( token );
                                }
 
+                               // Depending on server configuration, MediaWiki may forbid periods in URLs, due to an IE 6
+                               // XSS bug. So let's escape them here. See WebRequest::checkUrlExtension() and T30235.
+                               ajaxOptions.data = ajaxOptions.data.replace( /\./g, '%2E' );
+
                                if ( ajaxOptions.contentType === 'multipart/form-data' ) {
                                        // We were asked to emulate but can't, so drop the Content-Type header, otherwise
                                        // it'll be wrong and the server will fail to decode the POST body
                 * @since 1.22
                 */
                postWithToken: function ( tokenType, params, ajaxOptions ) {
-                       var api = this;
+                       var api = this,
+                               abortable;
 
-                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
+                       return ( abortable = api.getToken( tokenType, params.assert ) ).then( function ( token ) {
                                params.token = token;
-                               return api.post( params, ajaxOptions ).then(
+                               return ( abortable = api.post( params, ajaxOptions ) ).then(
                                        // If no error, return to caller as-is
                                        null,
                                        // Error handler
                                                        api.badToken( tokenType );
                                                        // Try again, once
                                                        params.token = undefined;
-                                                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
+                                                       return ( abortable = api.getToken( tokenType, params.assert ) ).then( function ( token ) {
                                                                params.token = token;
-                                                               return api.post( params, ajaxOptions );
+                                                               return ( abortable = api.post( params, ajaxOptions ) ).promise();
                                                        } );
                                                }
 
                                                return this;
                                        }
                                );
-                       } );
+                       } ).promise( { abort: function () {
+                               abortable.abort();
+                       } } );
                },
 
                /**
                'fileexists-shared-forbidden',
                'invalidtitle',
                'notloggedin',
+               'autoblocked',
+               'blocked',
 
                // Stash-specific errors - expanded
                'stashfailed',
index 1fabe17..8509fbc 100644 (file)
                        target = this.target || validTargets[ 0 ] || 'local',
                        layout = this;
 
-               // foreign-structured-upload-form-label-own-work-message-local
-               // foreign-structured-upload-form-label-own-work-message-shared
-               ownWorkMessage = mw.message( 'foreign-structured-upload-form-label-own-work-message-' + target );
-               // foreign-structured-upload-form-label-not-own-work-message-local
-               // foreign-structured-upload-form-label-not-own-work-message-shared
-               notOwnWorkMessage = mw.message( 'foreign-structured-upload-form-label-not-own-work-message-' + target );
-               // foreign-structured-upload-form-label-not-own-work-local-local
-               // foreign-structured-upload-form-label-not-own-work-local-shared
-               notOwnWorkLocal = mw.message( 'foreign-structured-upload-form-label-not-own-work-local-' + target );
+               // upload-form-label-own-work-message-local
+               // upload-form-label-own-work-message-shared
+               ownWorkMessage = mw.message( 'upload-form-label-own-work-message-' + target );
+               // upload-form-label-not-own-work-message-local
+               // upload-form-label-not-own-work-message-shared
+               notOwnWorkMessage = mw.message( 'upload-form-label-not-own-work-message-' + target );
+               // upload-form-label-not-own-work-local-local
+               // upload-form-label-not-own-work-local-shared
+               notOwnWorkLocal = mw.message( 'upload-form-label-not-own-work-local-' + target );
 
                if ( !ownWorkMessage.exists() ) {
-                       ownWorkMessage = mw.message( 'foreign-structured-upload-form-label-own-work-message-default' );
+                       ownWorkMessage = mw.message( 'upload-form-label-own-work-message-default' );
                }
                if ( !notOwnWorkMessage.exists() ) {
-                       notOwnWorkMessage = mw.message( 'foreign-structured-upload-form-label-not-own-work-message-default' );
+                       notOwnWorkMessage = mw.message( 'upload-form-label-not-own-work-message-default' );
                }
                if ( !notOwnWorkLocal.exists() ) {
-                       notOwnWorkLocal = mw.message( 'foreign-structured-upload-form-label-not-own-work-local-default' );
+                       notOwnWorkLocal = mw.message( 'upload-form-label-not-own-work-local-default' );
                }
 
                $ownWorkMessage = $( '<p>' ).append( ownWorkMessage.parseDom() )
                        new OO.ui.FieldLayout( this.ownWorkCheckbox, {
                                align: 'inline',
                                label: $( '<div>' ).append(
-                                       $( '<p>' ).text( mw.msg( 'foreign-structured-upload-form-label-own-work' ) ),
+                                       $( '<p>' ).text( mw.msg( 'upload-form-label-own-work' ) ),
                                        $ownWorkMessage
                                )
                        } ),
                                notices: [ mw.msg( 'upload-form-label-infoform-description-tooltip' ) ]
                        } ),
                        new OO.ui.FieldLayout( this.categoriesWidget, {
-                               label: mw.msg( 'foreign-structured-upload-form-label-infoform-categories' ),
+                               label: mw.msg( 'upload-form-label-infoform-categories' ),
                                align: 'top'
                        } ),
                        new OO.ui.FieldLayout( this.dateWidget, {
-                               label: mw.msg( 'foreign-structured-upload-form-label-infoform-date' ),
+                               label: mw.msg( 'upload-form-label-infoform-date' ),
                                align: 'top'
                        } )
                ] );
index c03c0d1..f90071c 100644 (file)
@@ -85,8 +85,7 @@
        ForeignStructuredUpload.prototype.getText = function () {
                return (
                        '== {{int:filedesc}} ==\n' +
-                       '{{' +
-                       this.getTemplateName() +
+                       '{{Information' +
                        '\n|description=' +
                        this.getDescriptions() +
                        '\n|date=' +
                return this.date.toString();
        };
 
-       /**
-        * Gets the name of the template to use for creating the file metadata.
-        * Override in subclasses for other templates.
-        *
-        * @private
-        * @return {string}
-        */
-       ForeignStructuredUpload.prototype.getTemplateName = function () {
-               return 'Information';
-       };
-
        /**
         * Fetches the wikitext for any descriptions that have been added
         * to the upload.
index 7d7b413..a35ce7a 100644 (file)
@@ -3,6 +3,16 @@
        margin-bottom: 0.1em;
 }
 
+.apihelp-header.apihelp-module-name {
+       /*
+        * This element is explicitly set to dir="ltr" in HTML.
+        * Set explicit alignment so that CSSJanus will flip it to "right";
+        * otherwise the alignment will be automatically set to "left" according
+        * to the element's direction, and this will have an inconsistent look.
+        */
+       text-align: left;
+}
+
 div.apihelp-linktrail {
        font-size: smaller;
 }
diff --git a/resources/src/moment-local-dmy.js b/resources/src/moment-local-dmy.js
deleted file mode 100644 (file)
index c67b93e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Use DMY date format for Moment.js, in accordance with MediaWiki's date formatting routines.
-// This affects English only (and languages without localisations, that fall back to English).
-// http://momentjs.com/docs/#/customization/long-date-formats/
-/*global moment */
-moment.locale( 'en', {
-       longDateFormat: {
-               // Unchanged, but have to be repeated here:
-               LT: 'h:mm A',
-               LTS: 'h:mm:ss A',
-               // Customized:
-               L: 'DD/MM/YYYY',
-               LL: 'D MMMM YYYY',
-               LLL: 'D MMMM YYYY LT',
-               LLLL: 'dddd, D MMMM YYYY LT'
-       }
-} );
diff --git a/resources/src/moment-locale-overrides.js b/resources/src/moment-locale-overrides.js
new file mode 100644 (file)
index 0000000..d49fcdc
--- /dev/null
@@ -0,0 +1,57 @@
+// Use DMY date format for Moment.js, in accordance with MediaWiki's date formatting routines.
+// This affects English only (and languages without localisations, that fall back to English).
+// http://momentjs.com/docs/#/customization/long-date-formats/
+/*global moment, mw */
+moment.locale( 'en', {
+       longDateFormat: {
+               // Unchanged, but have to be repeated here:
+               LT: 'h:mm A',
+               LTS: 'h:mm:ss A',
+               // Customized:
+               L: 'DD/MM/YYYY',
+               LL: 'D MMMM YYYY',
+               LLL: 'D MMMM YYYY LT',
+               LLLL: 'dddd, D MMMM YYYY LT'
+       }
+} );
+
+// HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
+// wgTranslateNumerals is respected.
+moment.locale( moment.locale(), {
+       preparse: function ( s ) {
+               var i,
+                       table = mw.language.getDigitTransformTable();
+               if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+                       for ( i = 0; i < 10; i++ ) {
+                               if ( table[ i ] !== undefined ) {
+                                       s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i );
+                               }
+                       }
+               }
+               // HACK: momentjs replaces commas in some languages, which is the only other use of preparse
+               // aside from digit transformation. We can only override preparse, not extend it, so we
+               // have to replicate the comma replacement functionality here.
+               if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+                       s = s.replace( /،/g, ',' );
+               }
+               return s;
+       },
+       postformat: function ( s ) {
+               var i,
+                       table = mw.language.getDigitTransformTable();
+               if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+                       for ( i = 0; i < 10; i++ ) {
+                               if ( table[ i ] !== undefined ) {
+                                       s = s.replace( new RegExp( mw.RegExp.escape( i ), 'g' ), table[ i ] );
+                               }
+                       }
+               }
+               // HACK: momentjs replaces commas in some languages, which is the only other use of postformat
+               // aside from digit transformation. We can only override postformat, not extend it, so we
+               // have to replicate the comma replacement functionality here.
+               if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+                       s = s.replace( /,/g, '،' );
+               }
+               return s;
+       }
+} );
index 7a980f7..572e2f8 100644 (file)
@@ -12,11 +12,10 @@ directory and make a symbolic link:
  mediawiki/skins$ ln -s ../../skins-trunk/FooBar
 
 The default skin Vector can be installed by cloning from Git:
-    git clone https://git.wikimedia.org/git/mediawiki/skins/Vector.git
+    git clone https://phabricator.wikimedia.org/diffusion/SVEC/Vector
 
 Other skins are also available:
-    https://gerrit.wikimedia.org/r/#/admin/projects/?filter=mediawiki%252Fskins%252F
-    https://git.wikimedia.org/project/mediawiki
+    https://phabricator.wikimedia.org/diffusion/SKIN/
 
 
 Please note that under POSIX systems (Linux...), parent of a symbolic path
diff --git a/tests/browser/ci.yml b/tests/browser/ci.yml
new file mode 100644 (file)
index 0000000..8c9865e
--- /dev/null
@@ -0,0 +1,8 @@
+BROWSER:
+  - firefox
+
+MEDIAWIKI_ENVIRONMENT:
+  - beta
+
+PLATFORM:
+  - Linux
index 98e0f2c..fa0570c 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 Given(/^I go to Create account page at (.+)$/) do |path|
   visit(CreateAccountPage, using_params: { page_title: path })
 end
index a80ca50..15069b2 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 Given(/^I am at file that does not exist$/) do
   visit(FileDoesNotExistPage, using_params: { page_name: @random_string })
 end
index 788bfc4..bda0faa 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 Given(/^I am at Log in page$/) do
   visit LoginPage
 end
index e1953a0..8ffdaf1 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 When(/^I click Appearance$/) do
   visit(PreferencesPage).appearance_link_element.when_present.click
 end
index 0a98e88..f691ffd 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 When(/^I click Editing$/) do
   visit(PreferencesPage).editing_link_element.when_present.click
 end
index 9c65db8..5660d49 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 When(/^I click User profile$/) do
   visit(PreferencesPage).user_profile_link_element.when_present.click
 end
index 9aa00cd..9c1c3ba 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class CreateAccountPage
   include PageObject
 
index 90762d2..632e303 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class FileDoesNotExistPage
   include PageObject
 
index 4f8fb66..c871e64 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class PreferencesAppearancePage
   include PageObject
 
index 25c384f..3b54d45 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class PreferencesEditingPage
   include PageObject
 
index b305ee2..1d836ea 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class PreferencesPage
   include PageObject
 
index 9e95eb5..ab5eb93 100644 (file)
@@ -1,14 +1,3 @@
-#
-# This file is subject to the license terms in the LICENSE file found in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/LICENSE. No part of
-# qa-browsertests, including this file, may be copied, modified, propagated, or
-# distributed except according to the terms contained in the LICENSE file.
-#
-# Copyright 2012-2014 by the Mediawiki developers. See the CREDITS file in the
-# qa-browsertests top-level directory and at
-# https://git.wikimedia.org/blob/qa%2Fbrowsertests/HEAD/CREDITS
-#
 class PreferencesUserProfilePage
   include PageObject
 
index 78e5f6f..ccb86d0 100644 (file)
@@ -27,6 +27,7 @@
  * @file
  * @ingroup Testing
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * @ingroup Testing
@@ -331,6 +332,18 @@ class ParserTest {
                Hooks::clear( 'InterwikiLoadPrefix' );
        }
 
+       /**
+        * Reset the Title-related services that need resetting
+        * for each test
+        */
+       public static function resetTitleServices() {
+               $services = MediaWikiServices::getInstance();
+               $services->resetServiceForTesting( 'TitleFormatter' );
+               $services->resetServiceForTesting( 'TitleParser' );
+               $services->resetServiceForTesting( '_MediaWikiTitleCodec' );
+
+       }
+
        public function setupRecorder( $options ) {
                if ( isset( $options['record'] ) ) {
                        $this->recorder = new DbTestRecorder( $this );
@@ -958,6 +971,8 @@ class ParserTest {
                MWTidy::destroySingleton();
                RepoGroup::destroySingleton();
 
+               self::resetTitleServices();
+
                return $context;
        }
 
index d846b57..25e0e31 100644 (file)
@@ -2,12 +2,23 @@
 use MediaWiki\Logger\LegacySpi;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\Logger\MonologSpi;
+use MediaWiki\MediaWikiServices;
 use Psr\Log\LoggerInterface;
 
 /**
  * @since 1.18
  */
 abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
+
+       /**
+        * The service locator created by prepareServices(). This service locator will
+        * be restored after each test. Tests that pollute the global service locator
+        * instance should use overrideMwServices() to isolate the test.
+        *
+        * @var MediaWikiServices|null
+        */
+       private static $serviceLocator = null;
+
        /**
         * $called tracks whether the setUp and tearDown method has been called.
         * class extending MediaWikiTestCase usually override setUp and tearDown
@@ -108,18 +119,202 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                }
        }
 
-       public function run( PHPUnit_Framework_TestResult $result = null ) {
+       public static function setUpBeforeClass() {
+               parent::setUpBeforeClass();
+
+               // NOTE: Usually, PHPUnitMaintClass::finalSetup already called this,
+               // but let's make doubly sure.
+               self::prepareServices( new GlobalVarConfig() );
+       }
+
+       /**
+        * Prepare service configuration for unit testing.
+        *
+        * This calls MediaWikiServices::resetGlobalInstance() to allow some critical services
+        * to be overridden for testing.
+        *
+        * prepareServices() only needs to be called once, but should be called as early as possible,
+        * before any class has a chance to grab a reference to any of the global services
+        * instances that get discarded by prepareServices(). Only the first call has any effect,
+        * later calls are ignored.
+        *
+        * @note This is called by PHPUnitMaintClass::finalSetup.
+        *
+        * @see MediaWikiServices::resetGlobalInstance()
+        *
+        * @param Config $bootstrapConfig The bootstrap config to use with the new
+        *        MediaWikiServices. Only used for the first call to this method.
+        */
+       public static function prepareServices( Config $bootstrapConfig ) {
+               static $servicesPrepared = false;
+
+               if ( $servicesPrepared ) {
+                       return;
+               } else {
+                       $servicesPrepared = true;
+               }
+
+               self::resetGlobalServices( $bootstrapConfig );
+       }
+
+       /**
+        * Reset global services, and install testing environment.
+        * This is the testing equivalent of MediaWikiServices::resetGlobalInstance().
+        * This should only be used to set up the testing environment, not when
+        * running unit tests. Use overrideMwServices() for that.
+        *
+        * @see MediaWikiServices::resetGlobalInstance()
+        * @see prepareServices()
+        * @see overrideMwServices()
+        *
+        * @param Config|null $bootstrapConfig The bootstrap config to use with the new
+        *        MediaWikiServices.
+        */
+       protected static function resetGlobalServices( Config $bootstrapConfig = null ) {
+               $oldServices = MediaWikiServices::getInstance();
+               $oldConfigFactory = $oldServices->getConfigFactory();
+
+               $testConfig = self::makeTestConfig( $bootstrapConfig );
+
+               MediaWikiServices::resetGlobalInstance( $testConfig );
+
+               self::$serviceLocator = MediaWikiServices::getInstance();
+               self::installTestServices(
+                       $oldConfigFactory,
+                       self::$serviceLocator
+               );
+       }
+
+       /**
+        * Create a config suitable for testing, based on a base config, default overrides,
+        * and custom overrides.
+        *
+        * @param Config|null $baseConfig
+        * @param Config|null $customOverrides
+        *
+        * @return Config
+        */
+       private static function makeTestConfig(
+               Config $baseConfig = null,
+               Config $customOverrides = null
+       ) {
+               $defaultOverrides = new HashConfig();
+
+               if ( !$baseConfig ) {
+                       $baseConfig = MediaWikiServices::getInstance()->getBootstrapConfig();
+               }
+
                /* Some functions require some kind of caching, and will end up using the db,
                 * which we can't allow, as that would open a new connection for mysql.
                 * Replace with a HashBag. They would not be going to persist anyway.
                 */
-               ObjectCache::$instances[CACHE_DB] = new HashBagOStuff;
+               $hashCache = [ 'class' => 'HashBagOStuff' ];
+               $objectCaches = [
+                               CACHE_DB => $hashCache,
+                               CACHE_ACCEL => $hashCache,
+                               CACHE_MEMCACHED => $hashCache,
+                               'apc' => $hashCache,
+                               'xcache' => $hashCache,
+                               'wincache' => $hashCache,
+                       ] + $baseConfig->get( 'ObjectCaches' );
+
+               $defaultOverrides->set( 'ObjectCaches', $objectCaches );
+               $defaultOverrides->set( 'MainCacheType', CACHE_NONE );
+
+               $testConfig = $customOverrides
+                       ? new MultiConfig( [ $customOverrides, $defaultOverrides, $baseConfig ] )
+                       : new MultiConfig( [ $defaultOverrides, $baseConfig ] );
+
+               return $testConfig;
+       }
+
+       /**
+        * @param ConfigFactory $oldConfigFactory
+        * @param MediaWikiServices $newServices
+        *
+        * @throws MWException
+        */
+       private static function installTestServices(
+               ConfigFactory $oldConfigFactory,
+               MediaWikiServices $newServices
+       ) {
+               // Use bootstrap config for all configuration.
+               // This allows config overrides via global variables to take effect.
+               $bootstrapConfig = $newServices->getBootstrapConfig();
+               $newServices->resetServiceForTesting( 'ConfigFactory' );
+               $newServices->redefineService(
+                       'ConfigFactory',
+                       self::makeTestConfigFactoryInstantiator(
+                               $oldConfigFactory,
+                               [ 'main' =>  $bootstrapConfig ]
+                       )
+               );
+       }
+
+       /**
+        * @param ConfigFactory $oldFactory
+        * @param Config[] $configurations
+        *
+        * @return Closure
+        */
+       private static function makeTestConfigFactoryInstantiator(
+               ConfigFactory $oldFactory,
+               array $configurations
+       ) {
+               return function( MediaWikiServices $services ) use ( $oldFactory, $configurations ) {
+                       $factory = new ConfigFactory();
+
+                       // clone configurations from $oldFactory that are not overwritten by $configurations
+                       $namesToClone = array_diff(
+                               $oldFactory->getConfigNames(),
+                               array_keys( $configurations )
+                       );
+
+                       foreach ( $namesToClone as $name ) {
+                               $factory->register( $name, $oldFactory->makeConfig( $name ) );
+                       }
+
+                       foreach ( $configurations as $name => $config ) {
+                               $factory->register( $name, $config );
+                       }
+
+                       return $factory;
+               };
+       }
+
+       /**
+        * Resets some well known services that typically have state that may interfere with unit tests.
+        * This is a lightweight alternative to resetGlobalServices().
+        *
+        * @note There is no guarantee that no references remain to stale service instances destroyed
+        * by a call to doLightweightServiceReset().
+        *
+        * @throws MWException if called outside of PHPUnit tests.
+        *
+        * @see resetGlobalServices()
+        */
+       private function doLightweightServiceReset() {
+               global $wgRequest;
 
-               // Sandbox APC by replacing with in-process hash instead.
-               // Ensures values are removed between tests.
-               ObjectCache::$instances['apc'] =
-               ObjectCache::$instances['xcache'] =
-               ObjectCache::$instances['wincache'] = new HashBagOStuff;
+               JobQueueGroup::destroySingletons();
+               ObjectCache::clear();
+               FileBackendGroup::destroySingleton();
+
+               // TODO: move global state into MediaWikiServices
+               RequestContext::resetMain();
+               MediaHandler::resetCache();
+               if ( session_id() !== '' ) {
+                       session_write_close();
+                       session_id( '' );
+               }
+
+               $wgRequest = new FauxRequest();
+               MediaWiki\Session\SessionManager::resetCache();
+       }
+
+       public function run( PHPUnit_Framework_TestResult $result = null ) {
+               // Reset all caches between tests.
+               $this->doLightweightServiceReset();
 
                $needsResetDB = false;
 
@@ -289,6 +484,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                }
                $this->mwGlobals = [];
                $this->restoreLoggers();
+
+               if ( self::$serviceLocator && MediaWikiServices::getInstance() !== self::$serviceLocator ) {
+                       MediaWikiServices::forceGlobalInstance( self::$serviceLocator );
+               }
+
+               // TODO: move global state into MediaWikiServices
                RequestContext::resetMain();
                MediaHandler::resetCache();
                if ( session_id() !== '' ) {
@@ -324,6 +525,30 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                );
        }
 
+       /**
+        * Sets a service, maintaining a stashed version of the previous service to be
+        * restored in tearDown
+        *
+        * @since 1.27
+        *
+        * @param string $name
+        * @param object $object
+        */
+       protected function setService( $name, $object ) {
+               // If we did not yet override the service locator, so so now.
+               if ( MediaWikiServices::getInstance() === self::$serviceLocator ) {
+                       $this->overrideMwServices();
+               }
+
+               MediaWikiServices::getInstance()->disableService( $name );
+               MediaWikiServices::getInstance()->redefineService(
+                       $name,
+                       function () use ( $object ) {
+                               return $object;
+                       }
+               );
+       }
+
        /**
         * Sets a global, maintaining a stashed version of the previous global to be
         * restored in tearDown
@@ -354,6 +579,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @param mixed $value Value to set the global to (ignored
         *  if an array is given as first argument).
         *
+        * @note To allow changes to global variables to take effect on global service instances,
+        *       call overrideMwServices().
+        *
         * @since 1.21
         */
        protected function setMwGlobals( $pairs, $value = null ) {
@@ -381,6 +609,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @param array|string $globalKeys Key to the global variable, or an array of keys.
         *
         * @throws Exception When trying to stash an unset global
+        *
+        * @note To allow changes to global variables to take effect on global service instances,
+        *       call overrideMwServices().
+        *
         * @since 1.23
         */
        protected function stashMwGlobals( $globalKeys ) {
@@ -421,6 +653,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         *
         * @throws MWException If the designated global is not an array.
         *
+        * @note To allow changes to global variables to take effect on global service instances,
+        *       call overrideMwServices().
+        *
         * @since 1.21
         */
        protected function mergeMwGlobalArrayValue( $name, $values ) {
@@ -441,6 +676,52 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $this->setMwGlobals( $name, $merged );
        }
 
+       /**
+        * Stashes the global instance of MediaWikiServices, and installs a new one,
+        * allowing test cases to override settings and services.
+        * The previous instance of MediaWikiServices will be restored on tearDown.
+        *
+        * @since 1.27
+        *
+        * @param Config $configOverrides Configuration overrides for the new MediaWikiServices instance.
+        * @param callable[] $services An associative array of services to re-define. Keys are service
+        *        names, values are callables.
+        *
+        * @return MediaWikiServices
+        * @throws MWException
+        */
+       protected function overrideMwServices( Config $configOverrides = null, array $services = [] ) {
+               if ( !$configOverrides ) {
+                       $configOverrides = new HashConfig();
+               }
+
+               $oldInstance = MediaWikiServices::getInstance();
+               $oldConfigFactory = $oldInstance->getConfigFactory();
+
+               $testConfig = self::makeTestConfig( null, $configOverrides );
+               $newInstance = new MediaWikiServices( $testConfig );
+
+               // Load the default wiring from the specified files.
+               // NOTE: this logic mirrors the logic in MediaWikiServices::newInstance.
+               $wiringFiles = $testConfig->get( 'ServiceWiringFiles' );
+               $newInstance->loadWiringFiles( $wiringFiles );
+
+               // Provide a traditional hook point to allow extensions to configure services.
+               Hooks::run( 'MediaWikiServices', [ $newInstance ] );
+
+               foreach ( $services as $name => $callback ) {
+                       $newInstance->redefineService( $name, $callback );
+               }
+
+               self::installTestServices(
+                       $oldConfigFactory,
+                       $newInstance
+               );
+               MediaWikiServices::forceGlobalInstance( $newInstance );
+
+               return $newInstance;
+       }
+
        /**
         * @since 1.27
         * @param string|Language $lang
@@ -475,6 +756,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @param LoggerInterface $logger
         */
        protected function setLogger( $channel, LoggerInterface $logger ) {
+               // TODO: Once loggers are managed by MediaWikiServices, use
+               //       overrideMwServices() to set loggers.
+
                $provider = LoggerFactory::getProvider();
                $wrappedProvider = TestingAccessWrapper::newFromObject( $provider );
                $singletons = $wrappedProvider->singletons;
@@ -566,6 +850,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $user = User::newFromName( 'UTSysop' );
                $comment = __METHOD__ . ': Sample page for unit test.';
 
+               // Avoid memory leak...?
+               // LinkCache::singleton()->clear();
+               // Maybe.  But doing this absolutely breaks $title->isRedirect() when called during unit tests....
+
                $page = WikiPage::factory( $title );
                $page->doEditContent( ContentHandler::makeContent( $text, $title ), $comment, 0, false, $user );
 
@@ -763,6 +1051,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        return;
                }
 
+               // TODO: the below should be re-written as soon as LBFactory, LoadBalancer,
+               // and DatabaseBase no longer use global state.
+
                self::$dbSetup = true;
 
                if ( !self::setupDatabaseWithTestPrefix( $db, $prefix ) ) {
diff --git a/tests/phpunit/data/media/yuv420.jpg b/tests/phpunit/data/media/yuv420.jpg
new file mode 100644 (file)
index 0000000..e741ca6
Binary files /dev/null and b/tests/phpunit/data/media/yuv420.jpg differ
diff --git a/tests/phpunit/data/media/yuv444.jpg b/tests/phpunit/data/media/yuv444.jpg
new file mode 100644 (file)
index 0000000..6bccefa
Binary files /dev/null and b/tests/phpunit/data/media/yuv444.jpg differ
index eb9adea..bb71610 100644 (file)
@@ -61,6 +61,18 @@ class WfAppendQueryTest extends MediaWikiTestCase {
                                'baz=quux&foo=baz',
                                'http://www.example.org/index.php?foo=bar&baz=quux&foo=baz',
                                'Modify query string'
+                       ],
+                       [
+                               'http://www.example.org/index.php#baz',
+                               'foo=bar',
+                               'http://www.example.org/index.php?foo=bar#baz',
+                               'URL with fragment'
+                       ],
+                       [
+                               'http://www.example.org/index.php?foo=bar#baz',
+                               'quux=blah',
+                               'http://www.example.org/index.php?foo=bar&quux=blah#baz',
+                               'URL with query string and fragment'
                        ]
                ];
        }
index e50b4f1..d701a81 100644 (file)
@@ -309,4 +309,118 @@ class LinkerTest extends MediaWikiLangTestCase {
                ];
                // @codingStandardsIgnoreEnd
        }
+
+       public static function provideLinkBeginHook() {
+               // @codingStandardsIgnoreStart Generic.Files.LineLength
+               return [
+                       // Modify $html
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $html = 'foobar';
+                               },
+                               '<a href="/wiki/Special:BlankPage" title="Special:BlankPage">foobar</a>'
+                       ],
+                       // Modify $attribs
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $attribs['bar'] = 'baz';
+                               },
+                               '<a href="/wiki/Special:BlankPage" title="Special:BlankPage" bar="baz">Special:BlankPage</a>'
+                       ],
+                       // Modify $query
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $query['bar'] = 'baz';
+                               },
+                               '<a href="/w/index.php?title=Special:BlankPage&amp;bar=baz" title="Special:BlankPage">Special:BlankPage</a>'
+                       ],
+                       // Force HTTP $options
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $options = [ 'http' ];
+                               },
+                               '<a href="http://example.org/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>'
+                       ],
+                       // Force 'forcearticlepath' in $options
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $options = [ 'forcearticlepath' ];
+                                       $query['foo'] = 'bar';
+                               },
+                               '<a href="/wiki/Special:BlankPage?foo=bar" title="Special:BlankPage">Special:BlankPage</a>'
+                       ],
+                       // Abort early
+                       [
+                               function( $dummy, $title, &$html, &$attribs, &$query, &$options, &$ret ) {
+                                       $ret = 'foobar';
+                                       return false;
+                               },
+                               'foobar'
+                       ],
+               ];
+               // @codingStandardsIgnoreEnd
+       }
+
+       /**
+        * @dataProvider provideLinkBeginHook
+        */
+       public function testLinkBeginHook( $callback, $expected ) {
+               $this->setMwGlobals( [
+                       'wgArticlePath' => '/wiki/$1',
+                       'wgWellFormedXml' => true,
+                       'wgServer' => '//example.org',
+                       'wgCanonicalServer' => 'http://example.org',
+                       'wgScriptPath' => '/w',
+                       'wgScript' => '/w/index.php',
+               ] );
+
+               $this->setMwGlobals( 'wgHooks', [ 'LinkBegin' => [ $callback ] ] );
+               $title = SpecialPage::getTitleFor( 'Blankpage' );
+               $out = Linker::link( $title );
+               $this->assertEquals( $expected, $out );
+       }
+
+       public static function provideLinkEndHook() {
+               return [
+                       // Override $html
+                       [
+                               function( $dummy, $title, $options, &$html, &$attribs, &$ret ) {
+                                       $html = 'foobar';
+                               },
+                               '<a href="/wiki/Special:BlankPage" title="Special:BlankPage">foobar</a>'
+                       ],
+                       // Modify $attribs
+                       [
+                               function( $dummy, $title, $options, &$html, &$attribs, &$ret ) {
+                                       $attribs['bar'] = 'baz';
+                               },
+                               '<a href="/wiki/Special:BlankPage" title="Special:BlankPage" bar="baz">Special:BlankPage</a>'
+                       ],
+                       // Fully override return value and abort hook
+                       [
+                               function( $dummy, $title, $options, &$html, &$attribs, &$ret ) {
+                                       $ret = 'blahblahblah';
+                                       return false;
+                               },
+                               'blahblahblah'
+                       ],
+
+               ];
+       }
+
+       /**
+        * @dataProvider provideLinkEndHook
+        */
+       public function testLinkEndHook( $callback, $expected ) {
+               $this->setMwGlobals( [
+                       'wgArticlePath' => '/wiki/$1',
+                       'wgWellFormedXml' => true,
+               ] );
+
+               $this->setMwGlobals( 'wgHooks', [ 'LinkEnd' => [ $callback ] ] );
+
+               $title = SpecialPage::getTitleFor( 'Blankpage' );
+               $out = Linker::link( $title );
+               $this->assertEquals( $expected, $out );
+       }
 }
index 1889575..467a2ad 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Services\ServiceDisabledException;
 
 /**
  * @covers MediaWiki\MediaWikiServices
@@ -9,23 +10,208 @@ use MediaWiki\MediaWikiServices;
  */
 class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
 
+       /**
+        * @return Config
+        */
+       private function newTestConfig() {
+               $globalConfig = new GlobalVarConfig();
+
+               $testConfig = new HashConfig();
+               $testConfig->set( 'ServiceWiringFiles', $globalConfig->get( 'ServiceWiringFiles' ) );
+               $testConfig->set( 'ConfigRegistry', $globalConfig->get( 'ConfigRegistry' ) );
+
+               return $testConfig;
+       }
+
+       /**
+        * @return MediaWikiServices
+        */
+       private function newMediaWikiServices( Config $config = null ) {
+               if ( $config === null ) {
+                       $config = $this->newTestConfig();
+               }
+
+               $instance = new MediaWikiServices( $config );
+
+               // Load the default wiring from the specified files.
+               $wiringFiles = $config->get( 'ServiceWiringFiles' );
+               $instance->loadWiringFiles( $wiringFiles );
+
+               return $instance;
+       }
+
        public function testGetInstance() {
                $services = MediaWikiServices::getInstance();
                $this->assertInstanceOf( 'MediaWiki\\MediaWikiServices', $services );
        }
 
+       public function testForceGlobalInstance() {
+               $newServices = $this->newMediaWikiServices();
+               $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
+
+               $this->assertInstanceOf( 'MediaWiki\\MediaWikiServices', $oldServices );
+               $this->assertNotSame( $oldServices, $newServices );
+
+               $theServices = MediaWikiServices::getInstance();
+               $this->assertSame( $theServices, $newServices );
+
+               MediaWikiServices::forceGlobalInstance( $oldServices );
+
+               $theServices = MediaWikiServices::getInstance();
+               $this->assertSame( $theServices, $oldServices );
+       }
+
+       public function testResetGlobalInstance() {
+               $newServices = $this->newMediaWikiServices();
+               $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
+
+               MediaWikiServices::resetGlobalInstance( $this->newTestConfig() );
+               $theServices = MediaWikiServices::getInstance();
+
+               $this->assertNotSame( $theServices, $newServices );
+               $this->assertNotSame( $theServices, $oldServices );
+
+               MediaWikiServices::forceGlobalInstance( $oldServices );
+       }
+
+       public function testDisableStorageBackend() {
+               $newServices = $this->newMediaWikiServices();
+               $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
+
+               $lbFactory = $this->getMockBuilder( 'LBFactorySimple' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $lbFactory->expects( $this->once() )
+                       ->method( 'destroy' );
+
+               $newServices->redefineService(
+                       'DBLoadBalancerFactory',
+                       function() use ( $lbFactory ) {
+                               return $lbFactory;
+                       }
+               );
+
+               // force the service to become active, so we can check that it does get destroyed
+               $newServices->getService( 'DBLoadBalancerFactory' );
+
+               MediaWikiServices::disableStorageBackend(); // should destroy DBLoadBalancerFactory
+
+               try {
+                       MediaWikiServices::getInstance()->getService( 'DBLoadBalancerFactory' );
+                       $this->fail( 'DBLoadBalancerFactory shoudl have been disabled' );
+               }
+               catch ( ServiceDisabledException $ex ) {
+                       // ok, as expected
+               }
+               catch ( Throwable $ex ) {
+                       $this->fail( 'ServiceDisabledException expected, caught ' . get_class( $ex ) );
+               }
+
+               MediaWikiServices::forceGlobalInstance( $oldServices );
+       }
+
+       public function testResetChildProcessServices() {
+               $newServices = $this->newMediaWikiServices();
+               $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
+
+               $lbFactory = $this->getMockBuilder( 'LBFactorySimple' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $lbFactory->expects( $this->once() )
+                       ->method( 'destroy' );
+
+               $newServices->redefineService(
+                       'DBLoadBalancerFactory',
+                       function() use ( $lbFactory ) {
+                               return $lbFactory;
+                       }
+               );
+
+               // force the service to become active, so we can check that it does get destroyed
+               $oldLBFactory = $newServices->getService( 'DBLoadBalancerFactory' );
+
+               MediaWikiServices::resetChildProcessServices();
+               $finalServices = MediaWikiServices::getInstance();
+
+               $newLBFactory = $finalServices->getService( 'DBLoadBalancerFactory' );
+
+               $this->assertNotSame( $oldLBFactory, $newLBFactory );
+
+               MediaWikiServices::forceGlobalInstance( $oldServices );
+       }
+
+       public function testResetServiceForTesting() {
+               $services = $this->newMediaWikiServices();
+               $serviceCounter = 0;
+
+               $services->defineService(
+                       'Test',
+                       function() use ( &$serviceCounter ) {
+                               $serviceCounter++;
+                               $service = $this->getMock( 'MediaWiki\Services\DestructibleService' );
+                               $service->expects( $this->once() )->method( 'destroy' );
+                               return $service;
+                       }
+               );
+
+               // This should do nothing. In particular, it should not create a service instance.
+               $services->resetServiceForTesting( 'Test' );
+               $this->assertEquals( 0, $serviceCounter, 'No service instance should be created yet.' );
+
+               $oldInstance = $services->getService( 'Test' );
+               $this->assertEquals( 1, $serviceCounter, 'A service instance should exit now.' );
+
+               // The old instance should be detached, and destroy() called.
+               $services->resetServiceForTesting( 'Test' );
+               $newInstance = $services->getService( 'Test' );
+
+               $this->assertNotSame( $oldInstance, $newInstance );
+
+               // Satisfy the expectation that destroy() is called also for the second service instance.
+               $newInstance->destroy();
+       }
+
+       public function testResetServiceForTesting_noDestroy() {
+               $services = $this->newMediaWikiServices();
+
+               $services->defineService(
+                       'Test',
+                       function() {
+                               $service = $this->getMock( 'MediaWiki\Services\DestructibleService' );
+                               $service->expects( $this->never() )->method( 'destroy' );
+                               return $service;
+                       }
+               );
+
+               $oldInstance = $services->getService( 'Test' );
+
+               // The old instance should be detached, but destroy() not called.
+               $services->resetServiceForTesting( 'Test', false );
+               $newInstance = $services->getService( 'Test' );
+
+               $this->assertNotSame( $oldInstance, $newInstance );
+       }
+
        public function provideGetters() {
-               // NOTE: This should list all service getters defined in MediaWikiServices.
-               // NOTE: For every test case defined here there should be a corresponding
-               // test case defined in provideGetService().
-               return [
-                       'BootstrapConfig' => [ 'getBootstrapConfig', Config::class ],
-                       'ConfigFactory' => [ 'getConfigFactory', ConfigFactory::class ],
-                       'MainConfig' => [ 'getMainConfig', Config::class ],
-                       'SiteStore' => [ 'getSiteStore', SiteStore::class ],
-                       'SiteLookup' => [ 'getSiteLookup', SiteLookup::class ],
-                       'StatsdDataFactory' => [ 'getStatsdDataFactory', StatsdDataFactory::class ],
-               ];
+               $getServiceCases = $this->provideGetService();
+               $getterCases = [];
+
+               // All getters should be named just like the service, with "get" added.
+               foreach ( $getServiceCases as $name => $case ) {
+                       if ( $name[0] === '_' ) {
+                               // Internal service, no getter
+                               continue;
+                       }
+                       list( $service, $class ) = $case;
+                       $getterCases[$name] = [
+                               'get' . $service,
+                               $class,
+                       ];
+               }
+
+               return $getterCases;
        }
 
        /**
@@ -49,6 +235,17 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
                        'SiteStore' => [ 'SiteStore', SiteStore::class ],
                        'SiteLookup' => [ 'SiteLookup', SiteLookup::class ],
                        'StatsdDataFactory' => [ 'StatsdDataFactory', StatsdDataFactory::class ],
+                       'EventRelayerGroup' => [ 'EventRelayerGroup', EventRelayerGroup::class ],
+                       'SearchEngineFactory' => [ 'SearchEngineFactory', SearchEngineFactory::class ],
+                       'SearchEngineConfig' => [ 'SearchEngineConfig', SearchEngineConfig::class ],
+                       'SkinFactory' => [ 'SkinFactory', SkinFactory::class ],
+                       'DBLoadBalancerFactory' => [ 'DBLoadBalancerFactory', 'LBFactory' ],
+                       'DBLoadBalancer' => [ 'DBLoadBalancer', 'LoadBalancer' ],
+                       'WatchedItemStore' => [ 'WatchedItemStore', WatchedItemStore::class ],
+                       'GenderCache' => [ 'GenderCache', GenderCache::class ],
+                       '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', MediaWikiTitleCodec::class ],
+                       'TitleFormatter' => [ 'TitleFormatter', TitleFormatter::class ],
+                       'TitleParser' => [ 'TitleParser', TitleParser::class ],
                ];
        }
 
index 5ea0cdf..22f6fa6 100644 (file)
@@ -21,10 +21,10 @@ class MergeHistoryTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideIsValidMerge
         * @covers MergeHistory::isValidMerge
-        * @param $source string Source page
-        * @param $dest string Destination page
-        * @param $timestamp string|bool Timestamp up to which revisions are merged (or false for all)
-        * @param $error string|bool Expected error for test (or true for no error)
+        * @param string $source Source page
+        * @param string $dest Destination page
+        * @param string|bool $timestamp Timestamp up to which revisions are merged (or false for all)
+        * @param string|bool $error Expected error for test (or true for no error)
         */
        public function testIsValidMerge( $source, $dest, $timestamp, $error ) {
                $this->setMwGlobals( 'wgContentHandlerUseDB', false );
index cf34b18..224b0cb 100644 (file)
@@ -581,4 +581,29 @@ class MessageTest extends MediaWikiLangTestCase {
                $msg = unserialize( serialize( $msg ) );
                $this->assertEquals( 'Hauptseite', $msg->plain() );
        }
+
+       /**
+        * @covers Message::newFromSpecifier
+        * @dataProvider provideNewFromSpecifier
+        */
+       public function testNewFromSpecifier( $value, $expectedText ) {
+               $message = Message::newFromSpecifier( $value );
+               $this->assertInstanceOf( Message::class, $message );
+               $this->assertSame( $expectedText, $message->text() );
+       }
+
+       public function provideNewFromSpecifier() {
+               $messageSpecifier = $this->getMockForAbstractClass( MessageSpecifier::class );
+               $messageSpecifier->expects( $this->any() )->method( 'getKey' )->willReturn( 'mainpage' );
+               $messageSpecifier->expects( $this->any() )->method( 'getParams' )->willReturn( [] );
+
+               return [
+                       'string' => [ 'mainpage', 'Main Page' ],
+                       'array' => [ [ 'youhavenewmessages', 'foo', 'bar' ], 'You have foo (bar).' ],
+                       'Message' => [ new Message( 'youhavenewmessages', [ 'foo', 'bar' ] ), 'You have foo (bar).' ],
+                       'RawMessage' => [ new RawMessage( 'foo ($1)', [ 'bar' ] ), 'foo (bar)' ],
+                       'MessageSpecifier' => [ $messageSpecifier, 'Main Page' ],
+               ];
+       }
 }
+
index 6d5154f..0ec200c 100644 (file)
@@ -4,6 +4,7 @@
  * @group Database
  */
 class PrefixSearchTest extends MediaWikiLangTestCase {
+       private $originalHandlers;
 
        public function addDBDataOnce() {
                if ( !$this->isWikitextNS( NS_MAIN ) ) {
@@ -40,7 +41,23 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
                }
 
                // Avoid special pages from extensions interferring with the tests
-               $this->setMwGlobals( 'wgSpecialPages', [] );
+               $this->setMwGlobals( [
+                       'wgSpecialPages' => [],
+                       'wgHooks' => [],
+               ] );
+
+               $this->originalHandlers = TestingAccessWrapper::newFromClass( 'Hooks' )->handlers;
+               TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = [];
+
+               SpecialPageFactory::resetList();
+       }
+
+       public function tearDown() {
+               parent::tearDown();
+
+               TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = $this->originalHandlers;
+
+               SpecialPageFactory::resetList();
        }
 
        protected function searchProvision( array $results = null ) {
index 942c45e..933777c 100644 (file)
@@ -69,11 +69,53 @@ class ServiceContainerTest extends PHPUnit_Framework_TestCase {
 
                $name = 'TestService92834576';
 
-               $this->setExpectedException( 'InvalidArgumentException' );
+               $this->setExpectedException( 'MediaWiki\Services\NoSuchServiceException' );
 
                $services->getService( $name );
        }
 
+       public function testPeekService() {
+               $services = $this->newServiceContainer();
+
+               $services->defineService(
+                       'Foo',
+                       function() {
+                               return new stdClass();
+                       }
+               );
+
+               $services->defineService(
+                       'Bar',
+                       function() {
+                               return new stdClass();
+                       }
+               );
+
+               // trigger instantiation of Foo
+               $services->getService( 'Foo' );
+
+               $this->assertInternalType(
+                       'object',
+                       $services->peekService( 'Foo' ),
+                       'Peek should return the service object if it had been accessed before.'
+               );
+
+               $this->assertNull(
+                       $services->peekService( 'Bar' ),
+                       'Peek should return null if the service was never accessed.'
+               );
+       }
+
+       public function testPeekService_fail_unknown() {
+               $services = $this->newServiceContainer();
+
+               $name = 'TestService92834576';
+
+               $this->setExpectedException( 'MediaWiki\Services\NoSuchServiceException' );
+
+               $services->peekService( $name );
+       }
+
        public function testDefineService() {
                $services = $this->newServiceContainer();
 
@@ -99,7 +141,7 @@ class ServiceContainerTest extends PHPUnit_Framework_TestCase {
                        return $theService;
                } );
 
-               $this->setExpectedException( 'RuntimeException' );
+               $this->setExpectedException( 'MediaWiki\Services\ServiceAlreadyDefinedException' );
 
                $services->defineService( $name, function() use ( $theService ) {
                        return $theService;
@@ -147,7 +189,7 @@ class ServiceContainerTest extends PHPUnit_Framework_TestCase {
                ];
 
                // loading the same file twice should fail, because
-               $this->setExpectedException( 'RuntimeException' );
+               $this->setExpectedException( 'MediaWiki\Services\ServiceAlreadyDefinedException' );
 
                $services->loadWiringFiles( $wiringFiles );
        }
@@ -184,7 +226,7 @@ class ServiceContainerTest extends PHPUnit_Framework_TestCase {
                $theService = new stdClass();
                $name = 'TestService92834576';
 
-               $this->setExpectedException( 'RuntimeException' );
+               $this->setExpectedException( 'MediaWiki\Services\NoSuchServiceException' );
 
                $services->redefineService( $name, function() use ( $theService ) {
                        return $theService;
@@ -204,11 +246,101 @@ class ServiceContainerTest extends PHPUnit_Framework_TestCase {
                // create the service, so it can no longer be redefined
                $services->getService( $name );
 
-               $this->setExpectedException( 'RuntimeException' );
+               $this->setExpectedException( 'MediaWiki\Services\CannotReplaceActiveServiceException' );
+
+               $services->redefineService( $name, function() use ( $theService ) {
+                       return $theService;
+               } );
+       }
+
+       public function testDisableService() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $destructible = $this->getMock( 'MediaWiki\Services\DestructibleService' );
+               $destructible->expects( $this->once() )
+                       ->method( 'destroy' );
+
+               $services->defineService( 'Foo', function() use ( $destructible ) {
+                       return $destructible;
+               } );
+               $services->defineService( 'Bar', function() {
+                       return new stdClass();
+               } );
+               $services->defineService( 'Qux', function() {
+                       return new stdClass();
+               } );
+
+               // instantiate Foo and Bar services
+               $services->getService( 'Foo' );
+               $services->getService( 'Bar' );
+
+               // disable service, should call destroy() once.
+               $services->disableService( 'Foo' );
+
+               // disabled service should still be listed
+               $this->assertContains( 'Foo', $services->getServiceNames() );
+
+               // getting other services should still work
+               $services->getService( 'Bar' );
+
+               // disable non-destructible service, and not-yet-instantiated service
+               $services->disableService( 'Bar' );
+               $services->disableService( 'Qux' );
+
+               $this->assertNull( $services->peekService( 'Bar' ) );
+               $this->assertNull( $services->peekService( 'Qux' ) );
+
+               // disabled service should still be listed
+               $this->assertContains( 'Bar', $services->getServiceNames() );
+               $this->assertContains( 'Qux', $services->getServiceNames() );
+
+               // re-enable Bar service
+               $services->redefineService( 'Bar', function() {
+                       return new stdClass();
+               } );
+
+               $services->getService( 'Bar' );
+
+               $this->setExpectedException( 'MediaWiki\Services\ServiceDisabledException' );
+               $services->getService( 'Qux' );
+       }
+
+       public function testDisableService_fail_undefined() {
+               $services = $this->newServiceContainer();
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $this->setExpectedException( 'MediaWiki\Services\NoSuchServiceException' );
 
                $services->redefineService( $name, function() use ( $theService ) {
                        return $theService;
                } );
        }
 
+       public function testDestroy() {
+               $services = $this->newServiceContainer();
+
+               $destructible = $this->getMock( 'MediaWiki\Services\DestructibleService' );
+               $destructible->expects( $this->once() )
+                       ->method( 'destroy' );
+
+               $services->defineService( 'Foo', function() use ( $destructible ) {
+                       return $destructible;
+               } );
+
+               $services->defineService( 'Bar', function() {
+                       return new stdClass();
+               } );
+
+               // create the service
+               $services->getService( 'Foo' );
+
+               // destroy the container
+               $services->destroy();
+
+               $this->setExpectedException( 'MediaWiki\Services\ContainerDisabledException' );
+               $services->getService( 'Bar' );
+       }
+
 }
index b506cb8..142c77f 100644 (file)
@@ -143,6 +143,7 @@ class TestUser {
        }
 
        /**
+        * @since 1.25
         * @return User
         */
        public function getUser() {
@@ -150,6 +151,7 @@ class TestUser {
        }
 
        /**
+        * @since 1.25
         * @return string
         */
        public function getPassword() {
index 7d025d2..496f18f 100644 (file)
@@ -144,6 +144,13 @@ class TitleTest extends MediaWikiTestCase {
                                ]
                        ]
                ] );
+
+               // Reset TitleParser since we modified $wgLocalInterwikis
+               $this->setService( 'TitleParser', new MediaWikiTitleCodec(
+                               Language::factory( 'en' ),
+                               new GenderCache(),
+                               [ 'localtestiw' ]
+               ) );
        }
 
        /**
index 5b2873a..f34af61 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @author Addshore
  *
@@ -22,7 +24,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
        public function testWatchAndUnWatchItem() {
                $user = $this->getUser();
                $title = Title::newFromText( 'WatchedItemStoreIntegrationTestPage' );
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                // Cleanup after previous tests
                $store->removeWatch( $user, $title );
                $initialWatchers = $store->countWatchers( $title );
@@ -108,7 +110,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                $user = $this->getUser();
                $otherUser = ( new TestUser( 'WatchedItemStoreIntegrationTestUser_otherUser' ) )->getUser();
                $title = Title::newFromText( 'WatchedItemStoreIntegrationTestPage' );
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                $store->addWatch( $user, $title );
                $this->assertNull( $store->loadWatchedItem( $user, $title )->getNotificationTimestamp() );
                $initialVisitingWatchers = $store->countVisitingWatchers( $title, '20150202020202' );
@@ -176,7 +178,7 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                $user = $this->getUser();
                $titleOld = Title::newFromText( 'WatchedItemStoreIntegrationTestPageOld' );
                $titleNew = Title::newFromText( 'WatchedItemStoreIntegrationTestPageNew' );
-               $store = WatchedItemStore::getDefaultInstance();
+               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
                $store->addWatch( $user, $titleOld->getSubjectPage() );
                $store->addWatch( $user, $titleOld->getTalkPage() );
                // Cleanup after previous tests
index d9fd4de..6c4a6f0 100644 (file)
@@ -6,7 +6,7 @@ use MediaWiki\Linker\LinkTarget;
  *
  * @covers WatchedItemStore
  */
-class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
+class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
        /**
         * @return PHPUnit_Framework_MockObject_MockObject|IDatabase
@@ -94,23 +94,6 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                );
        }
 
-       public function testGetDefaultInstance() {
-               $instanceOne = WatchedItemStore::getDefaultInstance();
-               $instanceTwo = WatchedItemStore::getDefaultInstance();
-               $this->assertSame( $instanceOne, $instanceTwo );
-       }
-
-       public function testOverrideDefaultInstance() {
-               $instance = WatchedItemStore::getDefaultInstance();
-               $scopedOverride = $instance->overrideDefaultInstance( null );
-
-               $this->assertNotSame( $instance, WatchedItemStore::getDefaultInstance() );
-
-               unset( $scopedOverride );
-
-               $this->assertSame( $instance, WatchedItemStore::getDefaultInstance() );
-       }
-
        public function testCountWatchedItems() {
                $user = $this->getMockNonAnonUserWithId( 1 );
 
@@ -2007,6 +1990,33 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                return $title;
        }
 
+       private function verifyCallbackJob(
+               $callback,
+               LinkTarget $expectedTitle,
+               $expectedUserId,
+               callable $notificationTimestampCondition
+       ) {
+               $this->assertInternalType( 'callable', $callback );
+
+               $callbackReflector = new ReflectionFunction( $callback );
+               $vars = $callbackReflector->getStaticVariables();
+               $this->assertArrayHasKey( 'job', $vars );
+               $this->assertInstanceOf( ActivityUpdateJob::class, $vars['job'] );
+
+               /** @var ActivityUpdateJob $job */
+               $job = $vars['job'];
+               $this->assertEquals( $expectedTitle->getDBkey(), $job->getTitle()->getDBkey() );
+               $this->assertEquals( $expectedTitle->getNamespace(), $job->getTitle()->getNamespace() );
+
+               $jobParams = $job->getParams();
+               $this->assertArrayHasKey( 'type', $jobParams );
+               $this->assertEquals( 'updateWatchlistNotification', $jobParams['type'] );
+               $this->assertArrayHasKey( 'userid', $jobParams );
+               $this->assertEquals( $expectedUserId, $jobParams['userid'] );
+               $this->assertArrayHasKey( 'notifTime', $jobParams );
+               $this->assertTrue( $notificationTimestampCondition( $jobParams['notifTime'] ) );
+       }
+
        public function testResetNotificationTimestamp_oldidSpecifiedLatestRevisionForced() {
                $user = $this->getMockNonAnonUserWithId( 1 );
                $oldid = 22;
@@ -2033,12 +2043,18 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        $mockCache
                );
 
-               // Note: This does not actually assert the job is correct
                $callableCallCounter = 0;
                $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function( $callable ) use ( &$callableCallCounter ) {
+                       function( $callable ) use ( &$callableCallCounter, $title, $user ) {
                                $callableCallCounter++;
-                               $this->assertInternalType( 'callable', $callable );
+                               $this->verifyCallbackJob(
+                                       $callable,
+                                       $title,
+                                       $user->getId(),
+                                       function( $time ) {
+                                               return $time === null;
+                                       }
+                               );
                        }
                );
 
@@ -2093,12 +2109,159 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                        $mockCache
                );
 
-               // Note: This does not actually assert the job is correct
                $addUpdateCallCounter = 0;
                $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function( $callable ) use ( &$addUpdateCallCounter ) {
+                       function( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
+                               $addUpdateCallCounter++;
+                               $this->verifyCallbackJob(
+                                       $callable,
+                                       $title,
+                                       $user->getId(),
+                                       function( $time ) {
+                                               return $time !== null && $time > '20151212010101';
+                                       }
+                               );
+                       }
+               );
+
+               $getTimestampCallCounter = 0;
+               $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
+                       function( $titleParam, $oldidParam ) use ( &$getTimestampCallCounter, $title, $oldid ) {
+                               $getTimestampCallCounter++;
+                               $this->assertEquals( $title, $titleParam );
+                               $this->assertEquals( $oldid, $oldidParam );
+                       }
+               );
+
+               $this->assertTrue(
+                       $store->resetNotificationTimestamp(
+                               $user,
+                               $title,
+                               'force',
+                               $oldid
+                       )
+               );
+               $this->assertEquals( 1, $addUpdateCallCounter );
+               $this->assertEquals( 1, $getTimestampCallCounter );
+
+               ScopedCallback::consume( $scopedOverrideDeferred );
+               ScopedCallback::consume( $scopedOverrideRevision );
+       }
+
+       public function testResetNotificationTimestamp_notWatchedPageForced() {
+               $user = $this->getMockNonAnonUserWithId( 1 );
+               $oldid = 22;
+               $title = $this->getMockTitle( 'SomeDbKey' );
+               $title->expects( $this->once() )
+                       ->method( 'getNextRevisionID' )
+                       ->with( $oldid )
+                       ->will( $this->returnValue( 33 ) );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->once() )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'watchlist',
+                               'wl_notificationtimestamp',
+                               [
+                                       'wl_user' => 1,
+                                       'wl_namespace' => 0,
+                                       'wl_title' => 'SomeDbKey',
+                               ]
+                       )
+                       ->will( $this->returnValue( false ) );
+
+               $mockCache = $this->getMockCache();
+               $mockDb->expects( $this->never() )
+                       ->method( 'get' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'set' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'delete' );
+
+               $store = $this->newWatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $callableCallCounter = 0;
+               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
+                       function( $callable ) use ( &$callableCallCounter, $title, $user ) {
+                               $callableCallCounter++;
+                               $this->verifyCallbackJob(
+                                       $callable,
+                                       $title,
+                                       $user->getId(),
+                                       function( $time ) {
+                                               return $time === null;
+                                       }
+                               );
+                       }
+               );
+
+               $this->assertTrue(
+                       $store->resetNotificationTimestamp(
+                               $user,
+                               $title,
+                               'force',
+                               $oldid
+                       )
+               );
+               $this->assertEquals( 1, $callableCallCounter );
+
+               ScopedCallback::consume( $scopedOverride );
+       }
+
+       public function testResetNotificationTimestamp_futureNotificationTimestampForced() {
+               $user = $this->getMockNonAnonUserWithId( 1 );
+               $oldid = 22;
+               $title = $this->getMockTitle( 'SomeDbKey' );
+               $title->expects( $this->once() )
+                       ->method( 'getNextRevisionID' )
+                       ->with( $oldid )
+                       ->will( $this->returnValue( 33 ) );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->once() )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'watchlist',
+                               'wl_notificationtimestamp',
+                               [
+                                       'wl_user' => 1,
+                                       'wl_namespace' => 0,
+                                       'wl_title' => 'SomeDbKey',
+                               ]
+                       )
+                       ->will( $this->returnValue(
+                               $this->getFakeRow( [ 'wl_notificationtimestamp' => '30151212010101' ] )
+                       ) );
+
+               $mockCache = $this->getMockCache();
+               $mockDb->expects( $this->never() )
+                       ->method( 'get' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'set' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'delete' );
+
+               $store = $this->newWatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $addUpdateCallCounter = 0;
+               $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
+                       function( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
                                $addUpdateCallCounter++;
-                               $this->assertInternalType( 'callable', $callable );
+                               $this->verifyCallbackJob(
+                                       $callable,
+                                       $title,
+                                       $user->getId(),
+                                       function( $time ) {
+                                               return $time === '30151212010101';
+                                       }
+                               );
                        }
                );
 
@@ -2126,6 +2289,83 @@ class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
                ScopedCallback::consume( $scopedOverrideRevision );
        }
 
+       public function testResetNotificationTimestamp_futureNotificationTimestampNotForced() {
+               $user = $this->getMockNonAnonUserWithId( 1 );
+               $oldid = 22;
+               $title = $this->getMockTitle( 'SomeDbKey' );
+               $title->expects( $this->once() )
+                       ->method( 'getNextRevisionID' )
+                       ->with( $oldid )
+                       ->will( $this->returnValue( 33 ) );
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->once() )
+                       ->method( 'selectRow' )
+                       ->with(
+                               'watchlist',
+                               'wl_notificationtimestamp',
+                               [
+                                       'wl_user' => 1,
+                                       'wl_namespace' => 0,
+                                       'wl_title' => 'SomeDbKey',
+                               ]
+                       )
+                       ->will( $this->returnValue(
+                               $this->getFakeRow( [ 'wl_notificationtimestamp' => '30151212010101' ] )
+                       ) );
+
+               $mockCache = $this->getMockCache();
+               $mockDb->expects( $this->never() )
+                       ->method( 'get' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'set' );
+               $mockDb->expects( $this->never() )
+                       ->method( 'delete' );
+
+               $store = $this->newWatchedItemStore(
+                       $this->getMockLoadBalancer( $mockDb ),
+                       $mockCache
+               );
+
+               $addUpdateCallCounter = 0;
+               $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
+                       function( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
+                               $addUpdateCallCounter++;
+                               $this->verifyCallbackJob(
+                                       $callable,
+                                       $title,
+                                       $user->getId(),
+                                       function( $time ) {
+                                               return $time === false;
+                                       }
+                               );
+                       }
+               );
+
+               $getTimestampCallCounter = 0;
+               $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
+                       function( $titleParam, $oldidParam ) use ( &$getTimestampCallCounter, $title, $oldid ) {
+                               $getTimestampCallCounter++;
+                               $this->assertEquals( $title, $titleParam );
+                               $this->assertEquals( $oldid, $oldidParam );
+                       }
+               );
+
+               $this->assertTrue(
+                       $store->resetNotificationTimestamp(
+                               $user,
+                               $title,
+                               '',
+                               $oldid
+                       )
+               );
+               $this->assertEquals( 1, $addUpdateCallCounter );
+               $this->assertEquals( 1, $getTimestampCallCounter );
+
+               ScopedCallback::consume( $scopedOverrideDeferred );
+               ScopedCallback::consume( $scopedOverrideRevision );
+       }
+
        public function testUpdateNotificationTimestamp_watchersExist() {
                $mockDb = $this->getMockDb();
                $mockDb->expects( $this->once() )
index c33ba7e..0182eb7 100644 (file)
@@ -6,13 +6,30 @@ use MediaWiki\Linker\LinkTarget;
  *
  * @covers WatchedItem
  */
-class WatchedItemUnitTest extends PHPUnit_Framework_TestCase {
+class WatchedItemUnitTest extends MediaWikiTestCase {
+
+       /**
+        * @param int $id
+        *
+        * @return PHPUnit_Framework_MockObject_MockObject|User
+        */
+       private function getMockUser( $id ) {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->any() )
+                       ->method( 'getId' )
+                       ->will( $this->returnValue( $id ) );
+               $user->expects( $this->any() )
+                       ->method( 'isAllowed' )
+                       ->will( $this->returnValue( true ) );
+               return $user;
+       }
 
        public function provideUserTitleTimestamp() {
+               $user = $this->getMockUser( 111 );
                return [
-                       [ User::newFromId( 111 ), Title::newFromText( 'SomeTitle' ), null ],
-                       [ User::newFromId( 111 ), Title::newFromText( 'SomeTitle' ), '20150101010101' ],
-                       [ User::newFromId( 111 ), new TitleValue( 0, 'TVTitle', 'frag' ), '20150101010101' ],
+                       [ $user, Title::newFromText( 'SomeTitle' ), null ],
+                       [ $user, Title::newFromText( 'SomeTitle' ), '20150101010101' ],
+                       [ $user, new TitleValue( 0, 'TVTitle', 'frag' ), '20150101010101' ],
                ];
        }
 
@@ -52,15 +69,13 @@ class WatchedItemUnitTest extends PHPUnit_Framework_TestCase {
                        ->method( 'loadWatchedItem' )
                        ->with( $user, $linkTarget )
                        ->will( $this->returnValue( new WatchedItem( $user, $linkTarget, $timestamp ) ) );
-               $scopedOverride = WatchedItemStore::overrideDefaultInstance( $store );
+               $this->setService( 'WatchedItemStore', $store );
 
                $item = WatchedItem::fromUserTitle( $user, $linkTarget, User::IGNORE_USER_RIGHTS );
 
                $this->assertEquals( $user, $item->getUser() );
                $this->assertEquals( $linkTarget, $item->getLinkTarget() );
                $this->assertEquals( $timestamp, $item->getNotificationTimestamp() );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        /**
@@ -86,12 +101,10 @@ class WatchedItemUnitTest extends PHPUnit_Framework_TestCase {
                                        return true;
                                }
                        ) );
-               $scopedOverride = WatchedItemStore::overrideDefaultInstance( $store );
+               $this->setService( 'WatchedItemStore', $store );
 
                $item = new WatchedItem( $user, $linkTarget, $timestamp );
                $item->resetNotificationTimestamp( $force, $oldid );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        public function testAddWatch() {
@@ -158,17 +171,15 @@ class WatchedItemUnitTest extends PHPUnit_Framework_TestCase {
                $store->expects( $this->once() )
                        ->method( 'duplicateAllAssociatedEntries' )
                        ->with( $oldTitle, $newTitle );
-               $scopedOverride = WatchedItemStore::overrideDefaultInstance( $store );
+               $this->setService( 'WatchedItemStore', $store );
 
                WatchedItem::duplicateEntries( $oldTitle, $newTitle );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        public function testBatchAddWatch() {
-               $itemOne = new WatchedItem( User::newFromId( 1 ), new TitleValue( 0, 'Title1' ), null );
+               $itemOne = new WatchedItem( $this->getMockUser( 1 ), new TitleValue( 0, 'Title1' ), null );
                $itemTwo = new WatchedItem(
-                       User::newFromId( 3 ),
+                       $this->getMockUser( 3 ),
                        Title::newFromText( 'Title2' ),
                        '20150101010101'
                );
@@ -194,11 +205,9 @@ class WatchedItemUnitTest extends PHPUnit_Framework_TestCase {
                                        $itemTwo->getTitle()->getTalkPage(),
                                ]
                        );
-               $scopedOverride = WatchedItemStore::overrideDefaultInstance( $store );
+               $this->setService( 'WatchedItemStore', $store );
 
                WatchedItem::batchAddWatch( [ $itemOne, $itemTwo ] );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
 }
diff --git a/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php b/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php
new file mode 100644 (file)
index 0000000..f1f9295
--- /dev/null
@@ -0,0 +1,1592 @@
+<?php
+
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ *
+ * @covers ApiQueryWatchlist
+ */
+class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
+
+       public function __construct( $name = null, array $data = [], $dataName = '' ) {
+               parent::__construct( $name, $data, $dataName );
+               $this->tablesUsed = array_unique(
+                       array_merge( $this->tablesUsed, [ 'watchlist', 'recentchanges', 'page' ] )
+               );
+       }
+
+       protected function setUp() {
+               parent::setUp();
+               self::$users['ApiQueryWatchlistIntegrationTestUser']
+                       = new TestUser( 'ApiQueryWatchlistIntegrationTestUser' );
+               self::$users['ApiQueryWatchlistIntegrationTestUser2']
+                       = new TestUser( 'ApiQueryWatchlistIntegrationTestUser2' );
+               $this->doLogin( 'ApiQueryWatchlistIntegrationTestUser' );
+       }
+
+       private function getTestUser() {
+               return self::$users['ApiQueryWatchlistIntegrationTestUser']->getUser();
+       }
+
+       private function getNonLoggedInTestUser() {
+               return self::$users['ApiQueryWatchlistIntegrationTestUser2']->getUser();
+       }
+
+       private function getSysopTestUser() {
+               return self::$users['sysop']->getUser();
+       }
+
+       private function doPageEdit( User $user, LinkTarget $target, $content, $summary ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $page->doEditContent(
+                       ContentHandler::makeContent( $content, $title ),
+                       $summary,
+                       0,
+                       false,
+                       $user
+               );
+       }
+
+       private function doMinorPageEdit( User $user, LinkTarget $target, $content, $summary ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $page->doEditContent(
+                       ContentHandler::makeContent( $content, $title ),
+                       $summary,
+                       EDIT_MINOR,
+                       false,
+                       $user
+               );
+       }
+
+       private function doBotPageEdit( User $user, LinkTarget $target, $content, $summary ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $page->doEditContent(
+                       ContentHandler::makeContent( $content, $title ),
+                       $summary,
+                       EDIT_FORCE_BOT,
+                       false,
+                       $user
+               );
+       }
+
+       private function doAnonPageEdit( LinkTarget $target, $content, $summary ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $page->doEditContent(
+                       ContentHandler::makeContent( $content, $title ),
+                       $summary,
+                       0,
+                       false,
+                       User::newFromId( 0 )
+               );
+       }
+
+       private function doPatrolledPageEdit(
+               User $user,
+               LinkTarget $target,
+               $content,
+               $summary,
+               User $patrollingUser
+       ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $status = $page->doEditContent(
+                       ContentHandler::makeContent( $content, $title ),
+                       $summary,
+                       0,
+                       false,
+                       $user
+               );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+               $rc = $rev->getRecentChange();
+               $rc->doMarkPatrolled( $patrollingUser, false, [] );
+       }
+
+       private function deletePage( LinkTarget $target, $reason ) {
+               $title = Title::newFromLinkTarget( $target );
+               $page = WikiPage::factory( $title );
+               $page->doDeleteArticleReal( $reason );
+       }
+
+       /**
+        * Performs a batch of page edits as a specified user
+        * @param User $user
+        * @param array $editData associative array, keys:
+        *                        - target    => LinkTarget page to edit
+        *                        - content   => string new content
+        *                        - summary   => string edit summary
+        *                        - minorEdit => bool mark as minor edit if true (defaults to false)
+        *                        - botEdit   => bool mark as bot edit if true (defaults to false)
+        */
+       private function doPageEdits( User $user, array $editData ) {
+               foreach ( $editData as $singleEditData ) {
+                       if ( array_key_exists( 'minorEdit', $singleEditData ) && $singleEditData['minorEdit'] ) {
+                               $this->doMinorPageEdit(
+                                       $user,
+                                       $singleEditData['target'],
+                                       $singleEditData['content'],
+                                       $singleEditData['summary']
+                               );
+                               continue;
+                       }
+                       if ( array_key_exists( 'botEdit', $singleEditData ) && $singleEditData['botEdit'] ) {
+                               $this->doBotPageEdit(
+                                       $user,
+                                       $singleEditData['target'],
+                                       $singleEditData['content'],
+                                       $singleEditData['summary']
+                               );
+                               continue;
+                       }
+                       $this->doPageEdit(
+                               $user,
+                               $singleEditData['target'],
+                               $singleEditData['content'],
+                               $singleEditData['summary']
+                       );
+               }
+       }
+
+       private function getWatchedItemStore() {
+               return MediaWikiServices::getInstance()->getWatchedItemStore();
+       }
+
+       /**
+        * @param User $user
+        * @param LinkTarget[] $targets
+        */
+       private function watchPages( User $user, array $targets ) {
+               $store = $this->getWatchedItemStore();
+               $store->addWatchBatchForUser( $user, $targets );
+       }
+
+       private function doListWatchlistRequest( array $params = [], $user = null ) {
+               return $this->doApiRequest(
+                       array_merge(
+                               [ 'action' => 'query', 'list' => 'watchlist' ],
+                               $params
+                       ), null, false, $user
+               );
+       }
+
+       private function doGeneratorWatchlistRequest( array $params = [] ) {
+               return $this->doApiRequest(
+                       array_merge(
+                               [ 'action' => 'query', 'generator' => 'watchlist' ],
+                               $params
+                       )
+               );
+       }
+
+       private function getItemsFromApiResponse( array $response ) {
+               return $response[0]['query']['watchlist'];
+       }
+
+       /**
+        * Convenience method to assert that actual items array fetched from API is equal to the expected
+        * array, Unlike assertEquals this only checks if values of specified keys are equal in both
+        * arrays. This could be used e.g. not to compare IDs that could change between test run
+        * but only stable keys.
+        * Optionally this also checks that specified keys are present in the actual item without
+        * performing any checks on the related values.
+        *
+        * @param array $actualItems               array of actual items (associative arrays)
+        * @param array $expectedItems             array of expected items (associative arrays),
+        *                                         those items have less keys than actual items
+        * @param array $keysUsedInValueComparison list of keys of the actual item that will be used
+        *                                         in the comparison of values
+        * @param array $requiredKeys              optional, list of keys that must be present in the
+        *                                         actual items. Values of those keys are not checked.
+        */
+       private function assertArraySubsetsEqual(
+               array $actualItems,
+               array $expectedItems,
+               array $keysUsedInValueComparison,
+               array $requiredKeys = []
+       ) {
+               $this->assertCount( count( $expectedItems ), $actualItems );
+
+               // not checking values of all keys of the actual item, so removing unwanted keys from comparison
+               $actualItemsOnlyComparedValues = array_map(
+                       function( array $item ) use ( $keysUsedInValueComparison ) {
+                               return array_intersect_key( $item, array_flip( $keysUsedInValueComparison ) );
+                       },
+                       $actualItems
+               );
+
+               $this->assertEquals(
+                       $expectedItems,
+                       $actualItemsOnlyComparedValues
+               );
+
+               // Check that each item in $actualItems contains all of keys specified in $requiredKeys
+               $actualItemsKeysOnly = array_map( 'array_keys', $actualItems );
+               foreach ( $actualItemsKeysOnly as $keysOfTheItem ) {
+                       $this->assertEmpty( array_diff( $requiredKeys, $keysOfTheItem ) );
+               }
+       }
+
+       private function getTitleFormatter() {
+               return new MediaWikiTitleCodec( Language::factory( 'en' ), GenderCache::singleton() );
+       }
+
+       private function getPrefixedText( LinkTarget $target ) {
+               $formatter = $this->getTitleFormatter();
+               return $formatter->getPrefixedText( $target );
+       }
+
+       private function cleanTestUsersWatchlist() {
+               $user = $this->getTestUser();
+               $store = $this->getWatchedItemStore();
+               $items = $store->getWatchedItemsForUser( $user );
+               foreach ( $items as $item ) {
+                       $store->removeWatch( $user, $item->getLinkTarget() );
+               }
+       }
+
+       public function testListWatchlist_returnsWatchedItemsWithRCInfo() {
+               // Clean up after previous tests that might have added something to the watchlist of
+               // the user with the same user ID as user used here as the test user
+               $this->cleanTestUsersWatchlist();
+
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest();
+
+               $this->assertArrayHasKey( 'query', $result[0] );
+               $this->assertArrayHasKey( 'watchlist', $result[0]['query'] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $result ),
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                                       'bot' => false,
+                                       'new' => true,
+                                       'minor' => false,
+                               ]
+                       ],
+                       [ 'type', 'ns', 'title', 'bot', 'new', 'minor' ],
+                       [ 'pageid', 'revid', 'old_revid' ]
+               );
+       }
+
+       public function testIdsPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'ids', ] );
+               $items = $this->getItemsFromApiResponse( $result );
+
+               $this->assertCount( 1, $items );
+               $this->assertArrayHasKey( 'pageid', $items[0] );
+               $this->assertArrayHasKey( 'revid', $items[0] );
+               $this->assertArrayHasKey( 'old_revid', $items[0] );
+               $this->assertEquals( 'new', $items[0]['type'] );
+       }
+
+       public function testTitlePropParameter() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $talkTarget,
+                                       'content' => 'Some Talk Page Content',
+                                       'summary' => 'Create Talk page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget ),
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testFlagsPropParameter() {
+               $user = $this->getTestUser();
+               $normalEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $minorEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageM' );
+               $botEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageB' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $normalEditTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $minorEditTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $minorEditTarget,
+                                       'content' => 'Slightly Better Content',
+                                       'summary' => 'Change content',
+                                       'minorEdit' => true,
+                               ],
+                               [
+                                       'target' => $botEditTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page with a bot',
+                                       'botEdit' => true,
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $normalEditTarget, $minorEditTarget, $botEditTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'flags', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'new' => true,
+                                       'minor' => false,
+                                       'bot' => true,
+                               ],
+                               [
+                                       'type' => 'edit',
+                                       'new' => false,
+                                       'minor' => true,
+                                       'bot' => false,
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'new' => true,
+                                       'minor' => false,
+                                       'bot' => false,
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testUserPropParameter() {
+               $user = $this->getTestUser();
+               $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
+               $this->doPageEdit(
+                       $user,
+                       $userEditTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doAnonPageEdit(
+                       $anonEditTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'user', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'anon' => true,
+                                       'user' => User::newFromId( 0 )->getName(),
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'user' => $user->getName(),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testUserIdPropParameter() {
+               $user = $this->getTestUser();
+               $userEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $anonEditTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPageA' );
+               $this->doPageEdit(
+                       $user,
+                       $userEditTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doAnonPageEdit(
+                       $anonEditTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $userEditTarget, $anonEditTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'userid', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'anon' => true,
+                                       'user' => 0,
+                                       'userid' => 0,
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'user' => $user->getId(),
+                                       'userid' => $user->getId(),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testCommentPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the <b>page</b>'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'comment', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'comment' => 'Create the <b>page</b>',
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testParsedCommentPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the <b>page</b>'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'parsedcomment', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'parsedcomment' => 'Create the &lt;b&gt;page&lt;/b&gt;',
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testTimestampPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'timestamp', ] );
+               $items = $this->getItemsFromApiResponse( $result );
+
+               $this->assertCount( 1, $items );
+               $this->assertArrayHasKey( 'timestamp', $items[0] );
+               $this->assertInternalType( 'string', $items[0]['timestamp'] );
+       }
+
+       public function testSizesPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'sizes', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'oldlen' => 0,
+                                       'newlen' => 12,
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testNotificationTimestampPropParameter() {
+               $otherUser = $this->getNonLoggedInTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $otherUser,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $store = $this->getWatchedItemStore();
+               $store->addWatch( $this->getTestUser(), $target );
+               $store->updateNotificationTimestamp(
+                       $otherUser,
+                       $target,
+                       '20151212010101'
+               );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'notificationtimestamp', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'notificationtimestamp' => '2015-12-12T01:01:01Z',
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       private function setupPatrolledSpecificFixtures( User $user ) {
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+
+               $this->doPatrolledPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page (this gets patrolled)',
+                       $user
+               );
+
+               $this->watchPages( $user, [ $target ] );
+       }
+
+       public function testPatrolPropParameter() {
+               $user = $this->getSysopTestUser();
+               $this->setupPatrolledSpecificFixtures( $user );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'patrol', ], $user );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'patrolled' => true,
+                                       'unpatrolled' => false,
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       private function createPageAndDeleteIt( LinkTarget $target ) {
+               $this->doPageEdit(
+                       $this->getTestUser(),
+                       $target,
+                       'Some Content',
+                       'Create the page that will be deleted'
+               );
+               $this->deletePage( $target, 'Important Reason' );
+       }
+
+       public function testLoginfoPropParameter() {
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->createPageAndDeleteIt( $target );
+
+               $this->watchPages( $this->getTestUser(), [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'loginfo', ] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $result ),
+                       [
+                               [
+                                       'type' => 'log',
+                                       'logtype' => 'delete',
+                                       'logaction' => 'delete',
+                                       'logparams' => [],
+                               ],
+                       ],
+                       [ 'type', 'logtype', 'logaction', 'logparams' ],
+                       [ 'logid' ]
+               );
+       }
+
+       public function testEmptyPropParameter() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => '', ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testNamespaceParam() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $talkTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the talk page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlnamespace' => '0', ] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $result ),
+                       [
+                               [
+                                       'ns' => 0,
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                               ],
+                       ],
+                       [ 'ns', 'title' ]
+               );
+       }
+
+       public function testUserParam() {
+               $user = $this->getTestUser();
+               $otherUser = $this->getNonLoggedInTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $subjectTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doPageEdit(
+                       $otherUser,
+                       $talkTarget,
+                       'What is this page about?',
+                       'Create the talk page'
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [
+                       'wlprop' => 'user|title',
+                       'wluser' => $otherUser->getName(),
+               ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget ),
+                                       'user' => $otherUser->getName(),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testExcludeUserParam() {
+               $user = $this->getTestUser();
+               $otherUser = $this->getNonLoggedInTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $subjectTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doPageEdit(
+                       $otherUser,
+                       $talkTarget,
+                       'What is this page about?',
+                       'Create the talk page'
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [
+                       'wlprop' => 'user|title',
+                       'wlexcludeuser' => $otherUser->getName(),
+               ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                                       'user' => $user->getName(),
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testShowMinorParams() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $target,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $target,
+                                       'content' => 'Slightly Better Content',
+                                       'summary' => 'Change content',
+                                       'minorEdit' => true,
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $resultMinor = $this->doListWatchlistRequest( [ 'wlshow' => 'minor', 'wlprop' => 'flags' ] );
+               $resultNotMinor = $this->doListWatchlistRequest( [ 'wlshow' => '!minor', 'wlprop' => 'flags' ] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $resultMinor ),
+                       [
+                               [ 'minor' => true, ]
+                       ],
+                       [ 'minor' ]
+               );
+               $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotMinor ) );
+       }
+
+       public function testShowBotParams() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doBotPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $resultBot = $this->doListWatchlistRequest( [ 'wlshow' => 'bot' ] );
+               $resultNotBot = $this->doListWatchlistRequest( [ 'wlshow' => '!bot' ] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $resultBot ),
+                       [
+                               [ 'bot' => true ],
+                       ],
+                       [ 'bot' ]
+               );
+               $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotBot ) );
+       }
+
+       public function testShowAnonParams() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doAnonPageEdit(
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $resultAnon = $this->doListWatchlistRequest( [
+                       'wlprop' => 'user',
+                       'wlshow' => 'anon'
+               ] );
+               $resultNotAnon = $this->doListWatchlistRequest( [
+                       'wlprop' => 'user',
+                       'wlshow' => '!anon'
+               ] );
+
+               $this->assertArraySubsetsEqual(
+                       $this->getItemsFromApiResponse( $resultAnon ),
+                       [
+                               [ 'anon' => true ],
+                       ],
+                       [ 'anon' ]
+               );
+               $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotAnon ) );
+       }
+
+       public function testShowUnreadParams() {
+               $user = $this->getTestUser();
+               $otherUser = $this->getNonLoggedInTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $subjectTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doPageEdit(
+                       $otherUser,
+                       $talkTarget,
+                       'Some Content',
+                       'Create the talk page'
+               );
+               $store = $this->getWatchedItemStore();
+               $store->addWatchBatchForUser( $user, [ $subjectTarget, $talkTarget ] );
+               $store->updateNotificationTimestamp(
+                       $otherUser,
+                       $talkTarget,
+                       '20151212010101'
+               );
+
+               $resultUnread = $this->doListWatchlistRequest( [
+                       'wlprop' => 'notificationtimestamp|title',
+                       'wlshow' => 'unread'
+               ] );
+               $resultNotUnread = $this->doListWatchlistRequest( [
+                       'wlprop' => 'notificationtimestamp|title',
+                       'wlshow' => '!unread'
+               ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'notificationtimestamp' => '2015-12-12T01:01:01Z',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget )
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $resultUnread )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'notificationtimestamp' => '',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget )
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $resultNotUnread )
+               );
+       }
+
+       public function testShowPatrolledParams() {
+               $user = $this->getSysopTestUser();
+               $this->setupPatrolledSpecificFixtures( $user );
+
+               $resultPatrolled = $this->doListWatchlistRequest( [
+                       'wlprop' => 'patrol',
+                       'wlshow' => 'patrolled'
+               ], $user );
+               $resultNotPatrolled = $this->doListWatchlistRequest( [
+                       'wlprop' => 'patrol',
+                       'wlshow' => '!patrolled'
+               ], $user );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'patrolled' => true,
+                                       'unpatrolled' => false,
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $resultPatrolled )
+               );
+               $this->assertEmpty( $this->getItemsFromApiResponse( $resultNotPatrolled ) );
+       }
+
+       public function testNewAndEditTypeParameters() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Other Content',
+                                       'summary' => 'Change the content',
+                               ],
+                               [
+                                       'target' => $talkTarget,
+                                       'content' => 'Some Talk Page Content',
+                                       'summary' => 'Create Talk page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $resultNew = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'new' ] );
+               $resultEdit = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'edit' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultNew )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'edit',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultEdit )
+               );
+       }
+
+       public function testLogTypeParameters() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->createPageAndDeleteIt( $subjectTarget );
+               $this->doPageEdit(
+                       $user,
+                       $talkTarget,
+                       'Some Talk Page Content',
+                       'Create Talk page'
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'log' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'log',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       private function getExternalRC( LinkTarget $target ) {
+               $title = Title::newFromLinkTarget( $target );
+
+               $rc = new RecentChange;
+               $rc->mTitle = $title;
+               $rc->mAttribs = [
+                       'rc_timestamp' => wfTimestamp( TS_MW ),
+                       'rc_namespace' => $title->getNamespace(),
+                       'rc_title' => $title->getDBkey(),
+                       'rc_type' => RC_EXTERNAL,
+                       'rc_source' => 'foo',
+                       'rc_minor' => 0,
+                       'rc_cur_id' => $title->getArticleID(),
+                       'rc_user' => 0,
+                       'rc_user_text' => 'External User',
+                       'rc_comment' => '',
+                       'rc_this_oldid' => $title->getLatestRevID(),
+                       'rc_last_oldid' => $title->getLatestRevID(),
+                       'rc_bot' => 0,
+                       'rc_ip' => '',
+                       'rc_patrolled' => 0,
+                       'rc_new' => 0,
+                       'rc_old_len' => $title->getLength(),
+                       'rc_new_len' => $title->getLength(),
+                       'rc_deleted' => 0,
+                       'rc_logid' => 0,
+                       'rc_log_type' => null,
+                       'rc_log_action' => '',
+                       'rc_params' => '',
+               ];
+               $rc->mExtra = [
+                       'prefixedDBkey' => $title->getPrefixedDBkey(),
+                       'lastTimestamp' => 0,
+                       'oldSize' => $title->getLength(),
+                       'newSize' => $title->getLength(),
+                       'pageStatus' => 'changed'
+               ];
+
+               return $rc;
+       }
+
+       public function testExternalTypeParameters() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $subjectTarget,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->doPageEdit(
+                       $user,
+                       $talkTarget,
+                       'Some Talk Page Content',
+                       'Create Talk page'
+               );
+
+               $rc = $this->getExternalRC( $subjectTarget );
+               $rc->save();
+
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'external' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'external',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testCategorizeTypeParameter() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $categoryTarget = new TitleValue( NS_CATEGORY, 'ApiQueryWatchlistIntegrationTestCategory' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $categoryTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the category',
+                               ],
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Content [[Category:ApiQueryWatchlistIntegrationTestCategory]]t',
+                                       'summary' => 'Create the page and add it to the category',
+                               ],
+                       ]
+               );
+               $title = Title::newFromLinkTarget( $subjectTarget );
+               $revision = Revision::newFromTitle( $title );
+
+               $rc = RecentChange::newForCategorization(
+                       $revision->getTimestamp(),
+                       Title::newFromLinkTarget( $categoryTarget ),
+                       $user,
+                       $revision->getComment(),
+                       $title,
+                       0,
+                       $revision->getId(),
+                       null,
+                       false
+               );
+               $rc->save();
+
+               $this->watchPages( $user, [ $subjectTarget, $categoryTarget ] );
+
+               $result = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wltype' => 'categorize' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'categorize',
+                                       'ns' => $categoryTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $categoryTarget ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testLimitParam() {
+               $user = $this->getTestUser();
+               $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $target1,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $target2,
+                                       'content' => 'Some Talk Page Content',
+                                       'summary' => 'Create Talk page',
+                               ],
+                               [
+                                       'target' => $target3,
+                                       'content' => 'Some Other Content',
+                                       'summary' => 'Create the page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $target1, $target2, $target3 ] );
+
+               $resultWithoutLimit = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
+               $resultWithLimit = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target3->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target3 )
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target2->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target2 )
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target1->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target1 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultWithoutLimit )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target3->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target3 )
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target2->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target2 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultWithLimit )
+               );
+               $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
+               $this->assertArrayHasKey( 'wlcontinue', $resultWithLimit[0]['continue'] );
+       }
+
+       public function testAllRevParam() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $target,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $target,
+                                       'content' => 'Some Other Content',
+                                       'summary' => 'Change the content',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $resultAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title', 'wlallrev' => '', ] );
+               $resultNoAllRev = $this->doListWatchlistRequest( [ 'wlprop' => 'title' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'edit',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultNoAllRev )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'edit',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultAllRev )
+               );
+       }
+
+       public function testDirParams() {
+               $user = $this->getTestUser();
+               $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $subjectTarget,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $talkTarget,
+                                       'content' => 'Some Talk Page Content',
+                                       'summary' => 'Create Talk page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $subjectTarget, $talkTarget ] );
+
+               $resultDirOlder = $this->doListWatchlistRequest( [ 'wldir' => 'older', 'wlprop' => 'title' ] );
+               $resultDirNewer = $this->doListWatchlistRequest( [ 'wldir' => 'newer', 'wlprop' => 'title' ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget )
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultDirOlder )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $subjectTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $subjectTarget )
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $talkTarget->getNamespace(),
+                                       'title' => $this->getPrefixedText( $talkTarget )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $resultDirNewer )
+               );
+       }
+
+       public function testStartEndParams() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $resultStart = $this->doListWatchlistRequest( [
+                       'wlstart' => '20010115000000',
+                       'wldir' => 'newer',
+                       'wlprop' => 'title',
+               ] );
+               $resultEnd = $this->doListWatchlistRequest( [
+                       'wlend' => '20010115000000',
+                       'wldir' => 'newer',
+                       'wlprop' => 'title',
+               ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $resultStart )
+               );
+               $this->assertEmpty( $this->getItemsFromApiResponse( $resultEnd ) );
+       }
+
+       public function testContinueParam() {
+               $user = $this->getTestUser();
+               $target1 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $target2 = new TitleValue( 1, 'ApiQueryWatchlistIntegrationTestPage' );
+               $target3 = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage2' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $target1,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $target2,
+                                       'content' => 'Some Talk Page Content',
+                                       'summary' => 'Create Talk page',
+                               ],
+                               [
+                                       'target' => $target3,
+                                       'content' => 'Some Other Content',
+                                       'summary' => 'Create the page',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $target1, $target2, $target3 ] );
+
+               $firstResult = $this->doListWatchlistRequest( [ 'wllimit' => 2, 'wlprop' => 'title' ] );
+               $this->assertArrayHasKey( 'continue', $firstResult[0] );
+               $this->assertArrayHasKey( 'wlcontinue', $firstResult[0]['continue'] );
+
+               $continuationParam = $firstResult[0]['continue']['wlcontinue'];
+
+               $continuedResult = $this->doListWatchlistRequest(
+                       [ 'wlcontinue' => $continuationParam, 'wlprop' => 'title' ]
+               );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target3->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target3 ),
+                               ],
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target2->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target2 ),
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $firstResult )
+               );
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target1->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target1 )
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $continuedResult )
+               );
+       }
+
+       public function testOwnerAndTokenParams() {
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $this->getTestUser(),
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+
+               $otherUser = $this->getNonLoggedInTestUser();
+               $otherUser->setOption( 'watchlisttoken', '1234567890' );
+               $otherUser->saveSettings();
+
+               $this->watchPages( $otherUser, [ $target ] );
+
+               $result = $this->doListWatchlistRequest( [
+                       'wlowner' => $otherUser->getName(),
+                       'wltoken' => '1234567890',
+                       'wlprop' => 'title',
+               ] );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target )
+                               ]
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+       }
+
+       public function testOwnerAndTokenParams_wrongToken() {
+               $otherUser = $this->getNonLoggedInTestUser();
+               $otherUser->setOption( 'watchlisttoken', '1234567890' );
+               $otherUser->saveSettings();
+
+               $this->setExpectedException( UsageException::class, 'Incorrect watchlist token provided' );
+
+               $this->doListWatchlistRequest( [
+                       'wlowner' => $otherUser->getName(),
+                       'wltoken' => 'wrong-token',
+               ] );
+       }
+
+       public function testOwnerAndTokenParams_noWatchlistTokenSet() {
+               $this->setExpectedException( UsageException::class, 'Incorrect watchlist token provided' );
+
+               $this->doListWatchlistRequest( [
+                       'wlowner' => $this->getNonLoggedInTestUser()->getName(),
+                       'wltoken' => 'some-token',
+               ] );
+       }
+
+       public function testGeneratorWatchlistPropInfo_returnsWatchedPages() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdit(
+                       $user,
+                       $target,
+                       'Some Content',
+                       'Create the page'
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'info' ] );
+
+               $this->assertArrayHasKey( 'query', $result[0] );
+               $this->assertArrayHasKey( 'pages', $result[0]['query'] );
+
+               // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
+               $pages = array_values( $result[0]['query']['pages'] );
+
+               $this->assertArraySubsetsEqual(
+                       $pages,
+                       [
+                               [
+                                       'ns' => $target->getNamespace(),
+                                       'title' => $this->getPrefixedText( $target ),
+                                       'new' => true,
+                               ]
+                       ],
+                       [ 'ns', 'title', 'new' ]
+               );
+       }
+
+       public function testGeneratorWatchlistPropRevisions_returnsWatchedItemsRevisions() {
+               $user = $this->getTestUser();
+               $target = new TitleValue( 0, 'ApiQueryWatchlistIntegrationTestPage' );
+               $this->doPageEdits(
+                       $user,
+                       [
+                               [
+                                       'target' => $target,
+                                       'content' => 'Some Content',
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $target,
+                                       'content' => 'Some Other Content',
+                                       'summary' => 'Change the content',
+                               ],
+                       ]
+               );
+               $this->watchPages( $user, [ $target ] );
+
+               $result = $this->doGeneratorWatchlistRequest( [ 'prop' => 'revisions', 'gwlallrev' => '' ] );
+
+               $this->assertArrayHasKey( 'query', $result[0] );
+               $this->assertArrayHasKey( 'pages', $result[0]['query'] );
+
+               // $result[0]['query']['pages'] uses page ids as keys. Page ids don't matter here, so drop them
+               $pages = array_values( $result[0]['query']['pages'] );
+
+               $this->assertCount( 1, $pages );
+               $this->assertEquals( 0, $pages[0]['ns'] );
+               $this->assertEquals( $this->getPrefixedText( $target ), $pages[0]['title'] );
+               $this->assertArraySubsetsEqual(
+                       $pages[0]['revisions'],
+                       [
+                               [
+                                       'comment' => 'Create the page',
+                                       'user' => $user->getName(),
+                                       'minor' => false,
+                               ],
+                               [
+                                       'comment' => 'Change the content',
+                                       'user' => $user->getName(),
+                                       'minor' => false,
+                               ],
+                       ],
+                       [ 'comment', 'user', 'minor' ]
+               );
+       }
+
+}
index 2efc802..45f1382 100644 (file)
@@ -161,7 +161,7 @@ class RecentChangeTest extends MediaWikiTestCase {
                $pageProps->expects( $this->once() )
                        ->method( 'getProperties' )
                        ->with( $categoryTitle, 'hiddencat' )
-                       ->will( $this->returnValue( $isHidden ? [ $categoryTitle->getArticleID() => '' ] : [ ] ) );
+                       ->will( $this->returnValue( $isHidden ? [ $categoryTitle->getArticleID() => '' ] : [] ) );
 
                $scopedOverride = PageProps::overrideInstance( $pageProps );
 
index 2288507..2c1d1e6 100644 (file)
@@ -8,17 +8,71 @@ class ConfigFactoryTest extends MediaWikiTestCase {
        public function testRegister() {
                $factory = new ConfigFactory();
                $factory->register( 'unittest', 'GlobalVarConfig::newInstance' );
-               $this->assertTrue( true ); // No exception thrown
+               $this->assertInstanceOf( GlobalVarConfig::class, $factory->makeConfig( 'unittest' ) );
+       }
+
+       /**
+        * @covers ConfigFactory::register
+        */
+       public function testRegisterInvalid() {
+               $factory = new ConfigFactory();
                $this->setExpectedException( 'InvalidArgumentException' );
                $factory->register( 'invalid', 'Invalid callback' );
        }
 
+       /**
+        * @covers ConfigFactory::register
+        */
+       public function testRegisterInstance() {
+               $config = GlobalVarConfig::newInstance();
+               $factory = new ConfigFactory();
+               $factory->register( 'unittest', $config );
+               $this->assertSame( $config, $factory->makeConfig( 'unittest' ) );
+       }
+
+       /**
+        * @covers ConfigFactory::register
+        */
+       public function testRegisterAgain() {
+               $factory = new ConfigFactory();
+               $factory->register( 'unittest', 'GlobalVarConfig::newInstance' );
+               $config1 = $factory->makeConfig( 'unittest' );
+
+               $factory->register( 'unittest', 'GlobalVarConfig::newInstance' );
+               $config2 = $factory->makeConfig( 'unittest' );
+
+               $this->assertNotSame( $config1, $config2 );
+       }
+
+       /**
+        * @covers ConfigFactory::register
+        */
+       public function testGetConfigNames() {
+               $factory = new ConfigFactory();
+               $factory->register( 'foo', 'GlobalVarConfig::newInstance' );
+               $factory->register( 'bar', new HashConfig() );
+
+               $this->assertEquals( [ 'foo', 'bar' ], $factory->getConfigNames() );
+       }
+
        /**
         * @covers ConfigFactory::makeConfig
         */
        public function testMakeConfig() {
                $factory = new ConfigFactory();
                $factory->register( 'unittest', 'GlobalVarConfig::newInstance' );
+
+               $conf = $factory->makeConfig( 'unittest' );
+               $this->assertInstanceOf( 'Config', $conf );
+               $this->assertSame( $conf, $factory->makeConfig( 'unittest' ) );
+       }
+
+       /**
+        * @covers ConfigFactory::makeConfig
+        */
+       public function testMakeConfigFallback() {
+               $factory = new ConfigFactory();
+               $factory->register( '*', 'GlobalVarConfig::newInstance' );
                $conf = $factory->makeConfig( 'unittest' );
                $this->assertInstanceOf( 'Config', $conf );
        }
@@ -48,10 +102,10 @@ class ConfigFactoryTest extends MediaWikiTestCase {
         * @covers ConfigFactory::getDefaultInstance
         */
        public function testGetDefaultInstance() {
+               // NOTE: the global config factory returned here has been overwritten
+               // for operation in test mode. It may not reflect LocalSettings.
                $factory = ConfigFactory::getDefaultInstance();
                $this->assertInstanceOf( 'Config', $factory->makeConfig( 'main' ) );
-
-               $this->setExpectedException( 'ConfigException' );
-               $factory->makeConfig( 'xyzzy' );
        }
+
 }
index 90438a0..602a175 100644 (file)
@@ -20,13 +20,19 @@ class MockSearch extends SearchEngine {
  */
 class SearchUpdateTest extends MediaWikiTestCase {
 
+       /**
+        * @var SearchUpdate
+        */
+       private $su;
+
        protected function setUp() {
                parent::setUp();
                $this->setMwGlobals( 'wgSearchType', 'MockSearch' );
+               $this->su = new SearchUpdate( 0, "" );
        }
 
        public function updateText( $text ) {
-               return trim( SearchUpdate::updateText( $text ) );
+               return trim( $this->su->updateText( $text ) );
        }
 
        /**
diff --git a/tests/phpunit/includes/htmlform/HTMLFormTest.php b/tests/phpunit/includes/htmlform/HTMLFormTest.php
new file mode 100644 (file)
index 0000000..b7e0053
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+
+class HTMLFormTest extends MediaWikiTestCase {
+       public function testGetHTML_empty() {
+               $form = new HTMLForm( [] );
+               $form->setTitle( Title::newFromText( 'Foo' ) );
+               $form->prepareForm();
+               $html = $form->getHTML( false );
+               $this->assertRegExp( '/<form\b/', $html );
+       }
+
+       /**
+        * @expectedException LogicException
+        */
+       public function testGetHTML_noPrepare() {
+               $form = new HTMLForm( [] );
+               $form->setTitle( Title::newFromText( 'Foo' ) );
+               $form->getHTML( false );
+       }
+}
diff --git a/tests/phpunit/includes/interwiki/InterwikiTest.php b/tests/phpunit/includes/interwiki/InterwikiTest.php
new file mode 100644 (file)
index 0000000..411d6a3
--- /dev/null
@@ -0,0 +1,254 @@
+<?php
+/**
+ * @covers Interwiki
+ *
+ * @group MediaWiki
+ * @group Database
+ */
+class InterwikiTest extends MediaWikiTestCase {
+
+       public function testConstructor() {
+               $interwiki = new Interwiki(
+                       'xyz',
+                       'http://xyz.acme.test/wiki/$1',
+                       'http://xyz.acme.test/w/api.php',
+                       'xyzwiki',
+                       1,
+                       0
+               );
+
+               $this->setContentLang( 'qqx' );
+
+               $this->assertSame( '(interwiki-name-xyz)', $interwiki->getName() );
+               $this->assertSame( '(interwiki-desc-xyz)', $interwiki->getDescription() );
+               $this->assertSame( 'http://xyz.acme.test/w/api.php', $interwiki->getAPI() );
+               $this->assertSame( 'http://xyz.acme.test/wiki/$1', $interwiki->getURL() );
+               $this->assertSame( 'xyzwiki', $interwiki->getWikiID() );
+               $this->assertTrue( $interwiki->isLocal() );
+               $this->assertFalse( $interwiki->isTranscludable() );
+       }
+
+       public function testGetUrl() {
+               $interwiki = new Interwiki(
+                       'xyz',
+                       'http://xyz.acme.test/wiki/$1'
+               );
+
+               $this->assertSame( 'http://xyz.acme.test/wiki/$1', $interwiki->getURL() );
+               $this->assertSame( 'http://xyz.acme.test/wiki/Foo%26Bar', $interwiki->getURL( 'Foo&Bar' ) );
+       }
+
+       //// tests for static data access methods below ///////////////////////////////////////////////
+
+       private function populateDB( $iwrows ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'interwiki', '*', __METHOD__ );
+               $dbw->insert( 'interwiki', array_values( $iwrows ), __METHOD__ );
+               $this->tablesUsed[] = 'interwiki';
+       }
+
+       public function testDatabaseStorage() {
+               // NOTE: database setup is expensive, so we only do
+               //  it once and run all the tests in one go.
+               $dewiki = [
+                       'iw_prefix' => 'de',
+                       'iw_url' => 'http://de.wikipedia.org/wiki/',
+                       'iw_api' => 'http://de.wikipedia.org/w/api.php',
+                       'iw_wikiid' => 'dewiki',
+                       'iw_local' => 1,
+                       'iw_trans' => 0
+               ];
+
+               $zzwiki = [
+                       'iw_prefix' => 'zz',
+                       'iw_url' => 'http://zzwiki.org/wiki/',
+                       'iw_api' => 'http://zzwiki.org/w/api.php',
+                       'iw_wikiid' => 'zzwiki',
+                       'iw_local' => 0,
+                       'iw_trans' => 0
+               ];
+
+               $this->populateDB( [ $dewiki, $zzwiki ] );
+
+               Interwiki::resetLocalCache();
+               $this->setMwGlobals( 'wgInterwikiCache', false );
+
+               $this->assertEquals(
+                       [ $dewiki, $zzwiki ],
+                       Interwiki::getAllPrefixes(),
+                       'getAllPrefixes()'
+               );
+               $this->assertEquals(
+                       [ $dewiki ],
+                       Interwiki::getAllPrefixes( true ),
+                       'getAllPrefixes()'
+               );
+               $this->assertEquals(
+                       [ $zzwiki ],
+                       Interwiki::getAllPrefixes( false ),
+                       'getAllPrefixes()'
+               );
+
+               $this->assertTrue( Interwiki::isValidInterwiki( 'de' ), 'known prefix is valid' );
+               $this->assertFalse( Interwiki::isValidInterwiki( 'xyz' ), 'unknown prefix is valid' );
+
+               $this->assertNull( Interwiki::fetch( null ), 'no prefix' );
+               $this->assertFalse( Interwiki::fetch( 'xyz' ), 'unknown prefix' );
+
+               $interwiki = Interwiki::fetch( 'de' );
+               $this->assertInstanceOf( 'Interwiki', $interwiki );
+               $this->assertSame( $interwiki, Interwiki::fetch( 'de' ), 'in-process caching' );
+
+               $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( 'http://de.wikipedia.org/w/api.php', $interwiki->getAPI(), 'getAPI' );
+               $this->assertSame( 'dewiki', $interwiki->getWikiID(), 'getWikiID' );
+               $this->assertSame( true, $interwiki->isLocal(), 'isLocal' );
+               $this->assertSame( false, $interwiki->isTranscludable(), 'isTranscludable' );
+
+               Interwiki::invalidateCache( 'de' );
+               $this->assertNotSame( $interwiki, Interwiki::fetch( 'de' ), 'invalidate cache' );
+       }
+
+       /**
+        * @param string $thisSite
+        * @param string[] $local
+        * @param string[] $global
+        *
+        * @return string[]
+        */
+       private function populateHash( $thisSite, $local, $global ) {
+               $hash = [];
+               $hash[ '__sites:' . wfWikiID() ] = $thisSite;
+
+               $globals = [];
+               $locals = [];
+
+               foreach ( $local as $row ) {
+                       $prefix = $row['iw_prefix'];
+                       $data = $row['iw_local'] . ' ' . $row['iw_url'];
+                       $locals[] = $prefix;
+                       $hash[ "_{$thisSite}:{$prefix}" ] = $data;
+               }
+
+               foreach ( $global as $row ) {
+                       $prefix = $row['iw_prefix'];
+                       $data = $row['iw_local'] . ' ' . $row['iw_url'];
+                       $globals[] = $prefix;
+                       $hash[ "__global:{$prefix}" ] = $data;
+               }
+
+               $hash[ '__list:__global' ] = implode( ' ', $globals );
+               $hash[ '__list:_' . $thisSite ] = implode( ' ', $locals );
+
+               return $hash;
+       }
+
+       private function populateCDB( $thisSite, $local, $global ) {
+               $cdbFile = tempnam( wfTempDir(), 'MW-ClassicInterwikiLookupTest-' ) . '.cdb';
+               $cdb = CdbWriter::open( $cdbFile );
+
+               $hash = $this->populateHash( $thisSite, $local, $global );
+
+               foreach ( $hash as $key => $value ) {
+                       $cdb->set( $key, $value );
+               }
+
+               $cdb->close();
+               return $cdbFile;
+       }
+
+       public function testCDBStorage() {
+               // NOTE: CDB setup is expensive, so we only do
+               //  it once and run all the tests in one go.
+
+               $dewiki = [
+                       'iw_prefix' => 'de',
+                       'iw_url' => 'http://de.wikipedia.org/wiki/',
+                       'iw_local' => 1
+               ];
+
+               $zzwiki = [
+                       'iw_prefix' => 'zz',
+                       'iw_url' => 'http://zzwiki.org/wiki/',
+                       'iw_local' => 0
+               ];
+
+               $cdbFile = $this->populateCDB(
+                       'en',
+                       [ $dewiki ],
+                       [ $zzwiki ]
+               );
+
+               Interwiki::resetLocalCache();
+               $this->setMwGlobals( 'wgInterwikiCache', $cdbFile );
+
+               $this->assertEquals(
+                       [ $dewiki, $zzwiki ],
+                       Interwiki::getAllPrefixes(),
+                       'getAllPrefixes()'
+               );
+
+               $this->assertTrue( Interwiki::isValidInterwiki( 'de' ), 'known prefix is valid' );
+               $this->assertTrue( Interwiki::isValidInterwiki( 'zz' ), 'known prefix is valid' );
+
+               $interwiki = Interwiki::fetch( 'de' );
+               $this->assertInstanceOf( 'Interwiki', $interwiki );
+
+               $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( true, $interwiki->isLocal(), 'isLocal' );
+
+               $interwiki = Interwiki::fetch( 'zz' );
+               $this->assertInstanceOf( 'Interwiki', $interwiki );
+
+               $this->assertSame( 'http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( false, $interwiki->isLocal(), 'isLocal' );
+
+               // cleanup temp file
+               unlink( $cdbFile );
+       }
+
+       public function testArrayStorage() {
+               $dewiki = [
+                       'iw_prefix' => 'de',
+                       'iw_url' => 'http://de.wikipedia.org/wiki/',
+                       'iw_local' => 1
+               ];
+
+               $zzwiki = [
+                       'iw_prefix' => 'zz',
+                       'iw_url' => 'http://zzwiki.org/wiki/',
+                       'iw_local' => 0
+               ];
+
+               $cdbData = $this->populateHash(
+                       'en',
+                       [ $dewiki ],
+                       [ $zzwiki ]
+               );
+
+               Interwiki::resetLocalCache();
+               $this->setMwGlobals( 'wgInterwikiCache', $cdbData );
+
+               $this->assertEquals(
+                       [ $dewiki, $zzwiki ],
+                       Interwiki::getAllPrefixes(),
+                       'getAllPrefixes()'
+               );
+
+               $this->assertTrue( Interwiki::isValidInterwiki( 'de' ), 'known prefix is valid' );
+               $this->assertTrue( Interwiki::isValidInterwiki( 'zz' ), 'known prefix is valid' );
+
+               $interwiki = Interwiki::fetch( 'de' );
+               $this->assertInstanceOf( 'Interwiki', $interwiki );
+
+               $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( true, $interwiki->isLocal(), 'isLocal' );
+
+               $interwiki = Interwiki::fetch( 'zz' );
+               $this->assertInstanceOf( 'Interwiki', $interwiki );
+
+               $this->assertSame( 'http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( false, $interwiki->isLocal(), 'isLocal' );
+       }
+
+}
index f24b68b..aaa3ac4 100644 (file)
@@ -150,8 +150,8 @@ class GIFHandlerTest extends MediaWikiMediaTestCase {
        }
 
        /**
-        * @param $filename string
-        * @param $expectedLength float
+        * @param string $filename
+        * @param float $expectedLength
         * @dataProvider provideGetLength
         */
        public function testGetLength( $filename, $expectedLength ) {
diff --git a/tests/phpunit/includes/media/JpegPixelFormatTest.php b/tests/phpunit/includes/media/JpegPixelFormatTest.php
new file mode 100644 (file)
index 0000000..6815a62
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Tests related to JPEG chroma subsampling via $wgJpegPixelFormat setting.
+ *
+ * @group Media
+ * @group medium
+ *
+ * @todo covers tags
+ */
+class JpegPixelFormatTest extends MediaWikiMediaTestCase {
+
+       protected function setUp() {
+               parent::setUp();
+       }
+
+       /**
+        * Mark this test as creating thumbnail files.
+        */
+       protected function createsThumbnails() {
+               return true;
+       }
+
+       /**
+        *
+        * @dataProvider providePixelFormats
+        */
+       public function testPixelFormatRendering( $sourceFile, $pixelFormat, $samplingFactor ) {
+               global $wgUseImageMagick, $wgUseImageResize;
+               if ( !$wgUseImageMagick ) {
+                       $this->markTestSkipped( "This test is only applicable when using ImageMagick thumbnailing" );
+               }
+               if ( !$wgUseImageResize ) {
+                       $this->markTestSkipped( "This test is only applicable when using thumbnailing" );
+               }
+
+               $fmtStr = var_export( $pixelFormat, true );
+               $this->setMwGlobals( 'wgJpegPixelFormat', $pixelFormat );
+
+               $file = $this->dataFile( $sourceFile, 'image/jpeg' );
+
+               $params = [
+                       'width' => 320,
+               ];
+               $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
+               $this->assertTrue( !$thumb->isError(), "created JPEG thumbnail for pixel format $fmtStr" );
+
+               $path = $thumb->getLocalCopyPath();
+               $this->assertTrue( is_string( $path ), "path returned for JPEG thumbnail for $fmtStr" );
+
+               $cmd = [
+                       'identify',
+                       '-format',
+                       '%[jpeg:sampling-factor]',
+                       $path
+               ];
+               $retval = null;
+               $output = wfShellExec( $cmd, $retval );
+               $this->assertTrue( $retval === 0, "ImageMagick's identify command should return success" );
+
+               $expected = $samplingFactor;
+               $actual = trim( $output );
+               $this->assertEquals(
+                       $expected,
+                       trim( $output ),
+                       "IM identify expects JPEG chroma subsampling \"$expected\" for $fmtStr"
+               );
+       }
+
+       public static function providePixelFormats() {
+               return [
+                       // From 4:4:4 source file
+                       [
+                               'yuv444.jpg',
+                               false,
+                               '1x1,1x1,1x1'
+                       ],
+                       [
+                               'yuv444.jpg',
+                               'yuv444',
+                               '1x1,1x1,1x1'
+                       ],
+                       [
+                               'yuv444.jpg',
+                               'yuv422',
+                               '2x1,1x1,1x1'
+                       ],
+                       [
+                               'yuv444.jpg',
+                               'yuv420',
+                               '2x2,1x1,1x1'
+                       ],
+                       // From 4:2:0 source file
+                       [
+                               'yuv420.jpg',
+                               false,
+                               '2x2,1x1,1x1'
+                       ],
+                       [
+                               'yuv420.jpg',
+                               'yuv444',
+                               '1x1,1x1,1x1'
+                       ],
+                       [
+                               'yuv420.jpg',
+                               'yuv422',
+                               '2x1,1x1,1x1'
+                       ],
+                       [
+                               'yuv420.jpg',
+                               'yuv420',
+                               '2x2,1x1,1x1'
+                       ]
+               ];
+       }
+}
index 1eddaff..7a052f6 100644 (file)
@@ -53,9 +53,9 @@ class MediaHandlerTest extends MediaWikiTestCase {
         * out of parameters:
         * $width, $height, { $max => $expected, $max2 => $expected2, ... }
         *
-        * @param $width int
-        * @param $height int
-        * @param $tests array associative array of $max => $expected values
+        * @param int $width
+        * @param int $height
+        * @param array $tests associative array of $max => $expected values
         * @return array
         */
        private static function generateTestFitBoxWidthData( $width, $height, $tests ) {
index afc338e..32d54df 100644 (file)
@@ -139,8 +139,8 @@ class PNGHandlerTest extends MediaWikiMediaTestCase {
        }
 
        /**
-        * @param $filename string
-        * @param $expectedLength float
+        * @param string $filename
+        * @param float $expectedLength
         * @dataProvider provideGetLength
         */
        public function testGetLength( $filename, $expectedLength ) {
index d6e1d9e..9f4e1fa 100644 (file)
@@ -22,7 +22,7 @@ class WikiCategoryPageTest extends MediaWikiLangTestCase {
                $pageProps->expects( $this->once() )
                        ->method( 'getProperties' )
                        ->with( $title, 'hiddencat' )
-                       ->will( $this->returnValue( [ ] ) );
+                       ->will( $this->returnValue( [] ) );
 
                $scopedOverride = PageProps::overrideInstance( $pageProps );
 
@@ -50,7 +50,7 @@ class WikiCategoryPageTest extends MediaWikiLangTestCase {
                $pageProps->expects( $this->once() )
                        ->method( 'getProperties' )
                        ->with( $categoryTitle, 'hiddencat' )
-                       ->will( $this->returnValue( $isHidden ? [ $categoryTitle->getArticleID() => '' ] : [ ] ) );
+                       ->will( $this->returnValue( $isHidden ? [ $categoryTitle->getArticleID() => '' ] : [] ) );
 
                $scopedOverride = PageProps::overrideInstance( $pageProps );
 
index 22bb237..4c973e5 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 /**
  * Although marked as a stub, can work independently.
  *
@@ -179,6 +178,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
+               ParserTest::resetTitleServices();
        }
 
        protected function tearDown() {
index 15b47b4..d57ad04 100644 (file)
@@ -56,17 +56,26 @@ class PoolCounterTest extends MediaWikiTestCase {
 
                $keysWithTwoSlots = $keysWithFiveSlots = [];
                foreach ( range( 1, 100 ) as $i ) {
-                       $keysWithTwoSlots[] = $hashKeyIntoSlots->invoke( $poolCounter, 'key ' . $i, 2 );
-                       $keysWithFiveSlots[] = $hashKeyIntoSlots->invoke( $poolCounter, 'key ' . $i, 5 );
+                       $keysWithTwoSlots[] = $hashKeyIntoSlots->invoke( $poolCounter, 'test', 'key ' . $i, 2 );
+                       $keysWithFiveSlots[] = $hashKeyIntoSlots->invoke( $poolCounter, 'test', 'key ' . $i, 5 );
                }
 
-               $this->assertArrayEquals( range( 0, 1 ), array_unique( $keysWithTwoSlots ) );
-               $this->assertArrayEquals( range( 0, 4 ), array_unique( $keysWithFiveSlots ) );
+               $twoSlotKeys = [];
+               for ( $i = 0; $i <= 1; $i++ ) {
+                       $twoSlotKeys[] = "test:$i";
+               }
+               $fiveSlotKeys = [];
+               for ( $i = 0; $i <= 4; $i++ ) {
+                       $fiveSlotKeys[] = "test:$i";
+               }
+
+               $this->assertArrayEquals( $twoSlotKeys, array_unique( $keysWithTwoSlots ) );
+               $this->assertArrayEquals( $fiveSlotKeys, array_unique( $keysWithFiveSlots ) );
 
                // make sure it is deterministic
                $this->assertEquals(
-                       $hashKeyIntoSlots->invoke( $poolCounter, 'asdfgh', 1000 ),
-                       $hashKeyIntoSlots->invoke( $poolCounter, 'asdfgh', 1000 )
+                       $hashKeyIntoSlots->invoke( $poolCounter, 'test', 'asdfgh', 1000 ),
+                       $hashKeyIntoSlots->invoke( $poolCounter, 'test', 'asdfgh', 1000 )
                );
        }
 }
index 27c0c60..0120d79 100644 (file)
@@ -50,7 +50,7 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                                self::$default,
                                $merge,
                        ],
-                       // No current hooks, adding one for "FooBaz"
+                       // No current hooks, adding one for "FooBaz" in string format
                        [
                                [],
                                [ 'Hooks' => [ 'FooBaz' => 'FooBazCallback' ] ] + self::$default,
@@ -62,6 +62,12 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                                [ 'Hooks' => [ 'FooBaz' => 'FooBazCallback' ] ] + self::$default,
                                [ 'FooBaz' => [ 'PriorCallback', 'FooBazCallback' ] ] + $merge,
                        ],
+                       // No current hooks, adding one for "FooBaz" in verbose array format
+                       [
+                               [],
+                               [ 'Hooks' => [ 'FooBaz' => [ 'FooBazCallback' ] ] ] + self::$default,
+                               [ 'FooBaz' => [ 'FooBazCallback' ] ] + $merge,
+                       ],
                        // Hook for "BarBaz", adding one for "FooBaz"
                        [
                                [ 'BarBaz' => [ 'BarBazCallback' ] ],
index 6a3f95b..e0de588 100644 (file)
@@ -1,9 +1,12 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group Search
  * @group Database
  */
 class SearchEnginePrefixTest extends MediaWikiLangTestCase {
+       private $originalHandlers;
 
        /**
         * @var SearchEngine
@@ -45,9 +48,26 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                }
 
                // Avoid special pages from extensions interferring with the tests
-               $this->setMwGlobals( 'wgSpecialPages', [] );
-               $this->search = SearchEngine::create();
+               $this->setMwGlobals( [
+                       'wgSpecialPages' => [],
+                       'wgHooks' => [],
+               ] );
+
+               $this->search = MediaWikiServices::getInstance()->newSearchEngine();
                $this->search->setNamespaces( [] );
+
+               $this->originalHandlers = TestingAccessWrapper::newFromClass( 'Hooks' )->handlers;
+               TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = [];
+
+               SpecialPageFactory::resetList();
+       }
+
+       public function tearDown() {
+               parent::tearDown();
+
+               TestingAccessWrapper::newFromClass( 'Hooks' )->handlers = $this->originalHandlers;
+
+               SpecialPageFactory::resetList();
        }
 
        protected function searchProvision( array $results = null ) {
index ff22bfa..8f7b2a6 100644 (file)
@@ -103,6 +103,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $anonInfo, $info->getUserInfo() );
                $this->assertTrue( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertFalse( $info->wasPersisted() );
                $this->assertFalse( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -118,6 +119,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $unverifiedUserInfo, $info->getUserInfo() );
                $this->assertTrue( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertFalse( $info->wasPersisted() );
                $this->assertFalse( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -132,6 +134,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $userInfo, $info->getUserInfo() );
                $this->assertTrue( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertFalse( $info->wasPersisted() );
                $this->assertTrue( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -150,6 +153,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $anonInfo, $info->getUserInfo() );
                $this->assertFalse( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertTrue( $info->wasPersisted() );
                $this->assertFalse( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -165,6 +169,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $userInfo, $info->getUserInfo() );
                $this->assertFalse( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertFalse( $info->wasPersisted() );
                $this->assertTrue( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -180,6 +185,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertSame( $userInfo, $info->getUserInfo() );
                $this->assertFalse( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertTrue( $info->wasPersisted() );
                $this->assertFalse( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
@@ -231,6 +237,25 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( SessionInfo::MIN_PRIORITY + 5, $info->getPriority() );
                $this->assertTrue( $info->isIdSafe() );
 
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY + 5, [
+                       'id' => $id,
+                       'forceUse' => true,
+               ] );
+               $this->assertFalse( $info->forceUse(), 'no provider' );
+
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY + 5, [
+                       'provider' => $provider,
+                       'forceUse' => true,
+               ] );
+               $this->assertFalse( $info->forceUse(), 'no id' );
+
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY + 5, [
+                       'provider' => $provider,
+                       'id' => $id,
+                       'forceUse' => true,
+               ] );
+               $this->assertTrue( $info->forceUse(), 'correct use' );
+
                $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
                        'id' => $id,
                        'forceHTTPS' => 1,
@@ -242,6 +267,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                        'provider' => $provider,
                        'userInfo' => $userInfo,
                        'idIsSafe' => true,
+                       'forceUse' => true,
                        'persisted' => true,
                        'remembered' => true,
                        'forceHTTPS' => true,
@@ -255,6 +281,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( $provider, $info->getProvider() );
                $this->assertSame( $userInfo, $info->getUserInfo() );
                $this->assertTrue( $info->isIdSafe() );
+               $this->assertTrue( $info->forceUse() );
                $this->assertTrue( $info->wasPersisted() );
                $this->assertTrue( $info->wasRemembered() );
                $this->assertTrue( $info->forceHTTPS() );
@@ -265,6 +292,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                        'provider' => $provider2,
                        'userInfo' => $unverifiedUserInfo,
                        'idIsSafe' => false,
+                       'forceUse' => false,
                        'persisted' => false,
                        'remembered' => false,
                        'forceHTTPS' => false,
@@ -276,6 +304,7 @@ class SessionInfoTest extends MediaWikiTestCase {
                $this->assertSame( $provider2, $info->getProvider() );
                $this->assertSame( $unverifiedUserInfo, $info->getUserInfo() );
                $this->assertFalse( $info->isIdSafe() );
+               $this->assertFalse( $info->forceUse() );
                $this->assertFalse( $info->wasPersisted() );
                $this->assertFalse( $info->wasRemembered() );
                $this->assertFalse( $info->forceHTTPS() );
index d04d7ec..5f387ea 100644 (file)
@@ -642,6 +642,35 @@ class SessionManagerTest extends MediaWikiTestCase {
                }
        }
 
+       public function testInvalidateSessionsForUser() {
+               $user = User::newFromName( 'UTSysop' );
+               $manager = $this->getManager();
+
+               $providerBuilder = $this->getMockBuilder( 'DummySessionProvider' )
+                       ->setMethods( [ 'invalidateSessionsForUser', '__toString' ] );
+
+               $provider1 = $providerBuilder->getMock();
+               $provider1->expects( $this->once() )->method( 'invalidateSessionsForUser' )
+                       ->with( $this->identicalTo( $user ) );
+               $provider1->expects( $this->any() )->method( '__toString' )
+                       ->will( $this->returnValue( 'MockProvider1' ) );
+
+               $provider2 = $providerBuilder->getMock();
+               $provider2->expects( $this->once() )->method( 'invalidateSessionsForUser' )
+                       ->with( $this->identicalTo( $user ) );
+               $provider2->expects( $this->any() )->method( '__toString' )
+                       ->will( $this->returnValue( 'MockProvider2' ) );
+
+               $this->config->set( 'SessionProviders', [
+                       $this->objectCacheDef( $provider1 ),
+                       $this->objectCacheDef( $provider2 ),
+               ] );
+
+               $oldToken = $user->getToken( true );
+               $manager->invalidateSessionsForUser( $user );
+               $this->assertNotEquals( $oldToken, $user->getToken() );
+       }
+
        public function testGetVaryHeaders() {
                $manager = $this->getManager();
 
@@ -1756,5 +1785,21 @@ class SessionManagerTest extends MediaWikiTestCase {
                        [ LogLevel::WARNING, 'Session "{session}": Hook aborted' ],
                ], $logger->getBuffer() );
                $logger->clearBuffer();
+               $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionCheckInfo' => [] ] );
+
+               // forceUse deletes bad backend data
+               $this->store->setSessionMeta( $id, [ 'userToken' => 'Bad' ] + $metadata );
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
+                       'provider' => $provider,
+                       'id' => $id,
+                       'userInfo' => $userInfo,
+                       'forceUse' => true,
+               ] );
+               $this->assertTrue( $loadSessionInfoFromStore( $info ) );
+               $this->assertFalse( $this->store->getSession( $id ) );
+               $this->assertSame( [
+                       [ LogLevel::WARNING, 'Session "{session}": User token mismatch' ],
+               ], $logger->getBuffer() );
+               $logger->clearBuffer();
        }
 }
index 18b1efd..f80baf2 100644 (file)
@@ -27,6 +27,8 @@ class SessionProviderTest extends MediaWikiTestCase {
                $this->assertSame( $manager, $priv->manager );
                $this->assertSame( $manager, $provider->getManager() );
 
+               $provider->invalidateSessionsForUser( new \User );
+
                $this->assertSame( [], $provider->getVaryHeaders() );
                $this->assertSame( [], $provider->getVaryCookies() );
                $this->assertSame( null, $provider->suggestLoginUsername( new \FauxRequest ) );
index e87f41d..3815416 100644 (file)
@@ -267,21 +267,9 @@ class SessionTest extends MediaWikiTestCase {
        }
 
        public function testTokens() {
-               $rc = new \ReflectionClass( Session::class );
-               if ( !method_exists( $rc, 'newInstanceWithoutConstructor' ) ) {
-                       $this->markTestSkipped(
-                               'ReflectionClass::newInstanceWithoutConstructor isn\'t available'
-                       );
-               }
-
-               // Instead of actually constructing the Session, we use reflection to
-               // bypass the constructor and plug a mock SessionBackend into the
-               // private fields to avoid having to actually create a SessionBackend.
-               $backend = new DummySessionBackend;
-               $session = $rc->newInstanceWithoutConstructor();
+               $session = TestUtils::getDummySession();
                $priv = \TestingAccessWrapper::newFromObject( $session );
-               $priv->backend = $backend;
-               $priv->index = 42;
+               $backend = $priv->backend;
 
                $token = \TestingAccessWrapper::newFromObject( $session->getToken() );
                $this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
@@ -313,4 +301,72 @@ class SessionTest extends MediaWikiTestCase {
                $this->assertArrayNotHasKey( 'wsTokenSecrets', $backend->data );
 
        }
+
+       /**
+        * @dataProvider provideSecretsRoundTripping
+        * @param mixed $data
+        */
+       public function testSecretsRoundTripping( $data ) {
+               $session = TestUtils::getDummySession();
+
+               // Simple round-trip
+               $session->setSecret( 'secret', $data );
+               $this->assertNotEquals( $data, $session->get( 'secret' ) );
+               $this->assertEquals( $data, $session->getSecret( 'secret', 'defaulted' ) );
+       }
+
+       public static function provideSecretsRoundTripping() {
+               return [
+                       [ 'Foobar' ],
+                       [ 42 ],
+                       [ [ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
+                       [ (object)[ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
+                       [ true ],
+                       [ false ],
+                       [ null ],
+               ];
+       }
+
+       public function testSecrets() {
+               $logger = new \TestLogger;
+               $session = TestUtils::getDummySession( null, -1, $logger );
+
+               // Simple defaulting
+               $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
+
+               // Bad encrypted data
+               $session->set( 'test', 'foobar' );
+               $logger->setCollect( true );
+               $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
+               $logger->setCollect( false );
+               $this->assertSame( [
+                       [ LogLevel::WARNING, 'Invalid sealed-secret format' ]
+               ], $logger->getBuffer() );
+               $logger->clearBuffer();
+
+               // Tampered data
+               $session->setSecret( 'test', 'foobar' );
+               $encrypted = $session->get( 'test' );
+               $session->set( 'test', $encrypted . 'x' );
+               $logger->setCollect( true );
+               $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
+               $logger->setCollect( false );
+               $this->assertSame( [
+                       [ LogLevel::WARNING, 'Sealed secret has been tampered with, aborting.' ]
+               ], $logger->getBuffer() );
+               $logger->clearBuffer();
+
+               // Unserializable data
+               $iv = \MWCryptRand::generate( 16, true );
+               list( $encKey, $hmacKey ) = \TestingAccessWrapper::newFromObject( $session )->getSecretKeys();
+               $ciphertext = openssl_encrypt( 'foobar', 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, $iv );
+               $sealed = base64_encode( $iv ) . '.' . base64_encode( $ciphertext );
+               $hmac = hash_hmac( 'sha256', $sealed, $hmacKey, true );
+               $encrypted = base64_encode( $hmac ) . '.' . $sealed;
+               $session->set( 'test', $encrypted );
+               \MediaWiki\suppressWarnings();
+               $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
+               \MediaWiki\restoreWarnings();
+       }
+
 }
index a4e4df1..4ea9686 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use MediaWiki\MediaWikiServices;
+
 /**
  * Test class for SpecialSearch class
  * Copyright © 2012, Antoine Musso
@@ -6,7 +8,6 @@
  * @author Antoine Musso
  * @group Database
  */
-
 class SpecialSearchTest extends MediaWikiTestCase {
 
        /**
@@ -57,7 +58,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
        }
 
        public static function provideSearchOptionsTests() {
-               $defaultNS = SearchEngine::defaultNamespaces();
+               $defaultNS = MediaWikiServices::getInstance()->getSearchEngineConfig()->defaultNamespaces();
                $EMPTY_REQUEST = [];
                $NO_USER_PREF = null;
 
index 0bb0afe..40065f5 100644 (file)
@@ -87,13 +87,14 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
 
        public static function provideFormat() {
                return [
-                       [ NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ],
-                       [ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ],
-                       [ false, 'Hansi_Maier', '', 'en', 'Hansi Maier' ],
+                       [ NS_MAIN, 'Foo_Bar', '', '', 'en', 'Foo Bar' ],
+                       [ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', '', 'en', 'User:Hansi Maier#stuff and so on' ],
+                       [ false, 'Hansi_Maier', '', '', 'en', 'Hansi Maier' ],
                        [
                                NS_USER_TALK,
                                'hansi__maier',
                                '',
+                               '',
                                'en',
                                'User talk:hansi  maier',
                                'User talk:Hansi maier'
@@ -101,20 +102,23 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
 
                        // getGenderCache() provides a mock that considers first
                        // names ending in "a" to be female.
-                       [ NS_USER, 'Lisa_Müller', '', 'de', 'Benutzerin:Lisa Müller' ],
+                       [ NS_USER, 'Lisa_Müller', '', '', 'de', 'Benutzerin:Lisa Müller' ],
+                       [ NS_MAIN, 'FooBar', '', 'remotetestiw', 'en', 'remotetestiw:FooBar' ],
                ];
        }
 
        /**
         * @dataProvider provideFormat
         */
-       public function testFormat( $namespace, $text, $fragment, $lang, $expected, $normalized = null ) {
+       public function testFormat( $namespace, $text, $fragment, $interwiki, $lang, $expected,
+               $normalized = null
+       ) {
                if ( $normalized === null ) {
                        $normalized = $expected;
                }
 
                $codec = $this->makeCodec( $lang );
-               $actual = $codec->formatTitle( $namespace, $text, $fragment );
+               $actual = $codec->formatTitle( $namespace, $text, $fragment, $interwiki );
 
                $this->assertEquals( $expected, $actual, 'formatted' );
 
@@ -123,7 +127,8 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $actual2 = $codec->formatTitle(
                        $parsed->getNamespace(),
                        $parsed->getText(),
-                       $parsed->getFragment()
+                       $parsed->getFragment(),
+                       $parsed->getInterwiki()
                );
 
                $this->assertEquals( $normalized, $actual2, 'normalized after round trip' );
@@ -174,6 +179,36 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
+       public static function provideGetPrefixedDBkey() {
+               return [
+                       [ NS_MAIN, 'Foo_Bar', '', '', 'en', 'Foo_Bar' ],
+                       [ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', '', 'en', 'User:Hansi_Maier' ],
+
+                       // No capitalization or normalization is applied while formatting!
+                       [ NS_USER_TALK, 'hansi__maier', '', '', 'en', 'User_talk:hansi__maier' ],
+
+                       // getGenderCache() provides a mock that considers first
+                       // names ending in "a" to be female.
+                       [ NS_USER, 'Lisa_Müller', '', '', 'de', 'Benutzerin:Lisa_Müller' ],
+
+                       [ NS_MAIN, 'Remote_page', '', 'remotetestiw', 'en', 'remotetestiw:Remote_page' ]
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetPrefixedDBkey
+        */
+       public function testGetPrefixedDBkey( $namespace, $dbkey, $fragment,
+               $interwiki, $lang, $expected
+       ) {
+               $codec = $this->makeCodec( $lang );
+               $title = new TitleValue( $namespace, $dbkey, $fragment, $interwiki );
+
+               $actual = $codec->getPrefixedDBkey( $title );
+
+               $this->assertEquals( $expected, $actual );
+       }
+
        public static function provideGetFullText() {
                return [
                        [ NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ],
@@ -293,7 +328,6 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
 
                        [ 'Talk:File:Foo.jpg' ],
                        [ 'Talk:localtestiw:Foo' ],
-                       [ 'remotetestiw:Foo' ],
                        [ '::1' ], // only valid in user namespace
                        [ 'User::x' ], // leading ":" in a user name is only valid of IPv6 addresses
 
index 913253b..4dbda74 100644 (file)
@@ -28,49 +28,58 @@ class TitleValueTest extends MediaWikiTestCase {
 
        public function goodConstructorProvider() {
                return [
-                       [ NS_USER, 'TestThis', 'stuff', true ],
-                       [ NS_USER, 'TestThis', '', false ],
+                       [ NS_USER, 'TestThis', 'stuff', '', true, false ],
+                       [ NS_USER, 'TestThis', '', 'baz', false, true ],
                ];
        }
 
        /**
         * @dataProvider goodConstructorProvider
         */
-       public function testConstruction( $ns, $text, $fragment, $hasFragment ) {
-               $title = new TitleValue( $ns, $text, $fragment );
+       public function testConstruction( $ns, $text, $fragment, $interwiki, $hasFragment,
+               $hasInterwiki
+       ) {
+               $title = new TitleValue( $ns, $text, $fragment, $interwiki );
 
                $this->assertEquals( $ns, $title->getNamespace() );
+               $this->assertTrue( $title->inNamespace( $ns ) );
                $this->assertEquals( $text, $title->getText() );
                $this->assertEquals( $fragment, $title->getFragment() );
                $this->assertEquals( $hasFragment, $title->hasFragment() );
+               $this->assertEquals( $interwiki, $title->getInterwiki() );
+               $this->assertEquals( $hasInterwiki, $title->isExternal() );
        }
 
        public function badConstructorProvider() {
                return [
-                       [ 'foo', 'title', 'fragment' ],
-                       [ null, 'title', 'fragment' ],
-                       [ 2.3, 'title', 'fragment' ],
+                       [ 'foo', 'title', 'fragment', '' ],
+                       [ null, 'title', 'fragment', '' ],
+                       [ 2.3, 'title', 'fragment', '' ],
 
-                       [ NS_MAIN, 5, 'fragment' ],
-                       [ NS_MAIN, null, 'fragment' ],
-                       [ NS_MAIN, '', 'fragment' ],
-                       [ NS_MAIN, 'foo bar', '' ],
-                       [ NS_MAIN, 'bar_', '' ],
-                       [ NS_MAIN, '_foo', '' ],
-                       [ NS_MAIN, ' eek ', '' ],
+                       [ NS_MAIN, 5, 'fragment', '' ],
+                       [ NS_MAIN, null, 'fragment', '' ],
+                       [ NS_MAIN, '', 'fragment', '' ],
+                       [ NS_MAIN, 'foo bar', '', '' ],
+                       [ NS_MAIN, 'bar_', '', '' ],
+                       [ NS_MAIN, '_foo', '', '' ],
+                       [ NS_MAIN, ' eek ', '', '' ],
 
-                       [ NS_MAIN, 'title', 5 ],
-                       [ NS_MAIN, 'title', null ],
-                       [ NS_MAIN, 'title', [] ],
+                       [ NS_MAIN, 'title', 5, '' ],
+                       [ NS_MAIN, 'title', null, '' ],
+                       [ NS_MAIN, 'title', [], '' ],
+
+                       [ NS_MAIN, 'title', '', 5 ],
+                       [ NS_MAIN, 'title', null, 5 ],
+                       [ NS_MAIN, 'title', [], 5 ],
                ];
        }
 
        /**
         * @dataProvider badConstructorProvider
         */
-       public function testConstructionErrors( $ns, $text, $fragment ) {
+       public function testConstructionErrors( $ns, $text, $fragment, $interwiki ) {
                $this->setExpectedException( 'InvalidArgumentException' );
-               new TitleValue( $ns, $text, $fragment );
+               new TitleValue( $ns, $text, $fragment, $interwiki );
        }
 
        public function fragmentTitleProvider() {
index 77690cd..d876c45 100755 (executable)
@@ -139,6 +139,10 @@ class PHPUnitMaintClass extends Maintenance {
                // may break testing against floating point values
                // treated with PHP's serialize()
                ini_set( 'serialize_precision', 17 );
+
+               // TODO: we should call MediaWikiTestCase::prepareServices( new GlobalVarConfig() ) here.
+               // But PHPUnit may not be loaded yet, so we have to wait until just
+               // before PHPUnit_TextUI_Command::main() is executed at the end of this file.
        }
 
        public function execute() {
@@ -237,4 +241,9 @@ echo defined( 'HHVM_VERSION' ) ?
        'Using HHVM ' . HHVM_VERSION . ' (' . PHP_VERSION . ")\n" :
        'Using PHP ' . PHP_VERSION . "\n";
 
+// Prepare global services for unit tests.
+// FIXME: this should be done in the finalSetup() method,
+// but PHPUnit may not have been loaded at that point.
+MediaWikiTestCase::prepareServices( new GlobalVarConfig() );
+
 $wgPhpUnitClass::main();
index 152c2eb..5d2f37e 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
+use Psr\Log\LoggerInterface;
 
 /**
  * @covers MediaWikiTestCase
@@ -98,6 +100,36 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
                $this->stashMwGlobals( self::GLOBAL_KEY_NONEXISTING );
        }
 
+       public function testOverrideMwServices() {
+               $initialServices = MediaWikiServices::getInstance();
+
+               $this->overrideMwServices();
+               $this->assertNotSame( $initialServices, MediaWikiServices::getInstance() );
+
+               $this->tearDown();
+               $this->assertSame( $initialServices, MediaWikiServices::getInstance() );
+       }
+
+       public function testSetService() {
+               $initialServices = MediaWikiServices::getInstance();
+               $initialService = $initialServices->getDBLoadBalancer();
+               $mockService = $this->getMockBuilder( LoadBalancer::class )
+                       ->disableOriginalConstructor()->getMock();
+
+               $this->setService( 'DBLoadBalancer', $mockService );
+               $this->assertNotSame( $initialServices, MediaWikiServices::getInstance() );
+               $this->assertNotSame(
+                       $initialService,
+                       MediaWikiServices::getInstance()->getDBLoadBalancer()
+               );
+               $this->assertSame( $mockService, MediaWikiServices::getInstance()->getDBLoadBalancer() );
+
+               $this->tearDown();
+               $this->assertSame( $initialServices, MediaWikiServices::getInstance() );
+               $this->assertNotSame( $mockService, MediaWikiServices::getInstance()->getDBLoadBalancer() );
+               $this->assertSame( $initialService, MediaWikiServices::getInstance()->getDBLoadBalancer() );
+       }
+
        /**
         * @covers MediaWikiTestCase::setLogger
         * @covers MediaWikiTestCase::restoreLogger
@@ -105,7 +137,7 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
        public function testLoggersAreRestoredOnTearDown() {
                // replacing an existing logger
                $logger1 = LoggerFactory::getInstance( 'foo' );
-               $this->setLogger( 'foo', $this->getMock( '\Psr\Log\LoggerInterface' ) );
+               $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
                $logger2 = LoggerFactory::getInstance( 'foo' );
                $this->tearDown();
                $logger3 = LoggerFactory::getInstance( 'foo' );
@@ -114,7 +146,7 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
                $this->assertNotSame( $logger1, $logger2 );
 
                // replacing a non-existing logger
-               $this->setLogger( 'bar', $this->getMock( '\Psr\Log\LoggerInterface' ) );
+               $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
                $logger1 = LoggerFactory::getInstance( 'bar' );
                $this->tearDown();
                $logger2 = LoggerFactory::getInstance( 'bar' );
@@ -124,8 +156,8 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
 
                // replacing same logger twice
                $logger1 = LoggerFactory::getInstance( 'baz' );
-               $this->setLogger( 'baz', $this->getMock( '\Psr\Log\LoggerInterface' ) );
-               $this->setLogger( 'baz', $this->getMock( '\Psr\Log\LoggerInterface' ) );
+               $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
+               $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
                $this->tearDown();
                $logger2 = LoggerFactory::getInstance( 'baz' );